]> code.citadel.org Git - citadel.git/blobdiff - webcit/messages.c
* more carefully render urls
[citadel.git] / webcit / messages.c
index a36bd38b4902497c97ed8f48f7ac5e2f9a4ad933..38298f799037e03e22915760d49aaa5aae88c8d5 100644 (file)
@@ -300,14 +300,15 @@ int webcit_rfc2047encode(char *target, int maxlen, char *source, long SourceLen)
 
        if (!need_to_encode) {
                memcpy (target, source, SourceLen);
+               target[SourceLen] = '\0';
                return SourceLen;
        }
        
        if (sizeof (headerStr + SourceLen + 2) > maxlen)
                return -1;
        memcpy (target, headerStr, sizeof (headerStr));
-       len = sizeof (headerStr);
-       for (i=0; (i < SourceLen) && (len < maxlen) ; ++i) {
+       len = sizeof (headerStr) - 1;
+       for (i=0; (i < SourceLen) && (len + 3< maxlen) ; ++i) {
                ch = (unsigned char) source[i];
                if ((ch < 32) || (ch > 126) || (ch == 61)) {
                        sprintf(&target[len], "=%02X", ch);
@@ -331,20 +332,23 @@ int webcit_rfc2047encode(char *target, int maxlen, char *source, long SourceLen)
 
 
 
-/**
- * \brief Look for URL's embedded in a buffer and make them linkable.  We use a
- * target window in order to keep the BBS session in its own window.
- * \param buf the message buffer
+/*
+ * Look for URL's embedded in a buffer and make them linkable.  We use a
+ * target window in order to keep the Citadel session in its own window.
  */
-void url(char *buf)
+void url(char *buf, size_t bufsize)
 {
-       int len;
+       int len, UrlLen, Offset, TrailerLen, outpos;
        char *start, *end, *pos;
        char urlbuf[SIZ];
-       char outbuf[1024];
+       char outbuf[SIZ];
 
        start = NULL;
        len = strlen(buf);
+       if (len > bufsize) {
+               lprintf(1, "URL: content longer than buffer!");
+               return;
+       }
        end = buf + len;
        for (pos = buf; (pos < end) && (start == NULL); ++pos) {
                if (!strncasecmp(pos, "http://", 7))
@@ -375,17 +379,33 @@ void url(char *buf)
                        end = pos;
                }
        }
+       
+       UrlLen = end - start;
+       if (UrlLen > sizeof(urlbuf)){
+               lprintf(1, "URL: content longer than buffer!");
+               return;
+       }
+       memcpy(urlbuf, start, UrlLen);
+       urlbuf[UrlLen] = '\0';
+
+       Offset = start - buf;
+       if ((Offset != 0) && (Offset < sizeof(outbuf)))
+               memcpy(outbuf, buf, Offset);
+       outpos = snprintf(&outbuf[Offset], sizeof(outbuf) - Offset,  
+                         "%ca href=%c%s%c TARGET=%c%s%c%c%s%c/A%c",
+                         LB, QU, urlbuf, QU, QU, TARGET, QU, RB, urlbuf, LB, RB);
+       if (outpos >= sizeof(outbuf) - Offset) {
+               lprintf(1, "URL: content longer than buffer!");
+               return;
+       }
 
-       strncpy(urlbuf, start, end - start);
-       urlbuf[end - start] = '\0';
-
-       if (start != buf)
-               strncpy(outbuf, buf, start - buf );
-       sprintf(&outbuf[start-buf], "%ca href=%c%s%c TARGET=%c%s%c%c%s%c/A%c",
-               LB, QU, urlbuf, QU, QU, TARGET, QU, RB, urlbuf, LB, RB);
-       strcat(outbuf, end);
-       if ( strlen(outbuf) < 250 )
-               strcpy(buf, outbuf);
+       TrailerLen = len - (end - start);
+       memcpy(outbuf + Offset + outpos, end, TrailerLen);
+       if ( Offset + TrailerLen + outpos > bufsize) {
+               lprintf(1, "URL: content longer than buffer!");
+               return;
+       }
+       memcpy (buf, outbuf, Offset + TrailerLen + outpos);
 }
 
 
@@ -777,6 +797,7 @@ void read_message(long msgnum, int printable_view, char *section) {
        char reply_to[512] = "";
        char reply_all[4096] = "";
        char reply_references[1024] = "";
+       char reply_inreplyto[256] = "";
        char now[64] = "";
        int format_type = 0;
        int nhdr = 0;
@@ -849,15 +870,10 @@ void read_message(long msgnum, int printable_view, char *section) {
                        safestrncpy(m_subject, &buf[5], sizeof m_subject);
                }
                if (!strncasecmp(buf, "msgn=", 5)) {
-                       safestrncpy(reply_references, &buf[5], sizeof reply_references);
+                       safestrncpy(reply_inreplyto, &buf[5], sizeof reply_inreplyto);
                }
                if (!strncasecmp(buf, "wefw=", 5)) {
-                       int rrlen = strlen(reply_references);
-                       if (rrlen > 0) {
-                               strcpy(&reply_references[rrlen++], "|");
-                       }
-                       safestrncpy(&reply_references[rrlen], &buf[5],
-                               (sizeof(reply_references) - rrlen) );
+                       safestrncpy(reply_references, &buf[5], sizeof reply_references);
                }
                if (!strncasecmp(buf, "cccc=", 5)) {
                        int len;
@@ -1000,7 +1016,16 @@ void read_message(long msgnum, int printable_view, char *section) {
 
        }
 
-       /** Generate a reply-to address */
+       /* Trim down excessively long lists of thread references.  We eliminate the
+        * second one in the list so that the thread root remains intact.
+        */
+       int rrtok = num_tokens(reply_references, '|');
+       int rrlen = strlen(reply_references);
+       if ( ((rrtok >= 3) && (rrlen > 900)) || (rrtok > 10) ) {
+               remove_token(reply_references, 1, '|');
+       }
+
+       /* Generate a reply-to address */
        if (!IsEmptyStr(rfca)) {
                if (!IsEmptyStr(from)) {
                        snprintf(reply_to, sizeof(reply_to), "%s <%s>", from, rfca);
@@ -1046,10 +1071,12 @@ void read_message(long msgnum, int printable_view, char *section) {
                                if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%20");
                                urlescputs(m_subject);
                        }
+                       wprintf("?references=");
                        if (!IsEmptyStr(reply_references)) {
-                               wprintf("?references=");
                                urlescputs(reply_references);
+                               urlescputs("|");
                        }
+                       urlescputs(reply_inreplyto);
                        wprintf("\"><span>[</span>%s<span>]</span></a> ", _("Reply"));
                }
 
@@ -1065,10 +1092,12 @@ void read_message(long msgnum, int printable_view, char *section) {
                                        if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%20");
                                        urlescputs(m_subject);
                                }
+                               wprintf("?references=");
                                if (!IsEmptyStr(reply_references)) {
-                                       wprintf("?references=");
                                        urlescputs(reply_references);
+                                       urlescputs("|");
                                }
+                               urlescputs(reply_inreplyto);
                                wprintf("\"><span>[</span>%s<span>]</span></a> ", _("ReplyQuoted"));
                        }
                }
@@ -1086,10 +1115,12 @@ void read_message(long msgnum, int printable_view, char *section) {
                                if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%20");
                                urlescputs(m_subject);
                        }
+                       wprintf("?references=");
                        if (!IsEmptyStr(reply_references)) {
-                               wprintf("?references=");
                                urlescputs(reply_references);
+                               urlescputs("|");
                        }
+                       urlescputs(reply_inreplyto);
                        wprintf("\"><span>[</span>%s<span>]</span></a> ", _("ReplyAll"));
                }
 
@@ -1245,7 +1276,7 @@ void read_message(long msgnum, int printable_view, char *section) {
                                bq = 0;
                        }
                        wprintf("<tt>");
-                       url(buf);
+                       url(buf, sizeof(buf));
                        escputs(buf);
                        wprintf("</tt><br />\n");
                }
@@ -1664,7 +1695,7 @@ void pullquote_message(long msgnum, int forward_attachments, int include_headers
                                bq = 0;
                        }
                        wprintf("<tt>");
-                       url(buf);
+                       url(buf, sizeof(buf));
                        msgescputs1(buf);
                        wprintf("</tt><br />");
                }
