X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fmessages.c;h=5f11916181b900c4f152af3f1ff15acb803fef27;hb=523c1b0f7a3002c6aaa3eb833b55eb0cf07674ff;hp=5c713a0c13fd161219fc7abd2e5def6c062e371a;hpb=ece441dda935c3929956b2043a8f4c29c05d54db;p=citadel.git diff --git a/webcit/messages.c b/webcit/messages.c index 5c713a0c1..5f1191618 100644 --- a/webcit/messages.c +++ b/webcit/messages.c @@ -5,29 +5,6 @@ * */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_ICONV -#include -#endif - #include "webcit.h" #include "vcard.h" #include "webserver.h" @@ -68,9 +45,9 @@ void utf8ify_rfc822_string(char *buf) { extract_token(encoding, start, 2, '?', sizeof encoding); extract_token(istr, start, 3, '?', sizeof istr); - strcpy(start, ""); - ++end; + /*strcpy(start, ""); ++end; + ++end;*/ ibuf = malloc(1024); isav = ibuf; @@ -93,6 +70,16 @@ void utf8ify_rfc822_string(char *buf) { osav = obuf; iconv(ic, &ibuf, &ibuflen, &obuf, &obuflen); osav[1024-obuflen] = 0; + + end = start; + end++; + strcpy(start, ""); + remove_token(end, 0, '?'); + remove_token(end, 0, '?'); + remove_token(end, 0, '?'); + remove_token(end, 0, '?'); + strcpy(end, &end[1]); + snprintf(newbuf, sizeof newbuf, "%s%s%s", buf, osav, end); strcpy(buf, newbuf); free(osav); @@ -351,11 +338,11 @@ void display_parsed_vcard(struct vCard *v, int full) { if (!strcasecmp(buf, "tel")) strcat(phone, ""); else if (!strcasecmp(buf, "work")) - strcat(phone, " (work)"); + strcat(phone, _(" (work)")); else if (!strcasecmp(buf, "home")) - strcat(phone, " (home)"); + strcat(phone, _(" (home)")); else if (!strcasecmp(buf, "cell")) - strcat(phone, " (cell)"); + strcat(phone, _(" (cell)")); else { strcat(phone, " ("); strcat(phone, buf); @@ -365,7 +352,9 @@ void display_parsed_vcard(struct vCard *v, int full) { } else if (!strcasecmp(firsttoken, "adr")) { if (pass == 2) { - wprintf("Address:"); + wprintf(""); + wprintf(_("Address:")); + wprintf(""); for (j=0; j 0) { @@ -423,9 +412,13 @@ void display_parsed_vcard(struct vCard *v, int full) { wprintf("\n"); if (strlen(phone) > 0) - wprintf("Telephone:%s\n", phone); + wprintf(""); + wprintf(_("Telephone:")); + wprintf("%s\n", phone); if (strlen(mailto) > 0) - wprintf("E-mail:%s\n", mailto); + wprintf(""); + wprintf(_("E-mail:")); + wprintf("%s\n", mailto); } } @@ -471,8 +464,6 @@ void display_vcard(char *vcard_source, char alpha, int full, char *storename) { } - - /* * I wanna SEE that message! */ @@ -486,11 +477,13 @@ void read_message(long msgnum, int suppress_buttons) { int mime_length; char mime_http[SIZ]; char m_subject[256]; + char m_cc[1024]; char from[256]; char node[256]; char rfca[256]; char reply_to[512]; - char now[256]; + char reply_all[4096]; + char now[64]; int format_type = 0; int nhdr = 0; int bq = 0; @@ -511,6 +504,7 @@ void read_message(long msgnum, int suppress_buttons) { strcpy(node, ""); strcpy(rfca, ""); strcpy(reply_to, ""); + strcpy(reply_all, ""); strcpy(vcard_partnum, ""); strcpy(cal_partnum, ""); strcpy(mime_http, ""); @@ -520,7 +514,9 @@ void read_message(long msgnum, int suppress_buttons) { serv_printf("MSG4 %ld", msgnum); serv_getln(buf, sizeof buf); if (buf[0] != '1') { - wprintf("ERROR: %s
\n", &buf[4]); + wprintf(""); + wprintf(_("ERROR:")); + wprintf(" %s
\n", &buf[4]); return; } @@ -535,10 +531,13 @@ void read_message(long msgnum, int suppress_buttons) { wprintf(""); strcpy(m_subject, ""); + strcpy(m_cc, ""); while (serv_getln(buf, sizeof buf), strcasecmp(buf, "text")) { if (!strcmp(buf, "000")) { - wprintf("unexpected end of message

\n"); + wprintf(""); + wprintf(_("unexpected end of message")); + wprintf("

