MSG: the database returns the buffer size, not the stringlength.
[citadel.git] / citadel / msgbase.c
index d9629700fcd3736ed516a2a72614f9ecf5c78acd..21c1aabb41bb16ff61581832b76673965439f7c0 100644 (file)
@@ -941,7 +941,6 @@ void memfmout(
                        MSGM_syslog(LOG_ERR, "memfmout(): aborting due to write failure.\n");
                        return;
                }
-               len = 0;
                client_write(nl, nllen);
                column = 0;
        }
@@ -1130,6 +1129,13 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body)
        ret->cm_anon_type = *mptr++;    /* Anon type byte */
        ret->cm_format_type = *mptr++;  /* Format type byte */
 
+
+       if (dmsgtext->ptr[dmsgtext->len - 1] != '\0')
+       {
+               MSG_syslog(LOG_ERR, "CtdlFetchMessage(%ld, %d) Forcefully terminating message!!\n", msgnum, with_body);
+               dmsgtext->ptr[dmsgtext->len - 1] = '\0';
+       }
+
        /*
         * The rest is zero or more arbitrary fields.  Load them in.
         * We're done when we encounter either a zero-length field or
@@ -1159,7 +1165,7 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body)
        if ( (CM_IsEmpty(ret, eMesageText)) && (with_body) ) {
                dmsgtext = cdb_fetch(CDB_BIGMSGS, &msgnum, sizeof(long));
                if (dmsgtext != NULL) {
-                       CM_SetAsField(ret, eMesageText, &dmsgtext->ptr, dmsgtext->len);
+                       CM_SetAsField(ret, eMesageText, &dmsgtext->ptr, dmsgtext->len - 1);
                        cdb_free(dmsgtext);
                }
        }
@@ -1585,21 +1591,20 @@ int CtdlOutputMsg(long msg_num,         /* message number (local) to fetch */
        if (section) if (!IsEmptyStr(section)) if (strcmp(section, "0")) {
                memset(&encap, 0, sizeof encap);
                safestrncpy(encap.desired_section, section, sizeof encap.desired_section);
-               mime_parser(TheMessage->cm_fields[eMesageText],
-                       NULL,
-                       *extract_encapsulated_message,
-                       NULL, NULL, (void *)&encap, 0
-               );
+               mime_parser(CM_RANGE(TheMessage, eMesageText),
+                           *extract_encapsulated_message,
+                           NULL, NULL, (void *)&encap, 0
+                       );
 
                if ((Author != NULL) && (*Author == NULL))
                {
-                       *Author = TheMessage->cm_fields[eAuthor];
-                       TheMessage->cm_fields[eAuthor] = NULL;
+                       long len;
+                       CM_GetAsField(TheMessage, eAuthor, Author, &len);
                }
                if ((Address != NULL) && (*Address == NULL))
                {       
-                       *Address = TheMessage->cm_fields[erFc822Addr];
-                       TheMessage->cm_fields[erFc822Addr] = NULL;
+                       long len;
+                       CM_GetAsField(TheMessage, erFc822Addr, Address, &len);
                }
                CM_Free(TheMessage);
                TheMessage = NULL;
@@ -1632,13 +1637,13 @@ int CtdlOutputMsg(long msg_num,         /* message number (local) to fetch */
                retcode = CtdlOutputPreLoadedMsg(TheMessage, mode, headers_only, do_proto, crlf, flags);
        if ((Author != NULL) && (*Author == NULL))
        {
-               *Author = TheMessage->cm_fields[eAuthor];
-               TheMessage->cm_fields[eAuthor] = NULL;
+               long len;
+               CM_GetAsField(TheMessage, eAuthor, Author, &len);
        }
        if ((Address != NULL) && (*Address == NULL))
        {       
-               *Address = TheMessage->cm_fields[erFc822Addr];
-               TheMessage->cm_fields[erFc822Addr] = NULL;
+               long len;
+               CM_GetAsField(TheMessage, erFc822Addr, Address, &len);
        }
 
        CM_Free(TheMessage);
@@ -2005,7 +2010,6 @@ int CtdlOutputPreLoadedMsg(
 ) {
        struct CitContext *CCC = CC;
        int i;
-       char *mptr = NULL;
        const char *nl; /* newline string */
        struct ma_info ma;
 
@@ -2037,7 +2041,7 @@ int CtdlOutputPreLoadedMsg(
         * Pad it with spaces in order to avoid changing the RFC822 length of the message.
         */
        if ( (flags & SUPPRESS_ENV_TO) && (!CM_IsEmpty(TheMessage, eenVelopeTo)) ) {
-               memset(TheMessage->cm_fields[eenVelopeTo], ' ', strlen(TheMessage->cm_fields[eenVelopeTo]));
+               memset(TheMessage->cm_fields[eenVelopeTo], ' ', TheMessage->cm_lengths[eenVelopeTo]);
        }
                
        /* Are we downloading a MIME component? */
@@ -2052,8 +2056,8 @@ int CtdlOutputPreLoadedMsg(
                                ERROR + RESOURCE_BUSY);
                } else {
                        /* Parse the message text component */
-                       mptr = TheMessage->cm_fields[eMesageText];
-                       mime_parser(mptr, NULL, *mime_download, NULL, NULL, NULL, 0);
+                       mime_parser(CM_RANGE(TheMessage, eMesageText),
+                                   *mime_download, NULL, NULL, NULL, 0);
                        /* If there's no file open by this time, the requested
                         * section wasn't found, so print an error
                         */
@@ -2079,8 +2083,8 @@ int CtdlOutputPreLoadedMsg(
                        /* Parse the message text component */
                        int found_it = 0;
 
-                       mptr = TheMessage->cm_fields[eMesageText];
-                       mime_parser(mptr, NULL, *mime_spew_section, NULL, NULL, (void *)&found_it, 0);
+                       mime_parser(CM_RANGE(TheMessage, eMesageText),
+                                   *mime_spew_section, NULL, NULL, (void *)&found_it, 0);
                        /* If section wasn't found, print an error
                         */
                        if (!found_it) {
@@ -2120,7 +2124,7 @@ int CtdlOutputPreLoadedMsg(
        strcpy(suser, "");
        strcpy(luser, "");
        strcpy(fuser, "");
-       strcpy(snode, NODENAME);
+       memcpy(snode, CFG_KEY(c_nodename) + 1);
        if (mode == MT_RFC822) 
                OutputRFC822MsgHeaders(
                        TheMessage,
@@ -2177,9 +2181,8 @@ START_TEXT:
        /* Tell the client about the MIME parts in this message */
        if (TheMessage->cm_format_type == FMT_RFC822) {
                if ( (mode == MT_CITADEL) || (mode == MT_MIME) ) {
-                       mptr = TheMessage->cm_fields[eMesageText];
                        memset(&ma, 0, sizeof(struct ma_info));
-                       mime_parser(mptr, NULL,
+                       mime_parser(CM_RANGE(TheMessage, eMesageText),
                                (do_proto ? *list_this_part : NULL),
                                (do_proto ? *list_this_pref : NULL),
                                (do_proto ? *list_this_suff : NULL),
@@ -2218,12 +2221,10 @@ START_TEXT:
         * message to the reader's screen width.
         */
        if (TheMessage->cm_format_type == FMT_CITADEL) {
-               mptr = TheMessage->cm_fields[eMesageText];
-
                if (mode == MT_MIME) {
                        cprintf("Content-type: text/x-citadel-variformat\n\n");
                }
-               memfmout(mptr, nl);
+               memfmout(TheMessage->cm_fields[eMesageText], nl);
        }
 
        /* If the message on disk is format 4 (MIME), we've gotta hand it
@@ -2239,17 +2240,17 @@ START_TEXT:
                        strcpy(ma.chosen_part, "1");
                        ma.chosen_pref = 9999;
                        ma.dont_decode = CCC->msg4_dont_decode;
-                       mime_parser(mptr, NULL,
-                               *choose_preferred, *fixed_output_pre,
-                               *fixed_output_post, (void *)&ma, 1);
-                       mime_parser(mptr, NULL,
-                               *output_preferred, NULL, NULL, (void *)&ma, 1);
+                       mime_parser(CM_RANGE(TheMessage, eMesageText),
+                                   *choose_preferred, *fixed_output_pre,
+                                   *fixed_output_post, (void *)&ma, 1);
+                       mime_parser(CM_RANGE(TheMessage, eMesageText),
+                                   *output_preferred, NULL, NULL, (void *)&ma, 1);
                }
                else {
                        ma.use_fo_hooks = 1;
-                       mime_parser(mptr, NULL,
-                               *fixed_output, *fixed_output_pre,
-                               *fixed_output_post, (void *)&ma, 0);
+                       mime_parser(CM_RANGE(TheMessage, eMesageText),
+                                   *fixed_output, *fixed_output_pre,
+                                   *fixed_output_post, (void *)&ma, 0);
                }
 
        }
@@ -2457,7 +2458,7 @@ long send_message(struct CtdlMessage *msg) {
        struct ser_ret smr;
        int is_bigmsg = 0;
        char *holdM = NULL;
-       long oldMLen = 0;
+       long holdMLen = 0;
 
        /* Get a new message number */
        newmsgid = get_new_message_number();
@@ -2478,7 +2479,7 @@ long send_message(struct CtdlMessage *msg) {
                        is_bigmsg = 1;
                        holdM = msg->cm_fields[eMesageText];
                        msg->cm_fields[eMesageText] = NULL;
-                       oldMLen = msg->cm_lengths[eMesageText];
+                       holdMLen = msg->cm_lengths[eMesageText];
                        msg->cm_lengths[eMesageText] = 0;
                }
        }
@@ -2488,6 +2489,7 @@ long send_message(struct CtdlMessage *msg) {
 
        if (is_bigmsg) {
                msg->cm_fields[eMesageText] = holdM;
+               msg->cm_lengths[eMesageText] = holdMLen;
        }
 
        if (smr.len == 0) {
@@ -2507,7 +2509,7 @@ long send_message(struct CtdlMessage *msg) {
                                  &newmsgid,
                                  (int)sizeof(long),
                                  holdM,
-                                 (oldMLen + 1)
+                                 (holdMLen + 1)
                                );
                }
                retval = newmsgid;
@@ -2966,29 +2968,31 @@ void quickie_message(const char *from,
        msg->cm_format_type = format_type;
 
        if (from != NULL) {
-               msg->cm_fields[eAuthor] = strdup(from);
+               CM_SetField(msg, eAuthor, from, strlen(from));
        }
        else if (fromaddr != NULL) {
-               msg->cm_fields[eAuthor] = strdup(fromaddr);
-               if (strchr(msg->cm_fields[eAuthor], '@')) {
-                       *strchr(msg->cm_fields[eAuthor], '@') = 0;
+               char *pAt;
+               CM_SetField(msg, eAuthor, fromaddr, strlen(fromaddr));
+               pAt = strchr(msg->cm_fields[eAuthor], '@');
+               if (pAt != NULL) {
+                       CM_CutFieldAt(msg, eAuthor, pAt - msg->cm_fields[eAuthor]);
                }
        }
        else {
                msg->cm_fields[eAuthor] = strdup("Citadel");
        }
 
-       if (fromaddr != NULL) msg->cm_fields[erFc822Addr] = strdup(fromaddr);
-       if (room != NULL) msg->cm_fields[eOriginalRoom] = strdup(room);
-       msg->cm_fields[eNodeName] = strdup(NODENAME);
+       if (fromaddr != NULL) CM_SetField(msg, erFc822Addr, fromaddr, strlen(fromaddr));
+       if (room != NULL) CM_SetField(msg, eOriginalRoom, room, strlen(room));
+       CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
        if (to != NULL) {
-               msg->cm_fields[eRecipient] = strdup(to);
+               CM_SetField(msg, eRecipient, to, strlen(to));
                recp = validate_recipients(to, NULL, 0);
        }
        if (subject != NULL) {
-               msg->cm_fields[eMsgSubject] = strdup(subject);
+               CM_SetField(msg, eMsgSubject, subject, strlen(subject));
        }
-       msg->cm_fields[eMesageText] = strdup(text);
+       CM_SetField(msg, eMesageText, text, strlen(text));
 
        CtdlSubmitMsg(msg, recp, room, 0);
        CM_Free(msg);
@@ -3432,6 +3436,7 @@ struct CtdlMessage *CtdlMakeMessageLen(
        }
        StrBufRFC2047encode(&FakeEncAuthor, FakeAuthor);
        CM_SetAsFieldSB(msg, eAuthor, &FakeEncAuthor);
+       FreeStrBuf(&FakeAuthor);
 
        if (CCC->room.QRflags & QR_MAILBOX) {           /* room */
                CM_SetField(msg, eOriginalRoom, &CCC->room.QRname[11], strlen(&CCC->room.QRname[11]));
@@ -3440,8 +3445,8 @@ struct CtdlMessage *CtdlMakeMessageLen(
                CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname));
        }
 
-       CM_SetField(msg, eNodeName, NODENAME, strlen(NODENAME));
-       CM_SetField(msg, eHumanNode, HUMANNODE, strlen(HUMANNODE));
+       CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
+       CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode));
 
        if (rcplen > 0) {
                CM_SetField(msg, eRecipient, recipient, rcplen);
@@ -3492,8 +3497,11 @@ struct CtdlMessage *CtdlMakeMessageLen(
                CM_SetField(msg, eMesageText, preformatted_text, textlen);
        }
        else {
-               preformatted_text = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0);
-               CM_SetField(msg, eMesageText, preformatted_text, strlen(preformatted_text));
+               StrBuf *MsgBody;
+               MsgBody = CtdlReadMessageBodyBuf(HKEY("000"), config.c_maxmsglen, NULL, 0, 0);
+               if (MsgBody != NULL) {
+                       CM_SetAsFieldSB(msg, eMesageText, &MsgBody);
+               }
        }
 
        return(msg);
@@ -3971,8 +3979,8 @@ void CtdlWriteObject(char *req_room,                      /* Room to stuff it in */
        msg->cm_format_type = 4;
        CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname));
        CM_SetField(msg, eOriginalRoom, req_room, strlen(req_room));
-       CM_SetField(msg, eNodeName, config.c_nodename, strlen(config.c_nodename));
-       CM_SetField(msg, eHumanNode, config.c_humannode, strlen(config.c_humannode));
+       CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
+       CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode));
        msg->cm_flags = flags;
        
        CM_SetAsFieldSB(msg, eMesageText, &encoded_message);