зеркало из https://github.com/microsoft/git.git
Merge branch 'ef/msys-imap'
* ef/msys-imap: Windows: use BLK_SHA1 again MSVC: Enable OpenSSL, and translate -lcrypto mingw: enable OpenSSL mingw: wrap SSL_set_(w|r)fd to call _get_osfhandle imap-send: build imap-send on Windows imap-send: fix compilation-error on Windows imap-send: use run-command API for tunneling imap-send: use separate read and write fds imap-send: remove useless uid code
This commit is contained in:
Коммит
a62e733be6
8
Makefile
8
Makefile
|
@ -358,6 +358,7 @@ EXTRA_PROGRAMS =
|
|||
PROGRAMS += $(EXTRA_PROGRAMS)
|
||||
PROGRAMS += git-fast-import$X
|
||||
PROGRAMS += git-hash-object$X
|
||||
PROGRAMS += git-imap-send$X
|
||||
PROGRAMS += git-index-pack$X
|
||||
PROGRAMS += git-merge-index$X
|
||||
PROGRAMS += git-merge-tree$X
|
||||
|
@ -906,7 +907,7 @@ ifdef MSVC
|
|||
GIT_VERSION := $(GIT_VERSION).MSVC
|
||||
pathsep = ;
|
||||
NO_PREAD = YesPlease
|
||||
NO_OPENSSL = YesPlease
|
||||
NEEDS_CRYPTO_WITH_SSL = YesPlease
|
||||
NO_LIBGEN_H = YesPlease
|
||||
NO_SYMLINK_HEAD = YesPlease
|
||||
NO_IPV6 = YesPlease
|
||||
|
@ -936,6 +937,7 @@ ifdef MSVC
|
|||
NO_REGEX = YesPlease
|
||||
NO_CURL = YesPlease
|
||||
NO_PTHREADS = YesPlease
|
||||
BLK_SHA1 = YesPlease
|
||||
|
||||
CC = compat/vcbuild/scripts/clink.pl
|
||||
AR = compat/vcbuild/scripts/lib.pl
|
||||
|
@ -958,7 +960,7 @@ else
|
|||
ifneq (,$(findstring MINGW,$(uname_S)))
|
||||
pathsep = ;
|
||||
NO_PREAD = YesPlease
|
||||
NO_OPENSSL = YesPlease
|
||||
NEEDS_CRYPTO_WITH_SSL = YesPlease
|
||||
NO_LIBGEN_H = YesPlease
|
||||
NO_SYMLINK_HEAD = YesPlease
|
||||
NO_IPV6 = YesPlease
|
||||
|
@ -985,6 +987,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
|
|||
UNRELIABLE_FSTAT = UnfortunatelyYes
|
||||
OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo
|
||||
NO_REGEX = YesPlease
|
||||
BLK_SHA1 = YesPlease
|
||||
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch
|
||||
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
|
||||
COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o
|
||||
|
@ -1082,7 +1085,6 @@ EXTLIBS += -lz
|
|||
|
||||
ifndef NO_POSIX_ONLY_PROGRAMS
|
||||
PROGRAMS += git-daemon$X
|
||||
PROGRAMS += git-imap-send$X
|
||||
endif
|
||||
ifndef NO_OPENSSL
|
||||
OPENSSL_LIBSSL = -lssl
|
||||
|
|
|
@ -124,6 +124,27 @@ static inline int waitpid(pid_t pid, int *status, unsigned options)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#ifndef NO_OPENSSL
|
||||
#include <openssl/ssl.h>
|
||||
static inline int mingw_SSL_set_fd(SSL *ssl, int fd)
|
||||
{
|
||||
return SSL_set_fd(ssl, _get_osfhandle(fd));
|
||||
}
|
||||
#define SSL_set_fd mingw_SSL_set_fd
|
||||
|
||||
static inline int mingw_SSL_set_rfd(SSL *ssl, int fd)
|
||||
{
|
||||
return SSL_set_rfd(ssl, _get_osfhandle(fd));
|
||||
}
|
||||
#define SSL_set_rfd mingw_SSL_set_rfd
|
||||
|
||||
static inline int mingw_SSL_set_wfd(SSL *ssl, int fd)
|
||||
{
|
||||
return SSL_set_wfd(ssl, _get_osfhandle(fd));
|
||||
}
|
||||
#define SSL_set_wfd mingw_SSL_set_wfd
|
||||
#endif
|
||||
|
||||
/*
|
||||
* implementations of missing functions
|
||||
*/
|
||||
|
|
|
@ -29,6 +29,9 @@ while (@ARGV) {
|
|||
push(@args, "zlib.lib");
|
||||
} elsif ("$arg" eq "-liconv") {
|
||||
push(@args, "iconv.lib");
|
||||
} elsif ("$arg" eq "-lcrypto") {
|
||||
push(@args, "libeay32.lib");
|
||||
push(@args, "ssleay32.lib");
|
||||
} elsif ("$arg" =~ /^-L/ && "$arg" ne "-LTCG") {
|
||||
$arg =~ s/^-L/-LIBPATH:/;
|
||||
push(@args, $arg);
|
||||
|
|
|
@ -315,6 +315,9 @@ sub handleLinkLine
|
|||
$appout = shift @parts;
|
||||
} elsif ("$part" eq "-lz") {
|
||||
push(@libs, "zlib.lib");
|
||||
} elsif ("$part" eq "-lcrypto") {
|
||||
push(@libs, "libeay32.lib");
|
||||
push(@libs, "ssleay32.lib");
|
||||
} elsif ($part =~ /^-/) {
|
||||
push(@lflags, $part);
|
||||
} elsif ($part =~ /\.(a|lib)$/) {
|
||||
|
|
226
imap-send.c
226
imap-send.c
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "cache.h"
|
||||
#include "exec_cmd.h"
|
||||
#include "run-command.h"
|
||||
#ifdef NO_OPENSSL
|
||||
typedef void *SSL;
|
||||
#endif
|
||||
|
@ -93,6 +94,7 @@ struct msg_data {
|
|||
unsigned int crlf:1;
|
||||
};
|
||||
|
||||
#undef DRV_OK
|
||||
#define DRV_OK 0
|
||||
#define DRV_MSG_BAD -1
|
||||
#define DRV_BOX_BAD -2
|
||||
|
@ -123,9 +125,6 @@ static int nfvasprintf(char **strp, const char *fmt, va_list ap)
|
|||
return len;
|
||||
}
|
||||
|
||||
static void arc4_init(void);
|
||||
static unsigned char arc4_getbyte(void);
|
||||
|
||||
struct imap_server_conf {
|
||||
char *name;
|
||||
char *tunnel;
|
||||
|
@ -154,7 +153,7 @@ struct imap_list {
|
|||
};
|
||||
|
||||
struct imap_socket {
|
||||
int fd;
|
||||
int fd[2];
|
||||
SSL *ssl;
|
||||
};
|
||||
|
||||
|
@ -308,8 +307,12 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve
|
|||
ssl_socket_perror("SSL_new");
|
||||
return -1;
|
||||
}
|
||||
if (!SSL_set_fd(sock->ssl, sock->fd)) {
|
||||
ssl_socket_perror("SSL_set_fd");
|
||||
if (!SSL_set_rfd(sock->ssl, sock->fd[0])) {
|
||||
ssl_socket_perror("SSL_set_rfd");
|
||||
return -1;
|
||||
}
|
||||
if (!SSL_set_wfd(sock->ssl, sock->fd[1])) {
|
||||
ssl_socket_perror("SSL_set_wfd");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -331,11 +334,12 @@ static int socket_read(struct imap_socket *sock, char *buf, int len)
|
|||
n = SSL_read(sock->ssl, buf, len);
|
||||
else
|
||||
#endif
|
||||
n = xread(sock->fd, buf, len);
|
||||
n = xread(sock->fd[0], buf, len);
|
||||
if (n <= 0) {
|
||||
socket_perror("read", sock, n);
|
||||
close(sock->fd);
|
||||
sock->fd = -1;
|
||||
close(sock->fd[0]);
|
||||
close(sock->fd[1]);
|
||||
sock->fd[0] = sock->fd[1] = -1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
@ -348,11 +352,12 @@ static int socket_write(struct imap_socket *sock, const char *buf, int len)
|
|||
n = SSL_write(sock->ssl, buf, len);
|
||||
else
|
||||
#endif
|
||||
n = write_in_full(sock->fd, buf, len);
|
||||
n = write_in_full(sock->fd[1], buf, len);
|
||||
if (n != len) {
|
||||
socket_perror("write", sock, n);
|
||||
close(sock->fd);
|
||||
sock->fd = -1;
|
||||
close(sock->fd[0]);
|
||||
close(sock->fd[1]);
|
||||
sock->fd[0] = sock->fd[1] = -1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
@ -365,7 +370,8 @@ static void socket_shutdown(struct imap_socket *sock)
|
|||
SSL_free(sock->ssl);
|
||||
}
|
||||
#endif
|
||||
close(sock->fd);
|
||||
close(sock->fd[0]);
|
||||
close(sock->fd[1]);
|
||||
}
|
||||
|
||||
/* simple line buffering */
|
||||
|
@ -493,52 +499,6 @@ static int nfsnprintf(char *buf, int blen, const char *fmt, ...)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct {
|
||||
unsigned char i, j, s[256];
|
||||
} rs;
|
||||
|
||||
static void arc4_init(void)
|
||||
{
|
||||
int i, fd;
|
||||
unsigned char j, si, dat[128];
|
||||
|
||||
if ((fd = open("/dev/urandom", O_RDONLY)) < 0 && (fd = open("/dev/random", O_RDONLY)) < 0) {
|
||||
fprintf(stderr, "Fatal: no random number source available.\n");
|
||||
exit(3);
|
||||
}
|
||||
if (read_in_full(fd, dat, 128) != 128) {
|
||||
fprintf(stderr, "Fatal: cannot read random number source.\n");
|
||||
exit(3);
|
||||
}
|
||||
close(fd);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
rs.s[i] = i;
|
||||
for (i = j = 0; i < 256; i++) {
|
||||
si = rs.s[i];
|
||||
j += si + dat[i & 127];
|
||||
rs.s[i] = rs.s[j];
|
||||
rs.s[j] = si;
|
||||
}
|
||||
rs.i = rs.j = 0;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
arc4_getbyte();
|
||||
}
|
||||
|
||||
static unsigned char arc4_getbyte(void)
|
||||
{
|
||||
unsigned char si, sj;
|
||||
|
||||
rs.i++;
|
||||
si = rs.s[rs.i];
|
||||
rs.j += si;
|
||||
sj = rs.s[rs.j];
|
||||
rs.s[rs.i] = sj;
|
||||
rs.s[rs.j] = si;
|
||||
return rs.s[(si + sj) & 0xff];
|
||||
}
|
||||
|
||||
static struct imap_cmd *v_issue_imap_cmd(struct imap_store *ctx,
|
||||
struct imap_cmd_cb *cb,
|
||||
const char *fmt, va_list ap)
|
||||
|
@ -964,7 +924,7 @@ static void imap_close_server(struct imap_store *ictx)
|
|||
{
|
||||
struct imap *imap = ictx->imap;
|
||||
|
||||
if (imap->buf.sock.fd != -1) {
|
||||
if (imap->buf.sock.fd[0] != -1) {
|
||||
imap_exec(ictx, NULL, "LOGOUT");
|
||||
socket_shutdown(&imap->buf.sock);
|
||||
}
|
||||
|
@ -986,40 +946,35 @@ static struct store *imap_open_store(struct imap_server_conf *srvc)
|
|||
struct imap_store *ctx;
|
||||
struct imap *imap;
|
||||
char *arg, *rsp;
|
||||
int s = -1, a[2], preauth;
|
||||
pid_t pid;
|
||||
int s = -1, preauth;
|
||||
|
||||
ctx = xcalloc(sizeof(*ctx), 1);
|
||||
|
||||
ctx->imap = imap = xcalloc(sizeof(*imap), 1);
|
||||
imap->buf.sock.fd = -1;
|
||||
imap->buf.sock.fd[0] = imap->buf.sock.fd[1] = -1;
|
||||
imap->in_progress_append = &imap->in_progress;
|
||||
|
||||
/* open connection to IMAP server */
|
||||
|
||||
if (srvc->tunnel) {
|
||||
const char *argv[4];
|
||||
struct child_process tunnel = {0};
|
||||
|
||||
imap_info("Starting tunnel '%s'... ", srvc->tunnel);
|
||||
|
||||
if (socketpair(PF_UNIX, SOCK_STREAM, 0, a)) {
|
||||
perror("socketpair");
|
||||
exit(1);
|
||||
}
|
||||
argv[0] = "sh";
|
||||
argv[1] = "-c";
|
||||
argv[2] = srvc->tunnel;
|
||||
argv[3] = NULL;
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0)
|
||||
_exit(127);
|
||||
if (!pid) {
|
||||
if (dup2(a[0], 0) == -1 || dup2(a[0], 1) == -1)
|
||||
_exit(127);
|
||||
close(a[0]);
|
||||
close(a[1]);
|
||||
execl("/bin/sh", "sh", "-c", srvc->tunnel, NULL);
|
||||
_exit(127);
|
||||
}
|
||||
tunnel.argv = argv;
|
||||
tunnel.in = -1;
|
||||
tunnel.out = -1;
|
||||
if (start_command(&tunnel))
|
||||
die("cannot start proxy %s", argv[0]);
|
||||
|
||||
close(a[0]);
|
||||
|
||||
imap->buf.sock.fd = a[1];
|
||||
imap->buf.sock.fd[0] = tunnel.out;
|
||||
imap->buf.sock.fd[1] = tunnel.in;
|
||||
|
||||
imap_info("ok\n");
|
||||
} else {
|
||||
|
@ -1096,7 +1051,8 @@ static struct store *imap_open_store(struct imap_server_conf *srvc)
|
|||
goto bail;
|
||||
}
|
||||
|
||||
imap->buf.sock.fd = s;
|
||||
imap->buf.sock.fd[0] = s;
|
||||
imap->buf.sock.fd[1] = dup(s);
|
||||
|
||||
if (srvc->use_ssl &&
|
||||
ssl_socket_connect(&imap->buf.sock, 0, srvc->ssl_verify)) {
|
||||
|
@ -1202,88 +1158,20 @@ static int imap_make_flags(int flags, char *buf)
|
|||
return d;
|
||||
}
|
||||
|
||||
#define TUIDL 8
|
||||
|
||||
static int imap_store_msg(struct store *gctx, struct msg_data *data, int *uid)
|
||||
static int imap_store_msg(struct store *gctx, struct msg_data *data)
|
||||
{
|
||||
struct imap_store *ctx = (struct imap_store *)gctx;
|
||||
struct imap *imap = ctx->imap;
|
||||
struct imap_cmd_cb cb;
|
||||
char *fmap, *buf;
|
||||
const char *prefix, *box;
|
||||
int ret, i, j, d, len, extra, nocr;
|
||||
int start, sbreak = 0, ebreak = 0;
|
||||
char flagstr[128], tuid[TUIDL * 2 + 1];
|
||||
int ret, d;
|
||||
char flagstr[128];
|
||||
|
||||
memset(&cb, 0, sizeof(cb));
|
||||
|
||||
fmap = data->data;
|
||||
len = data->len;
|
||||
nocr = !data->crlf;
|
||||
extra = 0, i = 0;
|
||||
if (!CAP(UIDPLUS) && uid) {
|
||||
nloop:
|
||||
start = i;
|
||||
while (i < len)
|
||||
if (fmap[i++] == '\n') {
|
||||
extra += nocr;
|
||||
if (i - 2 + nocr == start) {
|
||||
sbreak = ebreak = i - 2 + nocr;
|
||||
goto mktid;
|
||||
}
|
||||
if (!memcmp(fmap + start, "X-TUID: ", 8)) {
|
||||
extra -= (ebreak = i) - (sbreak = start) + nocr;
|
||||
goto mktid;
|
||||
}
|
||||
goto nloop;
|
||||
}
|
||||
/* invalid message */
|
||||
free(fmap);
|
||||
return DRV_MSG_BAD;
|
||||
mktid:
|
||||
for (j = 0; j < TUIDL; j++)
|
||||
sprintf(tuid + j * 2, "%02x", arc4_getbyte());
|
||||
extra += 8 + TUIDL * 2 + 2;
|
||||
}
|
||||
if (nocr)
|
||||
for (; i < len; i++)
|
||||
if (fmap[i] == '\n')
|
||||
extra++;
|
||||
|
||||
cb.dlen = len + extra;
|
||||
buf = cb.data = xmalloc(cb.dlen);
|
||||
i = 0;
|
||||
if (!CAP(UIDPLUS) && uid) {
|
||||
if (nocr) {
|
||||
for (; i < sbreak; i++)
|
||||
if (fmap[i] == '\n') {
|
||||
*buf++ = '\r';
|
||||
*buf++ = '\n';
|
||||
} else
|
||||
*buf++ = fmap[i];
|
||||
} else {
|
||||
memcpy(buf, fmap, sbreak);
|
||||
buf += sbreak;
|
||||
}
|
||||
memcpy(buf, "X-TUID: ", 8);
|
||||
buf += 8;
|
||||
memcpy(buf, tuid, TUIDL * 2);
|
||||
buf += TUIDL * 2;
|
||||
*buf++ = '\r';
|
||||
*buf++ = '\n';
|
||||
i = ebreak;
|
||||
}
|
||||
if (nocr) {
|
||||
for (; i < len; i++)
|
||||
if (fmap[i] == '\n') {
|
||||
*buf++ = '\r';
|
||||
*buf++ = '\n';
|
||||
} else
|
||||
*buf++ = fmap[i];
|
||||
} else
|
||||
memcpy(buf, fmap + i, len - i);
|
||||
|
||||
free(fmap);
|
||||
cb.dlen = data->len;
|
||||
cb.data = xmalloc(cb.dlen);
|
||||
memcpy(cb.data, data->data, data->len);
|
||||
|
||||
d = 0;
|
||||
if (data->flags) {
|
||||
|
@ -1292,26 +1180,14 @@ static int imap_store_msg(struct store *gctx, struct msg_data *data, int *uid)
|
|||
}
|
||||
flagstr[d] = 0;
|
||||
|
||||
if (!uid) {
|
||||
box = gctx->conf->trash;
|
||||
prefix = ctx->prefix;
|
||||
cb.create = 1;
|
||||
if (ctx->trashnc)
|
||||
imap->caps = imap->rcaps & ~(1 << LITERALPLUS);
|
||||
} else {
|
||||
box = gctx->name;
|
||||
prefix = !strcmp(box, "INBOX") ? "" : ctx->prefix;
|
||||
cb.create = 0;
|
||||
}
|
||||
cb.ctx = uid;
|
||||
box = gctx->name;
|
||||
prefix = !strcmp(box, "INBOX") ? "" : ctx->prefix;
|
||||
cb.create = 0;
|
||||
ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\" %s", prefix, box, flagstr);
|
||||
imap->caps = imap->rcaps;
|
||||
if (ret != DRV_OK)
|
||||
return ret;
|
||||
if (!uid)
|
||||
ctx->trashnc = 0;
|
||||
else
|
||||
gctx->count++;
|
||||
gctx->count++;
|
||||
|
||||
return DRV_OK;
|
||||
}
|
||||
|
@ -1487,7 +1363,6 @@ int main(int argc, char **argv)
|
|||
{
|
||||
struct msg_data all_msgs, msg;
|
||||
struct store *ctx = NULL;
|
||||
int uid = 0;
|
||||
int ofs = 0;
|
||||
int r;
|
||||
int total, n = 0;
|
||||
|
@ -1495,9 +1370,6 @@ int main(int argc, char **argv)
|
|||
|
||||
git_extract_argv0_path(argv[0]);
|
||||
|
||||
/* init the random number generator */
|
||||
arc4_init();
|
||||
|
||||
setup_git_directory_gently(&nongit_ok);
|
||||
git_config(git_imap_config, NULL);
|
||||
|
||||
|
@ -1544,7 +1416,7 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
if (server.use_html)
|
||||
wrap_in_html(&msg);
|
||||
r = imap_store_msg(ctx, &msg, &uid);
|
||||
r = imap_store_msg(ctx, &msg);
|
||||
if (r != DRV_OK)
|
||||
break;
|
||||
n++;
|
||||
|
|
Загрузка…
Ссылка в новой задаче