X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fmessages.c;h=90340896472e3686b4485c4fbbe558f4a8594816;hb=5685e790de93f77083ea240f474a4870b194c550;hp=61ce15f9dfe250238828233c058f9a1fd242278c;hpb=d998d3601407d81916625728dd26287a1bce71f4;p=citadel.git
diff --git a/webcit/messages.c b/webcit/messages.c
index 61ce15f9d..903408964 100644
--- a/webcit/messages.c
+++ b/webcit/messages.c
@@ -1,14 +1,11 @@
/*
* $Id$
- */
-/**
- * \defgroup MsgDisp Functions which deal with the fetching and displaying of messages.
- * \ingroup WebcitDisplayItems
+ *
+ * Functions which deal with the fetching and displaying of messages.
*
*/
-/*@{*/
+
#include "webcit.h"
-#include "vcard.h"
#include "webserver.h"
#include "groupdav.h"
@@ -16,7 +13,9 @@
#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)
*/
@@ -29,13 +28,13 @@ struct addrbookent {
#ifdef HAVE_ICONV
-/**
- * \brief Wrapper around iconv_open()
- * Our version adds aliases for non-standard Microsoft charsets
- * such as 'MS950', aliasing them to names like 'CP950'
+/*
+ * Wrapper around iconv_open()
+ * Our version adds aliases for non-standard Microsoft charsets
+ * such as 'MS950', aliasing them to names like 'CP950'
*
- * \param tocode Target encoding
- * \param fromcode Source encoding
+ * tocode Target encoding
+ * fromcode Source encoding
*/
iconv_t ctdl_iconv_open(const char *tocode, const char *fromcode)
{
@@ -54,14 +53,30 @@ iconv_t ctdl_iconv_open(const char *tocode, const char *fromcode)
}
-/**
- * \brief Handle subjects with RFC2047 encoding
- * such as:
+
+inline char *FindNextEnd (char *bptr)
+{
+ char * end;
+ /* Find the next ?Q? */
+ end = strchr(bptr + 2, '?');
+ if (end == NULL) return NULL;
+ if (((*(end + 1) == 'B') || (*(end + 1) == 'Q')) &&
+ (*(end + 2) == '?')) {
+ /* skip on to the end of the cluster, the next ?= */
+ end = strstr(end + 3, "?=");
+ }
+ else
+ /* sort of half valid encoding, try to find an end. */
+ end = strstr(bptr, "?=");
+ return end;
+}
+
+/*
+ * Handle subjects with RFC2047 encoding such as:
* =?koi8-r?B?78bP0s3Mxc7JxSDXz9rE1dvO2c3JINvB0sHNySDP?=
- * \param buf the stringbuffer to process
*/
void utf8ify_rfc822_string(char *buf) {
- char *start, *end;
+ char *start, *end, *next, *nextend, *ptr;
char newbuf[1024];
char charset[128];
char encoding[16];
@@ -74,25 +89,28 @@ void utf8ify_rfc822_string(char *buf) {
char *isav; /**< Saved pointer to input buffer */
char *osav; /**< Saved pointer to output buffer */
int passes = 0;
- int i;
+ int i, len, delta;
int illegal_non_rfc2047_encoding = 0;
- /** Sometimes, badly formed messages contain strings which were simply
+ /* Sometimes, badly formed messages contain strings which were simply
* written out directly in some foreign character set instead of
* using RFC2047 encoding. This is illegal but we will attempt to
* handle it anyway by converting from a user-specified default
* charset to UTF-8 if we see any nonprintable characters.
*/
- for (i=0; i \n",msgnum);
- /** Reply */
+ /* Reply */
if ( (WC->wc_view == VIEW_MAILBOX) || (WC->wc_view == VIEW_BBS) ) {
wprintf("is_mailbox) {
@@ -931,31 +1082,43 @@ void read_message(long msgnum, int printable_view, char *section) {
}
wprintf("?recp=");
urlescputs(reply_to);
- if (strlen(m_subject) > 0) {
+ if (!IsEmptyStr(m_subject)) {
wprintf("?subject=");
- if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%20");
+ if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%%20");
urlescputs(m_subject);
}
+ wprintf("?references=");
+ if (!IsEmptyStr(reply_references)) {
+ urlescputs(reply_references);
+ urlescputs("|");
+ }
+ urlescputs(reply_inreplyto);
wprintf("\">[%s] ", _("Reply"));
}
- /** ReplyQuoted */
+ /* ReplyQuoted */
if ( (WC->wc_view == VIEW_MAILBOX) || (WC->wc_view == VIEW_BBS) ) {
if (!WC->is_mailbox) {
wprintf(" 0) {
+ if (!IsEmptyStr(m_subject)) {
wprintf("?subject=");
- if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%20");
+ if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%%20");
urlescputs(m_subject);
}
+ wprintf("?references=");
+ if (!IsEmptyStr(reply_references)) {
+ urlescputs(reply_references);
+ urlescputs("|");
+ }
+ urlescputs(reply_inreplyto);
wprintf("\">[%s] ", _("ReplyQuoted"));
}
}
- /** ReplyAll */
+ /* ReplyAll */
if (WC->wc_view == VIEW_MAILBOX) {
wprintf(" 0) {
+ if (!IsEmptyStr(m_subject)) {
wprintf("?subject=");
- if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%20");
+ if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%%20");
urlescputs(m_subject);
}
+ wprintf("?references=");
+ if (!IsEmptyStr(reply_references)) {
+ urlescputs(reply_references);
+ urlescputs("|");
+ }
+ urlescputs(reply_inreplyto);
wprintf("\">[%s] ", _("ReplyAll"));
}
- /** Forward */
+ /* Forward */
if (WC->wc_view == VIEW_MAILBOX) {
wprintf("[%s] ", _("Forward"));
}
- /** If this is one of my own rooms, or if I'm an Aide or Room Aide, I can move/delete */
+ /* If this is one of my own rooms, or if I'm an Aide or Room Aide, I can move/delete */
if ( (WC->is_room_aide) || (WC->is_mailbox) || (WC->room_flags2 & QR2_COLLABDEL) ) {
/** Move */
wprintf("[%s] ",
@@ -993,33 +1162,46 @@ void read_message(long msgnum, int printable_view, char *section) {
);
}
- /** Headers */
+ /* Headers */
wprintf(""
"[%s]", msgnum, msgnum, _("Headers"));
- /** Print */
+ /* Print */
wprintf(""
"[%s]", msgnum, msgnum, _("Print"));
- wprintf("
");
+ size_t len;
+ if (!IsEmptyStr(mailto)) strcat(mailto, "
");
strcat(mailto,
"");
+ len = strlen(mailto);
+ urlesc(&mailto[len], SIZ - len, "\"");
+ len = strlen(mailto);
+ urlesc(&mailto[len], SIZ - len, fullname);
+ len = strlen(mailto);
+ urlesc(&mailto[len], SIZ - len, "\" <");
+ len = strlen(mailto);
+ urlesc(&mailto[len], SIZ - len, thisvalue);
+ len = strlen(mailto);
+ urlesc(&mailto[len], SIZ - len, ">");
strcat(mailto, "\">");
- stresc(&mailto[strlen(mailto)], thisvalue, 1, 1);
+ len = strlen(mailto);
+ stresc(mailto+len, SIZ - len, thisvalue, 1, 1);
strcat(mailto, "");
}
else if (!strcasecmp(firsttoken, "tel")) {
- if (strlen(phone) > 0) strcat(phone, "
");
+ if (!IsEmptyStr(phone)) strcat(phone, "
");
strcat(phone, thisvalue);
for (j=0; j");
for (j=0; j \n");
}
}
+ /* else if (!strcasecmp(firsttoken, "photo") && full && pass == 2) {
+ // Only output on second pass
+ wprintf("
");
else wprintf(" ");
@@ -531,6 +663,14 @@ void display_parsed_vcard(struct vCard *v, int full) {
wprintf(" \n");
+ } */
else if (!strcasecmp(firsttoken, "version")) {
/* ignore */
}
@@ -564,24 +704,24 @@ void display_parsed_vcard(struct vCard *v, int full) {
"");
escputs(fullname);
wprintf("");
- if (strlen(title) > 0) {
+ if (!IsEmptyStr(title)) {
wprintf("");
+ wprintf(_("Photo:"));
+ wprintf(" ");
+ wprintf("",msgnum);
+ wprintf(" \n", phone);
}
- if (strlen(mailto) > 0) {
+ if (!IsEmptyStr(mailto)) {
wprintf("");
wprintf(_("Telephone:"));
wprintf(" %s \n", mailto);
@@ -605,8 +745,10 @@ void display_parsed_vcard(struct vCard *v, int full) {
* \param alpha what???
* \param full should we usse all lines?
* \param storename where to store???
+ * \param msgnum Citadel message pointer
*/
-void display_vcard(char *vcard_source, char alpha, int full, char *storename) {
+void display_vcard(char *vcard_source, char alpha, int full, char *storename,
+ long msgnum) {
struct vCard *v;
char *name;
char buf[SIZ];
@@ -617,6 +759,7 @@ void display_vcard(char *vcard_source, char alpha, int full, char *storename) {
name = vcard_get_prop(v, "n", 1, 0, 0);
if (name != NULL) {
+ utf8ify_rfc822_string(name);
strcpy(buf, name);
this_alpha = buf[0];
}
@@ -628,7 +771,7 @@ void display_vcard(char *vcard_source, char alpha, int full, char *storename) {
|| ((isalpha(alpha)) && (tolower(alpha) == tolower(this_alpha)) )
|| ((!isalpha(alpha)) && (!isalpha(this_alpha)))
) {
- display_parsed_vcard(v, full);
+ display_parsed_vcard(v, full,msgnum);
}
vcard_free(v);
@@ -641,40 +784,45 @@ struct attach_link {
};
-/**
- * \brief I wanna SEE that message!
- * \param msgnum the citadel number of the message to display
- * \param printable_view are we doing a print view?
- * \param section Optional for encapsulated message/rfc822 submessage)
+/*
+ * I wanna SEE that message!
+ *
+ * msgnum Message number to display
+ * printable_view Nonzero to display a printable view
+ * section Optional for encapsulated message/rfc822 submessage
*/
void read_message(long msgnum, int printable_view, char *section) {
char buf[SIZ];
- char mime_partnum[256];
- char mime_name[256];
- char mime_filename[256];
- char mime_content_type[256];
- char mime_charset[256];
- char mime_disposition[256];
+ char mime_partnum[256] = "";
+ char mime_name[256] = "";
+ char mime_filename[256] = "";
+ char escaped_mime_filename[256] = "";
+ char mime_content_type[256] = "";
+ const char *mime_content_type_ptr;
+ char mime_charset[256] = "";
+ char mime_disposition[256] = "";
int mime_length;
struct attach_link *attach_links = NULL;
int num_attach_links = 0;
- char mime_submessages[256];
- char m_subject[256];
- char m_cc[1024];
- char from[256];
- char node[256];
- char rfca[256];
- char reply_to[512];
- char reply_all[4096];
- char now[64];
+ char mime_submessages[256] = "";
+ char m_subject[1024] = "";
+ char m_cc[1024] = "";
+ char from[256] = "";
+ char node[256] = "";
+ char rfca[256] = "";
+ 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;
int bq = 0;
int i = 0;
- char vcard_partnum[256];
- char cal_partnum[256];
+ char vcard_partnum[256] = "";
+ char cal_partnum[256] = "";
char *part_source = NULL;
- char msg4_partnum[32];
+ char msg4_partnum[32] = "";
#ifdef HAVE_ICONV
iconv_t ic = (iconv_t)(-1) ;
char *ibuf; /**< Buffer of characters to be converted */
@@ -684,13 +832,6 @@ void read_message(long msgnum, int printable_view, char *section) {
char *osav; /**< Saved pointer to output buffer */
#endif
- strcpy(from, "");
- strcpy(node, "");
- strcpy(rfca, "");
- strcpy(reply_to, "");
- strcpy(reply_all, "");
- strcpy(vcard_partnum, "");
- strcpy(cal_partnum, "");
strcpy(mime_content_type, "text/plain");
strcpy(mime_charset, "us-ascii");
strcpy(mime_submessages, "");
@@ -713,6 +854,7 @@ void read_message(long msgnum, int printable_view, char *section) {
/** begin message header table */
wprintf(" ");
-
-#ifdef HAVE_ICONV
utf8ify_rfc822_string(m_cc);
utf8ify_rfc822_string(m_subject);
-#endif
- if (strlen(m_cc) > 0) {
- wprintf(" ");
- }
- if (strlen(m_subject) > 0) {
- wprintf(" ");
- }
-
/** start msg buttons */
+
if (!printable_view) {
- wprintf("");
wprintf(_("E-mail:"));
wprintf(" %s
"); + wprintf(_("CC:")); + wprintf(" "); + escputs(m_cc); + wprintf("
"); + } + if (!IsEmptyStr(m_subject)) { + wprintf(" "); + } + wprintf(""); - /** Begin body */ + /* Begin body */ wprintf(" \n"); - /** end everythingamundo table */ + /* end everythingamundo table */ if (!printable_view) { wprintf("\n"); } @@ -1197,41 +1386,40 @@ ENDBODY: -/** - * \brief Unadorned HTML output of an individual message, suitable +/* + * Unadorned HTML output of an individual message, suitable * for placing in a hidden iframe, for printing, or whatever * - * \param msgnum_as_string Message number, as a string instead of as a long int + * 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(); } -/** - * \brief Printable view of a message +/* + * Printable view of a message * - * \param msgnum_as_string Message number, as a string instead of as a long int + * 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", - SERVER); + "Connection: close\r\n" + PACKAGE_STRING); begin_burst(); - wprintf("\r\n\r\n\n" - ""); @@ -1514,8 +1708,8 @@ void pullquote_message(long msgnum, int forward_attachments, int include_headers bq = 0; } wprintf(""); - url(buf); - msgescputs(buf); + url(buf, sizeof(buf)); + msgescputs1(buf); wprintf("
"); } wprintf("
"); @@ -1527,7 +1721,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 { @@ -1604,7 +1798,6 @@ ENDBODY: */ void display_summarized(int num) { char datebuf[64]; - wprintf("", WC->summ[num].msgnum, @@ -1613,7 +1806,8 @@ void display_summarized(int num) { ); wprintf(" \n"); } - - +/** + * \brief Output a message row for the mobile view + * \param The row number + */ +void display_mobile_summary(int num) { + char datebuf[64]; + wprintf("\n", SUBJ_COL_WIDTH_PCT); - escputs(WC->summ[num].subj); + + escputs(WC->summ[num].subj);//////////////////////////////////TODO: QP DECODE wprintf(" "); wprintf("", SENDER_COL_WIDTH_PCT); @@ -1621,14 +1815,32 @@ void display_summarized(int num) { wprintf(" "); wprintf("", DATE_PLUS_BUTTONS_WIDTH_PCT); - fmt_date(datebuf, WC->summ[num].date, 1); /* brief */ + webcit_fmt_date(datebuf, WC->summ[num].date, 1); /* brief */ escputs(datebuf); wprintf(" "); wprintf("",WC->summ[num].msgnum); +} /** * \brief display the adressbook overview @@ -1670,12 +1882,12 @@ void display_addressbook(long msgnum, char alpha) { } } - if (strlen(vcard_partnum) > 0) { + if (!IsEmptyStr(vcard_partnum)) { vcard_source = load_mimepart(msgnum, vcard_partnum); if (vcard_source != NULL) { /** Display the summary line */ - display_vcard(vcard_source, alpha, 0, NULL); + display_vcard(vcard_source, alpha, 0, NULL,msgnum); /** If it's my vCard I can edit it */ if ( (!strcasecmp(WC->wc_roomname, USERCONFIGROOM)) @@ -1731,7 +1943,7 @@ void fetch_ab_name(long msgnum, char *namebuf) { int mime_length; char vcard_partnum[SIZ]; char *vcard_source = NULL; - int i; + int i, len; struct message_summary summ; if (namebuf == NULL) return; @@ -1761,12 +1973,12 @@ void fetch_ab_name(long msgnum, char *namebuf) { } } - if (strlen(vcard_partnum) > 0) { + if (!IsEmptyStr(vcard_partnum)) { vcard_source = load_mimepart(msgnum, vcard_partnum); if (vcard_source != NULL) { /* Grab the name off the card */ - display_vcard(vcard_source, 0, 0, namebuf); + display_vcard(vcard_source, 0, 0, namebuf,msgnum); free(vcard_source); } @@ -1774,7 +1986,8 @@ void fetch_ab_name(long msgnum, char *namebuf) { lastfirst_firstlast(namebuf); striplt(namebuf); - for (i=0; i", + WC->summ[num].msgnum, + (WC->summ[num].is_new ? "bold" : "normal"), + WC->summ[num].msgnum + ); + wprintf("%s",WC->summ[num].from); + wprintf(""); + webcit_fmt_date(datebuf, WC->summ[num].date, 1); /* brief */ + escputs(datebuf); + wprintf("
"); + wprintf(WC->summ[num].subj); + wprintf("(num_ab - 1)) tablast = (num_ab - 1); - nametab(tabfirst_label, addrbook[tabfirst].ab_name); - nametab(tablast_label, addrbook[tablast].ab_name); + nametab(tabfirst_label, 64, addrbook[tabfirst].ab_name); + nametab(tablast_label, 64, addrbook[tablast].ab_name); sprintf(this_tablabel, "%s - %s", tabfirst_label, tablast_label); tablabels[i] = strdup(this_tablabel); } @@ -1890,7 +2103,7 @@ void do_addrbook_view(struct addrbookent *addrbook, int num_ab) { wprintf("", bstr("alpha")); + wprintf("?maxmsgs=1?is_summary=0?alpha=%s\">", bstr("alpha")); vcard_n_prettyize(addrbook[i].ab_name); escputs(addrbook[i].ab_name); wprintf("\n"); @@ -1920,8 +2133,10 @@ int load_msg_ptrs(char *servcmd, int with_headers) char fullname[128]; char nodename[128]; char inetaddr[128]; - char subject[256]; + char subject[1024]; + char *ptr; int nummsgs; + int sbjlen; int maxload = 0; int num_summ_alloc = 0; @@ -1964,47 +2179,49 @@ int load_msg_ptrs(char *servcmd, int with_headers) WC->summ[nummsgs-1].msgnum = WC->msgarr[nummsgs-1]; safestrncpy(WC->summ[nummsgs-1].subj, _("(no subject)"), sizeof WC->summ[nummsgs-1].subj); - if (strlen(fullname) > 0) { - safestrncpy(WC->summ[nummsgs-1].from, - fullname, sizeof WC->summ[nummsgs-1].from); - } - if (strlen(subject) > 0) { - safestrncpy(WC->summ[nummsgs-1].subj, subject, - sizeof WC->summ[nummsgs-1].subj); - } -#ifdef HAVE_ICONV + if (!IsEmptyStr(subject)) { /** Handle subjects with RFC2047 encoding */ - utf8ify_rfc822_string(WC->summ[nummsgs-1].subj); -#endif - if (strlen(WC->summ[nummsgs-1].subj) > 75) { - strcpy(&WC->summ[nummsgs-1].subj[72], "..."); + utf8ify_rfc822_string(subject); + safestrncpy(WC->summ[nummsgs-1].subj, subject, + sizeof WC->summ[nummsgs-1].subj); } + sbjlen = Ctdl_Utf8StrLen(WC->summ[nummsgs-1].subj); + if (sbjlen > 75) { + ptr = Ctdl_Utf8StrCut(WC->summ[nummsgs-1].subj, 72); - if (strlen(nodename) > 0) { - if ( ((WC->room_flags & QR_NETWORK) - || ((strcasecmp(nodename, serv_info.serv_nodename) - && (strcasecmp(nodename, serv_info.serv_fqdn))))) - ) { - strcat(WC->summ[nummsgs-1].from, " @ "); - strcat(WC->summ[nummsgs-1].from, nodename); - } + strcpy(ptr, "..."); } - WC->summ[nummsgs-1].date = datestamp; - -#ifdef HAVE_ICONV + if (!IsEmptyStr(fullname)) { /** Handle senders with RFC2047 encoding */ - utf8ify_rfc822_string(WC->summ[nummsgs-1].from); -#endif - if (strlen(WC->summ[nummsgs-1].from) > 25) { - strcpy(&WC->summ[nummsgs-1].from[22], "..."); + utf8ify_rfc822_string(fullname); + safestrncpy(WC->summ[nummsgs-1].from, + fullname, sizeof WC->summ[nummsgs-1].from); + } + if ((!IsEmptyStr(nodename)) && + ( ((WC->room_flags & QR_NETWORK) + || ((strcasecmp(nodename, serv_info.serv_nodename) + && (strcasecmp(nodename, serv_info.serv_fqdn))))))) + { + strcat(WC->summ[nummsgs-1].from, " @ "); + strcat(WC->summ[nummsgs-1].from, nodename); + + } + sbjlen = Ctdl_Utf8StrLen(WC->summ[nummsgs-1].from); + if (sbjlen > 25) { + ptr = Ctdl_Utf8StrCut(WC->summ[nummsgs-1].from, 23); + strcpy(ptr, "..."); } + + WC->summ[nummsgs-1].date = datestamp; } } } return (nummsgs); } + +typedef int (*QSortFunction) (const void*, const void*); /** * \brief qsort() compatible function to compare two longs in descending order. * @@ -2121,6 +2338,84 @@ int summcmp_rdate(const void *s1, const void *s2) { } +enum { + eUp, + eDown, + eNone +}; + +const char* SortIcons[3] = { + "static/up_pointer.gif", + "static/down_pointer.gif", + "static/sort_none.gif" +}; + + enum {/// SortByEnum + eDate, + eRDate, + eSubject, + eRSubject, + eSender, + eRSender, + eReverse, + eUnSet +}; + +/** SortEnum to plain string representation */ +static const char* SortByStrings[] = { + "date", + "rdate", + "subject", + "rsubject", + "sender", + "rsender", + "reverse", + "unset" +}; + +/** SortEnum to sort-Function Table */ +const QSortFunction SortFuncs[eUnSet] = { + summcmp_date, + summcmp_rdate, + summcmp_subj, + summcmp_rsubj, + summcmp_sender, + summcmp_rsender, + summcmp_rdate +}; + +/** 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? */ +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 + */ +//SortByEnum +int StrToESort (StrBuf *sortby) +{ + int result = eDate; + + if (!IsEmptyStr(ChrPtr(sortby))) while (result < eUnSet){ + if (!strcasecmp(ChrPtr(sortby), + SortByStrings[result])) + return result; + result ++; + } + return eRDate; +} + + + /** * \brief command loop for reading messages @@ -2129,7 +2424,7 @@ int summcmp_rdate(const void *s1, const void *s2) { */ void readloop(char *oper) { - char cmd[256]; + char cmd[256] = ""; char buf[SIZ]; char old_msgs[SIZ]; int a, b; @@ -2150,39 +2445,41 @@ void readloop(char *oper) int highest_displayed = 0; struct addrbookent *addrbook = NULL; int num_ab = 0; - char *sortby = NULL; - char sortpref_name[128]; - char sortpref_value[128]; - char *subjsort_button; - char *sendsort_button; - char *datesort_button; + StrBuf *sortby = NULL; + //SortByEnum + int SortBy = eRDate; + StrBuf *sortpref_name; + StrBuf *sortpref_value; int bbs_reverse = 0; + struct wcsession *WCC = WC; /* This is done to make it run faster; WC is a function */ - if (WC->wc_view == VIEW_WIKI) { - sprintf(buf, "wiki?room=%s?page=home", WC->wc_roomname); + if (WCC->wc_view == VIEW_WIKI) { + sprintf(buf, "wiki?room=%s?page=home", WCC->wc_roomname); http_redirect(buf); return; } - startmsg = atol(bstr("startmsg")); - maxmsgs = atoi(bstr("maxmsgs")); - is_summary = atoi(bstr("summary")); + startmsg = lbstr("startmsg"); + maxmsgs = ibstr("maxmsgs"); + is_summary = (ibstr("is_summary") && !WCC->is_mobile); if (maxmsgs == 0) maxmsgs = DEFAULT_MAXMSGS; - snprintf(sortpref_name, sizeof sortpref_name, "sort %s", WC->wc_roomname); - get_preference(sortpref_name, sortpref_value, sizeof sortpref_value); + sortpref_name = NewStrBuf (); + StrBufPrintf(sortpref_name, "sort %s", WCC->wc_roomname); + get_pref(sortpref_name, &sortpref_value); - sortby = bstr("sortby"); - if ( (strlen(sortby) > 0) && (strcasecmp(sortby, sortpref_value)) ) { - set_preference(sortpref_name, sortby, 1); + sortby = NewStrBufPlain(bstr("sortby"), -1); + if ( (!IsEmptyStr(ChrPtr(sortby))) && + (strcasecmp(ChrPtr(sortby), ChrPtr(sortpref_value)) != 0)) { + set_pref(sortpref_name, sortby, 1); + sortpref_value = NULL; + sortpref_value = sortby; } - if (strlen(sortby) == 0) sortby = sortpref_value; - - /** mailbox sort */ - if (strlen(sortby) == 0) sortby = "rdate"; - + + FreeStrBuf(&sortpref_name); + SortBy = StrToESort(sortpref_value); /** message board sort */ - if (!strcasecmp(sortby, "reverse")) { + if (SortBy == eReverse) { bbs_reverse = 1; } else { @@ -2202,26 +2499,26 @@ void readloop(char *oper) strcpy(cmd, "MSGS OLD"); } else if (!strcmp(oper, "do_search")) { - sprintf(cmd, "MSGS SEARCH|%s", bstr("query")); + snprintf(cmd, sizeof(cmd), "MSGS SEARCH|%s", bstr("query")); } else { strcpy(cmd, "MSGS ALL"); } - if ((WC->wc_view == VIEW_MAILBOX) && (maxmsgs > 1)) { + if ((WCC->wc_view == VIEW_MAILBOX) && (maxmsgs > 1) && !WCC->is_mobile) { is_summary = 1; if (!strcmp(oper, "do_search")) { - sprintf(cmd, "MSGS SEARCH|%s", bstr("query")); + snprintf(cmd, sizeof(cmd), "MSGS SEARCH|%s", bstr("query")); } else { strcpy(cmd, "MSGS ALL"); } } - if ((WC->wc_view == VIEW_ADDRESSBOOK) && (maxmsgs > 1)) { + if ((WCC->wc_view == VIEW_ADDRESSBOOK) && (maxmsgs > 1)) { is_addressbook = 1; if (!strcmp(oper, "do_search")) { - sprintf(cmd, "MSGS SEARCH|%s", bstr("query")); + snprintf(cmd, sizeof(cmd), "MSGS SEARCH|%s", bstr("query")); } else { strcpy(cmd, "MSGS ALL"); @@ -2229,13 +2526,17 @@ void readloop(char *oper) maxmsgs = 9999999; } - if (is_summary) { /**< fetch header summary */ - snprintf(cmd, sizeof cmd, "MSGS %s|%s||1", + if (is_summary || WCC->is_mobile) { /**< fetch header summary */ + snprintf(cmd, sizeof(cmd), "MSGS %s|%s||1", (!strcmp(oper, "do_search") ? "SEARCH" : "ALL"), (!strcmp(oper, "do_search") ? bstr("query") : "") ); startmsg = 1; maxmsgs = 9999999; + } + if (WCC->is_mobile) { + maxmsgs = 20; + SortBy = eRDate; } /** @@ -2244,7 +2545,7 @@ void readloop(char *oper) * new messages. */ strcpy(old_msgs, ""); - if (is_summary) { + if ((is_summary) || (WCC->wc_default_view == VIEW_CALENDAR) || WCC->is_mobile){ serv_puts("GTSN"); serv_getln(buf, sizeof buf); if (buf[0] == '2') { @@ -2252,30 +2553,29 @@ void readloop(char *oper) } } - is_singlecard = atoi(bstr("is_singlecard")); + is_singlecard = ibstr("is_singlecard"); - if (WC->wc_default_view == VIEW_CALENDAR) { /**< calendar */ + if (WCC->wc_default_view == VIEW_CALENDAR) { /**< calendar */ is_calendar = 1; - strcpy(cmd, "MSGS ALL"); + strcpy(cmd, "MSGS ALL|||1"); maxmsgs = 32767; } - if (WC->wc_default_view == VIEW_TASKS) { /**< tasks */ + if (WCC->wc_default_view == VIEW_TASKS) { /**< tasks */ is_tasks = 1; strcpy(cmd, "MSGS ALL"); maxmsgs = 32767; } - if (WC->wc_default_view == VIEW_NOTES) { /**< notes */ + if (WCC->wc_default_view == VIEW_NOTES) { /**< notes */ is_notes = 1; strcpy(cmd, "MSGS ALL"); maxmsgs = 32767; } if (is_notes) { - wprintf(" %s\n", _("Click on any note to edit it.")); wprintf("\n"); } - nummsgs = load_msg_ptrs(cmd, is_summary); + nummsgs = load_msg_ptrs(cmd, (is_summary || WCC->is_mobile)); if (nummsgs == 0) { if ((!is_tasks) && (!is_calendar) && (!is_notes) && (!is_addressbook)) { @@ -2293,15 +2593,15 @@ void readloop(char *oper) goto DONE; } - if (is_summary) { + if ((is_summary) || (WCC->wc_default_view == VIEW_CALENDAR) || WCC->is_mobile){ for (a = 0; a < nummsgs; ++a) { /** Are you a new message, or an old message? */ if (is_summary) { - if (is_msg_in_mset(old_msgs, WC->msgarr[a])) { - WC->summ[a].is_new = 0; + if (is_msg_in_mset(old_msgs, WCC->msgarr[a])) { + WCC->summ[a].is_new = 0; } else { - WC->summ[a].is_new = 1; + WCC->summ[a].is_new = 1; } } } @@ -2309,69 +2609,18 @@ void readloop(char *oper) if (startmsg == 0L) { if (bbs_reverse) { - startmsg = WC->msgarr[(nummsgs >= maxmsgs) ? (nummsgs - maxmsgs) : 0]; + startmsg = WCC->msgarr[(nummsgs >= maxmsgs) ? (nummsgs - maxmsgs) : 0]; } else { - startmsg = WC->msgarr[0]; + startmsg = WCC->msgarr[0]; } } - if (is_summary) { - if (!strcasecmp(sortby, "subject")) { - qsort(WC->summ, WC->num_summ, - sizeof(struct message_summary), summcmp_subj); - } - else if (!strcasecmp(sortby, "rsubject")) { - qsort(WC->summ, WC->num_summ, - sizeof(struct message_summary), summcmp_rsubj); - } - else if (!strcasecmp(sortby, "sender")) { - qsort(WC->summ, WC->num_summ, - sizeof(struct message_summary), summcmp_sender); - } - else if (!strcasecmp(sortby, "rsender")) { - qsort(WC->summ, WC->num_summ, - sizeof(struct message_summary), summcmp_rsender); - } - else if (!strcasecmp(sortby, "date")) { - qsort(WC->summ, WC->num_summ, - sizeof(struct message_summary), summcmp_date); - } - else if (!strcasecmp(sortby, "rdate")) { - qsort(WC->summ, WC->num_summ, - sizeof(struct message_summary), summcmp_rdate); - } - } - - if (!strcasecmp(sortby, "subject")) { - subjsort_button = "" ; - } - else if (!strcasecmp(sortby, "rsubject")) { - subjsort_button = "" ; - } - else { - subjsort_button = "" ; + if (is_summary || WCC->is_mobile) { + qsort(WCC->summ, WCC->num_summ, + sizeof(struct message_summary), SortFuncs[SortBy]); } - if (!strcasecmp(sortby, "sender")) { - sendsort_button = "" ; - } - else if (!strcasecmp(sortby, "rsender")) { - sendsort_button = "" ; - } - else { - sendsort_button = "" ; - } - - if (!strcasecmp(sortby, "date")) { - datesort_button = "" ; - } - else if (!strcasecmp(sortby, "rdate")) { - datesort_button = "" ; - } - else { - datesort_button = "" ; - } if (is_summary) { @@ -2389,9 +2638,9 @@ void readloop(char *oper) "" ""); /**< end of 'message_list' div */ - + /** Here's the grab-it-to-resize-the-message-list widget */ wprintf(" \n"); /**< end of 'fix_scrollbar_bug' div */ wprintf("" @@ -2498,6 +2839,8 @@ void readloop(char *oper) ); wprintf("tag. */ + wprintf("\n"); /** end of 'content' div */ wDumpContent(1); - if (addrbook != NULL) free(addrbook); /** free the summary */ - if (WC->summ != NULL) { - free(WC->summ); - WC->num_summ = 0; - WC->summ = NULL; + if (WCC->summ != NULL) { + free(WCC->summ); + WCC->num_summ = 0; + WCC->summ = NULL; } -wprintf("\n"); /** end of 'content' div */ + if (addrbook != NULL) free(addrbook); } -/** - * \brief Back end for post_message() +/* + * Back end for post_message() * ... this is where the actual message gets transmitted to the server. */ void post_mime_to_server(void) { - char boundary[SIZ]; + char top_boundary[SIZ]; + char alt_boundary[SIZ]; int is_multipart = 0; static int seq = 0; struct wc_attachment *att; char *encoded; size_t encoded_length; + size_t encoded_strlen; + char *txtmail = NULL; + + sprintf(top_boundary, "Citadel--Multipart--%s--%04x--%04x", + serv_info.serv_fqdn, + getpid(), + ++seq + ); + sprintf(alt_boundary, "Citadel--Multipart--%s--%04x--%04x", + serv_info.serv_fqdn, + getpid(), + ++seq + ); - /** RFC2045 requires this, and some clients look for it... */ + /* RFC2045 requires this, and some clients look for it... */ serv_puts("MIME-Version: 1.0"); - serv_puts("X-Mailer: " SERVER); + serv_puts("X-Mailer: " PACKAGE_STRING); - /** If there are attachments, we have to do multipart/mixed */ + /* If there are attachments, we have to do multipart/mixed */ if (WC->first_attachment != NULL) { is_multipart = 1; } if (is_multipart) { - sprintf(boundary, "Citadel--Multipart--%s--%04x--%04x", - serv_info.serv_fqdn, - getpid(), - ++seq - ); - - /** Remember, serv_printf() appends an extra newline */ - serv_printf("Content-type: multipart/mixed; " - "boundary=\"%s\"\n", boundary); + /* Remember, serv_printf() appends an extra newline */ + serv_printf("Content-type: multipart/mixed; boundary=\"%s\"\n", top_boundary); serv_printf("This is a multipart message in MIME format.\n"); - serv_printf("--%s", boundary); + serv_printf("--%s", top_boundary); } + /* Remember, serv_printf() appends an extra newline */ + serv_printf("Content-type: multipart/alternative; " + "boundary=\"%s\"\n", alt_boundary); + serv_printf("This is a multipart message in MIME format.\n"); + serv_printf("--%s", alt_boundary); + + serv_puts("Content-type: text/plain; charset=utf-8"); + serv_puts("Content-Transfer-Encoding: quoted-printable"); + serv_puts(""); + txtmail = html_to_ascii(bstr("msgtext"), 0, 80, 0); + text_to_server_qp(txtmail); /* Transmit message in quoted-printable encoding */ + free(txtmail); + + serv_printf("--%s", alt_boundary); + serv_puts("Content-type: text/html; charset=utf-8"); serv_puts("Content-Transfer-Encoding: quoted-printable"); serv_puts(""); serv_puts("\r\n"); - text_to_server_qp(bstr("msgtext")); /** Transmit message in quoted-printable encoding */ + text_to_server_qp(bstr("msgtext")); /* Transmit message in quoted-printable encoding */ serv_puts("\r\n"); + + serv_printf("--%s--", alt_boundary); if (is_multipart) { - /** Add in the attachments */ + /* Add in the attachments */ for (att = WC->first_attachment; att!=NULL; att=att->next) { encoded_length = ((att->length * 150) / 100); encoded = malloc(encoded_length); if (encoded == NULL) break; - CtdlEncodeBase64(encoded, att->data, att->length, 1); + encoded_strlen = CtdlEncodeBase64(encoded, att->data, att->length, 1); - serv_printf("--%s", boundary); + serv_printf("--%s", top_boundary); serv_printf("Content-type: %s", att->content_type); - serv_printf("Content-disposition: attachment; " - "filename=\"%s\"", att->filename); + serv_printf("Content-disposition: attachment; filename=\"%s\"", att->filename); serv_puts("Content-transfer-encoding: base64"); serv_puts(""); - serv_write(encoded, strlen(encoded)); + serv_write(encoded, encoded_strlen); serv_puts(""); serv_puts(""); free(encoded); } - serv_printf("--%s--", boundary); + serv_printf("--%s--", top_boundary); } serv_puts("000"); } -/** - * \brief Post message (or don't post message) +/* + * Post message (or don't post message) * * Note regarding the "dont_post" variable: * A random value (actually, it's just a timestamp) is inserted as a hidden @@ -2699,36 +3066,52 @@ void post_mime_to_server(void) { */ void post_message(void) { + urlcontent *u; + void *U; char buf[1024]; - char encoded_subject[1024]; + char *encoded_subject = NULL; static long dont_post = (-1L); struct wc_attachment *att, *aptr; int is_anonymous = 0; - char *display_name; + const char *display_name; + long dpLen = 0; + struct wcsession *WCC = WC; + char *ptr = NULL; + + if (havebstr("force_room")) { + gotoroom(bstr("force_room")); + } - display_name = bstr("display_name"); + 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 (WC->upload_length > 0) { + if (WCC->upload_length > 0) { - lprintf(9, "%s:%d: we are uploading %d bytes\n", __FILE__, __LINE__, WC->upload_length); + lprintf(9, "%s:%d: we are uploading %d bytes\n", __FILE__, __LINE__, WCC->upload_length); /** There's an attachment. Save it to this struct... */ att = malloc(sizeof(struct wc_attachment)); memset(att, 0, sizeof(struct wc_attachment)); - att->length = WC->upload_length; - strcpy(att->content_type, WC->upload_content_type); - strcpy(att->filename, WC->upload_filename); + att->length = WCC->upload_length; + strcpy(att->content_type, WCC->upload_content_type); + strcpy(att->filename, WCC->upload_filename); att->next = NULL; /** And add it to the list. */ - if (WC->first_attachment == NULL) { - WC->first_attachment = att; + if (WCC->first_attachment == NULL) { + WCC->first_attachment = att; } else { - aptr = WC->first_attachment; + aptr = WCC->first_attachment; while (aptr->next != NULL) aptr = aptr->next; aptr->next = att; } @@ -2749,49 +3132,102 @@ void post_message(void) * Transfer control of this memory from the upload struct * to the attachment struct. */ - att->data = WC->upload; - WC->upload_length = 0; - WC->upload = NULL; + att->data = WCC->upload; + WCC->upload_length = 0; + WCC->upload = NULL; display_enter(); return; } - if (strlen(bstr("cancel_button")) > 0) { - sprintf(WC->ImportantMessage, + if (havebstr("cancel_button")) { + sprintf(WCC->ImportantMessage, _("Cancelled. Message was not posted.")); - } else if (strlen(bstr("attach_button")) > 0) { + } else if (havebstr("attach_button")) { display_enter(); return; - } else if (atol(bstr("postseq")) == dont_post) { - sprintf(WC->ImportantMessage, + } else if (lbstr("postseq") == dont_post) { + sprintf(WCC->ImportantMessage, _("Automatically cancelled because you have already " "saved this message.")); } else { - rfc2047encode(encoded_subject, sizeof encoded_subject, bstr("subject")); - sprintf(buf, "ENT0 1|%s|%d|4|%s|%s||%s|%s|%s|%s", - bstr("recp"), + 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); + + if (havebstr("subject")) { + char *Subj; + size_t SLen; + /* + * 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 ? encoded_subject : ""), display_name, - bstr("cc"), - bstr("bcc"), - bstr("wikipage"), - bstr("my_email_addr") - ); - serv_puts(buf); + Cc, + Bcc, + Wikipage, + my_email_addr, + references); + lprintf(9, "%s\n", CmdBuf); + serv_puts(CmdBuf); serv_getln(buf, sizeof buf); + free (CmdBuf); + if (encoded_subject) free(encoded_subject); if (buf[0] == '4') { post_mime_to_server(); - if ( (strlen(bstr("recp")) > 0) - || (strlen(bstr("cc")) > 0) - || (strlen(bstr("bcc")) > 0) + if ( (havebstr("recp")) + || (havebstr("cc" )) + || (havebstr("bcc" )) ) { - sprintf(WC->ImportantMessage, _("Message has been sent.\n")); + sprintf(WCC->ImportantMessage, _("Message has been sent.\n")); } else { sprintf(WC->ImportantMessage, _("Message has been posted.\n")); } - dont_post = atol(bstr("postseq")); + dont_post = lbstr("postseq"); } else { lprintf(9, "%s:%d: server post error: %s\n", __FILE__, __LINE__, buf); sprintf(WC->ImportantMessage, "%s", &buf[4]); @@ -2800,19 +3236,19 @@ void post_message(void) } } - free_attachments(WC); + free_attachments(WCC); /** * We may have been supplied with instructions regarding the location * to which we must return after posting. If found, go there. */ - if (strlen(bstr("return_to")) > 0) { + if (havebstr("return_to")) { http_redirect(bstr("return_to")); } /** * If we were editing a page in a wiki room, go to that page now. */ - else if (strlen(bstr("wikipage")) > 0) { + else if (havebstr("wikipage")) { snprintf(buf, sizeof buf, "wiki?page=%s", bstr("wikipage")); http_redirect(buf); } @@ -2833,26 +3269,28 @@ void post_message(void) void display_enter(void) { char buf[SIZ]; - char ebuf[SIZ]; + StrBuf *ebuf; long now; char *display_name; 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); - if (strlen(bstr("force_room")) > 0) { + if (havebstr("force_room")) { gotoroom(bstr("force_room")); } - display_name = bstr("display_name"); + display_name = xbstr("display_name", &dplen); if (!strcmp(display_name, "__ANONYMOUS__")) { display_name = ""; + dplen = 0; is_anonymous = 1; } @@ -2864,47 +3302,44 @@ 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; } - if ((buf[3] != '\0') && - (buf[4] != '\0') && - !strncmp(&(buf[5]), "SUBJECTREQ", 10)) { - subject_required = 1; + /* Is the server strongly recommending that the user enter a message subject? */ + if ((buf[3] != '\0') && (buf[4] != '\0')) { + subject_required = extract_int(&buf[4], 1); } /** * 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, "", ""); + if (WCC->wc_default_view == VIEW_ADDRESSBOOK) { + do_edit_vcard(-1, "", "", WCC->wc_roomname); return; } -#ifdef WEBCIT_WITH_CALENDAR_SERVICE - /** + /* * 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; } - /** + /* * 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; } -#endif - /** + /* * Otherwise proceed normally. * Do a custom room banner with no navbar... */ @@ -2915,18 +3350,41 @@ void display_enter(void) wprintf(""); /**< The preview pane will initially be empty */ + } else if (WCC->is_mobile) { + wprintf(""); } /** @@ -2513,8 +2856,8 @@ void readloop(char *oper) */ if (is_bbview) { /** begin bbview scroller */ - wprintf("\n"); + wprintf(">"); + wprintf(_("newest to oldest")); + wprintf("\n"); + + wprintf("\n"); /** end bbview scroller */ } - + DONE: if (is_tasks) { do_tasks_view(); /** Render the task list */ @@ -2603,91 +2947,114 @@ DONE: } /** Note: wDumpContent() will output one additional\n" "\n"); /* end of "fix_scrollbar_bug" div */ + /* NOTE: address_book_popup() will close the "content" div. Don't close it here. */ DONE: address_book_popup(); wDumpContent(1); } @@ -3202,7 +3706,7 @@ void delete_msg(void) long msgid; char buf[SIZ]; - msgid = atol(bstr("msgid")); + msgid = lbstr("msgid"); if (WC->wc_is_trash) { /** Delete from Trash is a real delete */ serv_printf("DELE %ld", msgid); @@ -3226,9 +3730,9 @@ void move_msg(void) long msgid; char buf[SIZ]; - msgid = atol(bstr("msgid")); + msgid = lbstr("msgid"); - if (strlen(bstr("move_button")) > 0) { + if (havebstr("move_button")) { sprintf(buf, "MOVE %ld|%s", msgid, bstr("target_room")); serv_puts(buf); serv_getln(buf, sizeof buf); @@ -3244,8 +3748,8 @@ void move_msg(void) -/** - * \brief Confirm move of a message +/* + * Confirm move of a message */ void confirm_move_msg(void) { @@ -3253,17 +3757,17 @@ void confirm_move_msg(void) char buf[SIZ]; char targ[SIZ]; - msgid = atol(bstr("msgid")); + msgid = lbstr("msgid"); output_headers(1, 1, 2, 0, 0, 0); wprintf(" \n"); + wprintf(" \n\n"); + wprintf(""); + wprintf("\n"); + + wprintf("\n"); wprintf(""); @@ -3271,6 +3775,7 @@ void confirm_move_msg(void) wprintf("
\n"); wprintf("