X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=imap-send.c;h=3eaf025720c5432065b851ce98f861eee27eadee;hb=6900679c2f6d937a5a6ef616869c8887690ad19d;hp=1b38b3af676a2867c09d7eabe36956b87fa9478d;hpb=2593a410e095f89f0eef40edb90b39029574462b;p=git.git diff --git a/imap-send.c b/imap-send.c index 1b38b3af6..3eaf02572 100644 --- a/imap-send.c +++ b/imap-send.c @@ -24,13 +24,6 @@ #include "cache.h" -#include -#include -#include -#include -#include -#include - typedef struct store_conf { char *name; const char *path; /* should this be here? its interpretation is driver-specific */ @@ -93,7 +86,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 @@ -103,14 +96,13 @@ typedef struct { static int Verbose, Quiet; -static void info( const char *, ... ); -static void warn( const char *, ... ); +static void imap_info( const char *, ... ); +static void imap_warn( const char *, ... ); 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, ... ); @@ -232,7 +224,7 @@ socket_perror( const char *func, Socket_t *sock, int ret ) static int socket_read( Socket_t *sock, char *buf, int len ) { - int n = read( sock->fd, buf, len ); + int n = xread( sock->fd, buf, len ); if (n <= 0) { socket_perror( "read", sock, n ); close( sock->fd ); @@ -242,9 +234,9 @@ 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 ); + int n = write_in_full( sock->fd, buf, len ); if (n != len) { socket_perror( "write", sock, n ); close( sock->fd ); @@ -273,7 +265,7 @@ buffer_gets( buffer_t * b, char **s ) n = b->bytes - start; if (n) - memcpy( b->buf, b->buf + start, n ); + memmove(b->buf, b->buf + start, n); b->offset -= start; b->bytes = n; start = 0; @@ -305,7 +297,7 @@ buffer_gets( buffer_t * b, char **s ) } static void -info( const char *msg, ... ) +imap_info( const char *msg, ... ) { va_list va; @@ -318,7 +310,7 @@ info( const char *msg, ... ) } static void -warn( const char *msg, ... ) +imap_warn( const char *msg, ... ) { va_list va; @@ -335,12 +327,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; @@ -355,7 +347,7 @@ next_arg( char **s ) if (**s) *(*s)++ = 0; if (!**s) - *s = 0; + *s = NULL; } return ret; } @@ -371,21 +363,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, ... ) { @@ -399,15 +376,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; @@ -422,7 +390,7 @@ arc4_init( void ) fprintf( stderr, "Fatal: no random number source available.\n" ); exit( 3 ); } - if (read( fd, dat, 128 ) != 128) { + if (read_in_full( fd, dat, 128 ) != 128) { fprintf( stderr, "Fatal: cannot read random number source.\n" ); exit( 3 ); } @@ -475,7 +443,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", @@ -506,12 +474,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++; @@ -607,7 +575,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++; @@ -680,11 +648,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; } @@ -702,7 +670,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 @@ -789,7 +757,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 ); @@ -813,7 +781,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) { @@ -849,7 +817,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; } @@ -898,7 +866,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 ); @@ -924,6 +892,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 ); @@ -934,14 +903,17 @@ imap_open_store( imap_server_conf_t *srvc ) /* open connection to IMAP server */ if (srvc->tunnel) { - info( "Starting tunnel '%s'... ", srvc->tunnel ); + imap_info( "Starting tunnel '%s'... ", srvc->tunnel ); if (socketpair( PF_UNIX, SOCK_STREAM, 0, a )) { perror( "socketpair" ); 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] ); @@ -954,31 +926,31 @@ imap_open_store( imap_server_conf_t *srvc ) imap->buf.sock.fd = a[1]; - info( "ok\n" ); + imap_info( "ok\n" ); } else { memset( &addr, 0, sizeof(addr) ); addr.sin_port = htons( srvc->port ); addr.sin_family = AF_INET; - info( "Resolving %s... ", srvc->host ); + imap_info( "Resolving %s... ", srvc->host ); he = gethostbyname( srvc->host ); if (!he) { perror( "gethostbyname" ); goto bail; } - info( "ok\n" ); + imap_info( "ok\n" ); addr.sin_addr.s_addr = *((int *) he->h_addr_list[0]); s = socket( PF_INET, SOCK_STREAM, 0 ); - info( "Connecting to %s:%hu... ", inet_ntoa( addr.sin_addr ), ntohs( addr.sin_port ) ); + imap_info( "Connecting to %s:%hu... ", inet_ntoa( addr.sin_addr ), ntohs( addr.sin_port ) ); if (connect( s, (struct sockaddr *)&addr, sizeof(addr) )) { close( s ); perror( "connect" ); goto bail; } - info( "ok\n" ); + imap_info( "ok\n" ); imap->buf.sock.fd = s; @@ -1001,13 +973,13 @@ 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) { - info ("Logging in...\n"); + imap_info ("Logging in...\n"); if (!srvc->user) { fprintf( stderr, "Skipping server %s, no user\n", srvc->host ); goto bail; @@ -1028,14 +1000,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) { + imap_warn( "*** IMAP Warning *** Password is being sent in the clear\n" ); + if (imap_exec( ctx, NULL, "LOGIN \"%s\" \"%s\"", srvc->user, srvc->pass ) != RESP_OK) { fprintf( stderr, "IMAP error: LOGIN failed\n" ); goto bail; } @@ -1047,7 +1019,7 @@ imap_open_store( imap_server_conf_t *srvc ) bail: imap_close_store( &ctx->gen ); - return 0; + return NULL; } static int @@ -1202,6 +1174,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) @@ -1246,6 +1219,14 @@ split_msg( msg_data_t *all_msgs, msg_data_t *msg, int *ofs ) if (msg->len < 5 || strncmp( data, "From ", 5 )) return 0; + p = strchr( data, '\n' ); + if (p) { + p = &p[1]; + msg->len -= p-data; + *ofs += p-data; + data = p; + } + p = strstr( data, "\nFrom " ); if (p) msg->len = &p[1] - data; @@ -1283,7 +1264,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 )) @@ -1293,16 +1274,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; } @@ -1310,7 +1291,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; @@ -1332,6 +1313,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) { @@ -1339,7 +1326,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) {