@@ -1677,7 +1708,7 @@ void pullquote_message(long msgnum, int forward_attachments, int include_headers
                        strcat(buf, "\n");
                        msgescputs(buf);
                }
-       }
+       }//// TODO: charset? utf8?
 
        /** Unknown weirdness ... don't know how to handle this content type */
        else {
@@ -3109,15 +3140,17 @@ void post_message(void)
                } 
                lprintf(9, "Converted: %s\n", references);
 
-               if (GetHash(WCC->urlstrings, HKEY("subject"), &U)) {
-                       u = (urlcontent*) U;
+               if (havebstr("subject")) {
+                       char *Subj;
+                       size_t SLen;
                        /*
                         * make enough room for the encoded string; 
                         * plus the QP header 
                         */
-                       len = u->url_data_size * 3 + 32;
+                       Subj = xbstr("subject", &SLen);
+                       len = SLen * 3 + 32;
                        encoded_subject = malloc (len);
-                       len = webcit_rfc2047encode(encoded_subject, len, u->url_data, u->url_data_size);
+                       len = webcit_rfc2047encode(encoded_subject, len, Subj, SLen);
                        if (len < 0) {
                                free (encoded_subject);
                                return;
@@ -3312,11 +3345,10 @@ void display_enter(void)
                CmdBuf = (char*) malloc (len + 1);
 
                snprintf(CmdBuf, len, CMD,
-                       Recp,
-                       is_anonymous,
-                       display_name,
-                       Cc, Bcc, Wikipage);
-               serv_puts(buf);
+                        Recp, is_anonymous,
+                        display_name,
+                        Cc, Bcc, Wikipage);
+               serv_puts(CmdBuf);
                serv_getln(buf, sizeof buf);
 
                if (!strncmp(buf, "570", 3)) {  /** 570 means we have an invalid recipient listed */