Add "git show-ref" builtin command
[gitweb.git] / imap-send.c
index fddaac00c0adea7347934b008da9b33e72fe5b5f..362e4743740435dc0e5b08933c0e05c53b7b62af 100644 (file)
@@ -28,6 +28,7 @@
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
+#include <sys/socket.h>
 #include <netdb.h>
 
 typedef struct store_conf {
@@ -92,7 +93,7 @@ typedef struct {
        char *data;
        int len;
        unsigned char flags;
-       unsigned char crlf:1;
+       unsigned int crlf:1;
 } msg_data_t;
 
 #define DRV_OK          0
@@ -109,7 +110,6 @@ static char *next_arg( char ** );
 
 static void free_generic_messages( message_t * );
 
-static int nfvasprintf( char **str, const char *fmt, va_list va );
 static int nfsnprintf( char *buf, int blen, const char *fmt, ... );
 
 
@@ -241,7 +241,7 @@ socket_read( Socket_t *sock, char *buf, int len )
 }
 
 static int
-socket_write( Socket_t *sock, char *buf, int len )
+socket_write( Socket_t *sock, const char *buf, int len )
 {
        int n = write( sock->fd, buf, len );
        if (n != len) {
@@ -334,12 +334,12 @@ next_arg( char **s )
        char *ret;
 
        if (!s || !*s)
-               return 0;
+               return NULL;
        while (isspace( (unsigned char) **s ))
                (*s)++;
        if (!**s) {
-               *s = 0;
-               return 0;
+               *s = NULL;
+               return NULL;
        }
        if (**s == '"') {
                ++*s;
@@ -354,7 +354,7 @@ next_arg( char **s )
                if (**s)
                        *(*s)++ = 0;
                if (!**s)
-                       *s = 0;
+                       *s = NULL;
        }
        return ret;
 }
@@ -370,21 +370,6 @@ free_generic_messages( message_t *msgs )
        }
 }
 
-static int
-vasprintf( char **strp, const char *fmt, va_list ap )
-{
-       int len;
-       char tmp[1024];
-
-       if ((len = vsnprintf( tmp, sizeof(tmp), fmt, ap )) < 0 || !(*strp = xmalloc( len + 1 )))
-               return -1;
-       if (len >= (int)sizeof(tmp))
-               vsprintf( *strp, fmt, ap );
-       else
-               memcpy( *strp, tmp, len + 1 );
-       return len;
-}
-
 static int
 nfsnprintf( char *buf, int blen, const char *fmt, ... )
 {
@@ -398,15 +383,6 @@ nfsnprintf( char *buf, int blen, const char *fmt, ... )
        return ret;
 }
 
-static int
-nfvasprintf( char **str, const char *fmt, va_list va )
-{
-       int ret = vasprintf( str, fmt, va );
-       if (ret < 0)
-               die( "Fatal: Out of memory\n");
-       return ret;
-}
-
 static struct {
        unsigned char i, j, s[256];
 } rs;
@@ -474,7 +450,7 @@ v_issue_imap_cmd( imap_store_t *ctx, struct imap_cmd_cb *cb,
                memset( &cmd->cb, 0, sizeof(cmd->cb) );
 
        while (imap->literal_pending)
-               get_cmd_result( ctx, 0 );
+               get_cmd_result( ctx, NULL );
 
        bufl = nfsnprintf( buf, sizeof(buf), cmd->cb.data ? CAP(LITERALPLUS) ?
                           "%d %s{%d+}\r\n" : "%d %s{%d}\r\n" : "%d %s\r\n",
@@ -505,12 +481,12 @@ v_issue_imap_cmd( imap_store_t *ctx, struct imap_cmd_cb *cb,
                                free( cmd );
                                return NULL;
                        }
-                       cmd->cb.data = 0;
+                       cmd->cb.data = NULL;
                } else
                        imap->literal_pending = 1;
        } else if (cmd->cb.cont)
                imap->literal_pending = 1;
