Merge branch 'ef/msys-imap'
authorJunio C Hamano <gitster@pobox.com>
Wed, 18 Nov 2009 06:03:00 +0000 (22:03 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 18 Nov 2009 06:03:00 +0000 (22:03 -0800)
* 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

1  2 
Makefile
compat/vcbuild/scripts/clink.pl
imap-send.c
diff --combined Makefile
index 35f5294cf0e246affc1c59cbc0bfdf91a50da18e,f666d2f1b78985cd41bfd597e40f7a3e1c22b372..457f9274d75fc04e874548051506a2f32616492e
+++ b/Makefile
@@@ -153,15 -153,7 +153,15 @@@ all:
  #
  # Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
  #
 -# Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72.
 +# Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72
 +# (not v1.73 or v1.71).
 +#
 +# Define ASCIIDOC_NO_ROFF if your DocBook XSL escapes raw roff directives
 +# (versions 1.72 and later and 1.68.1 and earlier).
 +#
 +# Define GNU_ROFF if your target system uses GNU groff.  This forces
 +# apostrophes to be ASCII so that cut&pasting examples to the shell
 +# will work.
  #
  # Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's
  # MakeMaker (e.g. using ActiveState under Cygwin).
@@@ -358,6 -350,7 +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
@@@ -416,7 -409,6 +417,7 @@@ LIB_H += builtin.
  LIB_H += cache.h
  LIB_H += cache-tree.h
  LIB_H += commit.h
 +LIB_H += compat/bswap.h
  LIB_H += compat/cygwin.h
  LIB_H += compat/mingw.h
  LIB_H += csum-file.h
@@@ -457,7 -449,6 +458,7 @@@ LIB_H += sideband.
  LIB_H += sigchain.h
  LIB_H += strbuf.h
  LIB_H += string-list.h
 +LIB_H += submodule.h
  LIB_H += tag.h
  LIB_H += transport.h
  LIB_H += tree.h
@@@ -556,7 -547,6 +557,7 @@@ LIB_OBJS += sideband.
  LIB_OBJS += sigchain.o
  LIB_OBJS += strbuf.o
  LIB_OBJS += string-list.o
 +LIB_OBJS += submodule.o
  LIB_OBJS += symlinks.o
  LIB_OBJS += tag.o
  LIB_OBJS += trace.o
@@@ -745,7 -735,6 +746,7 @@@ ifeq ($(uname_S),SunOS
        NO_MKSTEMPS = YesPlease
        NO_REGEX = YesPlease
        NO_EXTERNAL_GREP = YesPlease
 +      THREADED_DELTA_SEARCH = YesPlease
        ifeq ($(uname_R),5.7)
                NEEDS_RESOLV = YesPlease
                NO_IPV6 = YesPlease
@@@ -852,18 -841,11 +853,18 @@@ ifeq ($(uname_S),IRIX
        NO_MEMMEM = YesPlease
        NO_MKSTEMPS = YesPlease
        NO_MKDTEMP = YesPlease
 +      # When compiled with the MIPSpro 7.4.4m compiler, and without pthreads
 +      # (i.e. NO_PTHREADS is set), and _with_ MMAP (i.e. NO_MMAP is not set),
 +      # git dies with a segmentation fault when trying to access the first
 +      # entry of a reflog.  The conservative choice is made to always set
 +      # NO_MMAP.  If you suspect that your compiler is not affected by this
 +      # issue, comment out the NO_MMAP statement.
        NO_MMAP = YesPlease
        NO_EXTERNAL_GREP = UnfortunatelyYes
        SNPRINTF_RETURNS_BOGUS = YesPlease
        SHELL_PATH = /usr/gnu/bin/bash
        NEEDS_LIBGEN = YesPlease
 +      THREADED_DELTA_SEARCH = YesPlease
  endif
  ifeq ($(uname_S),IRIX64)
        NO_SETENV=YesPlease
        NO_MEMMEM = YesPlease
        NO_MKSTEMPS = YesPlease
        NO_MKDTEMP = YesPlease
 +      # When compiled with the MIPSpro 7.4.4m compiler, and without pthreads
 +      # (i.e. NO_PTHREADS is set), and _with_ MMAP (i.e. NO_MMAP is not set),
 +      # git dies with a segmentation fault when trying to access the first
 +      # entry of a reflog.  The conservative choice is made to always set
 +      # NO_MMAP.  If you suspect that your compiler is not affected by this
 +      # issue, comment out the NO_MMAP statement.
        NO_MMAP = YesPlease
        NO_EXTERNAL_GREP = UnfortunatelyYes
        SNPRINTF_RETURNS_BOGUS = YesPlease
        SHELL_PATH=/usr/gnu/bin/bash
        NEEDS_LIBGEN = YesPlease
 +      THREADED_DELTA_SEARCH = YesPlease
  endif
  ifeq ($(uname_S),HP-UX)
        NO_IPV6=YesPlease
@@@ -906,7 -881,7 +907,7 @@@ ifdef MSV
        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
        NO_REGEX = YesPlease
        NO_CURL = YesPlease
        NO_PTHREADS = YesPlease
+       BLK_SHA1 = YesPlease
  
        CC = compat/vcbuild/scripts/clink.pl
        AR = compat/vcbuild/scripts/lib.pl
        CFLAGS =
 -      BASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32-D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
 +      BASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
        COMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o
        COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -DSTRIP_EXTENSION=\".exe\"
        BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib
@@@ -958,7 -934,7 +960,7 @@@ els
  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
        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 -1059,6 +1085,6 @@@ EXTLIBS += -l
  
  ifndef NO_POSIX_ONLY_PROGRAMS
        PROGRAMS += git-daemon$X
-       PROGRAMS += git-imap-send$X
  endif
  ifndef NO_OPENSSL
        OPENSSL_LIBSSL = -lssl
@@@ -1382,7 -1358,7 +1384,7 @@@ SHELL = $(SHELL_PATH
  
  all:: shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS
  ifneq (,$X)
 -      $(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), test '$p' -ef '$p$X' || $(RM) '$p';)
 +      $(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), test -d '$p' -o '$p' -ef '$p$X' || $(RM) '$p';)
  endif
  
  all::
@@@ -1806,10 -1782,7 +1808,10 @@@ dist: git.spec git-archive$(X) configur
        gzip -f -9 $(GIT_TARNAME).tar
  
  rpm: dist
 -      $(RPMBUILD) -ta $(GIT_TARNAME).tar.gz
 +      $(RPMBUILD) \
 +              --define "_source_filedigest_algorithm md5" \
 +              --define "_binary_filedigest_algorithm md5" \
 +              -ta $(GIT_TARNAME).tar.gz
  
  htmldocs = git-htmldocs-$(GIT_VERSION)
  manpages = git-manpages-$(GIT_VERSION)
@@@ -1837,7 -1810,7 +1839,7 @@@ distclean: clea
        $(RM) configure
  
  clean:
 -      $(RM) *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o compat/*/*.o xdiff/*.o \
 +      $(RM) *.o block-sha1/*.o arm/*.o ppc/*.o compat/*.o compat/*/*.o xdiff/*.o \
                $(LIB_FILE) $(XDIFF_LIB)
        $(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X
        $(RM) $(TEST_PROGRAMS)
index f9528c0ea10db41f948e6d24b84125d2d54f6dda,fce1e2423e4bf29d41d11059885b1f187be628df..8a2112f22f46b3066d75bd5472dfe05bf88836c8
@@@ -29,6 -29,9 +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);
@@@ -45,4 -48,4 +48,4 @@@ if ($is_linking) 
        push(@args, @cflags);
  }
  #printf("**** @args\n");
 -exit system(@args);
 +exit (system(@args) != 0);
diff --combined imap-send.c
index f805c6ed813bbc6130bcd2d9f89bdb44ad9625e1,69e614245681e86c56a50cd096a675e8dc96deec..6c9938a0757a3c3b440c227951462f6972923afe
@@@ -24,6 -24,7 +24,7 @@@
  
  #include "cache.h"
  #include "exec_cmd.h"
+ #include "run-command.h"
  #ifdef NO_OPENSSL
  typedef void *SSL;
  #endif
@@@ -93,6 -94,7 +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 +125,6 @@@ static int nfvasprintf(char **strp, con
        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 +153,7 @@@ struct imap_list 
  };
  
  struct imap_socket {
-       int fd;
+       int fd[2];
        SSL *ssl;
  };
  
@@@ -272,12 -271,8 +271,12 @@@ static int ssl_socket_connect(struct im
  #ifdef NO_OPENSSL
        fprintf(stderr, "SSL requested but SSL support not compiled in\n");
        return -1;
 +#else
 +#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
 +      const SSL_METHOD *meth;
  #else
        SSL_METHOD *meth;
 +#endif
        SSL_CTX *ctx;
        int ret;
  
                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 -330,12 +334,12 @@@ static int socket_read(struct imap_sock
                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 -348,12 +352,12 @@@ static int socket_write(struct imap_soc
                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 -366,8 +370,8 @@@ static void socket_shutdown(struct imap
                SSL_free(sock->ssl);
        }
  #endif
-       close(sock->fd);
+       close(sock->fd[0]);
+       close(sock->fd[1]);
  }
  
  /* simple line buffering */
@@@ -493,52 -495,6 +499,6 @@@ static int nfsnprintf(char *buf, int bl
        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 -920,7 +924,7 @@@ static void imap_close_server(struct im
  {
        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 -942,35 +946,35 @@@ static struct store *imap_open_store(st
        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) {
-               imap_info("Starting tunnel '%s'... ", srvc->tunnel);
+               const char *argv[4];
+               struct child_process tunnel = {0};
  
-               if (socketpair(PF_UNIX, SOCK_STREAM, 0, a)) {
-                       perror("socketpair");
-                       exit(1);
-               }
+               imap_info("Starting tunnel '%s'... ", srvc->tunnel);
  
-               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);
-               }
+               argv[0] = "sh";
+               argv[1] = "-c";
+               argv[2] = srvc->tunnel;
+               argv[3] = NULL;
  
-               close(a[0]);
+               tunnel.argv = argv;
+               tunnel.in = -1;
+               tunnel.out = -1;
+               if (start_command(&tunnel))
+                       die("cannot start proxy %s", argv[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 {
                        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 -1154,20 +1158,20 @@@ static int imap_make_flags(int flags, c
        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) {
        }
        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 -1359,6 +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;
  
        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);
  
                        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++;