#include "cache.h"
-#include <assert.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
typedef struct store_conf {
char *name;
const char *path; /* should this be here? its interpretation is driver-specific */
char *data;
int len;
unsigned char flags;
- unsigned char crlf:1;
+ unsigned int crlf:1;
} msg_data_t;
#define DRV_OK 0
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, ... );
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 );
}
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 );
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;
}
static void
-info( const char *msg, ... )
+imap_info( const char *msg, ... )
{
va_list va;
}
static void
-warn( const char *msg, ... )
+imap_warn( const char *msg, ... )
{
va_list va;
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;
if (**s)
*(*s)++ = 0;
if (!**s)
- *s = 0;
+ *s = NULL;
}
return ret;
}
}
}
-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, ... )
{
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;
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 );
}
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",
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++;
}
*curp = cur = xmalloc( sizeof(*cur) );
curp = &cur->next;
- cur->val = 0; /* for clean bail */
+ cur->val = NULL; /* for clean bail */
if (*s == '(') {
/* sublist */
s++;
goto bail;
}
*sp = s;
- *curp = 0;
+ *curp = NULL;
return 0;
bail:
- *curp = 0;
+ *curp = NULL;
return -1;
}
static list_t *
parse_list( char **sp )
{
- return parse_imap_list( 0, sp );
+ return parse_imap_list( NULL, sp );
}
static void
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 );
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) {
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;
}
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 );
struct hostent *he;
struct sockaddr_in addr;
int s, a[2], preauth;
+ pid_t pid;
ctx = xcalloc( sizeof(*ctx), 1 );
/* 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] );
close( a[1] );
- execl( "/bin/sh", "sh", "-c", srvc->tunnel, 0 );
+ execl( "/bin/sh", "sh", "-c", srvc->tunnel, NULL );
_exit( 127 );
}
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;
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;
* 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;
}
bail:
imap_close_store( &ctx->gen );
- return 0;
+ return NULL;
}
static int
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)
char *p = msg->data;
while (1) {
- if (!strncmp( "From ", p, 5 )) {
+ if (!prefixcmp(p, "From ")) {
count++;
p += 5;
}
data = &all_msgs->data[ *ofs ];
msg->len = all_msgs->len - *ofs;
- if (msg->len < 5 || strncmp( data, "From ", 5 ))
+ if (msg->len < 5 || prefixcmp(data, "From "))
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;
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 ))
+ if (!prefixcmp(val, "imap:"))
val += 5;
if (!server.port)
server.port = 143;
}
- if (!strncmp( "//", val, 2 ))
+ if (!prefixcmp(val, "//"))
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;
}
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;
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) {
return 1;
}
- total = count_messages( &all_msgs );
fprintf( stderr, "sending %d message%s\n", total, (total!=1)?"s":"" );
ctx->name = imap_folder;
while (1) {