-       cmd->next = 0;
+       cmd->next = NULL;
        *imap->in_progress_append = cmd;
        imap->in_progress_append = &cmd->next;
        imap->num_in_progress++;
@@ -606,7 +582,7 @@ parse_imap_list_l( imap_t *imap, char **sp, list_t **curp, int level )
                }
                *curp = cur = xmalloc( sizeof(*cur) );
                curp = &cur->next;
-               cur->val = 0; /* for clean bail */
+               cur->val = NULL; /* for clean bail */
                if (*s == '(') {
                        /* sublist */
                        s++;
@@ -679,11 +655,11 @@ parse_imap_list_l( imap_t *imap, char **sp, list_t **curp, int level )
                        goto bail;
        }
        *sp = s;
-       *curp = 0;
+       *curp = NULL;
        return 0;
 
   bail:
-       *curp = 0;
+       *curp = NULL;
        return -1;
 }
 
@@ -701,7 +677,7 @@ parse_imap_list( imap_t *imap, char **sp )
 static list_t *
 parse_list( char **sp )
 {
-       return parse_imap_list( 0, sp );
+       return parse_imap_list( NULL, sp );
 }
 
 static void
@@ -788,7 +764,7 @@ get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd )
                                imap->ns_shared = parse_list( &cmd );
                        } else if (!strcmp( "OK", arg ) || !strcmp( "BAD", arg ) ||
                                   !strcmp( "NO", arg ) || !strcmp( "BYE", arg )) {
-                               if ((resp = parse_response_code( ctx, 0, cmd )) != RESP_OK)
+                               if ((resp = parse_response_code( ctx, NULL, cmd )) != RESP_OK)
                                        return resp;
                        } else if (!strcmp( "CAPABILITY", arg ))
                                parse_capability( imap, cmd );
@@ -812,7 +788,7 @@ get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd )
                        if (cmdp->cb.data) {
                                n = socket_write( &imap->buf.sock, cmdp->cb.data, cmdp->cb.dlen );
                                free( cmdp->cb.data );
-                               cmdp->cb.data = 0;
+                               cmdp->cb.data = NULL;
                                if (n != (int)cmdp->cb.dlen)
                                        return RESP_BAD;
                        } else if (cmdp->cb.cont) {
@@ -848,7 +824,7 @@ get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd )
                                if (!strcmp( "NO", arg )) {
                                        if (cmdp->cb.create && cmd && (cmdp->cb.trycreate || !memcmp( cmd, "[TRYCREATE]", 11 ))) { /* SELECT, APPEND or UID COPY */
                                                p = strchr( cmdp->cmd, '"' );
-                                               if (!issue_imap_cmd( ctx, 0, "CREATE \"%.*s\"", strchr( p + 1, '"' ) - p + 1, p )) {
+                                               if (!issue_imap_cmd( ctx, NULL, "CREATE \"%.*s\"", strchr( p + 1, '"' ) - p + 1, p )) {
                                                        resp = RESP_BAD;
                                                        goto normal;
                                                }
@@ -897,7 +873,7 @@ imap_close_server( imap_store_t *ictx )
        imap_t *imap = ictx->imap;
 
        if (imap->buf.sock.fd != -1) {
-               imap_exec( ictx, 0, "LOGOUT" );
+               imap_exec( ictx, NULL, "LOGOUT" );
                close( imap->buf.sock.fd );
        }
        free_list( imap->ns_personal );
@@ -923,6 +899,7 @@ imap_open_store( imap_server_conf_t *srvc )
        struct hostent *he;
        struct sockaddr_in addr;
        int s, a[2], preauth;
+       pid_t pid;
 
        ctx = xcalloc( sizeof(*ctx), 1 );
 
@@ -940,12 +917,15 @@ imap_open_store( imap_server_conf_t *srvc )
                        exit( 1 );
                }
 
-               if (fork() == 0) {
+               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, 0 );
+                       execl( "/bin/sh", "sh", "-c", srvc->tunnel, NULL );
                        _exit( 127 );
                }
 
@@ -1000,8 +980,8 @@ imap_open_store( imap_server_conf_t *srvc )
                fprintf( stderr, "IMAP error: unknown greeting response\n" );
                goto bail;
        }
