From 537641afd99bf1c6a9055799184d86312da8be5d Mon Sep 17 00:00:00 2001 From: SJ Date: Tue, 22 Jul 2014 16:00:03 +0200 Subject: [PATCH] imap fixes --- src/config.h | 2 +- src/imap.c | 74 ++++++++++++++++++++++++++++-------------------- src/message.c | 4 +-- src/misc.c | 28 ++++++++++-------- src/misc.h | 2 +- src/parser.c | 4 +-- src/pilerpurge.c | 4 +-- 7 files changed, 67 insertions(+), 51 deletions(-) diff --git a/src/config.h b/src/config.h index 3b962981..dd2dbe24 100644 --- a/src/config.h +++ b/src/config.h @@ -14,7 +14,7 @@ #define VERSION "0.1.25-rc3" -#define BUILD 880 +#define BUILD 881 #define HOSTID "mailarchiver" diff --git a/src/imap.c b/src/imap.c index d84ab9ae..841c4163 100644 --- a/src/imap.c +++ b/src/imap.c @@ -87,7 +87,7 @@ END: int process_imap_folder(int sd, int *seq, char *folder, struct session_data *sdata, struct __data *data, int use_ssl, int dryrun, struct __config *cfg){ - int rc=ERR, i, n, messages=0, len, readlen, fd, nreads, readpos, finished, msglen, msg_written_len, tagoklen, tagbadlen; + int rc=ERR, i, n, messages=0, len, readlen, fd, nreads, readpos, finished, msglen, msg_written_len, tagoklen, tagbadlen, result; char *p, tag[SMALLBUFSIZE], tagok[SMALLBUFSIZE], tagbad[SMALLBUFSIZE], buf[MAXBUFSIZE], puf[MAXBUFSIZE], filename[SMALLBUFSIZE]; /* imap cmd: SELECT */ @@ -159,51 +159,63 @@ int process_imap_folder(int sd, int *seq, char *folder, struct session_data *sda do { nreads++; memset(puf, 0, sizeof(puf)); - p = split(p, '\n', puf, sizeof(puf)-1); + p = split(p, '\n', puf, sizeof(puf)-1, &result); len = strlen(puf); - if(nreads == 1){ + if(result == 1){ + // process a complete line - if(strcasestr(puf, " FETCH ")){ - msglen = get_message_length_from_imap_answer(puf); + if(nreads == 1){ - if(msglen == 0){ - finished = 1; - break; + if(strcasestr(puf, " FETCH ")){ + msglen = get_message_length_from_imap_answer(puf); + + if(msglen == 0){ + finished = 1; + break; + } + continue; } - continue; - } + if(strcasestr(puf, " BYE")){ + printf("imap server sent BYE response: '%s'\n", puf); + close(fd); + unlink(filename); + return ERR; + } - if(strcasestr(puf, " BYE")){ - printf("imap server sent BYE response: '%s'\n", puf); - close(fd); - unlink(filename); - return ERR; } - } - - if(len > 0){ - if(msg_written_len < msglen){ + + if(len > 0 && msg_written_len < msglen){ write(fd, puf, len); write(fd, "\n", 1); msg_written_len += len + 1; } - } - if(strncmp(puf, tagok, tagoklen) == 0){ - finished = 1; + if(strncmp(puf, tagok, tagoklen) == 0){ + finished = 1; + break; + } + + if(strncmp(puf, tagbad, tagbadlen) == 0){ + printf("ERROR happened reading the message!\n"); + finished = 1; + break; + } + + } + else { + // prepend the last incomplete line back to 'buf' + + snprintf(buf, sizeof(buf)-2, "%s", puf); + readpos = len; break; } - if(strncmp(puf, tagbad, tagbadlen) == 0){ - printf("ERROR happened reading the message!\n"); - finished = 1; - break; - } - - } while(p); + + + } else { readpos += n; @@ -342,7 +354,7 @@ void close_connection(int sd, struct __data *data, int use_ssl){ int list_folders(int sd, int *seq, int use_ssl, struct __data *data){ char *p, *q, *r, *buf, *ruf, tag[SMALLBUFSIZE], tagok[SMALLBUFSIZE], puf[MAXBUFSIZE]; - int len=MAXBUFSIZE+3, pos=0, n, rc=ERR, fldrlen=0; + int len=MAXBUFSIZE+3, pos=0, n, rc=ERR, fldrlen=0, result; printf("List of IMAP folders:\n"); @@ -382,7 +394,7 @@ int list_folders(int sd, int *seq, int use_ssl, struct __data *data){ p = buf; do { memset(puf, 0, sizeof(puf)); - p = split(p, '\n', puf, sizeof(puf)-1); + p = split(p, '\n', puf, sizeof(puf)-1, &result); trimBuffer(puf); if(strncmp(puf, "* LIST ", 7) == 0 || fldrlen){ diff --git a/src/message.c b/src/message.c index dff97e5c..df8524a3 100644 --- a/src/message.c +++ b/src/message.c @@ -146,7 +146,7 @@ int update_metadata_reference(struct session_data *sdata, struct _state *state, int store_meta_data(struct session_data *sdata, struct _state *state, struct __data *data, struct __config *cfg){ - int rc, ret=ERR; + int rc, ret=ERR, result; char *subj, *p, s[MAXBUFSIZE], s2[SMALLBUFSIZE], vcode[2*DIGEST_LENGTH+1], ref[2*DIGEST_LENGTH+1]; uint64 id=0; @@ -172,7 +172,7 @@ int store_meta_data(struct session_data *sdata, struct _state *state, struct __d p = state->b_from; do { memset(s2, 0, sizeof(s2)); - p = split(p, ' ', s2, sizeof(s2)-1); + p = split(p, ' ', s2, sizeof(s2)-1, &result); if(s2[0] == '\0') continue; diff --git a/src/misc.c b/src/misc.c index 063eb46d..09993521 100644 --- a/src/misc.c +++ b/src/misc.c @@ -112,23 +112,27 @@ void replaceCharacterInBuffer(char *p, char from, char to){ * split a string by a character as delimiter */ -char *split(char *row, int ch, char *s, int size){ - char *r; +char *split(char *str, int ch, char *buf, int buflen, int *result){ + char *p; - if(row == NULL || s == NULL) - return NULL; + *result = 0; - r = strchr(row, ch); - if(r) *r = '\0'; + if(str == NULL || buf == NULL || buflen < 2) return NULL; - snprintf(s, size, "%s", row); - - if(r){ - *r = ch; - r++; + p = strchr(str, ch); + if(p){ + *p = '\0'; } - return r; + snprintf(buf, buflen, "%s", str); + + if(p){ + *p = ch; + *result = 1; + p++; + } + + return p; } diff --git a/src/misc.h b/src/misc.h index 513940ec..27f41c93 100644 --- a/src/misc.h +++ b/src/misc.h @@ -21,7 +21,7 @@ long tvdiff(struct timeval a, struct timeval b); int searchStringInBuffer(char *s, int len1, char *what, int len2); int countCharacterInBuffer(char *p, char c); void replaceCharacterInBuffer(char *p, char from, char to); -char *split(char *row, int ch, char *s, int size); +char *split(char *str, int ch, char *buf, int buflen, int *result); char *split_str(char *row, char *what, char *s, int size); int trimBuffer(char *s); int extractEmail(char *rawmail, char *email); diff --git a/src/parser.c b/src/parser.c index 73807742..9b416ad6 100644 --- a/src/parser.c +++ b/src/parser.c @@ -173,7 +173,7 @@ void storno_attachment(struct _state *state){ int parse_line(char *buf, struct _state *state, struct session_data *sdata, int take_into_pieces, char *writebuffer, int writebuffersize, char *abuffer, int abuffersize, struct __data *data, struct __config *cfg){ char *p, *q, puf[SMALLBUFSIZE]; unsigned char b64buffer[MAXBUFSIZE]; - int n64, len, writelen, boundary_line=0; + int n64, len, writelen, boundary_line=0, result; if(cfg->debug == 1) printf("line: %s", buf); @@ -635,7 +635,7 @@ int parse_line(char *buf, struct _state *state, struct session_data *sdata, int do { memset(puf, 0, sizeof(puf)); - p = split(p, ' ', puf, sizeof(puf)-1); + p = split(p, ' ', puf, sizeof(puf)-1, &result); if(puf[0] == '\0') continue; diff --git a/src/pilerpurge.c b/src/pilerpurge.c index f9cda111..942d0f50 100644 --- a/src/pilerpurge.c +++ b/src/pilerpurge.c @@ -59,12 +59,12 @@ ENDE: int remove_message_frame_files(char *s, char *update_meta_sql, struct session_data *sdata, struct __config *cfg){ char *p, puf[SMALLBUFSIZE], filename[SMALLBUFSIZE]; - int n=0; + int n=0, result; struct stat st; p = s; do { - p = split(p, ' ', puf, sizeof(puf)-1); + p = split(p, ' ', puf, sizeof(puf)-1, &result); if(strlen(puf) == RND_STR_LEN){ snprintf(filename, sizeof(filename)-1, "%s/%02x/%c%c%c/%c%c/%c%c/%s.m", cfg->queuedir, cfg->server_id, puf[8], puf[9], puf[10], puf[RND_STR_LEN-4], puf[RND_STR_LEN-3], puf[RND_STR_LEN-2], puf[RND_STR_LEN-1], puf);