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:
Junio C Hamano 2009-11-17 22:03:00 -08:00
commit a62e733be6
5 changed files with 81 additions and 180 deletions

View file

@ -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

View file

@ -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
*/

View file

@ -29,6 +29,9 @@
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);

View file

@ -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)$/) {

View file

@ -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++;