preserve stringlengths when outputting stuff in the imap module
authorWilfried Goesgens <dothebart@citadel.org>
Mon, 30 Sep 2013 21:20:25 +0000 (23:20 +0200)
committerWilfried Goesgens <dothebart@citadel.org>
Mon, 30 Sep 2013 21:20:25 +0000 (23:20 +0200)
citadel/genstamp.c
citadel/genstamp.h
citadel/internet_addressing.h
citadel/modules/imap/imap_acl.c
citadel/modules/imap/imap_fetch.c
citadel/modules/imap/imap_list.c
citadel/modules/imap/imap_tools.c
citadel/modules/imap/imap_tools.h
citadel/modules/imap/serv_imap.c
citadel/msgbase.h

index eb594119ab01eb8fc1f6adeb229aa1d6c2e15603..9c5ba5f3d6e613c3c1f15ecb2781ac3438a49bb5 100644 (file)
@@ -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;
 }
index 43208d9105caa5a18d4ece8180f1f54ce399bc4c..ffe0d9c015569d64ea76b594253a70079b6baf49 100644 (file)
@@ -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,
index 87d35b923ae60541d40ec0aca90beeecc29d2614..e40ff4f510cda09e69e60be7c85500e946c62780 100644 (file)
@@ -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);
index b1c1f0fe869666928d181823272296bde9d051b3..0cd272860dfd887c4cff122d3421360cd7517c02 100644 (file)
@@ -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));
                        }
index ed7f271651c79a7c71dc1801c8747fbfc7fd6240..407eed21fcbf2e2696a8c0bc5a35227eb1efcfa8 100644 (file)
@@ -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(")");
index 5640ec5db854d8e09af2a545a0882f45388711bd..14cd0476ecee1f613b20fe537bf9a7e08e4c258e 100644 (file)
@@ -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; i<ImapFilter->num_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");
                }
        }
index bced70fd1f3e4fd50a035b368d594a284ca3eebe..e32320d000beabe5286d46f08e4e256b7b8454a4 100644 (file)
@@ -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.) */
 
index 099d9c39b062bdffeca7761a2767001ea1a2a5f0..2117a6ef4006d2763308122b95025d06c79d6cb0 100644 (file)
@@ -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);
index 7fb85e7f7124f563b8b53eb514d64eefb8cfc3a3..5a1e6aaea706d6fe8b60d2a8a9768346df964db6 100644 (file)
@@ -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);
index 058c902e583d231f399fb6b094bd7b61b940f99d..a9a4eaba47a1ef0848d10b8c7138014d11f074b5 100644 (file)
@@ -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,