Cleaned up some bad html
[citadel.git] / webcit / messages.c
index e3fc05d5334dda95933015e86b34927282a7ffc5..d4036a13386df7b803d25f1703e1f97fe79a06c1 100644 (file)
@@ -13,6 +13,8 @@
 #define SENDER_COL_WIDTH_PCT           30      /**< Mailbox view column width */
 #define DATE_PLUS_BUTTONS_WIDTH_PCT    20      /**< Mailbox view column width */
 
+void display_enter(void);
+
 /*
  * Address book entry (keep it short and sweet, it's just a quickie lookup
  * which we can use to get to the real meat and bones later)
@@ -661,14 +663,14 @@ void display_parsed_vcard(struct vCard *v, int full, long msgnum) {
                                        wprintf("</TD></TR>\n");
                                }
                        }
-                       else if (!strcasecmp(firsttoken, "photo") && full && pass == 2) { 
+                       /* else if (!strcasecmp(firsttoken, "photo") && full && pass == 2) { 
                                // Only output on second pass
                                wprintf("<tr><td>");
                                wprintf(_("Photo:"));
                                wprintf("</td><td>");
                                wprintf("<img src=\"/vcardphoto/%ld/\" alt=\"Contact photo\"/>",msgnum);
                                wprintf("</td></tr>\n");
-                       }
+                       } */
                        else if (!strcasecmp(firsttoken, "version")) {
                                /* ignore */
                        }