-       parse_response_code( ctx, 0, rsp );
-       if (!imap->caps && imap_exec( ctx, 0, "CAPABILITY" ) != RESP_OK)
+       parse_response_code( ctx, NULL, rsp );
+       if (!imap->caps && imap_exec( ctx, NULL, "CAPABILITY" ) != RESP_OK)
                goto bail;
 
        if (!preauth) {
@@ -1027,14 +1007,14 @@ imap_open_store( imap_server_conf_t *srvc )
                         * getpass() returns a pointer to a static buffer.  make a copy
                         * for long term storage.
                         */
-                       srvc->pass = strdup( arg );
+                       srvc->pass = xstrdup( arg );
                }
                if (CAP(NOLOGIN)) {
                        fprintf( stderr, "Skipping account %s@%s, server forbids LOGIN\n", srvc->user, srvc->host );
                        goto bail;
                }
                warn( "*** IMAP Warning *** Password is being sent in the clear\n" );
-               if (imap_exec( ctx, 0, "LOGIN \"%s\" \"%s\"", srvc->user, srvc->pass ) != RESP_OK) {
+               if (imap_exec( ctx, NULL, "LOGIN \"%s\" \"%s\"", srvc->user, srvc->pass ) != RESP_OK) {
                        fprintf( stderr, "IMAP error: LOGIN failed\n" );
                        goto bail;
                }
@@ -1046,7 +1026,7 @@ imap_open_store( imap_server_conf_t *srvc )
 
   bail:
        imap_close_store( &ctx->gen );
-       return 0;
+       return NULL;
 }
 
 static int
@@ -1201,6 +1181,7 @@ read_message( FILE *f, msg_data_t *msg )
                        p = xrealloc(msg->data, len+1);
                        if (!p)
                                break;
+                       msg->data = p;
                }
                r = fread( &msg->data[msg->len], 1, len - msg->len, f );
                if (r <= 0)
@@ -1282,7 +1263,7 @@ git_imap_config(const char *key, const char *val)
        key += sizeof imap_key - 1;
 
        if (!strcmp( "folder", key )) {
-               imap_folder = strdup( val );
+               imap_folder = xstrdup( val );
        } else if (!strcmp( "host", key )) {
                {
                        if (!strncmp( "imap:", val, 5 ))
@@ -1292,16 +1273,16 @@ git_imap_config(const char *key, const char *val)
                }
                if (!strncmp( "//", val, 2 ))
                        val += 2;
-               server.host = strdup( val );
+               server.host = xstrdup( val );
        }
        else if (!strcmp( "user", key ))
-               server.user = strdup( val );
+               server.user = xstrdup( val );
        else if (!strcmp( "pass", key ))
-               server.pass = strdup( val );
+               server.pass = xstrdup( val );
        else if (!strcmp( "port", key ))
                server.port = git_config_int( key, val );
        else if (!strcmp( "tunnel", key ))
-               server.tunnel = strdup( val );
+               server.tunnel = xstrdup( val );
        return 0;
 }
 
@@ -1309,7 +1290,7 @@ int
 main(int argc, char **argv)
 {
        msg_data_t all_msgs, msg;
-       store_t *ctx = 0;
+       store_t *ctx = NULL;
        int uid = 0;
        int ofs = 0;
        int r;
@@ -1331,6 +1312,12 @@ main(int argc, char **argv)
                return 1;
        }
 
+       total = count_messages( &all_msgs );
+       if (!total) {
+               fprintf(stderr,"no messages to send\n");
+               return 1;
+       }
+
        /* write it to the imap server */
        ctx = imap_open_store( &server );
        if (!ctx) {
@@ -1338,7 +1325,6 @@ main(int argc, char **argv)
                return 1;
        }
 
-       total = count_messages( &all_msgs );
        fprintf( stderr, "sending %d message%s\n", total, (total!=1)?"s":"" );
        ctx->name = imap_folder;
        while (1) {