From 2b80e75820618944e1c75b9c01aeeefc8b6b0c81 Mon Sep 17 00:00:00 2001 From: Wilfried Goesgens Date: Mon, 30 Sep 2013 23:20:25 +0200 Subject: [PATCH] preserve stringlengths when outputting stuff in the imap module --- citadel/genstamp.c | 11 +++-- citadel/genstamp.h | 2 +- citadel/internet_addressing.h | 8 --- citadel/modules/imap/imap_acl.c | 2 +- citadel/modules/imap/imap_fetch.c | 82 +++++++++++++++---------------- citadel/modules/imap/imap_list.c | 7 +-- citadel/modules/imap/imap_tools.c | 77 ++++------------------------- citadel/modules/imap/imap_tools.h | 6 +-- citadel/modules/imap/serv_imap.c | 10 ++-- citadel/msgbase.h | 2 + 10 files changed, 74 insertions(+), 133 deletions(-) diff --git a/citadel/genstamp.c b/citadel/genstamp.c index eb594119a..9c5ba5f3d 100644 --- a/citadel/genstamp.c +++ b/citadel/genstamp.c @@ -36,7 +36,7 @@ static char *weekdays[] = { * Supplied with a unix timestamp, generate an RFC822-compliant textual * time and date stamp. */ -void datestring(char *buf, size_t n, time_t xtime, int which_format) { +long datestring(char *buf, size_t n, time_t xtime, int which_format) { struct tm t; long offset; @@ -62,7 +62,9 @@ void datestring(char *buf, size_t n, time_t xtime, int which_format) { switch(which_format) { case DATESTRING_RFC822: - snprintf(buf, n, "%s, %02d %s %04d %02d:%02d:%02d %c%04ld", + return snprintf( + buf, n, + "%s, %02d %s %04d %02d:%02d:%02d %c%04ld", weekdays[t.tm_wday], t.tm_mday, months[t.tm_mon], @@ -75,7 +77,9 @@ void datestring(char *buf, size_t n, time_t xtime, int which_format) { break; case DATESTRING_IMAP: - snprintf(buf, n, "%02d-%s-%04d %02d:%02d:%02d %c%04ld", + return snprintf( + buf, n, + "%02d-%s-%04d %02d:%02d:%02d %c%04ld", t.tm_mday, months[t.tm_mon], t.tm_year + 1900, @@ -87,4 +91,5 @@ void datestring(char *buf, size_t n, time_t xtime, int which_format) { break; } + return 0; } diff --git a/citadel/genstamp.h b/citadel/genstamp.h index 43208d910..ffe0d9c01 100644 --- a/citadel/genstamp.h +++ b/citadel/genstamp.h @@ -1,5 +1,5 @@ -void datestring(char *buf, size_t n, time_t xtime, int which_format); +long datestring(char *buf, size_t n, time_t xtime, int which_format); enum { DATESTRING_RFC822, diff --git a/citadel/internet_addressing.h b/citadel/internet_addressing.h index 87d35b923..e40ff4f51 100644 --- a/citadel/internet_addressing.h +++ b/citadel/internet_addressing.h @@ -2,14 +2,6 @@ #include "server.h" #include "ctdl_module.h" -struct internet_address_list { - struct internet_address_list *next; - char ial_user[SIZ]; - char ial_node[SIZ]; - char ial_name[SIZ]; -}; - - recptypes *validate_recipients(const char *recipients, const char *RemoteIdentifier, int Flags); diff --git a/citadel/modules/imap/imap_acl.c b/citadel/modules/imap/imap_acl.c index b1c1f0fe8..0cd272860 100644 --- a/citadel/modules/imap/imap_acl.c +++ b/citadel/modules/imap/imap_acl.c @@ -192,7 +192,7 @@ void imap_getacl(int num_parms, ConstStr *Params) { imap_acl_flags(rights, ra); if (StrLength(rights) > 0) { IAPuts(" "); - plain_imap_strout(temp.fullname); + IPutStr(temp.fullname, strlen(temp.fullname)); IAPuts(" "); iaputs(SKEY( rights)); } diff --git a/citadel/modules/imap/imap_fetch.c b/citadel/modules/imap/imap_fetch.c index ed7f27165..407eed21f 100644 --- a/citadel/modules/imap/imap_fetch.c +++ b/citadel/modules/imap/imap_fetch.c @@ -355,25 +355,25 @@ void imap_output_envelope_from(struct CtdlMessage *msg) { /* For everything else, we do stuff. */ IAPuts("(("); /* open double-parens */ - plain_imap_strout(msg->cm_fields[eAuthor]); /* personal name */ + IPutMsgField(eAuthor); /* personal name */ IAPuts(" NIL "); /* source route (not used) */ if (!CM_IsEmpty(msg, erFc822Addr)) { process_rfc822_addr(msg->cm_fields[erFc822Addr], user, node, name); - plain_imap_strout(user); /* mailbox name (user id) */ + IPutStr(user, strlen(user)); /* mailbox name (user id) */ IAPuts(" "); if (!strcasecmp(node, config.c_nodename)) { - plain_imap_strout(config.c_fqdn); + IPutStr(config.c_fqdn, strlen(config.c_fqdn)); } else { - plain_imap_strout(node); /* host name */ + IPutStr(node, strlen(node)); /* host name */ } } else { - plain_imap_strout(msg->cm_fields[eAuthor]); /* mailbox name (user id) */ + IPutMsgField(eAuthor); /* mailbox name (user id) */ IAPuts(" "); - plain_imap_strout(msg->cm_fields[eNodeName]); /* host name */ + IPutMsgField(eNodeName); /* host name */ } IAPuts(")) "); /* close double-parens */ @@ -416,11 +416,11 @@ void imap_output_envelope_addr(char *addr) { striplt(individual_addr); process_rfc822_addr(individual_addr, user, node, name); IAPuts("("); - plain_imap_strout(name); + IPutStr(name, strlen(name)); IAPuts(" NIL "); - plain_imap_strout(user); + IPutStr(user, strlen(user)); IAPuts(" "); - plain_imap_strout(node); + IPutStr(node, strlen(node)); IAPuts(")"); if (i < (num_addrs-1)) IAPuts(" "); @@ -451,8 +451,8 @@ void imap_fetch_envelope(struct CtdlMessage *msg) { else { msgdate = time(NULL); } - datestring(datestringbuf, sizeof datestringbuf, - msgdate, DATESTRING_IMAP); + len = datestring(datestringbuf, sizeof datestringbuf, + msgdate, DATESTRING_IMAP); /* Now start spewing data fields. The order is important, as it is * defined by the protocol specification. Nonexistent fields must @@ -462,11 +462,11 @@ void imap_fetch_envelope(struct CtdlMessage *msg) { IAPuts("ENVELOPE ("); /* Date */ - plain_imap_strout(datestringbuf); + IPutStr(datestringbuf, len); IAPuts(" "); /* Subject */ - plain_imap_strout(msg->cm_fields[eMsgSubject]); + IPutMsgField(eMsgSubject); IAPuts(" "); /* From */ @@ -513,7 +513,7 @@ void imap_fetch_envelope(struct CtdlMessage *msg) { /* In-reply-to */ fieldptr = rfc822_fetch_field(msg->cm_fields[eMesageText], "In-reply-to"); - plain_imap_strout(fieldptr); + IPutStr(fieldptr, (fieldptr)?strlen(fieldptr):0); IAPuts(" "); if (fieldptr != NULL) free(fieldptr); @@ -525,7 +525,7 @@ void imap_fetch_envelope(struct CtdlMessage *msg) { (msg->cm_fields[emessageId][len - 1] == '>')) ) { - plain_imap_strout(msg->cm_fields[emessageId]); + IPutMsgField(emessageId); } else { @@ -822,14 +822,14 @@ void imap_fetch_bodystructure_post( void *content, char *cbtype, char *cbcharset, size_t length, char *encoding, char *cbid, void *cbuserdata ) { - + long len; char subtype[128]; IAPuts(" "); /* disposition */ - extract_token(subtype, cbtype, 1, '/', sizeof subtype); - plain_imap_strout(subtype); + len = extract_token(subtype, cbtype, 1, '/', sizeof subtype); + IPutStr(subtype, len); /* body language */ /* IAPuts(" NIL"); We thought we needed this at one point, but maybe we don't... */ @@ -855,56 +855,57 @@ void imap_fetch_bodystructure_part( size_t i; char cbmaintype[128]; char cbsubtype[128]; + long cbmaintype_len; + long cbsubtype_len; if (cbtype != NULL) if (!IsEmptyStr(cbtype)) have_cbtype = 1; if (have_cbtype) { - extract_token(cbmaintype, cbtype, 0, '/', sizeof cbmaintype); - extract_token(cbsubtype, cbtype, 1, '/', sizeof cbsubtype); + cbmaintype_len = extract_token(cbmaintype, cbtype, 0, '/', sizeof cbmaintype); + cbsubtype_len = extract_token(cbsubtype, cbtype, 1, '/', sizeof cbsubtype); } else { strcpy(cbmaintype, "TEXT"); + cbmaintype_len = 4; strcpy(cbsubtype, "PLAIN"); + cbsubtype_len = 5; } IAPuts("("); - plain_imap_strout(cbmaintype); /* body type */ + IPutStr(cbmaintype, cbmaintype_len); /* body type */ IAPuts(" "); - plain_imap_strout(cbsubtype); /* body subtype */ + IPutStr(cbsubtype, cbsubtype_len); /* body subtype */ IAPuts(" "); - IAPuts("("); /* begin body parameter list */ + IAPuts("("); /* begin body parameter list */ /* "NAME" must appear as the first parameter. This is not required by IMAP, * but the Asterisk voicemail application blindly assumes that NAME will be in * the first position. If it isn't, it rejects the message. */ - if (name != NULL) if (!IsEmptyStr(name)) { + if ((name != NULL) && (!IsEmptyStr(name))) { IAPuts("\"NAME\" "); - plain_imap_strout(name); + IPutStr(name, strlen(name)); IAPuts(" "); } IAPuts("\"CHARSET\" "); - if (cbcharset == NULL) { - plain_imap_strout("US-ASCII"); - } - else if (cbcharset[0] == 0) { - plain_imap_strout("US-ASCII"); + if ((cbcharset == NULL) || (cbcharset[0] == 0)){ + IPutStr(HKEY("US-ASCII")); } else { - plain_imap_strout(cbcharset); + IPutStr(cbcharset, strlen(cbcharset)); } - IAPuts(") "); /* end body parameter list */ + IAPuts(") "); /* end body parameter list */ IAPuts("NIL "); /* Body ID */ IAPuts("NIL "); /* Body description */ - if (encoding != NULL) if (encoding[0] != 0) have_encoding = 1; + if ((encoding != NULL) && (encoding[0] != 0)) have_encoding = 1; if (have_encoding) { - plain_imap_strout(encoding); + IPutStr(encoding, strlen(encoding)); } else { - plain_imap_strout("7BIT"); + IPutStr(HKEY("7BIT")); } IAPuts(" "); @@ -935,18 +936,15 @@ void imap_fetch_bodystructure_part( IAPuts("NIL "); /* Disposition */ - if (disp == NULL) { - IAPuts("NIL"); - } - else if (IsEmptyStr(disp)) { + if ((disp == NULL) || IsEmptyStr(disp)) { IAPuts("NIL"); } else { IAPuts("("); - plain_imap_strout(disp); - if (filename != NULL) if (!IsEmptyStr(filename)) { + IPutStr(disp, strlen(disp)); + if ((filename != NULL) && (!IsEmptyStr(filename))) { IAPuts(" (\"FILENAME\" "); - plain_imap_strout(filename); + IPutStr(filename, strlen(filename)); IAPuts(")"); } IAPuts(")"); diff --git a/citadel/modules/imap/imap_list.c b/citadel/modules/imap/imap_list.c index 5640ec5db..14cd0476e 100644 --- a/citadel/modules/imap/imap_list.c +++ b/citadel/modules/imap/imap_list.c @@ -97,7 +97,7 @@ void imap_list_floors(char *verb, int num_patterns, StrBuf **patterns) } if (match) { IAPrintf("* %s (\\NoSelect \\HasChildren) \"/\" ", verb); - plain_imap_strout(fl->f_name); + IPutStr(fl->f_name, (fl->f_name)?strlen(fl->f_name):0); IAPuts("\r\n"); } } @@ -168,7 +168,8 @@ void imap_listroom(struct ctdlroom *qrbuf, void *data) } if (yes_output_this_room) { - imap_mailboxname(MailboxName, sizeof MailboxName, qrbuf); + long len; + len = imap_mailboxname(MailboxName, sizeof MailboxName, qrbuf); match = 0; for (i=0; inum_patterns; ++i) { if (imap_mailbox_matches_pattern(ChrPtr(ImapFilter->patterns[i]), MailboxName)) { @@ -177,7 +178,7 @@ void imap_listroom(struct ctdlroom *qrbuf, void *data) } if (match) { IAPrintf("* %s (%s) \"/\" ", ImapFilter->verb, return_options); - plain_imap_strout(MailboxName); + IPutStr(MailboxName, len); IAPuts("\r\n"); } } diff --git a/citadel/modules/imap/imap_tools.c b/citadel/modules/imap/imap_tools.c index bced70fd1..e32320d00 100644 --- a/citadel/modules/imap/imap_tools.c +++ b/citadel/modules/imap/imap_tools.c @@ -552,11 +552,12 @@ int imap_parameterize(citimap_command *Cmd) /* Convert a struct ctdlroom to an IMAP-compatible mailbox name. */ -void imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf) +long imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf) { char* bufend = buf+bufsize; struct floor *fl; char* p = buf; + const char *pend; /* For mailboxes, just do it straight. * Do the Cyrus-compatible thing: all private folders are @@ -565,13 +566,17 @@ void imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf) if (qrbuf->QRflags & QR_MAILBOX) { if (strcasecmp(qrbuf->QRname+11, MAILROOM) == 0) - toimap(p, bufend, "INBOX"); + { + pend = toimap(p, bufend, "INBOX"); + return pend - p; + } else { p = toimap(p, bufend, "INBOX"); if (p < bufend) *p++ = '/'; - toimap(p, bufend, qrbuf->QRname+11); + pend = toimap(p, bufend, qrbuf->QRname+11); + return pend - p; } } else @@ -582,7 +587,8 @@ void imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf) p = toimap(p, bufend, fl->f_name); if (p < bufend) *p++ = '/'; - toimap(p, bufend, qrbuf->QRname); + pend = toimap(p, bufend, qrbuf->QRname); + return pend - p; } } @@ -681,33 +687,6 @@ exit: return(ret); } -/* - * Output a struct internet_address_list in the form an IMAP client wants - */ -void imap_ial_out(struct internet_address_list *ialist) -{ - struct internet_address_list *iptr; - - if (ialist == NULL) { - IAPuts("NIL"); - return; - } - IAPuts("("); - - for (iptr = ialist; iptr != NULL; iptr = iptr->next) { - IAPuts("("); - plain_imap_strout(iptr->ial_name); - IAPuts(" NIL "); - plain_imap_strout(iptr->ial_user); - IAPuts(" "); - plain_imap_strout(iptr->ial_node); - IAPuts(")"); - } - - IAPuts(")"); -} - - /* * Determine whether the supplied string is a valid message set. @@ -979,42 +958,6 @@ void IReplyPrintf(const char *Format, ...) } - -/* Output a string to the IMAP client, either as a literal or quoted. - * (We do a literal if it has any double-quotes or backslashes.) */ - -void plain_imap_strout(char *buf) -{ - int i; - int is_literal = 0; - long Len; - citimap *Imap = IMAP; - - if (buf == NULL) { /* yeah, we handle this */ - IAPuts("NIL"); - return; - } - - Len = strlen(buf); - for (i = 0; i < Len; ++i) { - if ((buf[i] == '\"') || (buf[i] == '\\')) - is_literal = 1; - } - - if (is_literal) { - StrBufAppendPrintf(Imap->Reply, "{%ld}\r\n", Len); - StrBufAppendBufPlain(Imap->Reply, buf, Len, 0); - } else { - StrBufAppendBufPlain(Imap->Reply, - HKEY("\""), 0); - StrBufAppendBufPlain(Imap->Reply, - buf, Len, 0); - StrBufAppendBufPlain(Imap->Reply, - HKEY("\""), 0); - } -} - - /* Output a string to the IMAP client, either as a literal or quoted. * (We do a literal if it has any double-quotes or backslashes.) */ diff --git a/citadel/modules/imap/imap_tools.h b/citadel/modules/imap/imap_tools.h index 099d9c39b..2117a6ef4 100644 --- a/citadel/modules/imap/imap_tools.h +++ b/citadel/modules/imap/imap_tools.h @@ -24,10 +24,8 @@ int CmdAdjust(citimap_command *Cmd, void imap_strout(ConstStr *args); void imap_strbuffer(StrBuf *Reply, ConstStr *args); void plain_imap_strbuffer(StrBuf *Reply, char *buf); -void plain_imap_strout(char *buf); int imap_parameterize(citimap_command *Cmd); -void imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf); -void imap_ial_out(struct internet_address_list *ialist); +long imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf); int imap_roomname(char *buf, int bufsize, const char *foldername); int imap_is_message_set(const char *); int imap_mailbox_matches_pattern(const char *pattern, char *mailboxname); @@ -53,5 +51,5 @@ void IReplyPrintf(const char *Format, ...); void IPutStr(const char *Msg, long Len); #define IPutCStr(_ConstStr) IPutStr(CKEY(_ConstStr)) #define IPutCParamStr(n) IPutStr(CKEY(Params[n])) - +#define IPutMsgField(Which) IPutStr(CM_KEY(msg, Which)) void IUnbuffer (void); diff --git a/citadel/modules/imap/serv_imap.c b/citadel/modules/imap/serv_imap.c index 7fb85e7f7..5a1e6aaea 100644 --- a/citadel/modules/imap/serv_imap.c +++ b/citadel/modules/imap/serv_imap.c @@ -985,6 +985,7 @@ void imap_close(int num_parms, ConstStr *Params) */ void imap_namespace(int num_parms, ConstStr *Params) { + long len; int i; struct floor *fl; int floors = 0; @@ -1005,8 +1006,8 @@ void imap_namespace(int num_parms, ConstStr *Params) if (fl->f_flags & F_INUSE) { /* if (floors > 0) IAPuts(" "); samjam says this confuses javamail */ IAPuts("("); - snprintf(Namespace, sizeof(Namespace), "%s/", fl->f_name); - plain_imap_strout(Namespace); + len = snprintf(Namespace, sizeof(Namespace), "%s/", fl->f_name); + IPutStr(Namespace, len); IAPuts(" \"/\")"); ++floors; } @@ -1158,6 +1159,7 @@ int imap_grabroom(char *returned_roomname, const char *foldername, int zapped_ok */ void imap_status(int num_parms, ConstStr *Params) { + long len; int ret; char roomname[ROOMNAMELEN]; char imaproomname[SIZ]; @@ -1186,9 +1188,9 @@ void imap_status(int num_parms, ConstStr *Params) * names and simply spew all possible data items. It's far easier to * code and probably saves us some processing time too. */ - imap_mailboxname(imaproomname, sizeof imaproomname, &CC->room); + len = imap_mailboxname(imaproomname, sizeof imaproomname, &CC->room); IAPuts("* STATUS "); - plain_imap_strout(imaproomname); + IPutStr(imaproomname, len); IAPrintf(" (MESSAGES %d ", msgs); IAPrintf("RECENT %d ", new); /* Initially, new==recent */ IAPrintf("UIDNEXT %ld ", CitControl.MMhighest + 1); diff --git a/citadel/msgbase.h b/citadel/msgbase.h index 058c902e5..a9a4eaba4 100644 --- a/citadel/msgbase.h +++ b/citadel/msgbase.h @@ -145,6 +145,8 @@ void CM_Free (struct CtdlMessage *msg); void CM_FreeContents (struct CtdlMessage *msg); int CM_IsValidMsg (struct CtdlMessage *msg); +#define CM_KEY(Message, Which) Message->cm_fields[Which], Message->cm_lengths[Which] + void CtdlSerializeMessage(struct ser_ret *, struct CtdlMessage *); void ReplicationChecks(struct CtdlMessage *); int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newmsgs, -- 2.30.2