\n"); wprintf("
\n"); return; } @@ -550,7 +549,8 @@ void read_message(long msgnum, int suppress_buttons) { format_type = atoi(&buf[5]); if (!strncasecmp(buf, "from=", 5)) { strcpy(from, &buf[5]); - wprintf("from "); } - if (!strncasecmp(buf, "subj=", 5)) - strcpy(m_subject, &buf[5]); + if (!strncasecmp(buf, "subj=", 5)) { + safestrncpy(m_subject, &buf[5], sizeof m_subject); + } + if (!strncasecmp(buf, "cccc=", 5)) { + safestrncpy(m_cc, &buf[5], sizeof m_cc); + if (strlen(reply_all) > 0) { + strcat(reply_all, ", "); + } + safestrncpy(&reply_all[strlen(reply_all)], &buf[5], + (sizeof reply_all - strlen(reply_all)) ); + } if ((!strncasecmp(buf, "hnod=", 5)) - && (strcasecmp(&buf[5], serv_info.serv_humannode))) + && (strcasecmp(&buf[5], serv_info.serv_humannode))) { wprintf("(%s) ", &buf[5]); + } if ((!strncasecmp(buf, "room=", 5)) && (strcasecmp(&buf[5], WC->wc_roomname)) - && (strlen(&buf[5])>0) ) - wprintf("in %s> ", &buf[5]); + && (strlen(&buf[5])>0) ) { + wprintf(_("in ")); + wprintf("%s> ", &buf[5]); + } if (!strncasecmp(buf, "rfca=", 5)) { strcpy(rfca, &buf[5]); wprintf("<"); @@ -585,8 +597,16 @@ void read_message(long msgnum, int suppress_buttons) { wprintf("@%s ", &buf[5]); } } - if (!strncasecmp(buf, "rcpt=", 5)) - wprintf("to %s ", &buf[5]); + if (!strncasecmp(buf, "rcpt=", 5)) { + wprintf(_("to ")); + escputs(&buf[5]); + wprintf(" "); + if (strlen(reply_all) > 0) { + strcat(reply_all, ", "); + } + safestrncpy(&reply_all[strlen(reply_all)], &buf[5], + (sizeof reply_all - strlen(reply_all)) ); + } if (!strncasecmp(buf, "time=", 5)) { fmt_date(now, atol(&buf[5]), 0); wprintf("%s ", now); @@ -660,14 +680,24 @@ void read_message(long msgnum, int suppress_buttons) { wprintf(""); #ifdef HAVE_ICONV + utf8ify_rfc822_string(m_cc); utf8ify_rfc822_string(m_subject); #endif + if (strlen(m_cc) > 0) { + wprintf("
" + ""); + wprintf(_("CC:")); + wprintf(" "); + escputs(m_cc); + wprintf(""); + } if (strlen(m_subject) > 0) { wprintf("
" - "" - "Subject: %s" - "", m_subject - ); + ""); + wprintf(_("Subject:")); + wprintf(" "); + escputs(m_subject); + wprintf(""); } wprintf("\n"); @@ -681,23 +711,42 @@ void read_message(long msgnum, int suppress_buttons) { wprintf("?subject="); if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%20"); urlescputs(m_subject); - wprintf("\">[Reply]
"); + wprintf("\">[%s] ", _("Reply")); + + /* ReplyAll */ + if (WC->wc_view == VIEW_MAILBOX) { + wprintf("[%s] ", _("ReplyAll")); + } + + /* Forward */ + if (WC->wc_view == VIEW_MAILBOX) { + wprintf("[%s] ", _("Forward")); + } if (WC->is_room_aide) { - /* Move */ - wprintf("[Move] ", - msgnum); + wprintf("[%s] ", + msgnum, _("Move")); /* Delete */ wprintf("" - "[Delete] ", msgnum); - + "onClick=\"return confirm('%s');\">" + "[%s] ", msgnum, _("Delete this message?"), _("Delete") + ); } - wprintf("" - "[Print]", msgnum); + wprintf("" + "[%s]", msgnum, _("Print")); wprintf(""); } @@ -714,7 +763,9 @@ void read_message(long msgnum, int suppress_buttons) { strcpy(mime_content_type, "text/plain"); while (serv_getln(buf, sizeof buf), (strlen(buf) > 0)) { if (!strcmp(buf, "000")) { - wprintf("unexpected end of message

\n"); + wprintf(""); + wprintf(_("unexpected end of message")); + wprintf("

\n"); goto ENDBODY; } if (!strncasecmp(buf, "Content-type: ", 14)) { @@ -747,11 +798,12 @@ void read_message(long msgnum, int suppress_buttons) { /* Messages in legacy Citadel variformat get handled thusly... */ if (!strcasecmp(mime_content_type, "text/x-citadel-variformat")) { - fmout(NULL, "JUSTIFY"); + fmout("JUSTIFY"); } /* Boring old 80-column fixed format text gets handled this way... */ - else if (!strcasecmp(mime_content_type, "text/plain")) { + else if ( (!strcasecmp(mime_content_type, "text/plain")) + || (!strcasecmp(mime_content_type, "text")) ) { while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0; if (buf[strlen(buf)-1] == '\r') buf[strlen(buf)-1] = 0; @@ -796,8 +848,8 @@ void read_message(long msgnum, int suppress_buttons) { /* Unknown weirdness */ else { - wprintf("I don't know how to display %s
\n", - mime_content_type); + wprintf(_("I don't know how to display %s"), mime_content_type); + wprintf("
\n", mime_content_type); while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { } } @@ -819,7 +871,7 @@ void read_message(long msgnum, int suppress_buttons) { wprintf("", msgnum, vcard_partnum); - wprintf("[edit]"); + wprintf("[%s]", _("edit")); } /* In all cases, display the full card */ @@ -872,7 +924,7 @@ void embed_message(void) { targetdiv = bstr("targetdiv"); print_it = bstr("print_it"); - output_headers(1, 0, 0, 0, 0, 1, 0); + output_headers(1, 0, 0, 0, 1, 0); begin_burst(); wprintf(""); @@ -885,19 +937,31 @@ void embed_message(void) { " \n", targetdiv, sourceiframe ); + if (!strcasecmp(print_it, "yes")) wprintf( +" \n" +" \n", + sourceiframe, + sourceiframe + ); + wprintf(""); wprintf(" 0) { wprintf(" onLoad='loaded_now_copy_it();'"); } if (!strcasecmp(print_it, "yes")) { - wprintf(" onLoad='window.print();'"); + wprintf(" onLoad='loaded_now_print_it();'"); } wprintf(">\n"); read_message(msgnum, (!strcasecmp(print_it, "yes") ? 1 : 0) ); @@ -908,6 +972,309 @@ void embed_message(void) { +/* + * Read message in simple, JavaScript-embeddable form for 'forward' + * or 'reply quoted' operations. + * + * NOTE: it is VITALLY IMPORTANT that we output no single-quotes or linebreaks + * in this function. Doing so would throw a JavaScript error in the + * 'supplied text' argument to the editor. + */ +void pullquote_message(long msgnum, int forward_attachments) { + char buf[SIZ]; + char mime_partnum[256]; + char mime_filename[256]; + char mime_content_type[256]; + char mime_charset[256]; + char mime_disposition[256]; + int mime_length; + char mime_http[SIZ]; + char *attachments = NULL; + int num_attachments = 0; + struct wc_attachment *att, *aptr; + char m_subject[256]; + char from[256]; + char node[256]; + char rfca[256]; + char reply_to[512]; + char now[256]; + int format_type = 0; + int nhdr = 0; + int bq = 0; + int i = 0; +#ifdef HAVE_ICONV + iconv_t ic = (iconv_t)(-1) ; + char *ibuf; /* Buffer of characters to be converted */ + char *obuf; /* Buffer for converted characters */ + size_t ibuflen; /* Length of input buffer */ + size_t obuflen; /* Length of output buffer */ + char *osav; /* Saved pointer to output buffer */ +#endif + + strcpy(from, ""); + strcpy(node, ""); + strcpy(rfca, ""); + strcpy(reply_to, ""); + strcpy(mime_http, ""); + strcpy(mime_content_type, "text/plain"); + strcpy(mime_charset, "us-ascii"); + + serv_printf("MSG4 %ld", msgnum); + serv_getln(buf, sizeof buf); + if (buf[0] != '1') { + wprintf(_("ERROR:")); + wprintf("%s
", &buf[4]); + return; + } + + strcpy(m_subject, ""); + + while (serv_getln(buf, sizeof buf), strcasecmp(buf, "text")) { + if (!strcmp(buf, "000")) { + wprintf(_("unexpected end of message")); + return; + } + if (!strncasecmp(buf, "nhdr=yes", 8)) + nhdr = 1; + if (nhdr == 1) + buf[0] = '_'; + if (!strncasecmp(buf, "type=", 5)) + format_type = atoi(&buf[5]); + if (!strncasecmp(buf, "from=", 5)) { + strcpy(from, &buf[5]); + wprintf(_("from ")); +#ifdef HAVE_ICONV + utf8ify_rfc822_string(from); +#endif + msgescputs(from); + } + if (!strncasecmp(buf, "subj=", 5)) { + strcpy(m_subject, &buf[5]); + } + if ((!strncasecmp(buf, "hnod=", 5)) + && (strcasecmp(&buf[5], serv_info.serv_humannode))) { + wprintf("(%s) ", &buf[5]); + } + if ((!strncasecmp(buf, "room=", 5)) + && (strcasecmp(&buf[5], WC->wc_roomname)) + && (strlen(&buf[5])>0) ) { + wprintf(_("in ")); + wprintf("%s> ", &buf[5]); + } + if (!strncasecmp(buf, "rfca=", 5)) { + strcpy(rfca, &buf[5]); + wprintf("<"); + msgescputs(rfca); + wprintf("> "); + } + + if (!strncasecmp(buf, "node=", 5)) { + strcpy(node, &buf[5]); + if ( ((WC->room_flags & QR_NETWORK) + || ((strcasecmp(&buf[5], serv_info.serv_nodename) + && (strcasecmp(&buf[5], serv_info.serv_fqdn))))) + && (strlen(rfca)==0) + ) { + wprintf("@%s ", &buf[5]); + } + } + if (!strncasecmp(buf, "rcpt=", 5)) { + wprintf(_("to ")); + wprintf("%s ", &buf[5]); + } + if (!strncasecmp(buf, "time=", 5)) { + fmt_date(now, atol(&buf[5]), 0); + wprintf("%s ", now); + } + + /* + * Save attachment info for later. We can't start downloading them + * yet because we're in the middle of a server transaction. + */ + if (!strncasecmp(buf, "part=", 5)) { + ++num_attachments; + attachments = realloc(attachments, (num_attachments * 1024)); + strcat(attachments, &buf[5]); + strcat(attachments, "\n"); + } + + } + + wprintf("
"); + +#ifdef HAVE_ICONV + utf8ify_rfc822_string(m_subject); +#endif + if (strlen(m_subject) > 0) { + wprintf(_("Subject:")); + wprintf(" "); + msgescputs(m_subject); + wprintf("
"); + } + + /* + * Begin body + */ + wprintf("
"); + + /* + * Learn the content type + */ + strcpy(mime_content_type, "text/plain"); + while (serv_getln(buf, sizeof buf), (strlen(buf) > 0)) { + if (!strcmp(buf, "000")) { + wprintf(_("unexpected end of message")); + goto ENDBODY; + } + if (!strncasecmp(buf, "Content-type: ", 14)) { + safestrncpy(mime_content_type, &buf[14], + sizeof(mime_content_type)); + for (i=0; i 0) && (isspace(buf[strlen(buf) - 1]))) + buf[strlen(buf) - 1] = 0; + if ((bq == 0) && + ((!strncmp(buf, ">", 1)) || (!strncmp(buf, " >", 2)) || (!strncmp(buf, " :-)", 4)))) { + wprintf("
"); + bq = 1; + } else if ((bq == 1) && + (strncmp(buf, ">", 1)) && (strncmp(buf, " >", 2)) && (strncmp(buf, " :-)", 4))) { + wprintf("
"); + bq = 0; + } + wprintf(""); + url(buf); + msgescputs(buf); + wprintf("
"); + } + wprintf("
"); + } + + /* HTML just gets escaped and stuffed back into the editor */ + else if (!strcasecmp(mime_content_type, "text/html")) { + while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { + msgescputs(buf); + } + } + + /* Unknown weirdness ... don't know how to handle this content type */ + else { + while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { } + } + +ENDBODY: + /* end of body handler */ + + /* + * If there were attachments, we have to download them and insert them + * into the attachment chain for the forwarded message we are composing. + */ + if (num_attachments) { + for (i=0; ilength = mime_length; + strcpy(att->content_type, mime_content_type); + strcpy(att->filename, mime_filename); + att->next = NULL; + att->data = load_mimepart(msgnum, mime_partnum); + + /* And add it to the list. */ + if (WC->first_attachment == NULL) { + WC->first_attachment = att; + } + else { + aptr = WC->first_attachment; + while (aptr->next != NULL) aptr = aptr->next; + aptr->next = att; + } + } + + } + free(attachments); + } + +#ifdef HAVE_ICONV + if (ic != (iconv_t)(-1) ) { + iconv_close(ic); + } +#endif +} + + + + + + void display_summarized(int num) { char datebuf[64]; @@ -936,65 +1303,6 @@ void display_summarized(int num) { } -void summarize_message(int num, long msgnum, int is_new) { - char buf[SIZ]; - - memset(&WC->summ[num], 0, sizeof(struct message_summary)); - safestrncpy(WC->summ[num].subj, "(no subject)", sizeof WC->summ[num].subj); - WC->summ[num].is_new = is_new; - WC->summ[num].msgnum = msgnum; - - /* ask for headers only with no MIME */ - sprintf(buf, "MSG0 %ld|3", msgnum); - serv_puts(buf); - serv_getln(buf, sizeof buf); - if (buf[0] != '1') return; - - while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { - if (!strncasecmp(buf, "from=", 5)) { - safestrncpy(WC->summ[num].from, &buf[5], sizeof WC->summ[num].from); - } - if (!strncasecmp(buf, "subj=", 5)) { - if (strlen(&buf[5]) > 0) { - safestrncpy(WC->summ[num].subj, &buf[5], - sizeof WC->summ[num].subj); -#ifdef HAVE_ICONV - /* Handle subjects with RFC2047 encoding */ - utf8ify_rfc822_string(WC->summ[num].subj); -#endif - if (strlen(WC->summ[num].subj) > 75) { - strcpy(&WC->summ[num].subj[72], "..."); - } - } - } - - if (!strncasecmp(buf, "node=", 5)) { - if ( ((WC->room_flags & QR_NETWORK) - || ((strcasecmp(&buf[5], serv_info.serv_nodename) - && (strcasecmp(&buf[5], serv_info.serv_fqdn))))) - ) { - strcat(WC->summ[num].from, " @ "); - strcat(WC->summ[num].from, &buf[5]); - } - } - - if (!strncasecmp(buf, "rcpt=", 5)) { - safestrncpy(WC->summ[num].to, &buf[5], sizeof WC->summ[num].to); - } - - if (!strncasecmp(buf, "time=", 5)) { - WC->summ[num].date = atol(&buf[5]); - } - } - -#ifdef HAVE_ICONV - /* Handle senders with RFC2047 encoding */ - utf8ify_rfc822_string(WC->summ[num].from); -#endif - if (strlen(WC->summ[num].from) > 25) { - strcpy(&WC->summ[num].from[22], "..."); - } -} @@ -1010,7 +1318,7 @@ void display_addressbook(long msgnum, char alpha) { struct message_summary summ; memset(&summ, 0, sizeof(summ)); - safestrncpy(summ.subj, "(no subject)", sizeof summ.subj); + safestrncpy(summ.subj, _("(no subject)"), sizeof summ.subj); sprintf(buf, "MSG0 %ld|1", msgnum); /* ask for headers only */ serv_puts(buf); @@ -1047,7 +1355,7 @@ void display_addressbook(long msgnum, char alpha) { wprintf("", msgnum, vcard_partnum); - wprintf("[edit]"); + wprintf("[%s]", _("edit")); } free(vcard_source); @@ -1133,7 +1441,7 @@ void fetch_ab_name(long msgnum, char *namebuf) { for (i=0; iThis address book is empty.\n"); + wprintf("


"); + wprintf(_("This address book is empty.")); + wprintf("
\n"); return; } @@ -1253,12 +1563,29 @@ void do_addrbook_view(struct addrbookent *addrbook, int num_ab) { /* * load message pointers from the server */ -int load_msg_ptrs(char *servcmd) +int load_msg_ptrs(char *servcmd, int with_headers) { - char buf[SIZ]; + char buf[1024]; + time_t datestamp; + char displayname[128]; + char nodename[128]; + char inetaddr[128]; + char subject[256]; int nummsgs; int maxload = 0; + int num_summ_alloc = 0; + + if (with_headers) { + if (WC->num_summ != 0) { + free(WC->summ); + WC->num_summ = 0; + } + } + num_summ_alloc = 100; + WC->num_summ = 0; + WC->summ = malloc(num_summ_alloc * sizeof(struct message_summary)); + nummsgs = 0; maxload = sizeof(WC->msgarr) / sizeof(long) ; serv_puts(servcmd); @@ -1269,8 +1596,59 @@ int load_msg_ptrs(char *servcmd) } while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { if (nummsgs < maxload) { - WC->msgarr[nummsgs] = atol(buf); + WC->msgarr[nummsgs] = extract_long(buf, 0); + datestamp = extract_long(buf, 1); + extract_token(displayname, buf, 2, '|', sizeof displayname); + extract_token(nodename, buf, 3, '|', sizeof nodename); + extract_token(inetaddr, buf, 4, '|', sizeof inetaddr); + extract_token(subject, buf, 5, '|', sizeof subject); ++nummsgs; + + if (with_headers) { + if (nummsgs > num_summ_alloc) { + num_summ_alloc *= 2; + WC->summ = realloc(WC->summ, num_summ_alloc * sizeof(struct message_summary)); + } + ++WC->num_summ; + + memset(&WC->summ[nummsgs-1], 0, sizeof(struct message_summary)); + 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(displayname) > 0) { + safestrncpy(WC->summ[nummsgs-1].from, displayname, 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 + /* 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], "..."); + } + + 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); + } + } + + WC->summ[nummsgs-1].date = datestamp; + +#ifdef HAVE_ICONV + /* 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], "..."); + } + } } } return (nummsgs); @@ -1345,7 +1723,6 @@ void readloop(char *oper) char cmd[SIZ]; char buf[SIZ]; char old_msgs[SIZ]; - int is_new = 0; int a, b; int nummsgs; long startmsg; @@ -1389,7 +1766,7 @@ void readloop(char *oper) if (strlen(sortby) == 0) sortby = sortpref_value; if (strlen(sortby) == 0) sortby = "msgid"; - output_headers(1, 1, 1, 0, 0, 0, 0); + 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. @@ -1416,7 +1793,7 @@ void readloop(char *oper) } if (is_summary) { - strcpy(cmd, "MSGS ALL"); + strcpy(cmd, "MSGS ALL|||1"); /* fetch header summary */ startmsg = 1; maxmsgs = 9999999; } @@ -1452,33 +1829,26 @@ void readloop(char *oper) maxmsgs = 32767; } - nummsgs = load_msg_ptrs(cmd); + nummsgs = load_msg_ptrs(cmd, is_summary); if (nummsgs == 0) { - if ((!is_tasks) && (!is_calendar) && (!is_notes)) { + if ((!is_tasks) && (!is_calendar) && (!is_notes) && (!is_addressbook)) { + wprintf(""); if (!strcmp(oper, "readnew")) { - wprintf("No new messages.\n"); + wprintf(_("No new messages.")); } else if (!strcmp(oper, "readold")) { - wprintf("No old messages.\n"); + wprintf(_("No old messages.")); } else { - wprintf("No messages here.\n"); + wprintf(_("No messages here.")); } + wprintf("\n"); } goto DONE; } if (is_summary) { - if (WC->num_summ != 0) { - WC->num_summ = 0; - free(WC->summ); - } - WC->num_summ = nummsgs; - WC->summ = malloc(WC->num_summ*sizeof(struct message_summary)); for (a = 0; a < nummsgs; ++a) { - /* Gather summary information */ - summarize_message(a, WC->msgarr[a], is_new); - /* Are you a new message, or an old message? */ if (is_summary) { if (is_msg_in_mset(old_msgs, WC->msgarr[a])) { @@ -1570,18 +1940,19 @@ void readloop(char *oper) "\n" "" - "" - "" - "" - "" + "" + "" + "" + "VALUE=\"%s\">" "\n" , - subjsort_button, - sendsort_button, - datesort_button + _("Subject"), subjsort_button, + _("Sender"), sendsort_button, + _("Date"), datesort_button, + _("Delete") ); } @@ -1645,6 +2016,8 @@ void readloop(char *oper) "\n"); /* end of 'fix_scrollbar_bug' div */ wprintf(""); /* end of 'message_list' div */ + wprintf("
"); /* slider */ + wprintf("
"); /* The preview pane will initially be empty */ } @@ -1659,19 +2032,19 @@ void readloop(char *oper) if ((!is_tasks) && (!is_calendar) && (!is_addressbook) && (!is_notes) && (!is_singlecard)) { wprintf("
" - "
Subject %sSender %sDate %s%s %s%s %s%s %s
\n" - "
" - "Reading #%d of %d messages.", - lowest_displayed, nummsgs); + "
"); + wprintf(_("Reading #%d of %d messages."), lowest_displayed, nummsgs); + wprintf(""); if (pn_previous > 0L) { wprintf("" - "Previous \n", + "%s \n", oper, - pn_previous ); + pn_previous, + _("Previous")); } if (pn_next > 0L) { @@ -1679,18 +2052,20 @@ void readloop(char *oper) "?startmsg=%ld" "?maxmsgs=1" "?summary=0\">" - "Next \n", + "%s \n", oper, - pn_next ); + pn_next, + _("Next")); } wprintf("" - "Summary" + "%s" "", oper, WC->msgarr[0], - DEFAULT_MAXMSGS + DEFAULT_MAXMSGS, + _("Summary") ); wprintf("
\n"); @@ -1708,7 +2083,7 @@ void readloop(char *oper) wprintf("
\n"); - wprintf("Reading #", lowest_displayed, highest_displayed); + wprintf(_("Reading #"), lowest_displayed, highest_displayed); wprintf(" of %d messages.", nummsgs); + wprintf(" "); + wprintf(_("of %d messages."), nummsgs); wprintf("
\n"); } } @@ -1795,6 +2171,9 @@ void post_mime_to_server(void) { char *encoded; size_t encoded_length; + /* RFC2045 requires this, and some clients look for it... */ + serv_puts("MIME-Version: 1.0"); + /* If there are attachments, we have to do multipart/mixed */ if (WC->first_attachment != NULL) { is_multipart = 1; @@ -1886,8 +2265,8 @@ void post_message(void) aptr->next = att; } - /* Netscape sends a simple filename, which is what we want, - * but Satan's browser sends an entire pathname. Reduce + /* Mozilla sends a simple filename, which is what we want, + * but Satan's Browser sends an entire pathname. Reduce * the path to just a filename if we need to. */ while (num_tokens(att->filename, '/') > 1) { @@ -1907,34 +2286,41 @@ void post_message(void) return; } - if (!strcasecmp(bstr("sc"), "Cancel")) { + if (strlen(bstr("cancel_button")) > 0) { sprintf(WC->ImportantMessage, - "Cancelled. Message was not posted."); - } else if (!strcasecmp(bstr("attach"), "Add")) { + _("Cancelled. Message was not posted.")); + } else if (strlen(bstr("attach_button")) > 0) { display_enter(); return; } else if (atol(bstr("postseq")) == dont_post) { sprintf(WC->ImportantMessage, - "Automatically cancelled because you have already " - "saved this message."); + _("Automatically cancelled because you have already " + "saved this message.")); } else { - sprintf(buf, "ENT0 1|%s|0|4|%s", + sprintf(buf, "ENT0 1|%s|0|4|%s|||%s|%s", bstr("recp"), - bstr("subject") ); + bstr("subject"), + bstr("cc"), + bstr("bcc") + ); serv_puts(buf); serv_getln(buf, sizeof buf); if (buf[0] == '4') { post_mime_to_server(); - if (strlen(bstr("recp")) > 0) { - sprintf(WC->ImportantMessage, "Message has been sent.\n"); + if ( (strlen(bstr("recp")) > 0) + || (strlen(bstr("cc")) > 0) + || (strlen(bstr("bcc")) > 0) + ) { + sprintf(WC->ImportantMessage, _("Message has been sent.\n")); } else { - sprintf(WC->ImportantMessage, "Message has been posted.\n"); + sprintf(WC->ImportantMessage, _("Message has been posted.\n")); } dont_post = atol(bstr("postseq")); } else { - sprintf(WC->ImportantMessage, - "%s", &buf[4]); + sprintf(WC->ImportantMessage, "%s", &buf[4]); + display_enter(); + return; } } @@ -1953,6 +2339,8 @@ void display_enter(void) char buf[SIZ]; long now; struct wc_attachment *att; + int recipient_required = 0; + int recipient_bad = 0; if (strlen(bstr("force_room")) > 0) { gotoroom(bstr("force_room")); @@ -1984,8 +2372,11 @@ void display_enter(void) } #endif - /* Otherwise proceed normally. Do a custom room banner with no navbar... */ - output_headers(1, 1, 2, 0, 0, 0, 0); + /* + * Otherwise proceed normally. + * Do a custom room banner with no navbar... + */ + output_headers(1, 1, 2, 0, 0, 0); wprintf("
\n"); embed_room_banner(NULL, navbar_none); wprintf("
\n"); @@ -1993,67 +2384,123 @@ void display_enter(void) "
" "
"); - sprintf(buf, "ENT0 0|%s|0|0", bstr("recp")); - serv_puts(buf); + /* First test to see whether this is a room that requires recipients to be entered */ + serv_puts("ENT0 0"); serv_getln(buf, sizeof buf); - - if (!strncmp(buf, "570", 3)) { - if (strlen(bstr("recp")) > 0) { - svprintf("RECPERROR", WCS_STRING, - "%s
\n", - &buf[4] - ); - } - do_template("prompt_for_recipient"); - goto DONE; + if (!strncmp(buf, "570", 3)) { /* 570 means that we need a recipient here */ + recipient_required = 1; } - if (buf[0] != '2') { + else if (buf[0] != '2') { /* Any other error means that we cannot continue */ wprintf("%s
\n", &buf[4]); goto DONE; } + /* Now check our actual recipients if there are any */ + if (recipient_required) { + sprintf(buf, "ENT0 0|%s|0|0||||%s|%s", bstr("recp"), bstr("cc"), bstr("bcc")); + serv_puts(buf); + serv_getln(buf, sizeof buf); + + if (!strncmp(buf, "570", 3)) { /* 570 means we have an invalid recipient listed */ + if (strlen(bstr("recp")) + strlen(bstr("cc")) + strlen(bstr("bcc")) > 0) { + recipient_bad = 1; + } + } + else if (buf[0] != '2') { /* Any other error means that we cannot continue */ + wprintf("%s
\n", &buf[4]); + goto DONE; + } + } + + /* If we got this far, we can display the message entry screen. */ + now = time(NULL); fmt_date(buf, now, 0); - strcat(&buf[strlen(buf)], " from "); + strcat(&buf[strlen(buf)], _(" from ")); stresc(&buf[strlen(buf)], WC->wc_username, 1, 1); + + /* Don't need this anymore, it's in the input box below if (strlen(bstr("recp")) > 0) { - strcat(&buf[strlen(buf)], " to "); + strcat(&buf[strlen(buf)], _(" to ")); stresc(&buf[strlen(buf)], bstr("recp"), 1, 1); } - strcat(&buf[strlen(buf)], " in "); + */ + + strcat(&buf[strlen(buf)], _(" in ")); stresc(&buf[strlen(buf)], WC->wc_roomname, 1, 1); /* begin message entry screen */ - // wprintf("
\n"); - wprintf("
\n"); - wprintf("\n", - bstr("recp")); - wprintf("\n", - now); + wprintf("\n", now); - wprintf("%s
\n", buf); /* header bar */ wprintf("\""); - /* "onLoad=\"document.enterform.msgtext.focus();\" " */ - wprintf("Subject (optional):" + wprintf("%s
\n", buf); /* header bar */ + + wprintf("\n"); + if (recipient_required) { + + wprintf("\n"); + + wprintf("\n"); + + wprintf("\n"); + + /* Initialize the autocomplete ajax helpers (found in wclib.js) */ + wprintf(" \n" + ); + } + + wprintf("
"); + wprintf(""); + wprintf(_("To:")); + wprintf(""); + wprintf("" + ""); + wprintf("
"); + wprintf("
"); + wprintf(""); + wprintf(_("CC:")); + wprintf(""); + wprintf("" + ""); + wprintf("
"); + wprintf("
"); + wprintf(""); + wprintf(_("BCC:")); + wprintf(""); + wprintf("" + ""); + wprintf("
"); + wprintf("
"); + wprintf(""); + wprintf(_("Subject (optional):")); + wprintf(""); + wprintf("" "" - " " - ); + wprintf("\" size=50 maxlength=70>\n"); - wprintf(" 0) { - wprintf("Send message"); + wprintf(" " - "\n"); + "\n", _("Cancel")); + wprintf("
\n"); wprintf("
\n" @@ -2069,6 +2516,12 @@ void display_enter(void) "

\n"); @@ -2090,7 +2543,17 @@ void display_enter(void) wprintf("   " "Attach file: \n  " - "\n"); + "\n", _("Add")); + + /* Seth asked for these to be at the top *and* bottom... */ + wprintf(" " + "\n", _("Cancel")); wprintf("
\n"); @@ -2112,7 +2575,7 @@ void delete_msg(void) msgid = atol(bstr("msgid")); - output_headers(1, 1, 1, 0, 0, 0, 0); + output_headers(1, 1, 1, 0, 0, 0); sprintf(buf, "DELE %ld", msgid); serv_puts(buf); @@ -2136,17 +2599,20 @@ void confirm_move_msg(void) msgid = atol(bstr("msgid")); - output_headers(1, 1, 1, 0, 0, 0, 0); + output_headers(1, 1, 1, 0, 0, 0); wprintf("
" "
"); wprintf("Confirm move of message\n"); + wprintf(""); + wprintf(_("Confirm move of message")); + wprintf("\n"); wprintf("
\n"); wprintf("
"); - wprintf("Move this message to:
\n"); + wprintf(_("Move this message to:")); + wprintf("
\n"); wprintf("
\n"); wprintf("\n", @@ -2167,9 +2633,9 @@ void confirm_move_msg(void) wprintf("\n"); wprintf("
\n"); - wprintf(""); + wprintf("", _("Move")); wprintf(" "); - wprintf(""); + wprintf("", _("Cancel")); wprintf("
\n"); wprintf("\n"); @@ -2185,15 +2651,17 @@ void move_msg(void) msgid = atol(bstr("msgid")); - output_headers(1, 1, 1, 0, 0, 0, 0); + output_headers(1, 1, 1, 0, 0, 0); - if (!strcasecmp(bstr("yesno"), "Move")) { + if (strlen(bstr("move_button")) > 0) { sprintf(buf, "MOVE %ld|%s", msgid, bstr("target_room")); serv_puts(buf); serv_getln(buf, sizeof buf); wprintf("%s
\n", &buf[4]); } else { - wprintf("Message not moved.
\n"); + wprintf(""); + wprintf(_("The message was not moved.")); + wprintf("
\n"); } wDumpContent(1); @@ -2205,8 +2673,7 @@ void move_msg(void) * (such as deleting them). */ void do_stuff_to_msgs(void) { - char buf[SIZ]; - char sc[SIZ]; + char buf[256]; struct stuff_t { struct stuff_t *next; @@ -2215,6 +2682,7 @@ void do_stuff_to_msgs(void) { struct stuff_t *stuff = NULL; struct stuff_t *ptr; + int delete_button_pressed = 0; serv_puts("MSGS ALL"); @@ -2227,14 +2695,16 @@ void do_stuff_to_msgs(void) { stuff = ptr; } - strcpy(sc, bstr("sc")); + if (strlen(bstr("delete_button")) > 0) { + delete_button_pressed = 1; + } while (stuff != NULL) { sprintf(buf, "msg_%ld", stuff->msgnum); if (!strcasecmp(bstr(buf), "yes")) { - if (!strcasecmp(sc, "Delete")) { + if (delete_button_pressed) { serv_printf("DELE %ld", stuff->msgnum); serv_getln(buf, sizeof buf); }