diff options
author | Eduardo Chappa <chappa@washington.edu> | 2013-11-02 02:51:18 -0600 |
---|---|---|
committer | Eduardo Chappa <chappa@washington.edu> | 2013-11-02 02:51:18 -0600 |
commit | 7fe712882b909931088a318c08041b0e7974a000 (patch) | |
tree | 2770f9b084e2efc7fc55e96e9bf4352cf2ff33a3 /imap/src/c-client/imap4r1.c | |
parent | bdfc834badee92ceeb2befe02f1d065ced5b9ddf (diff) | |
download | alpine-7fe712882b909931088a318c08041b0e7974a000.tar.xz |
* Update to version 2.19.1
* Upgrade UW-IMAP to Panda IMAP from https://github.com/jonabbey/panda-imap.
* Replace tabs by spaces in From and Subject fields to control for size in
screen of these fields. Change only in index screen display.
Diffstat (limited to 'imap/src/c-client/imap4r1.c')
-rw-r--r-- | imap/src/c-client/imap4r1.c | 153 |
1 files changed, 90 insertions, 63 deletions
diff --git a/imap/src/c-client/imap4r1.c b/imap/src/c-client/imap4r1.c index 48017cab..9c72e642 100644 --- a/imap/src/c-client/imap4r1.c +++ b/imap/src/c-client/imap4r1.c @@ -1,13 +1,5 @@ /* ======================================================================== - * Copyright 1988-2008 University of Washington - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * + * Copyright 2008-2011 Mark Crispin * ======================================================================== */ @@ -15,13 +7,19 @@ * Program: Interactive Message Access Protocol 4rev1 (IMAP4R1) routines * * Author: Mark Crispin - * UW Technology - * University of Washington - * Seattle, WA 98195 - * Internet: MRC@CAC.Washington.EDU * * Date: 15 June 1988 - * Last Edited: 8 May 2008 + * Last Edited: 3 October 2011 + * + * Previous versions of this file were + * + * Copyright 1988-2008 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 * * This original version of this file is * Copyright 1988 Stanford University @@ -362,7 +360,7 @@ void *imap_parameters (long function,void *value) if (((IMAPLOCAL *) ((MAILSTREAM *) value)->local)->cap.namespace && !((IMAPLOCAL *) ((MAILSTREAM *) value)->local)->namespace) imap_send (((MAILSTREAM *) value),"NAMESPACE",NIL); - value = (void *) &((IMAPLOCAL *) ((MAILSTREAM *) value)->local)->namespace; + value = (void *) ((IMAPLOCAL *) ((MAILSTREAM *) value)->local)->namespace; break; case GET_THREADERS: value = (void *) @@ -493,7 +491,7 @@ void imap_list (MAILSTREAM *stream,char *ref,char *pat) void imap_lsub (MAILSTREAM *stream,char *ref,char *pat) { void *sdb = NIL; - char *s,mbx[MAILTMPLEN]; + char *s,mbx[MAILTMPLEN],tmp[MAILTMPLEN]; /* do it on the server */ imap_list_work (stream,"LSUB",ref,pat,NIL); if (*pat == '{') { /* if remote pattern, must be IMAP */ @@ -506,9 +504,10 @@ void imap_lsub (MAILSTREAM *stream,char *ref,char *pat) if (ref && *ref) sprintf (mbx,"%s%s",ref,pat); else strcpy (mbx,pat); - if (s = sm_read (&sdb)) do if (imap_valid (s) && pmatch (s,mbx)) + if (s = sm_read (tmp,&sdb)) do if (imap_valid (s) && pmatch (s,mbx)) mm_lsub (stream,NIL,s,NIL); - while (s = sm_read (&sdb)); /* until no more subscriptions */ + /* until no more subscriptions */ + while (s = sm_read (tmp,&sdb)); } /* IMAP find list of mailboxes @@ -965,7 +964,7 @@ MAILSTREAM *imap_open (MAILSTREAM *stream) if (LOCAL->tls1) strcat (tmp,"/tls1"); if (LOCAL->tls1_1) strcat (tmp,"/tls1_1"); if (LOCAL->tls1_2) strcat (tmp,"/tls1_2"); - if (LOCAL->dtls1) strcat (tmp,"/dtls"); + if (LOCAL->dtls1) strcat (tmp,"/dtls1"); if (LOCAL->tlssslv23) strcat (tmp,"/tls-sslv23"); if (LOCAL->notlsflag) strcat (tmp,"/notls"); if (LOCAL->sslflag) strcat (tmp,"/ssl"); @@ -3715,8 +3714,7 @@ void imap_parse_unsolicited (MAILSTREAM *stream,IMAPPARSEDREPLY *reply) } /* get message data type, canonicalize upper */ s = ucase (strtok_r (reply->text," ",&r)); - /* and locate the text after it */ - t = strtok_r (NIL,"\n",&r); + t = strtok_r (NIL,"\n",&r); /* and locate the text after it */ /* now take the action */ /* change in size of mailbox */ if (!strcmp (s,"EXISTS") && (msgno >= stream->nmsgs)) @@ -3731,7 +3729,7 @@ void imap_parse_unsolicited (MAILSTREAM *stream,IMAPPARSEDREPLY *reply) mail_expunged (stream,msgno); } - else if ((!strcmp (s,"FETCH") || !strcmp (s,"STORE")) && + else if (t && (!strcmp (s,"FETCH") || !strcmp (s,"STORE")) && msgno && (msgno <= stream->nmsgs)) { char *prop; GETS_DATA md; @@ -3742,8 +3740,7 @@ void imap_parse_unsolicited (MAILSTREAM *stream,IMAPPARSEDREPLY *reply) (imapenvelope_t) mail_parameters (stream,GET_IMAPENVELOPE,NIL); ++t; /* skip past open parenthesis */ /* parse Lisp-form property list */ - while (prop = (strtok_r (t," )",&r))) { - t = strtok_r (NIL,"\n",&r); + while ((prop = (strtok_r (t," )",&r))) && (t = strtok_r (NIL,"\n",&r))) { INIT_GETS (md,stream,elt->msgno,NIL,0,0); e = NIL; /* not pointing at any envelope yet */ /* canonicalize property, parse it */ @@ -3892,6 +3889,11 @@ void imap_parse_unsolicited (MAILSTREAM *stream,IMAPPARSEDREPLY *reply) } if (e && *e) env = *e; /* note envelope if we got one */ } + if (prop) { + sprintf (LOCAL->tmp,"Missing data for property: %.80s",prop); + mm_notify (stream,LOCAL->tmp,WARN); + stream->unhealthy = T; + } /* do callback if requested */ if (ie && env) (*ie) (stream,msgno,env); } @@ -4278,17 +4280,7 @@ void imap_parse_response (MAILSTREAM *stream,char *text,long errflg,long ntfy) if (s = strchr (strncpy (t = LOCAL->tmp,s,i),' ')) *s++ = '\0'; if (s) { /* have argument? */ ntfy = NIL; /* suppress mm_notify if normal SELECT data */ - if (!compare_cstring (t,"UIDVALIDITY") && - ((j = strtoul (s,NIL,10)) != stream->uid_validity)) { - mailcache_t mc = (mailcache_t) mail_parameters (NIL,GET_CACHE,NIL); - stream->uid_validity = j; - /* purge any UIDs in cache */ - for (j = 1; j <= stream->nmsgs; j++) - if (elt = (MESSAGECACHE *) (*mc) (stream,j,CH_ELT)) - elt->private.uid = 0; - } - else if (!compare_cstring (t,"UIDNEXT")) - stream->uid_last = strtoul (s,NIL,10) - 1; + if (!compare_cstring (t,"CAPABILITY")) imap_parse_capabilities(stream,s); else if (!compare_cstring (t,"PERMANENTFLAGS") && (*s == '(') && (t[i-1] == ')')) { t[i-1] = '\0'; /* tie off flags */ @@ -4312,8 +4304,19 @@ void imap_parse_response (MAILSTREAM *stream,char *text,long errflg,long ntfy) while (s = strtok_r (NIL," ",&r)); } - else if (!compare_cstring (t,"CAPABILITY")) - imap_parse_capabilities (stream,s); + else if (!compare_cstring (t,"UIDVALIDITY") && (j = strtoul (s,NIL,10))){ + /* do this in separate if because of ntfy */ + if (j != stream->uid_validity) { + mailcache_t mc = (mailcache_t) mail_parameters (NIL,GET_CACHE,NIL); + stream->uid_validity = j; + /* purge any UIDs in cache */ + for (j = 1; j <= stream->nmsgs; j++) + if (elt = (MESSAGECACHE *) (*mc) (stream,j,CH_ELT)) + elt->private.uid = 0; + } + } + else if (!compare_cstring (t,"UIDNEXT")) + stream->uid_last = strtoul (s,NIL,10) - 1; else if ((j = LEVELUIDPLUS (stream) && LOCAL->appendmailbox) && !compare_cstring (t,"COPYUID") && (cu = (copyuid_t) mail_parameters (NIL,GET_COPYUID,NIL)) && @@ -4574,9 +4577,10 @@ void imap_parse_envelope (MAILSTREAM *stream,ENVELOPE **env, unsigned char **txtptr,IMAPPARSEDREPLY *reply) { ENVELOPE *oenv = *env; - char c = *((*txtptr)++); /* grab first character */ + char c = **txtptr; /* grab first character */ /* ignore leading spaces */ - while (c == ' ') c = *((*txtptr)++); + while (c == ' ') c = *++*txtptr; + if (c) ++*txtptr; /* skip past first character */ switch (c) { /* dispatch on first character */ case '(': /* if envelope S-expression */ *env = mail_newenvelope (); /* parse the new envelope */ @@ -4639,7 +4643,7 @@ ADDRESS *imap_parse_adrlist (MAILSTREAM *stream,unsigned char **txtptr, char c = **txtptr; /* sniff at first character */ /* ignore leading spaces */ while (c == ' ') c = *++*txtptr; - ++*txtptr; /* skip past open paren */ + if (c) ++*txtptr; /* skip past open paren */ switch (c) { case '(': /* if envelope S-expression */ adr = imap_parse_address (stream,txtptr,reply); @@ -4786,11 +4790,11 @@ void imap_parse_flags (MAILSTREAM *stream,MESSAGECACHE *elt, elt->user_flags = NIL; /* zap old flag values */ elt->seen = elt->deleted = elt->flagged = elt->answered = elt->draft = elt->recent = NIL; - while (c != ')') { /* parse list of flags */ + do { /* parse list of flags */ /* point at a flag */ while (*(flag = ++*txtptr) == ' '); /* scan for end of flag */ - while (**txtptr != ' ' && **txtptr != ')') ++*txtptr; + while (**txtptr && (**txtptr != ' ') && (**txtptr != ')')) ++*txtptr; c = **txtptr; /* save delimiter */ **txtptr = '\0'; /* tie off flag */ if (!*flag) break; /* null flag */ @@ -4805,8 +4809,12 @@ void imap_parse_flags (MAILSTREAM *stream,MESSAGECACHE *elt, } /* otherwise user flag */ else elt->user_flags |= imap_parse_user_flag (stream,flag); + } while (c && (c != ')')); + if (c) ++*txtptr; /* bump past delimiter */ + else { + mm_notify (stream,"Unterminated flags list",WARN); + stream->unhealthy = T; } - ++*txtptr; /* bump past delimiter */ if (!old.valid || (old.seen != elt->seen) || (old.deleted != elt->deleted) || (old.flagged != elt->flagged) || (old.answered != elt->answered) || (old.draft != elt->draft) || @@ -4899,7 +4907,7 @@ unsigned char *imap_parse_string (MAILSTREAM *stream,unsigned char **txtptr, (readprogress_t) mail_parameters (NIL,GET_READPROGRESS,NIL); /* ignore leading spaces */ while (c == ' ') c = *++*txtptr; - st = ++*txtptr; /* remember start of string */ + if (c) st = ++*txtptr; /* remember start of string */ switch (c) { case '"': /* if quoted string */ i = 0; /* initial byte count */ @@ -4947,14 +4955,21 @@ unsigned char *imap_parse_string (MAILSTREAM *stream,unsigned char **txtptr, if (len) *len = 0; break; case '{': /* if literal string */ + if (!isdigit (**txtptr)) { + sprintf (LOCAL->tmp,"Invalid server literal length %.80s",*txtptr); + mm_notify (stream,LOCAL->tmp,WARN); + stream->unhealthy = T; /* read and discard */ + i = 0; + } /* get size of string */ - if ((i = strtoul (*txtptr,(char **) txtptr,10)) > MAXSERVERLIT) { + else if ((i = strtoul (*txtptr,(char **) txtptr,10)) > MAXSERVERLIT) { sprintf (LOCAL->tmp,"Absurd server literal length %lu",i); mm_notify (stream,LOCAL->tmp,WARN); stream->unhealthy = T; /* read and discard */ - do net_getbuffer (LOCAL->netstream,j = min (i,(long) IMAPTMPLEN - 1), - LOCAL->tmp); - while (i -= j); + for (j = IMAPTMPLEN - 1; i; i -= j) { + if (j > i) j = i; + net_getbuffer (LOCAL->netstream,j,LOCAL->tmp); + } } if (len) *len = i; /* set return value */ if (md && mg) { /* have special routine to slurp string? */ @@ -5113,9 +5128,10 @@ void imap_parse_body_structure (MAILSTREAM *stream,BODY *body, int i; char *s; PART *part = NIL; - char c = *((*txtptr)++); /* grab first character */ + char c = **txtptr; /* grab first character */ /* ignore leading spaces */ - while (c == ' ') c = *((*txtptr)++); + while (c == ' ') c = *++*txtptr; + if (c) ++*txtptr; /* skip past first character */ switch (c) { /* dispatch on first character */ case '(': /* body structure list */ if (**txtptr == '(') { /* multipart body? */ @@ -5172,9 +5188,12 @@ void imap_parse_body_structure (MAILSTREAM *stream,BODY *body, (i <= TYPEMAX) && body_types[i] && strcmp (s,body_types[i]); i++); if (i <= TYPEMAX) { /* only if found a slot */ body->type = i; /* set body type */ - if (body_types[i]) fs_give ((void **) &s); - else body_types[i]=s; /* assign empty slot */ + if (!body_types[i]) { /* assign empty slot */ + body_types[i] = s; + s = NIL; /* don't free this string */ + } } + if (s) fs_give ((void **) &s); } if (body->subtype = imap_parse_string(stream,txtptr,reply,NIL,NIL,LONGT)) ucase (body->subtype); /* parse subtype */ @@ -5195,10 +5214,13 @@ void imap_parse_body_structure (MAILSTREAM *stream,BODY *body, if (i > ENCMAX) body->encoding = ENCOTHER; else { /* only if found a slot */ body->encoding = i; /* set body encoding */ - if (body_encodings[i]) fs_give ((void **) &s); /* assign empty slot */ - else body_encodings[i] = s; + if (!body_encodings[i]) { + body_encodings[i] = s; + s = NIL; /* don't free this string */ + } } + if (s) fs_give ((void **) &s); } /* parse size of contents in bytes */ body->size.bytes = strtoul (*txtptr,(char **) txtptr,10); @@ -5212,6 +5234,7 @@ void imap_parse_body_structure (MAILSTREAM *stream,BODY *body, if (!env) { mm_notify (stream,"Missing body message envelope",WARN); stream->unhealthy = T; + fs_give ((void **) &body->subtype); body->subtype = cpystr ("RFC822_MISSING_ENVELOPE"); break; } @@ -5284,8 +5307,7 @@ PARAMETER *imap_parse_body_parameter (MAILSTREAM *stream, char c,*s; /* ignore leading spaces */ while ((c = *(*txtptr)++) == ' '); - /* parse parameter list */ - if (c == '(') while (c != ')') { + if (c == '(') do { /* parse parameter list */ /* append new parameter to tail */ if (ret) par = par->next = mail_newbody_parameter (); else ret = par = mail_newbody_parameter (); @@ -5308,13 +5330,17 @@ PARAMETER *imap_parse_body_parameter (MAILSTREAM *stream, case ')': /* end of attribute/value pairs */ ++*txtptr; /* skip past closing paren */ break; + case '\0': + mm_notify (stream,"Unterminated parameter list", WARN); + stream->unhealthy = T; + break; default: sprintf (LOCAL->tmp,"Junk at end of parameter: %.80s",(char *) *txtptr); mm_notify (stream,LOCAL->tmp,WARN); stream->unhealthy = T; break; } - } + } while (c && (c != ')')); /* empty parameter, must be NIL */ else if (((c == 'N') || (c == 'n')) && ((*(s = *txtptr) == 'I') || (*s == 'i')) && @@ -5364,7 +5390,7 @@ void imap_parse_disposition (MAILSTREAM *stream,BODY *body, mm_notify (stream,LOCAL->tmp,WARN); stream->unhealthy = T; /* try to skip to next space */ - while ((*++*txtptr != ' ') && (**txtptr != ')') && **txtptr); + while (**txtptr && (*++*txtptr != ' ') && (**txtptr != ')')); break; } } @@ -5437,12 +5463,13 @@ void imap_parse_extension (MAILSTREAM *stream,unsigned char **txtptr, unsigned long i,j; switch (*++*txtptr) { /* action depends upon first character */ case '(': - while (**txtptr != ')') imap_parse_extension (stream,txtptr,reply); - ++*txtptr; /* bump past closing parenthesis */ + while (**txtptr && (**txtptr != ')')) + imap_parse_extension (stream,txtptr,reply); + if (**txtptr) ++*txtptr; /* bump past closing parenthesis */ break; case '"': /* if quoted string */ - while (*++*txtptr != '"') if (**txtptr == '\\') ++*txtptr; - ++*txtptr; /* bump past closing quote */ + while ((*++*txtptr != '"') && **txtptr) if (**txtptr == '\\') ++*txtptr; + if (**txtptr) ++*txtptr; /* bump past closing quote */ break; case 'N': /* if NIL */ case 'n': @@ -5471,7 +5498,7 @@ void imap_parse_extension (MAILSTREAM *stream,unsigned char **txtptr, mm_notify (stream,LOCAL->tmp,WARN); stream->unhealthy = T; /* try to skip to next space */ - while ((*++*txtptr != ' ') && (**txtptr != ')') && **txtptr); + while (**txtptr && (*++*txtptr != ' ') && (**txtptr != ')')); break; } } |