@@ -1069,6 +1071,8 @@ void read_message(long msgnum, int printable_view, char *section) {
 
         /** start msg buttons */
 
+       char Urlsep = '?';
+
         if (!printable_view) {
                 wprintf("<p id=\"msg%ld\" class=\"msgbuttons\" >\n",msgnum);
 
@@ -1076,16 +1080,18 @@ void read_message(long msgnum, int printable_view, char *section) {
                if ( (WC->wc_view == VIEW_MAILBOX) || (WC->wc_view == VIEW_BBS) ) {
                        wprintf("<a href=\"display_enter");
                        if (WC->is_mailbox) {
-                               wprintf("?replyquote=%ld", msgnum);
+                               wprintf("%creplyquote=%ld", Urlsep, msgnum);
+                               Urlsep = '&';
                        }
-                       wprintf("?recp=");
+                       wprintf("%crecp=", Urlsep);
+                       Urlsep = '&';
                        urlescputs(reply_to);
                        if (!IsEmptyStr(m_subject)) {
-                               wprintf("?subject=");
+                               wprintf("%csubject=", Urlsep);
                                if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%%20");
                                urlescputs(m_subject);
                        }
-                       wprintf("?references=");
+                       wprintf("%creferences=", Urlsep);
                        if (!IsEmptyStr(reply_references)) {
                                urlescputs(reply_references);
                                urlescputs("|");
@@ -1099,14 +1105,14 @@ void read_message(long msgnum, int printable_view, char *section) {
                        if (!WC->is_mailbox) {
                                wprintf("<a href=\"display_enter");
                                wprintf("?replyquote=%ld", msgnum);
-                               wprintf("?recp=");
+                               wprintf("&recp=");
                                urlescputs(reply_to);
                                if (!IsEmptyStr(m_subject)) {
-                                       wprintf("?subject=");
+                                       wprintf("&subject=");
                                        if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%%20");
                                        urlescputs(m_subject);
                                }
-                               wprintf("?references=");
+                               wprintf("&references=");
                                if (!IsEmptyStr(reply_references)) {
                                        urlescputs(reply_references);
                                        urlescputs("|");
@@ -1120,16 +1126,16 @@ void read_message(long msgnum, int printable_view, char *section) {
                if (WC->wc_view == VIEW_MAILBOX) {
                        wprintf("<a href=\"display_enter");
                        wprintf("?replyquote=%ld", msgnum);
-                       wprintf("?recp=");
+                       wprintf("&recp=");
                        urlescputs(reply_to);
-                       wprintf("?cc=");
+                       wprintf("&cc=");
                        urlescputs(reply_all);
                        if (!IsEmptyStr(m_subject)) {
-                               wprintf("?subject=");
+                               wprintf("&subject=");
                                if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%%20");
                                urlescputs(m_subject);
                        }
-                       wprintf("?references=");
+                       wprintf("&references=");
                        if (!IsEmptyStr(reply_references)) {
                                urlescputs(reply_references);
                                urlescputs("|");
@@ -1140,7 +1146,7 @@ void read_message(long msgnum, int printable_view, char *section) {
 
                /* Forward */
                if (WC->wc_view == VIEW_MAILBOX) {
-                       wprintf("<a href=\"display_enter?fwdquote=%ld?subject=", msgnum);
+                       wprintf("<a href=\"display_enter?fwdquote=%ld&subject=", msgnum);
                        if (strncasecmp(m_subject, "Fwd:", 4)) wprintf("Fwd:%%20");
                        urlescputs(m_subject);
                        wprintf("\"><span>[</span>%s<span>]</span></a> ", _("Forward"));
@@ -1299,7 +1305,7 @@ void read_message(long msgnum, int printable_view, char *section) {
 
        /* HTML is fun, but we've got to strip it first */
        else if (!strcasecmp(mime_content_type, "text/html")) {
-               output_html(mime_charset, (WC->wc_view == VIEW_WIKI ? 1 : 0));
+               output_html(mime_charset, (WC->wc_view == VIEW_WIKI ? 1 : 0), msgnum);
        }
 
        /* Unknown weirdness */
@@ -1341,7 +1347,7 @@ ENDBODY:  /* If there are attached submessages, display them now... */
                                || (!strcasecmp(&WC->wc_roomname[11], USERCONFIGROOM))
                                || (WC->wc_view == VIEW_ADDRESSBOOK)
                        ) {
-                               wprintf("<a href=\"edit_vcard?msgnum=%ld?partnum=%s\">",
+                               wprintf("<a href=\"edit_vcard?msgnum=%ld&partnum=%s\">",
                                        msgnum, vcard_partnum);
                                wprintf("[%s]</a>", _("edit"));
                        }
@@ -1390,13 +1396,11 @@ ENDBODY:        /* If there are attached submessages, display them now... */
  *
  * msgnum_as_string == Message number, as a string instead of as a long int
  */
-void embed_message(char *msgnum_as_string) {
+void embed_message(void) {
        long msgnum = 0L;
 
-       msgnum = atol(msgnum_as_string);
-       begin_ajax_response();
+       msgnum = StrTol(WC->UrlFragment1);
        read_message(msgnum, 0, "");
-       end_ajax_response();
 }
 
 
@@ -1405,19 +1409,19 @@ void embed_message(char *msgnum_as_string) {
  *
  * msgnum_as_string == Message number, as a string instead of as a long int
  */
-void print_message(char *msgnum_as_string) {
+void print_message(void) {
        long msgnum = 0L;
 
-       msgnum = atol(msgnum_as_string);
+       msgnum = StrTol(WC->UrlFragment1);
        output_headers(0, 0, 0, 0, 0, 0);
 
-       wprintf("Content-type: text/html\r\n"
+       hprintf("Content-type: text/html\r\n"
                "Server: %s\r\n"
                "Connection: close\r\n",
                PACKAGE_STRING);
        begin_burst();
 
-       wprintf("\r\n\r\n<html>\n<head><title>");
+       wprintf("\r\n<html>\n<head><title>");
        escputs(WC->wc_fullname);
        wprintf("</title></head>\n"
                "<body onLoad=\" window.print(); window.close(); \">\n"
@@ -1429,21 +1433,34 @@ void print_message(char *msgnum_as_string) {
        wDumpContent(0);
 }
 
-
+/* 
+ * Mobile browser view of message
+ *
+ * @param msg_num_as_string Message number as a string instead of as a long int 
+ */
+void mobile_message_view(void) {
+  long msgnum = 0L;
+  msgnum = StrTol(WC->UrlFragment1);
+  output_headers(1, 0, 0, 0, 0, 1);
+  begin_burst();
+  do_template("msgcontrols", NULL);
+  read_message(msgnum,1, "");
+  wDumpContent(0);
+}
 
 /**
  * \brief Display a message's headers
  *
  * \param msgnum_as_string Message number, as a string instead of as a long int
  */
-void display_headers(char *msgnum_as_string) {
+void display_headers(void) {
        long msgnum = 0L;
        char buf[1024];
 
-       msgnum = atol(msgnum_as_string);
+       msgnum = StrTol(WC->UrlFragment1);
        output_headers(0, 0, 0, 0, 0, 0);
 
-       wprintf("Content-type: text/plain\r\n"
+       hprintf("Content-type: text/plain\r\n"
                "Server: %s\r\n"
                "Connection: close\r\n",
                PACKAGE_STRING);
@@ -1678,8 +1695,8 @@ void pullquote_message(long msgnum, int forward_attachments, int include_headers
                while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
                        int len;
                        len = strlen(buf);
-                       if (buf[len-1] == '\n') buf[--len] = 0;
-                       if (buf[len-1] == '\r') buf[--len] = 0;
+                       if ((len > 0) && (buf[len-1] == '\n')) buf[--len] = 0;
+                       if ((len > 0) && (buf[len-1] == '\r')) buf[--len] = 0;
 
 #ifdef HAVE_ICONV
                        if (ic != (iconv_t)(-1) ) {
@@ -1801,7 +1818,7 @@ void display_summarized(int num) {
        wprintf("<tr id=\"m%ld\" style=\"font-weight:%s;\" "
                "onMouseDown=\"CtdlMoveMsgMouseDown(event,%ld)\">",
                WC->summ[num].msgnum,
-               (WC->summ[num].is_new ? "bold" : "normal"),
+               ((WC->summ[num].is_new) ? "bold" : "normal"),
                WC->summ[num].msgnum
        );
 
@@ -1833,12 +1850,12 @@ void display_mobile_summary(int num) {
                (WC->summ[num].is_new ? "bold" : "normal"),
                WC->summ[num].msgnum
        );
-               wprintf("<span>%s</span>",WC->summ[num].from);
+               wprintf("<span class=\"from\">%s</span>",WC->summ[num].from);
                wprintf("<span style=\"float: right;\">");
                webcit_fmt_date(datebuf, WC->summ[num].date, 1);        /* brief */
-       escputs(datebuf);
+               escputs(datebuf);
                wprintf("</span><br/><span class=\"subject\">");
-               wprintf(WC->summ[num].subj);
+               escputs(WC->summ[num].subj);
                wprintf("</span></div><div id=\"m_%ld\" class=\"msgview\" onMouseDown=\"\"></div></div>",WC->summ[num].msgnum);
 }
 
@@ -1895,7 +1912,7 @@ void display_addressbook(long msgnum, char alpha) {
                                || (WC->wc_view == VIEW_ADDRESSBOOK)
                        ) {
                                wprintf("<a href=\"edit_vcard?"
-                                       "msgnum=%ld?partnum=%s\">",
+                                       "msgnum=%ld&partnum=%s\">",
                                        msgnum, vcard_partnum);
                                wprintf("[%s]</a>", _("edit"));
                        }
@@ -2101,7 +2118,7 @@ void do_addrbook_view(struct addrbookent *addrbook, int num_ab) {
        
                wprintf("<td>");
 
-               wprintf("<a href=\"readfwd?startmsg=%ld&is_singlecard=1",
+               wprintf("<a href=\"readfwd?startmsg=%ld?is_singlecard=1",
                        addrbook[i].ab_msgnum);
                wprintf("?maxmsgs=1?is_summary=0?alpha=%s\">", bstr("alpha"));
                vcard_n_prettyize(addrbook[i].ab_name);
@@ -2110,9 +2127,20 @@ void do_addrbook_view(struct addrbookent *addrbook, int num_ab) {
                ++displayed;
        }
 
+       /* Placeholders for empty columns at end */
+       if ((num_ab % 4) != 0) {
+               for (i=0; i<(4-(num_ab % 4)); ++i) {
+                       wprintf("<td>&nbsp;</td>");
+               }
+       }
+
        wprintf("</tr></table>\n");
        end_tab((num_pages-1), num_pages);
 
+       begin_tab(num_pages, num_pages);
+       /* FIXME there ought to be something here */
+       end_tab(num_pages, num_pages);
+
        for (i=0; i<num_pages; ++i) {
                free(tablabels[i]);
        }
@@ -2121,10 +2149,11 @@ void do_addrbook_view(struct addrbookent *addrbook, int num_ab) {
 
 
 
-/**
- * \brief load message pointers from the server
- * \param servcmd the citadel command to send to the citserver
- * \param with_headers what headers???
+/*
+ * load message pointers from the server for a "read messages" operation
+ *
+ * servcmd:            the citadel command to send to the citserver
+ * with_headers:       also include some of the headers with the message numbers (more expensive)
  */
 int load_msg_ptrs(char *servcmd, int with_headers)
 {
@@ -2222,11 +2251,9 @@ int load_msg_ptrs(char *servcmd, int with_headers)
 
 
 typedef int (*QSortFunction) (const void*, const void*);
-/**
- * \brief qsort() compatible function to compare two longs in descending order.
- *
- * \param s1 first number to compare 
- * \param s2 second number to compare
+
+/*
+ * qsort() compatible function to compare two longs in descending order.
  */
 int longcmp_r(const void *s1, const void *s2) {
        long l1;
@@ -2241,11 +2268,8 @@ int longcmp_r(const void *s1, const void *s2) {
 }
 
  
-/**
- * \brief qsort() compatible function to compare two message summary structs by ascending subject.
- *
- * \param s1 first item to compare 
- * \param s2 second item to compare
+/*
+ * qsort() compatible function to compare two message summary structs by ascending subject.
  */
 int summcmp_subj(const void *s1, const void *s2) {
        struct message_summary *summ1;
@@ -2256,11 +2280,8 @@ int summcmp_subj(const void *s1, const void *s2) {
        return strcasecmp(summ1->subj, summ2->subj);
 }
 
-/**
- * \brief qsort() compatible function to compare two message summary structs by descending subject.
- *
- * \param s1 first item to compare 
- * \param s2 second item to compare
+/*
+ * qsort() compatible function to compare two message summary structs by descending subject.
  */
 int summcmp_rsubj(const void *s1, const void *s2) {
        struct message_summary *summ1;
@@ -2271,11 +2292,8 @@ int summcmp_rsubj(const void *s1, const void *s2) {
        return strcasecmp(summ2->subj, summ1->subj);
 }
 
-/**
- * \brief qsort() compatible function to compare two message summary structs by ascending sender.
- *
- * \param s1 first item to compare 
- * \param s2 second item to compare
+/*
+ * qsort() compatible function to compare two message summary structs by ascending sender.
  */
 int summcmp_sender(const void *s1, const void *s2) {
        struct message_summary *summ1;
@@ -2286,11 +2304,8 @@ int summcmp_sender(const void *s1, const void *s2) {
        return strcasecmp(summ1->from, summ2->from);
 }
 
-/**
- * \brief qsort() compatible function to compare two message summary structs by descending sender.
- *
- * \param s1 first item to compare 
- * \param s2 second item to compare
+/*
+ * qsort() compatible function to compare two message summary structs by descending sender.
  */
 int summcmp_rsender(const void *s1, const void *s2) {
        struct message_summary *summ1;
@@ -2301,11 +2316,8 @@ int summcmp_rsender(const void *s1, const void *s2) {
        return strcasecmp(summ2->from, summ1->from);
 }
 
-/**
- * \brief qsort() compatible function to compare two message summary structs by ascending date.
- *
- * \param s1 first item to compare 
- * \param s2 second item to compare
+/*
+ * qsort() compatible function to compare two message summary structs by ascending date.
  */
 int summcmp_date(const void *s1, const void *s2) {
        struct message_summary *summ1;
@@ -2319,11 +2331,8 @@ int summcmp_date(const void *s1, const void *s2) {
        else return 0;
 }
 
-/**
- * \brief qsort() compatible function to compare two message summary structs by descending date.
- *
- * \param s1 first item to compare 
- * \param s2 second item to compare
+/*
+ * qsort() compatible function to compare two message summary structs by descending date.
  */
 int summcmp_rdate(const void *s1, const void *s2) {
        struct message_summary *summ1;
@@ -2361,7 +2370,7 @@ const char* SortIcons[3] = {
        eUnSet
 }; 
 
-/** SortEnum to plain string representation */
+/* SortEnum to plain string representation */
 static const char* SortByStrings[] = {
        "date",
        "rdate",
@@ -2373,7 +2382,7 @@ static const char* SortByStrings[] = {
        "unset"
 };
 
-/** SortEnum to sort-Function Table */
+/* SortEnum to sort-Function Table */
 const QSortFunction SortFuncs[eUnSet] = {
        summcmp_date,
        summcmp_rdate,
@@ -2384,24 +2393,23 @@ const QSortFunction SortFuncs[eUnSet] = {
        summcmp_rdate
 };
 
-/** given a SortEnum, which icon should we choose? */
+/* given a SortEnum, which icon should we choose? */
 const int SortDateToIcon[eUnSet] = { eUp, eDown, eNone, eNone, eNone, eNone, eNone};
 const int SortSubjectToIcon[eUnSet] = { eNone, eNone, eUp, eDown, eNone, eNone, eNone};
 const int SortSenderToIcon[eUnSet] = { eNone, eNone, eNone, eNone, eUp, eDown, eNone};
 
-/** given a SortEnum, which would be the "opposite" search option? */
+/* given a SortEnum, which would be the "opposite" search option? */
 const int DateInvertSortString[eUnSet] =  { eRDate, eDate, eDate, eDate, eDate, eDate, eDate};
 const int SubjectInvertSortString[eUnSet] =  { eSubject, eSubject, eRSubject, eUnSet, eSubject, eSubject, eSubject};
 const int SenderInvertSortString[eUnSet] =  { eSender, eSender, eSender, eSender, eRSender, eUnSet, eSender};
 
 
-/**
- * \Brief Translates sortoption String to its SortEnum representation 
- * \param SortBy string to translate
- * \return the enum matching the string; defaults to RDate
+/*
+ * Translates sortoption String to its SortEnum representation 
+ * returns the enum matching the string; defaults to RDate
  */
 //SortByEnum 
-int StrToESort (StrBuf *sortby)
+int StrToESort (const StrBuf *sortby)
 {
        int result = eDate;
 
@@ -2417,10 +2425,10 @@ int StrToESort (StrBuf *sortby)
 
 
 
-/**
- * \brief command loop for reading messages
+/*
+ * command loop for reading messages
  *
- * \param oper Set to "readnew" or "readold" or "readfwd" or "headers"
+ * Set oper to "readnew" or "readold" or "readfwd" or "headers"
  */
 void readloop(char *oper)
 {
@@ -2445,16 +2453,15 @@ void readloop(char *oper)
        int highest_displayed = 0;
        struct addrbookent *addrbook = NULL;
        int num_ab = 0;
-       StrBuf *sortby = NULL;
+       const StrBuf *sortby = NULL;
        //SortByEnum 
        int SortBy = eRDate;
-       StrBuf *sortpref_name;
-       StrBuf *sortpref_value;
+       const StrBuf *sortpref_value;
        int bbs_reverse = 0;
        struct wcsession *WCC = WC;     /* This is done to make it run faster; WC is a function */
 
        if (WCC->wc_view == VIEW_WIKI) {
-               sprintf(buf, "wiki?room=%s?page=home", WCC->wc_roomname);
+               sprintf(buf, "wiki?room=%s&page=home", WCC->wc_roomname);
                http_redirect(buf);
                return;
        }
@@ -2464,21 +2471,18 @@ void readloop(char *oper)
        is_summary = (ibstr("is_summary") && !WCC->is_mobile);
        if (maxmsgs == 0) maxmsgs = DEFAULT_MAXMSGS;
 
-       sortpref_name = NewStrBuf ();
-       StrBufPrintf(sortpref_name, "sort %s", WCC->wc_roomname);
-       get_pref(sortpref_name, &sortpref_value);
+       sortpref_value = get_room_pref("sort");
 
-       sortby = NewStrBufPlain(bstr("sortby"), -1);
+       sortby = sbstr("sortby");
        if ( (!IsEmptyStr(ChrPtr(sortby))) && 
             (strcasecmp(ChrPtr(sortby), ChrPtr(sortpref_value)) != 0)) {
-               set_pref(sortpref_name, sortby, 1);
+               set_room_pref("sort", NewStrBufDup(sortby), 1);
                sortpref_value = NULL;
                sortpref_value = sortby;
        }
-       
-       FreeStrBuf(&sortpref_name);
+
        SortBy = StrToESort(sortpref_value);
-       /** message board sort */
+       /* message board sort */
        if (SortBy == eReverse) {
                bbs_reverse = 1;
        }
@@ -2488,7 +2492,7 @@ void readloop(char *oper)
 
        output_headers(1, 1, 1, 0, 0, 0);
 
-       /**
+       /*
         * When in summary mode, always show ALL messages instead of just
         * new or old.  Otherwise, show what the user asked for.
         */
@@ -2526,7 +2530,7 @@ void readloop(char *oper)
                maxmsgs = 9999999;
        }
 
-       if (is_summary || WCC->is_mobile) {                     /**< fetch header summary */
+       if (is_summary) {                       /**< fetch header summary */
                snprintf(cmd, sizeof(cmd), "MSGS %s|%s||1",
                        (!strcmp(oper, "do_search") ? "SEARCH" : "ALL"),
                        (!strcmp(oper, "do_search") ? bstr("query") : "")
@@ -2536,10 +2540,14 @@ void readloop(char *oper)
        } 
        if (WCC->is_mobile) {
                maxmsgs = 20;
+               snprintf(cmd, sizeof(cmd), "MSGS %s|%s||1",
+                       (!strcmp(oper, "do_search") ? "SEARCH" : "ALL"),
+                       (!strcmp(oper, "do_search") ? bstr("query") : "")
+               );
                SortBy =  eRDate;
        }
 
-       /**
+       /*
         * Are we doing a summary view?  If so, we need to know old messages
         * and new messages, so we can do that pretty boldface thing for the
         * new messages.
@@ -2703,9 +2711,9 @@ void readloop(char *oper)
                                if (lo < 1) lo = 1;
                                wprintf("<option %s value="
                                        "\"%s"
-                                       "?startmsg=%ld"
-                                       "?maxmsgs=%d"
-                                       "?is_summary=%d\">"
+                                       "&startmsg=%ld"
+                                       "&maxmsgs=%d"
+                                       "&is_summary=%d\">"
                                        "%d-%d</option> \n",
                                        ((WCC->msgarr[lo-1] == startmsg) ? "selected" : ""),
                                        oper,
@@ -2722,9 +2730,9 @@ void readloop(char *oper)
                                if (hi > nummsgs) hi = nummsgs;
                                wprintf("<option %s value="
                                        "\"%s"
-                                       "?startmsg=%ld"
-                                       "?maxmsgs=%d"
-                                       "?is_summary=%d\">"
+                                       "&startmsg=%ld"
+                                       "&maxmsgs=%d"
+                                       "&is_summary=%d\">"
                                        "%d-%d</option> \n",
                                        ((WCC->msgarr[b] == startmsg) ? "selected" : ""),
                                        oper,
@@ -2736,7 +2744,7 @@ void readloop(char *oper)
                }
 
                wprintf("<option value=\"%s?startmsg=%ld"
-                       "?maxmsgs=9999999?is_summary=%d\">",
+                       "&maxmsgs=9999999&is_summary=%d\">",
                        oper,
                        WCC->msgarr[0], is_summary);
                wprintf(_("All"));
@@ -2870,9 +2878,9 @@ void readloop(char *oper)
                                if (lo < 1) lo = 1;
                                wprintf("<option %s value="
                                        "\"%s"
-                                       "?startmsg=%ld"
-                                       "?maxmsgs=%d"
-                                       "?is_summary=%d\">"
+                                       "&startmsg=%ld"
+                                       "&maxmsgs=%d"
+                                       "&is_summary=%d\">"
                                        "%d-%d</option> \n",
                                        ((WCC->msgarr[lo-1] == startmsg) ? "selected" : ""),
                                        oper,
@@ -2889,9 +2897,9 @@ void readloop(char *oper)
                                if (hi > nummsgs) hi = nummsgs;
                                wprintf("<option %s value="
                                        "\"%s"
-                                       "?startmsg=%ld"
-                                       "?maxmsgs=%d"
-                                       "?is_summary=%d\">"
+                                       "&startmsg=%ld"
+                                       "&maxmsgs=%d"
+                                       "&is_summary=%d\">"
                                        "%d-%d</option> \n",
                                        ((WCC->msgarr[b] == startmsg) ? "selected" : ""),
                                        oper,
@@ -2902,8 +2910,8 @@ void readloop(char *oper)
                        }
                }
 
-               wprintf("<option value=\"%s?startmsg=%ld"
-                       "?maxmsgs=9999999?is_summary=%d\">",
+               wprintf("<option value=\"%s&startmsg=%ld"
+                       "&maxmsgs=9999999&is_summary=%d\">",
                        oper,
                        WCC->msgarr[0], is_summary);
                wprintf(_("All"));
@@ -2913,7 +2921,7 @@ void readloop(char *oper)
 
                /** forward/reverse */
                wprintf("<input type=\"radio\" %s name=\"direction\" value=\"\""
-                       "OnChange=\"location.href='%s?sortby=forward'\"",  
+                       "OnChange=\"location.href='%s&sortby=forward'\"",  
                        (bbs_reverse ? "" : "checked"),
                        oper
                );
@@ -2921,7 +2929,7 @@ void readloop(char *oper)
                wprintf(_("oldest to newest"));
                wprintf("&nbsp;&nbsp;&nbsp;&nbsp;");
                wprintf("<input type=\"radio\" %s name=\"direction\" value=\"\""
-                       "OnChange=\"location.href='%s?sortby=reverse'\"", 
+                       "OnChange=\"location.href='%s&sortby=reverse'\"", 
                        (bbs_reverse ? "checked" : ""),
                        oper
                );
@@ -3066,33 +3074,24 @@ void post_mime_to_server(void) {
  */
 void post_message(void)
 {
-       urlcontent *u;
-       void *U;
        char buf[1024];
-       char *encoded_subject = NULL;
+       StrBuf *encoded_subject = NULL;
        static long dont_post = (-1L);
        struct wc_attachment *att, *aptr;
        int is_anonymous = 0;
-       const char *display_name;
-       long dpLen = 0;
+       const StrBuf *display_name = NULL;
        struct wcsession *WCC = WC;
-       char *ptr = NULL;
-
+       
        if (havebstr("force_room")) {
                gotoroom(bstr("force_room"));
        }
 
-       if (GetHash(WC->urlstrings, HKEY("display_name"), &U)) {
-               u = (urlcontent*) U;
-               display_name = u->url_data;
-               dpLen = u->url_data_size;
-       }
-       else {
-               display_name="";
-       }
-       if (!strcmp(display_name, "__ANONYMOUS__")) {
-               display_name = "";
-               is_anonymous = 1;
+       if (havebstr("display_name")) {
+               display_name = sbstr("display_name");
+               if (!strcmp(ChrPtr(display_name), "__ANONYMOUS__")) {
+                       display_name = NULL;
+                       is_anonymous = 1;
+               }
        }
 
        if (WCC->upload_length > 0) {
@@ -3151,71 +3150,66 @@ void post_message(void)
                        "saved this message."));
        } else {
                const char CMD[] = "ENT0 1|%s|%d|4|%s|%s||%s|%s|%s|%s|%s";
-               const char *Recp = ""; 
-               const char *Cc = "";
-               const char *Bcc = "";
-               const char *Wikipage = "";
-               const char *my_email_addr = "";
-               char *CmdBuf = NULL;;
-               long len = 0;
-               size_t nLen;
-               char references[SIZ] = "";
-               size_t references_len = 0;
-
-               safestrncpy(references, bstr("references"), sizeof references);
-               lprintf(9, "Converting: %s\n", references);
-               for (ptr=references; *ptr != 0; ++ptr) {
-                       if (*ptr == '|') *ptr = '!';
-                       ++references_len;
-               } 
-               lprintf(9, "Converted: %s\n", references);
-
+               const StrBuf *Recp = NULL; 
+               const StrBuf *Cc = NULL;
+               const StrBuf *Bcc = NULL;
+               const StrBuf *Wikipage = NULL;
+               const StrBuf *my_email_addr = NULL;
+               StrBuf *CmdBuf = NULL;;
+               StrBuf *references = NULL;
+
+               if (havebstr("references"))
+               {
+                       const StrBuf *ref = sbstr("references");
+                       references = NewStrBufPlain(ChrPtr(ref), StrLength(ref));
+                       lprintf(9, "Converting: %s\n", ChrPtr(references));
+                       StrBufReplaceChars(references, '|', '!');
+                       lprintf(9, "Converted: %s\n", ChrPtr(references));
+               }
                if (havebstr("subject")) {
-                       char *Subj;
-                       size_t SLen;
+                       const StrBuf *Subj;
                        /*
                         * make enough room for the encoded string; 
                         * plus the QP header 
                         */
-                       Subj = xbstr("subject", &SLen);
-                       len = SLen * 3 + 32;
-                       encoded_subject = malloc (len);
-                       len = webcit_rfc2047encode(encoded_subject, len, Subj, SLen);
-                       if (len < 0) {
-                               free (encoded_subject);
-                               return;
-                       }
-               }
-               len += sizeof (CMD) + dpLen;
-               Recp = xbstr("recp", &nLen);
-               len += nLen;
-               Cc = xbstr("cc", &nLen);
-               len += nLen;
-               Bcc = xbstr("bcc", &nLen);
-               len += nLen;
-               Wikipage = xbstr("wikipage", &nLen);
-               len += nLen;
-               my_email_addr = xbstr("my_email_addr", &nLen);
-               len += nLen;
-               len += references_len;
-
-               CmdBuf = (char*) malloc (len + 11);
-
-               snprintf(CmdBuf, len + 1, CMD,
-                       Recp,
-                       is_anonymous,
-                       (encoded_subject ? encoded_subject : ""),
-                       display_name,
-                       Cc,
-                       Bcc,
-                       Wikipage,
-                       my_email_addr,
-                       references);
+                       Subj = sbstr("subject");
+                       
+                       StrBufRFC2047encode(&encoded_subject, Subj);
+               }
+               Recp = sbstr("recp");
+               Cc = sbstr("cc");
+               Bcc = sbstr("bcc");
+               Wikipage = sbstr("wikipage");
+               my_email_addr = sbstr("my_email_addr");
+               
+               CmdBuf = NewStrBufPlain(NULL, 
+                                       sizeof (CMD) + 
+                                       StrLength(Recp) + 
+                                       StrLength(encoded_subject) +
+                                       StrLength(Cc) +
+                                       StrLength(Bcc) + 
+                                       StrLength(Wikipage) +
+                                       StrLength(my_email_addr) + 
+                                       StrLength(references));
+
+               StrBufPrintf(CmdBuf, 
+                            CMD,
+                            ChrPtr(Recp),
+                            is_anonymous,
+                            ChrPtr(encoded_subject),
+                            ChrPtr(display_name),
+                            ChrPtr(Cc),
+                            ChrPtr(Bcc),
+                            ChrPtr(Wikipage),
+                            ChrPtr(my_email_addr),
+                            ChrPtr(references));
+               FreeStrBuf(&references);
+
                lprintf(9, "%s\n", CmdBuf);
-               serv_puts(CmdBuf);
+               serv_puts(ChrPtr(CmdBuf));
                serv_getln(buf, sizeof buf);
-               free (CmdBuf);
-               if (encoded_subject) free(encoded_subject);
+               FreeStrBuf(&CmdBuf);
+               FreeStrBuf(&encoded_subject);
                if (buf[0] == '4') {
                        post_mime_to_server();
                        if (  (havebstr("recp"))
@@ -3271,15 +3265,14 @@ void display_enter(void)
        char buf[SIZ];
        StrBuf *ebuf;
        long now;
-       char *display_name;
+       const StrBuf *display_name = NULL;
        struct wc_attachment *att;
        int recipient_required = 0;
        int subject_required = 0;
        int recipient_bad = 0;
-       int i;
        int is_anonymous = 0;
        long existing_page = (-1L);
-       size_t dplen;
+       struct wcsession *WCC = WC;
 
        now = time(NULL);
 
@@ -3287,10 +3280,9 @@ void display_enter(void)
                gotoroom(bstr("force_room"));
        }
 
-       display_name = xbstr("display_name", &dplen);
-       if (!strcmp(display_name, "__ANONYMOUS__")) {
-               display_name = "";
-               dplen = 0;
+       display_name = sbstr("display_name");
+       if (!strcmp(ChrPtr(display_name), "__ANONYMOUS__")) {
+               display_name = NULL;
                is_anonymous = 1;
        }
 
@@ -3302,7 +3294,7 @@ void display_enter(void)
                recipient_required = 1;
        }
        else if (buf[0] != '2') {               /** Any other error means that we cannot continue */
-               sprintf(WC->ImportantMessage, "%s", &buf[4]);
+               sprintf(WCC->ImportantMessage, "%s", &buf[4]);
                readloop("readnew");
                return;
        }
@@ -3316,8 +3308,8 @@ void display_enter(void)
         * Are we perhaps in an address book view?  If so, then an "enter
         * message" command really means "add new entry."
         */
-       if (WC->wc_default_view == VIEW_ADDRESSBOOK) {
-               do_edit_vcard(-1, "", "", WC->wc_roomname);
+       if (WCC->wc_default_view == VIEW_ADDRESSBOOK) {
+               do_edit_vcard(-1, "", "", WCC->wc_roomname);
                return;
        }
 
@@ -3325,7 +3317,7 @@ void display_enter(void)
         * Are we perhaps in a calendar room?  If so, then an "enter
         * message" command really means "add new calendar item."
         */
-       if (WC->wc_default_view == VIEW_CALENDAR) {
+       if (WCC->wc_default_view == VIEW_CALENDAR) {
                display_edit_event();
                return;
        }
@@ -3334,7 +3326,7 @@ void display_enter(void)
         * Are we perhaps in a tasks view?  If so, then an "enter
         * message" command really means "add new task."
         */
-       if (WC->wc_default_view == VIEW_TASKS) {
+       if (WCC->wc_default_view == VIEW_TASKS) {
                display_edit_task();
                return;
        }
@@ -3352,34 +3344,37 @@ void display_enter(void)
 
        /* Now check our actual recipients if there are any */
        if (recipient_required) {
-               const char *Recp = ""; 
-               const char *Cc = "";
-               const char *Bcc = "";
-               const char *Wikipage = "";
-               char *CmdBuf = NULL;;
-               size_t len = 0;
-               size_t nLen;
+               const StrBuf *Recp = NULL; 
+               const StrBuf *Cc = NULL;
+               const StrBuf *Bcc = NULL;
+               const StrBuf *Wikipage = NULL;
+               StrBuf *CmdBuf = NULL;;
                const char CMD[] = "ENT0 0|%s|%d|0||%s||%s|%s|%s";
                
-               len = sizeof(CMD) + dplen;
-               Recp = xbstr("recp", &nLen);
-               len += nLen;
-               Cc = xbstr("cc", &nLen);
-               len += nLen;
-               Bcc = xbstr("bcc", &nLen);
-               len += nLen;
-               Wikipage = xbstr("wikipage", &nLen);
-               len += nLen;
+               Recp = sbstr("recp");
+               Cc = sbstr("cc");
+               Bcc = sbstr("bcc");
+               Wikipage = sbstr("wikipage");
                
-
-               CmdBuf = (char*) malloc (len + 1);
-
-               snprintf(CmdBuf, len, CMD,
-                        Recp, is_anonymous,
-                        display_name,
-                        Cc, Bcc, Wikipage);
-               serv_puts(CmdBuf);
+               CmdBuf = NewStrBufPlain(NULL, 
+                                       sizeof (CMD) + 
+                                       StrLength(Recp) + 
+                                       StrLength(display_name) +
+                                       StrLength(Cc) +
+                                       StrLength(Bcc) + 
+                                       StrLength(Wikipage));
+
+               StrBufPrintf(CmdBuf, 
+                            CMD,
+                            ChrPtr(Recp), 
+                            is_anonymous,
+                            ChrPtr(display_name),
+                            ChrPtr(Cc), 
+                            ChrPtr(Bcc), 
+                            ChrPtr(Wikipage));
+               serv_puts(ChrPtr(CmdBuf));
                serv_getln(buf, sizeof buf);
+               FreeStrBuf(&CmdBuf);
 
                if (!strncmp(buf, "570", 3)) {  /** 570 means we have an invalid recipient listed */
                        if (havebstr("recp") && 
@@ -3405,13 +3400,13 @@ void display_enter(void)
                "name=\"enterform\""
                ">\n");
        wprintf("<input type=\"hidden\" name=\"postseq\" value=\"%ld\">\n", now);
-       if (WC->wc_view == VIEW_WIKI) {
+       if (WCC->wc_view == VIEW_WIKI) {
                wprintf("<input type=\"hidden\" name=\"wikipage\" value=\"%s\">\n", bstr("wikipage"));
        }
        wprintf("<input type=\"hidden\" name=\"return_to\" value=\"%s\">\n", bstr("return_to"));
-       wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
+       wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WCC->nonce);
        wprintf("<input type=\"hidden\" name=\"force_room\" value=\"");
-       escputs(WC->wc_roomname);
+       escputs(WCC->wc_roomname);
        wprintf("\">\n");
        wprintf("<input type=\"hidden\" name=\"references\" value=\"");
        escputs(bstr("references"));
@@ -3463,9 +3458,9 @@ void display_enter(void)
                }
        }
 
-       if (WC->room_flags & QR_ANONOPT) {
+       if (WCC->room_flags & QR_ANONOPT) {
                wprintf("<option %s value=\"__ANONYMOUS__\">%s</option>\n",
-                       ((!strcasecmp(bstr("__ANONYMOUS__"), WC->wc_fullname)) ? "selected" : ""),
+                       ((!strcasecmp(bstr("__ANONYMOUS__"), WCC->wc_fullname)) ? "selected" : ""),
                        _("Anonymous")
                );
        }
@@ -3492,7 +3487,7 @@ void display_enter(void)
        }
 
        wprintf(_(" <I>in</I> "));
-       escputs(WC->wc_roomname);
+       escputs(WCC->wc_roomname);
 
        wprintf("</td></tr>");
 
@@ -3601,7 +3596,7 @@ void display_enter(void)
        }
 
        /** If we're editing a wiki page, insert the existing page here... */
-       else if (WC->wc_view == VIEW_WIKI) {
+       else if (WCC->wc_view == VIEW_WIKI) {
                safestrncpy(buf, bstr("wikipage"), sizeof buf);
                str_wiki_index(buf);
                existing_page = locate_message_by_uid(buf);
@@ -3611,38 +3606,44 @@ void display_enter(void)
        }
 
        /** Insert our signature if appropriate... */
-       if ( (WC->is_mailbox) && yesbstr("sig_inserted") ) {
+       if ( (WCC->is_mailbox) && !yesbstr("sig_inserted") ) {
                int UseSig;
                get_pref_yesno("use_sig", &UseSig, 0);
                if (UseSig) {
-                       int len;
+                       StrBuf *Sig;
+                       const char *sig, *esig;
+
                        get_preference("signature", &ebuf);
-                       euid_unescapize(buf, ChrPtr(ebuf));/////TODO
+                       Sig = NewStrBuf();
+                       StrBufEUid_unescapize(Sig, ebuf);
+                       sig = ChrPtr(Sig);
+                       esig = sig + StrLength(Sig);
                        wprintf("<br>--<br>");
-                       len = strlen(buf);
-                       for (i=0; i<len; ++i) {
-                               if (buf[i] == '\n') {
+                       while (sig <= esig) {
+                               if (*sig == '\n') {
                                        wprintf("<br>");
                                }
-                               else if (buf[i] == '<') {
+                               else if (*sig == '<') {
                                        wprintf("&lt;");
                                }
-                               else if (buf[i] == '>') {
+                               else if (*sig == '>') {
                                        wprintf("&gt;");
                                }
-                               else if (buf[i] == '&') {
+                               else if (*sig == '&') {
                                        wprintf("&amp;");
                                }
-                               else if (buf[i] == '\"') {
+                               else if (*sig == '\"') {
                                        wprintf("&quot;");
                                }
-                               else if (buf[i] == '\'') {
+                               else if (*sig == '\'') {
                                        wprintf("&#39;");
                                }
-                               else if (isprint(buf[i])) {
-                                       wprintf("%c", buf[i]);
-                               }
+                               else /* since we're utf 8, is this a good idea? if (isprint(*sig))*/ {
+                                       wprintf("%c", *sig);
+                               } 
+                               sig ++;
                        }
+                       FreeStrBuf(&Sig);
                }
        }
 
@@ -3656,14 +3657,14 @@ void display_enter(void)
         * The following template embeds the TinyMCE richedit control, and automatically
         * transforms the textarea into a richedit textarea.
         */
-       do_template("richedit");
+       do_template("richedit", NULL);
 
        /** Enumerate any attachments which are already in place... */
        wprintf("<div class=\"attachment buttons\"><img src=\"static/diskette_24x.gif\" class=\"imgedit\" > ");
        wprintf(_("Attachments:"));
        wprintf(" ");
        wprintf("<select name=\"which_attachment\" size=1>");
-       for (att = WC->first_attachment; att != NULL; att = att->next) {
+       for (att = WCC->first_attachment; att != NULL; att = att->next) {
                wprintf("<option value=\"");
                urlescputs(att->filename);
                wprintf("\">");
@@ -3795,3 +3796,30 @@ void confirm_move_msg(void)
        wprintf("</CENTER>\n");
        wDumpContent(1);
 }
+
+void readnew(void) { readloop("readnew");}
+void readold(void) { readloop("readold");}
+void readfwd(void) { readloop("readfwd");}
+void headers(void) { readloop("headers");}
+void do_search(void) { readloop("do_search");}
+
+void 
+InitModule_MSG
+(void)
+{
+       WebcitAddUrlHandler(HKEY("readnew"), readnew, 0);
+       WebcitAddUrlHandler(HKEY("readold"), readold, 0);
+       WebcitAddUrlHandler(HKEY("readfwd"), readfwd, 0);
+       WebcitAddUrlHandler(HKEY("headers"), headers, 0);
+       WebcitAddUrlHandler(HKEY("do_search"), do_search, 0);
+       WebcitAddUrlHandler(HKEY("display_enter"), display_enter, 0);
+       WebcitAddUrlHandler(HKEY("post"), post_message, 0);
+       WebcitAddUrlHandler(HKEY("move_msg"), move_msg, 0);
+       WebcitAddUrlHandler(HKEY("delete_msg"), delete_msg, 0);
+       WebcitAddUrlHandler(HKEY("confirm_move_msg"), confirm_move_msg, 0);
+       WebcitAddUrlHandler(HKEY("msg"), embed_message, NEED_URL|AJAX);
+       WebcitAddUrlHandler(HKEY("printmsg"), print_message, NEED_URL);
+       WebcitAddUrlHandler(HKEY("mobilemsg"), mobile_message_view, NEED_URL);
+       WebcitAddUrlHandler(HKEY("msgheaders"), display_headers, NEED_URL);
+       return ;
+}