00001
00002
00003
00010 #include "webcit.h"
00011 #include "vcard.h"
00012 #include "webserver.h"
00013 #include "groupdav.h"
00014
00015 #define SUBJ_COL_WIDTH_PCT 50
00016 #define SENDER_COL_WIDTH_PCT 30
00017 #define DATE_PLUS_BUTTONS_WIDTH_PCT 20
00023 struct addrbookent {
00024 char ab_name[64];
00025 long ab_msgnum;
00026 };
00027
00028
00029
00030 #ifdef HAVE_ICONV
00031
00040 iconv_t ctdl_iconv_open(const char *tocode, const char *fromcode)
00041 {
00042 iconv_t ic = (iconv_t)(-1) ;
00043 ic = iconv_open(tocode, fromcode);
00044 if (ic == (iconv_t)(-1) ) {
00045 char alias_fromcode[64];
00046 if ( (strlen(fromcode) == 5) && (!strncasecmp(fromcode, "MS", 2)) ) {
00047 safestrncpy(alias_fromcode, fromcode, sizeof alias_fromcode);
00048 alias_fromcode[0] = 'C';
00049 alias_fromcode[1] = 'P';
00050 ic = iconv_open(tocode, alias_fromcode);
00051 }
00052 }
00053 return(ic);
00054 }
00055
00056
00063 void utf8ify_rfc822_string(char *buf) {
00064 char *start, *end;
00065 char newbuf[1024];
00066 char charset[128];
00067 char encoding[16];
00068 char istr[1024];
00069 iconv_t ic = (iconv_t)(-1) ;
00070 char *ibuf;
00071 char *obuf;
00072 size_t ibuflen;
00073 size_t obuflen;
00074 char *isav;
00075 char *osav;
00076 int passes = 0;
00077 int i;
00078 int illegal_non_rfc2047_encoding = 0;
00079
00086 for (i=0; i<strlen(buf); ++i) {
00087 if ((buf[i] < 32) || (buf[i] > 126)) {
00088 illegal_non_rfc2047_encoding = 1;
00089 }
00090 }
00091 if (illegal_non_rfc2047_encoding) {
00092 char default_header_charset[128];
00093 get_preference("default_header_charset", default_header_charset, sizeof default_header_charset);
00094 if ( (strcasecmp(default_header_charset, "UTF-8")) && (strcasecmp(default_header_charset, "us-ascii")) ) {
00095 ic = ctdl_iconv_open("UTF-8", default_header_charset);
00096 if (ic != (iconv_t)(-1) ) {
00097 ibuf = malloc(1024);
00098 isav = ibuf;
00099 safestrncpy(ibuf, buf, 1024);
00100 ibuflen = strlen(ibuf);
00101 obuflen = 1024;
00102 obuf = (char *) malloc(obuflen);
00103 osav = obuf;
00104 iconv(ic, &ibuf, &ibuflen, &obuf, &obuflen);
00105 osav[1024-obuflen] = 0;
00106 strcpy(buf, osav);
00107 free(osav);
00108 iconv_close(ic);
00109 free(isav);
00110 }
00111 }
00112 }
00113
00117 while (start=strstr(buf, "=?"), end=strstr(buf, "?="),
00118 ((start != NULL) && (end != NULL) && (end > start)) )
00119 {
00120 extract_token(charset, start, 1, '?', sizeof charset);
00121 extract_token(encoding, start, 2, '?', sizeof encoding);
00122 extract_token(istr, start, 3, '?', sizeof istr);
00123
00124 ibuf = malloc(1024);
00125 isav = ibuf;
00126 if (!strcasecmp(encoding, "B")) {
00127 ibuflen = CtdlDecodeBase64(ibuf, istr, strlen(istr));
00128 }
00129 else if (!strcasecmp(encoding, "Q")) {
00130 size_t len;
00131 long pos;
00132
00133 len = strlen(istr);
00134 pos = 0;
00135 while (pos < len)
00136 {
00137 if (istr[pos] == '_') istr[pos] = ' ';
00138 pos++;
00139 }
00140
00141 ibuflen = CtdlDecodeQuotedPrintable(ibuf, istr, len);
00142 }
00143 else {
00144 strcpy(ibuf, istr);
00145 ibuflen = strlen(istr);
00146 }
00147
00148 ic = ctdl_iconv_open("UTF-8", charset);
00149 if (ic != (iconv_t)(-1) ) {
00150 obuflen = 1024;
00151 obuf = (char *) malloc(obuflen);
00152 osav = obuf;
00153 iconv(ic, &ibuf, &ibuflen, &obuf, &obuflen);
00154 osav[1024-obuflen] = 0;
00155
00156 end = start;
00157 end++;
00158 strcpy(start, "");
00159 remove_token(end, 0, '?');
00160 remove_token(end, 0, '?');
00161 remove_token(end, 0, '?');
00162 remove_token(end, 0, '?');
00163 strcpy(end, &end[1]);
00164
00165 snprintf(newbuf, sizeof newbuf, "%s%s%s", buf, osav, end);
00166 strcpy(buf, newbuf);
00167 free(osav);
00168 iconv_close(ic);
00169 }
00170 else {
00171 end = start;
00172 end++;
00173 strcpy(start, "");
00174 remove_token(end, 0, '?');
00175 remove_token(end, 0, '?');
00176 remove_token(end, 0, '?');
00177 remove_token(end, 0, '?');
00178 strcpy(end, &end[1]);
00179
00180 snprintf(newbuf, sizeof newbuf, "%s(unreadable)%s", buf, end);
00181 strcpy(buf, newbuf);
00182 }
00183
00184 free(isav);
00185
00192 ++passes;
00193 if (passes > 20) return;
00194 }
00195
00196 }
00197 #endif
00198
00199
00200
00201
00211 void rfc2047encode(char *target, int maxlen, char *source)
00212 {
00213 int need_to_encode = 0;
00214 int i;
00215 unsigned char ch;
00216
00217 if (target == NULL) return;
00218
00219 for (i=0; i<strlen(source); ++i) {
00220 if ((source[i] < 32) || (source[i] > 126)) {
00221 need_to_encode = 1;
00222 }
00223 }
00224
00225 if (!need_to_encode) {
00226 safestrncpy(target, source, maxlen);
00227 return;
00228 }
00229
00230 strcpy(target, "=?UTF-8?Q?");
00231 for (i=0; i<strlen(source); ++i) {
00232 ch = (unsigned char) source[i];
00233 if ((ch < 32) || (ch > 126) || (ch == 61)) {
00234 sprintf(&target[strlen(target)], "=%02X", ch);
00235 }
00236 else {
00237 sprintf(&target[strlen(target)], "%c", ch);
00238 }
00239 }
00240
00241 strcat(target, "?=");
00242 }
00243
00244
00245
00246
00252 void url(char *buf)
00253 {
00254
00255 int pos;
00256 int start, end;
00257 char urlbuf[SIZ];
00258 char outbuf[1024];
00259 start = (-1);
00260 end = strlen(buf);
00261
00262 for (pos = 0; pos < strlen(buf); ++pos) {
00263 if (!strncasecmp(&buf[pos], "http://", 7))
00264 start = pos;
00265 if (!strncasecmp(&buf[pos], "ftp://", 6))
00266 start = pos;
00267 }
00268
00269 if (start < 0)
00270 return;
00271
00272 for (pos = strlen(buf); pos > start; --pos) {
00273 if ( (!isprint(buf[pos]))
00274 || (isspace(buf[pos]))
00275 || (buf[pos] == '{')
00276 || (buf[pos] == '}')
00277 || (buf[pos] == '|')
00278 || (buf[pos] == '\\')
00279 || (buf[pos] == '^')
00280 || (buf[pos] == '[')
00281 || (buf[pos] == ']')
00282 || (buf[pos] == '`')
00283 || (buf[pos] == '<')
00284 || (buf[pos] == '>')
00285 || (buf[pos] == '(')
00286 || (buf[pos] == ')')
00287 ) {
00288 end = pos;
00289 }
00290 }
00291
00292 strncpy(urlbuf, &buf[start], end - start);
00293 urlbuf[end - start] = 0;
00294
00295 strncpy(outbuf, buf, start);
00296 sprintf(&outbuf[start], "%ca href=%c%s%c TARGET=%c%s%c%c%s%c/A%c",
00297 LB, QU, urlbuf, QU, QU, TARGET, QU, RB, urlbuf, LB, RB);
00298 strcat(outbuf, &buf[end]);
00299 if ( strlen(outbuf) < 250 )
00300 strcpy(buf, outbuf);
00301 }
00302
00303
00308 void vcard_n_prettyize(char *name)
00309 {
00310 char *original_name;
00311 int i;
00312
00313 original_name = strdup(name);
00314 for (i=0; i<5; ++i) {
00315 if (strlen(original_name) > 0) {
00316 if (original_name[strlen(original_name)-1] == ' ') {
00317 original_name[strlen(original_name)-1] = 0;
00318 }
00319 if (original_name[strlen(original_name)-1] == ';') {
00320 original_name[strlen(original_name)-1] = 0;
00321 }
00322 }
00323 }
00324 strcpy(name, "");
00325 for (i=0; i<strlen(original_name); ++i) {
00326 if (original_name[i] == ';') {
00327 strcat(name, ", ");
00328 }
00329 else {
00330 name[strlen(name)+1] = 0;
00331 name[strlen(name)] = original_name[i];
00332 }
00333 }
00334 free(original_name);
00335 }
00336
00337
00338
00339
00349 void fetchname_parsed_vcard(struct vCard *v, char *storename) {
00350 char *name;
00351
00352 strcpy(storename, "");
00353
00354 name = vcard_get_prop(v, "n", 1, 0, 0);
00355 if (name != NULL) {
00356 strcpy(storename, name);
00357
00358 }
00359
00360 }
00361
00362
00363
00380 void display_parsed_vcard(struct vCard *v, int full) {
00381 int i, j;
00382 char buf[SIZ];
00383 char *name;
00384 int is_qp = 0;
00385 int is_b64 = 0;
00386 char *thisname, *thisvalue;
00387 char firsttoken[SIZ];
00388 int pass;
00389
00390 char fullname[SIZ];
00391 char title[SIZ];
00392 char org[SIZ];
00393 char phone[SIZ];
00394 char mailto[SIZ];
00395
00396 strcpy(fullname, "");
00397 strcpy(phone, "");
00398 strcpy(mailto, "");
00399 strcpy(title, "");
00400 strcpy(org, "");
00401
00402 if (!full) {
00403 wprintf("<TD>");
00404 name = vcard_get_prop(v, "fn", 1, 0, 0);
00405 if (name != NULL) {
00406 escputs(name);
00407 }
00408 else if (name = vcard_get_prop(v, "n", 1, 0, 0), name != NULL) {
00409 strcpy(fullname, name);
00410 vcard_n_prettyize(fullname);
00411 escputs(fullname);
00412 }
00413 else {
00414 wprintf(" ");
00415 }
00416 wprintf("</TD>");
00417 return;
00418 }
00419
00420 wprintf("<div align=center>"
00421 "<table bgcolor=#aaaaaa width=50%%>");
00422 for (pass=1; pass<=2; ++pass) {
00423
00424 if (v->numprops) for (i=0; i<(v->numprops); ++i) {
00425
00426 thisname = strdup(v->prop[i].name);
00427 extract_token(firsttoken, thisname, 0, ';', sizeof firsttoken);
00428
00429 for (j=0; j<num_tokens(thisname, ';'); ++j) {
00430 extract_token(buf, thisname, j, ';', sizeof buf);
00431 if (!strcasecmp(buf, "encoding=quoted-printable")) {
00432 is_qp = 1;
00433 remove_token(thisname, j, ';');
00434 }
00435 if (!strcasecmp(buf, "encoding=base64")) {
00436 is_b64 = 1;
00437 remove_token(thisname, j, ';');
00438 }
00439 }
00440
00441 if (is_qp) {
00442 thisvalue = malloc(strlen(v->prop[i].value) + 50);
00443 j = CtdlDecodeQuotedPrintable(
00444 thisvalue, v->prop[i].value,
00445 strlen(v->prop[i].value) );
00446 thisvalue[j] = 0;
00447 }
00448 else if (is_b64) {
00449 thisvalue = malloc(strlen(v->prop[i].value) + 50);
00450 CtdlDecodeBase64(
00451 thisvalue, v->prop[i].value,
00452 strlen(v->prop[i].value) );
00453 }
00454 else {
00455 thisvalue = strdup(v->prop[i].value);
00456 }
00457
00461 if (!strcasecmp(firsttoken, "n")) {
00462 if (strlen(fullname) == 0) {
00463 strcpy(fullname, thisvalue);
00464 vcard_n_prettyize(fullname);
00465 }
00466 }
00467
00469 else if (!strcasecmp(firsttoken, "fn")) {
00470 strcpy(fullname, thisvalue);
00471 }
00472
00474 else if (!strcasecmp(firsttoken, "title")) {
00475 strcpy(title, thisvalue);
00476 }
00477
00479 else if (!strcasecmp(firsttoken, "org")) {
00480 strcpy(org, thisvalue);
00481 }
00482
00483 else if (!strcasecmp(firsttoken, "email")) {
00484 if (strlen(mailto) > 0) strcat(mailto, "<br />");
00485 strcat(mailto,
00486 "<a href=\"display_enter"
00487 "?force_room=_MAIL_?recp=");
00488
00489 urlesc(&mailto[strlen(mailto)], fullname);
00490 urlesc(&mailto[strlen(mailto)], " <");
00491 urlesc(&mailto[strlen(mailto)], thisvalue);
00492 urlesc(&mailto[strlen(mailto)], ">");
00493
00494 strcat(mailto, "\">");
00495 stresc(&mailto[strlen(mailto)], thisvalue, 1, 1);
00496 strcat(mailto, "</A>");
00497 }
00498 else if (!strcasecmp(firsttoken, "tel")) {
00499 if (strlen(phone) > 0) strcat(phone, "<br />");
00500 strcat(phone, thisvalue);
00501 for (j=0; j<num_tokens(thisname, ';'); ++j) {
00502 extract_token(buf, thisname, j, ';', sizeof buf);
00503 if (!strcasecmp(buf, "tel"))
00504 strcat(phone, "");
00505 else if (!strcasecmp(buf, "work"))
00506 strcat(phone, _(" (work)"));
00507 else if (!strcasecmp(buf, "home"))
00508 strcat(phone, _(" (home)"));
00509 else if (!strcasecmp(buf, "cell"))
00510 strcat(phone, _(" (cell)"));
00511 else {
00512 strcat(phone, " (");
00513 strcat(phone, buf);
00514 strcat(phone, ")");
00515 }
00516 }
00517 }
00518 else if (!strcasecmp(firsttoken, "adr")) {
00519 if (pass == 2) {
00520 wprintf("<TR><TD>");
00521 wprintf(_("Address:"));
00522 wprintf("</TD><TD>");
00523 for (j=0; j<num_tokens(thisvalue, ';'); ++j) {
00524 extract_token(buf, thisvalue, j, ';', sizeof buf);
00525 if (strlen(buf) > 0) {
00526 escputs(buf);
00527 if (j<3) wprintf("<br />");
00528 else wprintf(" ");
00529 }
00530 }
00531 wprintf("</TD></TR>\n");
00532 }
00533 }
00534 else if (!strcasecmp(firsttoken, "version")) {
00535
00536 }
00537 else if (!strcasecmp(firsttoken, "rev")) {
00538
00539 }
00540 else if (!strcasecmp(firsttoken, "label")) {
00541
00542 }
00543 else {
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 }
00555
00556 free(thisname);
00557 free(thisvalue);
00558 }
00559
00560 if (pass == 1) {
00561 wprintf("<TR BGCOLOR=\"#AAAAAA\">"
00562 "<TD COLSPAN=2 BGCOLOR=\"#FFFFFF\">"
00563 "<IMG ALIGN=CENTER src=\"static/viewcontacts_48x.gif\">"
00564 "<FONT SIZE=+1><B>");
00565 escputs(fullname);
00566 wprintf("</B></FONT>");
00567 if (strlen(title) > 0) {
00568 wprintf("<div align=right>");
00569 escputs(title);
00570 wprintf("</div>");
00571 }
00572 if (strlen(org) > 0) {
00573 wprintf("<div align=right>");
00574 escputs(org);
00575 wprintf("</div>");
00576 }
00577 wprintf("</TD></TR>\n");
00578
00579 if (strlen(phone) > 0) {
00580 wprintf("<tr><td>");
00581 wprintf(_("Telephone:"));
00582 wprintf("</td><td>%s</td></tr>\n", phone);
00583 }
00584 if (strlen(mailto) > 0) {
00585 wprintf("<tr><td>");
00586 wprintf(_("E-mail:"));
00587 wprintf("</td><td>%s</td></tr>\n", mailto);
00588 }
00589 }
00590
00591 }
00592
00593 wprintf("</table></div>\n");
00594 }
00595
00596
00597
00609 void display_vcard(char *vcard_source, char alpha, int full, char *storename) {
00610 struct vCard *v;
00611 char *name;
00612 char buf[SIZ];
00613 char this_alpha = 0;
00614
00615 v = vcard_load(vcard_source);
00616 if (v == NULL) return;
00617
00618 name = vcard_get_prop(v, "n", 1, 0, 0);
00619 if (name != NULL) {
00620 strcpy(buf, name);
00621 this_alpha = buf[0];
00622 }
00623
00624 if (storename != NULL) {
00625 fetchname_parsed_vcard(v, storename);
00626 }
00627 else if ( (alpha == 0)
00628 || ((isalpha(alpha)) && (tolower(alpha) == tolower(this_alpha)) )
00629 || ((!isalpha(alpha)) && (!isalpha(this_alpha)))
00630 ) {
00631 display_parsed_vcard(v, full);
00632 }
00633
00634 vcard_free(v);
00635 }
00636
00637
00638 struct attach_link {
00639 char partnum[32];
00640 char html[1024];
00641 };
00642
00643
00650 void read_message(long msgnum, int printable_view, char *section) {
00651 char buf[SIZ];
00652 char mime_partnum[256];
00653 char mime_name[256];
00654 char mime_filename[256];
00655 char mime_content_type[256];
00656 char mime_charset[256];
00657 char mime_disposition[256];
00658 int mime_length;
00659 struct attach_link *attach_links = NULL;
00660 int num_attach_links = 0;
00661 char mime_submessages[256];
00662 char m_subject[256];
00663 char m_cc[1024];
00664 char from[256];
00665 char node[256];
00666 char rfca[256];
00667 char reply_to[512];
00668 char reply_all[4096];
00669 char now[64];
00670 int format_type = 0;
00671 int nhdr = 0;
00672 int bq = 0;
00673 int i = 0;
00674 char vcard_partnum[256];
00675 char cal_partnum[256];
00676 char *part_source = NULL;
00677 char msg4_partnum[32];
00678 #ifdef HAVE_ICONV
00679 iconv_t ic = (iconv_t)(-1) ;
00680 char *ibuf;
00681 char *obuf;
00682 size_t ibuflen;
00683 size_t obuflen;
00684 char *osav;
00685 #endif
00686
00687 strcpy(from, "");
00688 strcpy(node, "");
00689 strcpy(rfca, "");
00690 strcpy(reply_to, "");
00691 strcpy(reply_all, "");
00692 strcpy(vcard_partnum, "");
00693 strcpy(cal_partnum, "");
00694 strcpy(mime_content_type, "text/plain");
00695 strcpy(mime_charset, "us-ascii");
00696 strcpy(mime_submessages, "");
00697
00698 serv_printf("MSG4 %ld|%s", msgnum, section);
00699 serv_getln(buf, sizeof buf);
00700 if (buf[0] != '1') {
00701 wprintf("<strong>");
00702 wprintf(_("ERROR:"));
00703 wprintf("</strong> %s<br />\n", &buf[4]);
00704 return;
00705 }
00706
00708 if (!printable_view) {
00709 wprintf("<div class=\"fix_scrollbar_bug message\" ");
00710 wprintf("onMouseOver=document.getElementById(\"msg%ld\").style.visibility=\"visible\" ", msgnum);
00711 wprintf("onMouseOut=document.getElementById(\"msg%ld\").style.visibility=\"hidden\" >", msgnum);
00712 }
00713
00715 wprintf("<div class=\"message_header\">");
00716 strcpy(m_subject, "");
00717 strcpy(m_cc, "");
00718
00719 while (serv_getln(buf, sizeof buf), strcasecmp(buf, "text")) {
00720 if (!strcmp(buf, "000")) {
00721 wprintf("<i>");
00722 wprintf(_("unexpected end of message"));
00723 wprintf(" (1)</i><br /><br />\n");
00724 wprintf("</div>\n");
00725 return;
00726 }
00727 if (!strncasecmp(buf, "nhdr=yes", 8))
00728 nhdr = 1;
00729 if (nhdr == 1)
00730 buf[0] = '_';
00731 if (!strncasecmp(buf, "type=", 5))
00732 format_type = atoi(&buf[5]);
00733 if (!strncasecmp(buf, "from=", 5)) {
00734 strcpy(from, &buf[5]);
00735 wprintf(_("from "));
00736 wprintf("<a href=\"showuser?who=");
00737 #ifdef HAVE_ICONV
00738 utf8ify_rfc822_string(from);
00739 #endif
00740 urlescputs(from);
00741 wprintf("\">");
00742 escputs(from);
00743 wprintf("</a> ");
00744 }
00745 if (!strncasecmp(buf, "subj=", 5)) {
00746 safestrncpy(m_subject, &buf[5], sizeof m_subject);
00747 }
00748 if (!strncasecmp(buf, "cccc=", 5)) {
00749 safestrncpy(m_cc, &buf[5], sizeof m_cc);
00750 if (strlen(reply_all) > 0) {
00751 strcat(reply_all, ", ");
00752 }
00753 safestrncpy(&reply_all[strlen(reply_all)], &buf[5],
00754 (sizeof reply_all - strlen(reply_all)) );
00755 }
00756 if ((!strncasecmp(buf, "hnod=", 5))
00757 && (strcasecmp(&buf[5], serv_info.serv_humannode))) {
00758 wprintf("(%s) ", &buf[5]);
00759 }
00760 if ((!strncasecmp(buf, "room=", 5))
00761 && (strcasecmp(&buf[5], WC->wc_roomname))
00762 && (strlen(&buf[5])>0) ) {
00763 wprintf(_("in "));
00764 wprintf("%s> ", &buf[5]);
00765 }
00766 if (!strncasecmp(buf, "rfca=", 5)) {
00767 strcpy(rfca, &buf[5]);
00768 wprintf("<");
00769 escputs(rfca);
00770 wprintf("> ");
00771 }
00772
00773 if (!strncasecmp(buf, "node=", 5)) {
00774 strcpy(node, &buf[5]);
00775 if ( ((WC->room_flags & QR_NETWORK)
00776 || ((strcasecmp(&buf[5], serv_info.serv_nodename)
00777 && (strcasecmp(&buf[5], serv_info.serv_fqdn)))))
00778 && (strlen(rfca)==0)
00779 ) {
00780 wprintf("@%s ", &buf[5]);
00781 }
00782 }
00783 if (!strncasecmp(buf, "rcpt=", 5)) {
00784 wprintf(_("to "));
00785 if (strlen(reply_all) > 0) {
00786 strcat(reply_all, ", ");
00787 }
00788 safestrncpy(&reply_all[strlen(reply_all)], &buf[5],
00789 (sizeof reply_all - strlen(reply_all)) );
00790 #ifdef HAVE_ICONV
00791 utf8ify_rfc822_string(&buf[5]);
00792 #endif
00793 escputs(&buf[5]);
00794 wprintf(" ");
00795 }
00796 if (!strncasecmp(buf, "time=", 5)) {
00797 fmt_date(now, atol(&buf[5]), 0);
00798 wprintf("%s ", now);
00799 }
00800
00801 if (!strncasecmp(buf, "part=", 5)) {
00802 extract_token(mime_name, &buf[5], 0, '|', sizeof mime_filename);
00803 extract_token(mime_filename, &buf[5], 1, '|', sizeof mime_filename);
00804 extract_token(mime_partnum, &buf[5], 2, '|', sizeof mime_partnum);
00805 extract_token(mime_disposition, &buf[5], 3, '|', sizeof mime_disposition);
00806 extract_token(mime_content_type, &buf[5], 4, '|', sizeof mime_content_type);
00807 mime_length = extract_int(&buf[5], 5);
00808
00809 striplt(mime_name);
00810 striplt(mime_filename);
00811 if ( (strlen(mime_filename) == 0) && (strlen(mime_name) > 0) ) {
00812 strcpy(mime_filename, mime_name);
00813 }
00814
00815 if (!strcasecmp(mime_content_type, "message/rfc822")) {
00816 if (strlen(mime_submessages) > 0) {
00817 strcat(mime_submessages, "|");
00818 }
00819 strcat(mime_submessages, mime_partnum);
00820 }
00821 else if ((!strcasecmp(mime_disposition, "inline"))
00822 && (!strncasecmp(mime_content_type, "image/", 6)) ){
00823 ++num_attach_links;
00824 attach_links = realloc(attach_links,
00825 (num_attach_links*sizeof(struct attach_link)));
00826 safestrncpy(attach_links[num_attach_links-1].partnum, mime_partnum, 32);
00827 snprintf(attach_links[num_attach_links-1].html, 1024,
00828 "<img src=\"mimepart/%ld/%s/%s\">",
00829 msgnum, mime_partnum, mime_filename);
00830 }
00831 else if ( ( (!strcasecmp(mime_disposition, "attachment"))
00832 || (!strcasecmp(mime_disposition, "inline"))
00833 || (!strcasecmp(mime_disposition, ""))
00834 ) && (strlen(mime_content_type) > 0)
00835 ) {
00836 ++num_attach_links;
00837 attach_links = realloc(attach_links,
00838 (num_attach_links*sizeof(struct attach_link)));
00839 safestrncpy(attach_links[num_attach_links-1].partnum, mime_partnum, 32);
00840 snprintf(attach_links[num_attach_links-1].html, 1024,
00841 "<img src=\"static/diskette_24x.gif\" "
00842 "border=0 align=middle>\n"
00843 "%s (%s, %d bytes) [ "
00844 "<a href=\"mimepart/%ld/%s/%s\""
00845 "target=\"wc.%ld.%s\">%s</a>"
00846 " | "
00847 "<a href=\"mimepart_download/%ld/%s/%s\">%s</a>"
00848 " ]<br />\n",
00849 mime_filename,
00850 mime_content_type, mime_length,
00851 msgnum, mime_partnum, mime_filename,
00852 msgnum, mime_partnum,
00853 _("View"),
00854 msgnum, mime_partnum, mime_filename,
00855 _("Download")
00856 );
00857 }
00858
00860 if ( (!strcasecmp(mime_content_type, "text/x-vcard"))
00861 || (!strcasecmp(mime_content_type, "text/vcard")) ) {
00862 strcpy(vcard_partnum, mime_partnum);
00863 }
00864
00865 if (!strcasecmp(mime_content_type, "text/calendar")) {
00866 strcpy(cal_partnum, mime_partnum);
00867 }
00868
00871 }
00872
00873 }
00874
00876 if (strlen(rfca) > 0) {
00877 if (strlen(from) > 0) {
00878 snprintf(reply_to, sizeof(reply_to), "%s <%s>", from, rfca);
00879 }
00880 else {
00881 strcpy(reply_to, rfca);
00882 }
00883 }
00884 else {
00885 if ( (strlen(node) > 0)
00886 && (strcasecmp(node, serv_info.serv_nodename))
00887 && (strcasecmp(node, serv_info.serv_humannode)) ) {
00888 snprintf(reply_to, sizeof(reply_to), "%s @ %s",
00889 from, node);
00890 }
00891 else {
00892 snprintf(reply_to, sizeof(reply_to), "%s", from);
00893 }
00894 }
00895
00896 if (nhdr == 1) {
00897 wprintf("****");
00898 }
00899
00900 wprintf("</div>");
00901
00902 #ifdef HAVE_ICONV
00903 utf8ify_rfc822_string(m_cc);
00904 utf8ify_rfc822_string(m_subject);
00905 #endif
00906 if (strlen(m_cc) > 0) {
00907 wprintf("<div class=\"message_subject\">");
00908 wprintf(_("CC:"));
00909 wprintf(" ");
00910 escputs(m_cc);
00911 wprintf("</div>");
00912 }
00913 if (strlen(m_subject) > 0) {
00914 wprintf("<div class=\"message_subject\">");
00915 wprintf(_("Subject:"));
00916 wprintf(" ");
00917 escputs(m_subject);
00918 wprintf("</div>");
00919 }
00920
00921
00923 if (!printable_view) {
00924 wprintf("<div id=\"msg%ld\" class=\"msgbuttons\" >\n",msgnum);
00925
00927 if ( (WC->wc_view == VIEW_MAILBOX) || (WC->wc_view == VIEW_BBS) ) {
00928 wprintf("<a href=\"display_enter");
00929 if (WC->is_mailbox) {
00930 wprintf("?replyquote=%ld", msgnum);
00931 }
00932 wprintf("?recp=");
00933 urlescputs(reply_to);
00934 if (strlen(m_subject) > 0) {
00935 wprintf("?subject=");
00936 if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%20");
00937 urlescputs(m_subject);
00938 }
00939 wprintf("\"><span>[</span>%s<span>]</span></a> ", _("Reply"));
00940 }
00941
00943 if ( (WC->wc_view == VIEW_MAILBOX) || (WC->wc_view == VIEW_BBS) ) {
00944 if (!WC->is_mailbox) {
00945 wprintf("<a href=\"display_enter");
00946 wprintf("?replyquote=%ld", msgnum);
00947 wprintf("?recp=");
00948 urlescputs(reply_to);
00949 if (strlen(m_subject) > 0) {
00950 wprintf("?subject=");
00951 if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%20");
00952 urlescputs(m_subject);
00953 }
00954 wprintf("\"><span>[</span>%s<span>]</span></a> ", _("ReplyQuoted"));
00955 }
00956 }
00957
00959 if (WC->wc_view == VIEW_MAILBOX) {
00960 wprintf("<a href=\"display_enter");
00961 wprintf("?replyquote=%ld", msgnum);
00962 wprintf("?recp=");
00963 urlescputs(reply_to);
00964 wprintf("?cc=");
00965 urlescputs(reply_all);
00966 if (strlen(m_subject) > 0) {
00967 wprintf("?subject=");
00968 if (strncasecmp(m_subject, "Re:", 3)) wprintf("Re:%20");
00969 urlescputs(m_subject);
00970 }
00971 wprintf("\"><span>[</span>%s<span>]</span></a> ", _("ReplyAll"));
00972 }
00973
00975 if (WC->wc_view == VIEW_MAILBOX) {
00976 wprintf("<a href=\"display_enter?fwdquote=%ld?subject=", msgnum);
00977 if (strncasecmp(m_subject, "Fwd:", 4)) wprintf("Fwd:%20");
00978 urlescputs(m_subject);
00979 wprintf("\"><span>[</span>%s<span>]</span></a> ", _("Forward"));
00980 }
00981
00983 if ( (WC->is_room_aide) || (WC->is_mailbox) || (WC->room_flags2 & QR2_COLLABDEL) ) {
00985 wprintf("<a href=\"confirm_move_msg?msgid=%ld\"><span>[</span>%s<span>]</span></a> ",
00986 msgnum, _("Move"));
00987
00989 wprintf("<a href=\"delete_msg?msgid=%ld\" "
00990 "onClick=\"return confirm('%s');\">"
00991 "<span>[</span>%s<span>]</span> "
00992 "</a> ", msgnum, _("Delete this message?"), _("Delete")
00993 );
00994 }
00995
00997 wprintf("<a href=\"#\" onClick=\"window.open('msgheaders/%ld', 'headers%ld', 'toolbar=no,location=no,directories=no,copyhistory=no,status=yes,scrollbars=yes,resizable=yes,width=600,height=400'); \" >"
00998 "<span>[</span>%s<span>]</span></a>", msgnum, msgnum, _("Headers"));
00999
01000
01002 wprintf("<a href=\"#\" onClick=\"window.open('printmsg/%ld', 'print%ld', 'toolbar=no,location=no,directories=no,copyhistory=no,status=yes,scrollbars=yes,resizable=yes,width=600,height=400'); \" >"
01003 "<span>[</span>%s<span>]</span></a>", msgnum, msgnum, _("Print"));
01004
01005 wprintf("</div>");
01006
01007 }
01008
01009
01010
01012 wprintf("<div class=\"message_content\">");
01013
01017 strcpy(mime_content_type, "text/plain");
01018 while (serv_getln(buf, sizeof buf), (strlen(buf) > 0)) {
01019 if (!strcmp(buf, "000")) {
01020 wprintf("<i>");
01021 wprintf(_("unexpected end of message"));
01022 wprintf(" (2)</i><br /><br />\n");
01023 goto ENDBODY;
01024 }
01025 if (!strncasecmp(buf, "X-Citadel-MSG4-Partnum:", 23)) {
01026 safestrncpy(msg4_partnum, &buf[23], sizeof(msg4_partnum));
01027 striplt(msg4_partnum);
01028 }
01029 if (!strncasecmp(buf, "Content-type:", 13)) {
01030 safestrncpy(mime_content_type, &buf[13], sizeof(mime_content_type));
01031 striplt(mime_content_type);
01032 for (i=0; i<strlen(mime_content_type); ++i) {
01033 if (!strncasecmp(&mime_content_type[i], "charset=", 8)) {
01034 safestrncpy(mime_charset, &mime_content_type[i+8],
01035 sizeof mime_charset);
01036 }
01037 }
01038 for (i=0; i<strlen(mime_content_type); ++i) {
01039 if (mime_content_type[i] == ';') {
01040 mime_content_type[i] = 0;
01041 }
01042 }
01043 for (i=0; i<strlen(mime_charset); ++i) {
01044 if (mime_charset[i] == ';') {
01045 mime_charset[i] = 0;
01046 }
01047 }
01048 }
01049 }
01050
01052 #ifdef HAVE_ICONV
01053 if (strchr(mime_charset, ';')) strcpy(strchr(mime_charset, ';'), "");
01054 if ( (strcasecmp(mime_charset, "us-ascii"))
01055 && (strcasecmp(mime_charset, "UTF-8"))
01056 && (strcasecmp(mime_charset, ""))
01057 ) {
01058 ic = ctdl_iconv_open("UTF-8", mime_charset);
01059 if (ic == (iconv_t)(-1) ) {
01060 lprintf(5, "%s:%d iconv_open(UTF-8, %s) failed: %s\n",
01061 __FILE__, __LINE__, mime_charset, strerror(errno));
01062 }
01063 }
01064 #endif
01065
01067 if (!strcasecmp(mime_content_type, "text/x-citadel-variformat")) {
01068 fmout("JUSTIFY");
01069 }
01070
01072 else if ( (!strcasecmp(mime_content_type, "text/plain"))
01073 || (!strcasecmp(mime_content_type, "text")) ) {
01074 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
01075 if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0;
01076 if (buf[strlen(buf)-1] == '\r') buf[strlen(buf)-1] = 0;
01077
01078 #ifdef HAVE_ICONV
01079 if (ic != (iconv_t)(-1) ) {
01080 ibuf = buf;
01081 ibuflen = strlen(ibuf);
01082 obuflen = SIZ;
01083 obuf = (char *) malloc(obuflen);
01084 osav = obuf;
01085 iconv(ic, &ibuf, &ibuflen, &obuf, &obuflen);
01086 osav[SIZ-obuflen] = 0;
01087 safestrncpy(buf, osav, sizeof buf);
01088 free(osav);
01089 }
01090 #endif
01091
01092 while ((strlen(buf) > 0) && (isspace(buf[strlen(buf) - 1])))
01093 buf[strlen(buf) - 1] = 0;
01094 if ((bq == 0) &&
01095 ((!strncmp(buf, ">", 1)) || (!strncmp(buf, " >", 2)) )) {
01096 wprintf("<blockquote>");
01097 bq = 1;
01098 } else if ((bq == 1) &&
01099 (strncmp(buf, ">", 1)) && (strncmp(buf, " >", 2)) ) {
01100 wprintf("</blockquote>");
01101 bq = 0;
01102 }
01103 wprintf("<tt>");
01104 url(buf);
01105 escputs(buf);
01106 wprintf("</tt><br />\n");
01107 }
01108 wprintf("</i><br />");
01109 }
01110
01111 else
01112 if (!strcasecmp(mime_content_type, "text/html")) {
01113 output_html(mime_charset, (WC->wc_view == VIEW_WIKI ? 1 : 0));
01114 }
01115
01117 else {
01118 wprintf(_("I don't know how to display %s"), mime_content_type);
01119 wprintf("<br />\n", mime_content_type);
01120 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { }
01121 }
01122
01124 if ( (strlen(mime_submessages) > 0) && (!section[0]) ) {
01125 for (i=0; i<num_tokens(mime_submessages, '|'); ++i) {
01126 extract_token(buf, mime_submessages, i, '|', sizeof buf);
01128 wprintf("<blockquote>");
01129 read_message(msgnum, 1, buf);
01130 wprintf("</blockquote>");
01131 }
01132 }
01133
01134
01136 if ( (num_attach_links > 0) && (!section[0]) ) {
01137 for (i=0; i<num_attach_links; ++i) {
01138 if (strcasecmp(attach_links[i].partnum, msg4_partnum)) {
01139 wprintf("%s", attach_links[i].html);
01140 }
01141 }
01142 }
01143
01145 if (strlen(vcard_partnum) > 0) {
01146 part_source = load_mimepart(msgnum, vcard_partnum);
01147 if (part_source != NULL) {
01148
01150 if ( (!strcasecmp(WC->wc_roomname, USERCONFIGROOM))
01151 || (!strcasecmp(&WC->wc_roomname[11], USERCONFIGROOM))
01152 || (WC->wc_view == VIEW_ADDRESSBOOK)
01153 ) {
01154 wprintf("<a href=\"edit_vcard?"
01155 "msgnum=%ld?partnum=%s\">",
01156 msgnum, vcard_partnum);
01157 wprintf("[%s]</a>", _("edit"));
01158 }
01159
01161 display_vcard(part_source, 0, 1, NULL);
01162 }
01163 }
01164
01166 if (strlen(cal_partnum) > 0) {
01167 part_source = load_mimepart(msgnum, cal_partnum);
01168 if (part_source != NULL) {
01169 cal_process_attachment(part_source,
01170 msgnum, cal_partnum);
01171 }
01172 }
01173
01174 if (part_source) {
01175 free(part_source);
01176 part_source = NULL;
01177 }
01178
01179 ENDBODY:
01180 wprintf("</div>\n");
01181
01183 if (!printable_view) {
01184 wprintf("</div>\n");
01185 }
01186
01187 if (num_attach_links > 0) {
01188 free(attach_links);
01189 }
01190
01191 #ifdef HAVE_ICONV
01192 if (ic != (iconv_t)(-1) ) {
01193 iconv_close(ic);
01194 }
01195 #endif
01196 }
01197
01198
01199
01206 void embed_message(char *msgnum_as_string) {
01207 long msgnum = 0L;
01208
01209 msgnum = atol(msgnum_as_string);
01210 begin_ajax_response();
01211 read_message(msgnum, 0, "");
01212 end_ajax_response();
01213 }
01214
01215
01221 void print_message(char *msgnum_as_string) {
01222 long msgnum = 0L;
01223
01224 msgnum = atol(msgnum_as_string);
01225 output_headers(0, 0, 0, 0, 0, 0);
01226
01227 wprintf("Content-type: text/html\r\n"
01228 "Server: %s\r\n"
01229 "Connection: close\r\n",
01230 SERVER);
01231 begin_burst();
01232
01233 wprintf("\r\n\r\n<html>\n"
01234 "<head><title>Printable view</title></head>\n"
01235 "<body onLoad=\" window.print(); window.close(); \">\n"
01236 );
01237
01238 read_message(msgnum, 1, "");
01239
01240 wprintf("\n</body></html>\n\n");
01241 wDumpContent(0);
01242 }
01243
01244
01245
01251 void display_headers(char *msgnum_as_string) {
01252 long msgnum = 0L;
01253 char buf[1024];
01254
01255 msgnum = atol(msgnum_as_string);
01256 output_headers(0, 0, 0, 0, 0, 0);
01257
01258 wprintf("Content-type: text/plain\r\n"
01259 "Server: %s\r\n"
01260 "Connection: close\r\n",
01261 SERVER);
01262 begin_burst();
01263
01264 serv_printf("MSG2 %ld|3", msgnum);
01265 serv_getln(buf, sizeof buf);
01266 if (buf[0] == '1') {
01267 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
01268 wprintf("%s\n", buf);
01269 }
01270 }
01271
01272 wDumpContent(0);
01273 }
01274
01275
01276
01288 void pullquote_message(long msgnum, int forward_attachments, int include_headers) {
01289 char buf[SIZ];
01290 char mime_partnum[256];
01291 char mime_filename[256];
01292 char mime_content_type[256];
01293 char mime_charset[256];
01294 char mime_disposition[256];
01295 int mime_length;
01296 char *attachments = NULL;
01297 char *ptr = NULL;
01298 int num_attachments = 0;
01299 struct wc_attachment *att, *aptr;
01300 char m_subject[256];
01301 char from[256];
01302 char node[256];
01303 char rfca[256];
01304 char reply_to[512];
01305 char now[256];
01306 int format_type = 0;
01307 int nhdr = 0;
01308 int bq = 0;
01309 int i = 0;
01310 #ifdef HAVE_ICONV
01311 iconv_t ic = (iconv_t)(-1) ;
01312 char *ibuf;
01313 char *obuf;
01314 size_t ibuflen;
01315 size_t obuflen;
01316 char *osav;
01317 #endif
01318
01319 strcpy(from, "");
01320 strcpy(node, "");
01321 strcpy(rfca, "");
01322 strcpy(reply_to, "");
01323 strcpy(mime_content_type, "text/plain");
01324 strcpy(mime_charset, "us-ascii");
01325
01326 serv_printf("MSG4 %ld", msgnum);
01327 serv_getln(buf, sizeof buf);
01328 if (buf[0] != '1') {
01329 wprintf(_("ERROR:"));
01330 wprintf("%s<br />", &buf[4]);
01331 return;
01332 }
01333
01334 strcpy(m_subject, "");
01335
01336 while (serv_getln(buf, sizeof buf), strcasecmp(buf, "text")) {
01337 if (!strcmp(buf, "000")) {
01338 wprintf("%s (3)", _("unexpected end of message"));
01339 return;
01340 }
01341 if (include_headers) {
01342 if (!strncasecmp(buf, "nhdr=yes", 8))
01343 nhdr = 1;
01344 if (nhdr == 1)
01345 buf[0] = '_';
01346 if (!strncasecmp(buf, "type=", 5))
01347 format_type = atoi(&buf[5]);
01348 if (!strncasecmp(buf, "from=", 5)) {
01349 strcpy(from, &buf[5]);
01350 wprintf(_("from "));
01351 #ifdef HAVE_ICONV
01352 utf8ify_rfc822_string(from);
01353 #endif
01354 msgescputs(from);
01355 }
01356 if (!strncasecmp(buf, "subj=", 5)) {
01357 strcpy(m_subject, &buf[5]);
01358 }
01359 if ((!strncasecmp(buf, "hnod=", 5))
01360 && (strcasecmp(&buf[5], serv_info.serv_humannode))) {
01361 wprintf("(%s) ", &buf[5]);
01362 }
01363 if ((!strncasecmp(buf, "room=", 5))
01364 && (strcasecmp(&buf[5], WC->wc_roomname))
01365 && (strlen(&buf[5])>0) ) {
01366 wprintf(_("in "));
01367 wprintf("%s> ", &buf[5]);
01368 }
01369 if (!strncasecmp(buf, "rfca=", 5)) {
01370 strcpy(rfca, &buf[5]);
01371 wprintf("<");
01372 msgescputs(rfca);
01373 wprintf("> ");
01374 }
01375
01376 if (!strncasecmp(buf, "node=", 5)) {
01377 strcpy(node, &buf[5]);
01378 if ( ((WC->room_flags & QR_NETWORK)
01379 || ((strcasecmp(&buf[5], serv_info.serv_nodename)
01380 && (strcasecmp(&buf[5], serv_info.serv_fqdn)))))
01381 && (strlen(rfca)==0)
01382 ) {
01383 wprintf("@%s ", &buf[5]);
01384 }
01385 }
01386 if (!strncasecmp(buf, "rcpt=", 5)) {
01387 wprintf(_("to "));
01388 wprintf("%s ", &buf[5]);
01389 }
01390 if (!strncasecmp(buf, "time=", 5)) {
01391 fmt_date(now, atol(&buf[5]), 0);
01392 wprintf("%s ", now);
01393 }
01394 }
01395
01400 if (!strncasecmp(buf, "part=", 5)) {
01401 ptr = malloc( (strlen(buf) + ((attachments != NULL) ? strlen(attachments) : 0)) ) ;
01402 if (ptr != NULL) {
01403 ++num_attachments;
01404 sprintf(ptr, "%s%s\n",
01405 ((attachments != NULL) ? attachments : ""),
01406 &buf[5]
01407 );
01408 free(attachments);
01409 attachments = ptr;
01410 lprintf(9, "attachments=<%s>\n", attachments);
01411 }
01412 }
01413
01414 }
01415
01416 if (include_headers) {
01417 wprintf("<br>");
01418
01419 #ifdef HAVE_ICONV
01420 utf8ify_rfc822_string(m_subject);
01421 #endif
01422 if (strlen(m_subject) > 0) {
01423 wprintf(_("Subject:"));
01424 wprintf(" ");
01425 msgescputs(m_subject);
01426 wprintf("<br />");
01427 }
01428
01432 wprintf("<br />");
01433 }
01434
01438 strcpy(mime_content_type, "text/plain");
01439 while (serv_getln(buf, sizeof buf), (strlen(buf) > 0)) {
01440 if (!strcmp(buf, "000")) {
01441 wprintf("%s (4)", _("unexpected end of message"));
01442 goto ENDBODY;
01443 }
01444 if (!strncasecmp(buf, "Content-type: ", 14)) {
01445 safestrncpy(mime_content_type, &buf[14],
01446 sizeof(mime_content_type));
01447 for (i=0; i<strlen(mime_content_type); ++i) {
01448 if (!strncasecmp(&mime_content_type[i], "charset=", 8)) {
01449 safestrncpy(mime_charset, &mime_content_type[i+8],
01450 sizeof mime_charset);
01451 }
01452 }
01453 for (i=0; i<strlen(mime_content_type); ++i) {
01454 if (mime_content_type[i] == ';') {
01455 mime_content_type[i] = 0;
01456 }
01457 }
01458 for (i=0; i<strlen(mime_charset); ++i) {
01459 if (mime_charset[i] == ';') {
01460 mime_charset[i] = 0;
01461 }
01462 }
01463 }
01464 }
01465
01467 #ifdef HAVE_ICONV
01468 if ( (strcasecmp(mime_charset, "us-ascii"))
01469 && (strcasecmp(mime_charset, "UTF-8"))
01470 && (strcasecmp(mime_charset, ""))
01471 ) {
01472 ic = ctdl_iconv_open("UTF-8", mime_charset);
01473 if (ic == (iconv_t)(-1) ) {
01474 lprintf(5, "%s:%d iconv_open(%s, %s) failed: %s\n",
01475 __FILE__, __LINE__, "UTF-8", mime_charset, strerror(errno));
01476 }
01477 }
01478 #endif
01479
01481 if (!strcasecmp(mime_content_type, "text/x-citadel-variformat")) {
01482 pullquote_fmout();
01483 }
01484
01485
01486 else if (!strcasecmp(mime_content_type, "text/plain")) {
01487 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
01488 if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0;
01489 if (buf[strlen(buf)-1] == '\r') buf[strlen(buf)-1] = 0;
01490
01491 #ifdef HAVE_ICONV
01492 if (ic != (iconv_t)(-1) ) {
01493 ibuf = buf;
01494 ibuflen = strlen(ibuf);
01495 obuflen = SIZ;
01496 obuf = (char *) malloc(obuflen);
01497 osav = obuf;
01498 iconv(ic, &ibuf, &ibuflen, &obuf, &obuflen);
01499 osav[SIZ-obuflen] = 0;
01500 safestrncpy(buf, osav, sizeof buf);
01501 free(osav);
01502 }
01503 #endif
01504
01505 while ((strlen(buf) > 0) && (isspace(buf[strlen(buf) - 1])))
01506 buf[strlen(buf) - 1] = 0;
01507 if ((bq == 0) &&
01508 ((!strncmp(buf, ">", 1)) || (!strncmp(buf, " >", 2)) )) {
01509 wprintf("<blockquote>");
01510 bq = 1;
01511 } else if ((bq == 1) &&
01512 (strncmp(buf, ">", 1)) && (strncmp(buf, " >", 2)) ) {
01513 wprintf("</blockquote>");
01514 bq = 0;
01515 }
01516 wprintf("<tt>");
01517 url(buf);
01518 msgescputs(buf);
01519 wprintf("</tt><br />");
01520 }
01521 wprintf("</i><br />");
01522 }
01523
01525 else if (!strcasecmp(mime_content_type, "text/html")) {
01526 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
01527 strcat(buf, "\n");
01528 msgescputs(buf);
01529 }
01530 }
01531
01533 else {
01534 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { }
01535 }
01536
01537 ENDBODY:
01540
01541
01542
01543
01544 if ( (forward_attachments) && (num_attachments) ) {
01545 for (i=0; i<num_attachments; ++i) {
01546 extract_token(buf, attachments, i, '\n', sizeof buf);
01547 extract_token(mime_filename, buf, 1, '|', sizeof mime_filename);
01548 extract_token(mime_partnum, buf, 2, '|', sizeof mime_partnum);
01549 extract_token(mime_disposition, buf, 3, '|', sizeof mime_disposition);
01550 extract_token(mime_content_type, buf, 4, '|', sizeof mime_content_type);
01551 mime_length = extract_int(buf, 5);
01552
01553
01554
01555
01556
01557 lprintf(9, "fwd filename: %s\n", mime_filename);
01558 lprintf(9, "fwd partnum : %s\n", mime_partnum);
01559 lprintf(9, "fwd conttype: %s\n", mime_content_type);
01560 lprintf(9, "fwd dispose : %s\n", mime_disposition);
01561 lprintf(9, "fwd length : %d\n", mime_length);
01562
01563 if ( (!strcasecmp(mime_disposition, "inline"))
01564 || (!strcasecmp(mime_disposition, "attachment")) ) {
01565
01566
01567 att = malloc(sizeof(struct wc_attachment));
01568 memset(att, 0, sizeof(struct wc_attachment));
01569 att->length = mime_length;
01570 strcpy(att->content_type, mime_content_type);
01571 strcpy(att->filename, mime_filename);
01572 att->next = NULL;
01573 att->data = load_mimepart(msgnum, mime_partnum);
01574
01575
01576 if (WC->first_attachment == NULL) {
01577 WC->first_attachment = att;
01578 }
01579 else {
01580 aptr = WC->first_attachment;
01581 while (aptr->next != NULL) aptr = aptr->next;
01582 aptr->next = att;
01583 }
01584 }
01585
01586 }
01587 }
01588
01589 #ifdef HAVE_ICONV
01590 if (ic != (iconv_t)(-1) ) {
01591 iconv_close(ic);
01592 }
01593 #endif
01594
01595 if (attachments != NULL) {
01596 free(attachments);
01597 }
01598 }
01599
01605 void display_summarized(int num) {
01606 char datebuf[64];
01607
01608 wprintf("<tr id=\"m%ld\" style=\"font-weight:%s;\" "
01609 "onMouseDown=\"CtdlMoveMsgMouseDown(event,%ld)\">",
01610 WC->summ[num].msgnum,
01611 (WC->summ[num].is_new ? "bold" : "normal"),
01612 WC->summ[num].msgnum
01613 );
01614
01615 wprintf("<td width=%d%%>", SUBJ_COL_WIDTH_PCT);
01616 escputs(WC->summ[num].subj);
01617 wprintf("</td>");
01618
01619 wprintf("<td width=%d%%>", SENDER_COL_WIDTH_PCT);
01620 escputs(WC->summ[num].from);
01621 wprintf("</td>");
01622
01623 wprintf("<td width=%d%%>", DATE_PLUS_BUTTONS_WIDTH_PCT);
01624 fmt_date(datebuf, WC->summ[num].date, 1);
01625 escputs(datebuf);
01626 wprintf("</td>");
01627
01628 wprintf("</tr>\n");
01629 }
01630
01631
01632
01638 void display_addressbook(long msgnum, char alpha) {
01639 char buf[SIZ];
01640 char mime_partnum[SIZ];
01641 char mime_filename[SIZ];
01642 char mime_content_type[SIZ];
01643 char mime_disposition[SIZ];
01644 int mime_length;
01645 char vcard_partnum[SIZ];
01646 char *vcard_source = NULL;
01647 struct message_summary summ;
01648
01649 memset(&summ, 0, sizeof(summ));
01650 safestrncpy(summ.subj, _("(no subject)"), sizeof summ.subj);
01651
01652 sprintf(buf, "MSG0 %ld|1", msgnum);
01653 serv_puts(buf);
01654 serv_getln(buf, sizeof buf);
01655 if (buf[0] != '1') return;
01656
01657 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
01658 if (!strncasecmp(buf, "part=", 5)) {
01659 extract_token(mime_filename, &buf[5], 1, '|', sizeof mime_filename);
01660 extract_token(mime_partnum, &buf[5], 2, '|', sizeof mime_partnum);
01661 extract_token(mime_disposition, &buf[5], 3, '|', sizeof mime_disposition);
01662 extract_token(mime_content_type, &buf[5], 4, '|', sizeof mime_content_type);
01663 mime_length = extract_int(&buf[5], 5);
01664
01665 if ( (!strcasecmp(mime_content_type, "text/x-vcard"))
01666 || (!strcasecmp(mime_content_type, "text/vcard")) ) {
01667 strcpy(vcard_partnum, mime_partnum);
01668 }
01669
01670 }
01671 }
01672
01673 if (strlen(vcard_partnum) > 0) {
01674 vcard_source = load_mimepart(msgnum, vcard_partnum);
01675 if (vcard_source != NULL) {
01676
01678 display_vcard(vcard_source, alpha, 0, NULL);
01679
01681 if ( (!strcasecmp(WC->wc_roomname, USERCONFIGROOM))
01682 || (!strcasecmp(&WC->wc_roomname[11], USERCONFIGROOM))
01683 || (WC->wc_view == VIEW_ADDRESSBOOK)
01684 ) {
01685 wprintf("<a href=\"edit_vcard?"
01686 "msgnum=%ld?partnum=%s\">",
01687 msgnum, vcard_partnum);
01688 wprintf("[%s]</a>", _("edit"));
01689 }
01690
01691 free(vcard_source);
01692 }
01693 }
01694
01695 }
01696
01697
01698
01703 void lastfirst_firstlast(char *namebuf) {
01704 char firstname[SIZ];
01705 char lastname[SIZ];
01706 int i;
01707
01708 if (namebuf == NULL) return;
01709 if (strchr(namebuf, ';') != NULL) return;
01710
01711 i = num_tokens(namebuf, ' ');
01712 if (i < 2) return;
01713
01714 extract_token(lastname, namebuf, i-1, ' ', sizeof lastname);
01715 remove_token(namebuf, i-1, ' ');
01716 strcpy(firstname, namebuf);
01717 sprintf(namebuf, "%s; %s", lastname, firstname);
01718 }
01719
01725 void fetch_ab_name(long msgnum, char *namebuf) {
01726 char buf[SIZ];
01727 char mime_partnum[SIZ];
01728 char mime_filename[SIZ];
01729 char mime_content_type[SIZ];
01730 char mime_disposition[SIZ];
01731 int mime_length;
01732 char vcard_partnum[SIZ];
01733 char *vcard_source = NULL;
01734 int i;
01735 struct message_summary summ;
01736
01737 if (namebuf == NULL) return;
01738 strcpy(namebuf, "");
01739
01740 memset(&summ, 0, sizeof(summ));
01741 safestrncpy(summ.subj, "(no subject)", sizeof summ.subj);
01742
01743 sprintf(buf, "MSG0 %ld|0", msgnum);
01744 serv_puts(buf);
01745 serv_getln(buf, sizeof buf);
01746 if (buf[0] != '1') return;
01747
01748 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
01749 if (!strncasecmp(buf, "part=", 5)) {
01750 extract_token(mime_filename, &buf[5], 1, '|', sizeof mime_filename);
01751 extract_token(mime_partnum, &buf[5], 2, '|', sizeof mime_partnum);
01752 extract_token(mime_disposition, &buf[5], 3, '|', sizeof mime_disposition);
01753 extract_token(mime_content_type, &buf[5], 4, '|', sizeof mime_content_type);
01754 mime_length = extract_int(&buf[5], 5);
01755
01756 if ( (!strcasecmp(mime_content_type, "text/x-vcard"))
01757 || (!strcasecmp(mime_content_type, "text/vcard")) ) {
01758 strcpy(vcard_partnum, mime_partnum);
01759 }
01760
01761 }
01762 }
01763
01764 if (strlen(vcard_partnum) > 0) {
01765 vcard_source = load_mimepart(msgnum, vcard_partnum);
01766 if (vcard_source != NULL) {
01767
01768
01769 display_vcard(vcard_source, 0, 0, namebuf);
01770
01771 free(vcard_source);
01772 }
01773 }
01774
01775 lastfirst_firstlast(namebuf);
01776 striplt(namebuf);
01777 for (i=0; i<strlen(namebuf); ++i) {
01778 if (namebuf[i] != ';') return;
01779 }
01780 strcpy(namebuf, _("(no name)"));
01781 }
01782
01783
01784
01790 int abcmp(const void *ab1, const void *ab2) {
01791 return(strcasecmp(
01792 (((const struct addrbookent *)ab1)->ab_name),
01793 (((const struct addrbookent *)ab2)->ab_name)
01794 ));
01795 }
01796
01797
01804 void nametab(char *tabbuf, char *name) {
01805 stresc(tabbuf, name, 0, 0);
01806 tabbuf[0] = toupper(tabbuf[0]);
01807 tabbuf[1] = tolower(tabbuf[1]);
01808 tabbuf[2] = tolower(tabbuf[2]);
01809 tabbuf[3] = 0;
01810 }
01811
01812
01818 void do_addrbook_view(struct addrbookent *addrbook, int num_ab) {
01819 int i = 0;
01820 int displayed = 0;
01821 int bg = 0;
01822 static int NAMESPERPAGE = 60;
01823 int num_pages = 0;
01824 int tabfirst = 0;
01825 char tabfirst_label[64];
01826 int tablast = 0;
01827 char tablast_label[64];
01828 char this_tablabel[64];
01829 int page = 0;
01830 char **tablabels;
01831
01832 if (num_ab == 0) {
01833 wprintf("<br /><br /><br /><div align=\"center\"><i>");
01834 wprintf(_("This address book is empty."));
01835 wprintf("</i></div>\n");
01836 return;
01837 }
01838
01839 if (num_ab > 1) {
01840 qsort(addrbook, num_ab, sizeof(struct addrbookent), abcmp);
01841 }
01842
01843 num_pages = (num_ab / NAMESPERPAGE) + 1;
01844
01845 tablabels = malloc(num_pages * sizeof (char *));
01846 if (tablabels == NULL) {
01847 wprintf("<br /><br /><br /><div align=\"center\"><i>");
01848 wprintf(_("An internal error has occurred."));
01849 wprintf("</i></div>\n");
01850 return;
01851 }
01852
01853 for (i=0; i<num_pages; ++i) {
01854 tabfirst = i * NAMESPERPAGE;
01855 tablast = tabfirst + NAMESPERPAGE - 1;
01856 if (tablast > (num_ab - 1)) tablast = (num_ab - 1);
01857 nametab(tabfirst_label, addrbook[tabfirst].ab_name);
01858 nametab(tablast_label, addrbook[tablast].ab_name);
01859 sprintf(this_tablabel, "%s - %s", tabfirst_label, tablast_label);
01860 tablabels[i] = strdup(this_tablabel);
01861 }
01862
01863 tabbed_dialog(num_pages, tablabels);
01864 page = (-1);
01865
01866 for (i=0; i<num_ab; ++i) {
01867
01868 if ((i / NAMESPERPAGE) != page) {
01869 page = (i / NAMESPERPAGE);
01870 if (page > 0) {
01871 wprintf("</tr></table>\n");
01872 end_tab(page-1, num_pages);
01873 }
01874 begin_tab(page, num_pages);
01875 wprintf("<table border=0 cellspacing=0 cellpadding=3 width=100%%>\n");
01876 displayed = 0;
01877 }
01878
01879 if ((displayed % 4) == 0) {
01880 if (displayed > 0) {
01881 wprintf("</tr>\n");
01882 }
01883 bg = 1 - bg;
01884 wprintf("<tr bgcolor=\"#%s\">",
01885 (bg ? "DDDDDD" : "FFFFFF")
01886 );
01887 }
01888
01889 wprintf("<td>");
01890
01891 wprintf("<a href=\"readfwd?startmsg=%ld&is_singlecard=1",
01892 addrbook[i].ab_msgnum);
01893 wprintf("?maxmsgs=1?summary=0?alpha=%s\">", bstr("alpha"));
01894 vcard_n_prettyize(addrbook[i].ab_name);
01895 escputs(addrbook[i].ab_name);
01896 wprintf("</a></td>\n");
01897 ++displayed;
01898 }
01899
01900 wprintf("</tr></table>\n");
01901 end_tab((num_pages-1), num_pages);
01902
01903 for (i=0; i<num_pages; ++i) {
01904 free(tablabels[i]);
01905 }
01906 free(tablabels);
01907 }
01908
01909
01910
01916 int load_msg_ptrs(char *servcmd, int with_headers)
01917 {
01918 char buf[1024];
01919 time_t datestamp;
01920 char fullname[128];
01921 char nodename[128];
01922 char inetaddr[128];
01923 char subject[256];
01924 int nummsgs;
01925 int maxload = 0;
01926
01927 int num_summ_alloc = 0;
01928
01929 if (WC->summ != NULL) {
01930 free(WC->summ);
01931 WC->num_summ = 0;
01932 WC->summ = NULL;
01933 }
01934 num_summ_alloc = 100;
01935 WC->num_summ = 0;
01936 WC->summ = malloc(num_summ_alloc * sizeof(struct message_summary));
01937
01938 nummsgs = 0;
01939 maxload = sizeof(WC->msgarr) / sizeof(long) ;
01940 serv_puts(servcmd);
01941 serv_getln(buf, sizeof buf);
01942 if (buf[0] != '1') {
01943 return (nummsgs);
01944 }
01945 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
01946 if (nummsgs < maxload) {
01947 WC->msgarr[nummsgs] = extract_long(buf, 0);
01948 datestamp = extract_long(buf, 1);
01949 extract_token(fullname, buf, 2, '|', sizeof fullname);
01950 extract_token(nodename, buf, 3, '|', sizeof nodename);
01951 extract_token(inetaddr, buf, 4, '|', sizeof inetaddr);
01952 extract_token(subject, buf, 5, '|', sizeof subject);
01953 ++nummsgs;
01954
01955 if (with_headers) {
01956 if (nummsgs > num_summ_alloc) {
01957 num_summ_alloc *= 2;
01958 WC->summ = realloc(WC->summ,
01959 num_summ_alloc * sizeof(struct message_summary));
01960 }
01961 ++WC->num_summ;
01962
01963 memset(&WC->summ[nummsgs-1], 0, sizeof(struct message_summary));
01964 WC->summ[nummsgs-1].msgnum = WC->msgarr[nummsgs-1];
01965 safestrncpy(WC->summ[nummsgs-1].subj,
01966 _("(no subject)"), sizeof WC->summ[nummsgs-1].subj);
01967 if (strlen(fullname) > 0) {
01968 safestrncpy(WC->summ[nummsgs-1].from,
01969 fullname, sizeof WC->summ[nummsgs-1].from);
01970 }
01971 if (strlen(subject) > 0) {
01972 safestrncpy(WC->summ[nummsgs-1].subj, subject,
01973 sizeof WC->summ[nummsgs-1].subj);
01974 }
01975 #ifdef HAVE_ICONV
01976
01977 utf8ify_rfc822_string(WC->summ[nummsgs-1].subj);
01978 #endif
01979 if (strlen(WC->summ[nummsgs-1].subj) > 75) {
01980 strcpy(&WC->summ[nummsgs-1].subj[72], "...");
01981 }
01982
01983 if (strlen(nodename) > 0) {
01984 if ( ((WC->room_flags & QR_NETWORK)
01985 || ((strcasecmp(nodename, serv_info.serv_nodename)
01986 && (strcasecmp(nodename, serv_info.serv_fqdn)))))
01987 ) {
01988 strcat(WC->summ[nummsgs-1].from, " @ ");
01989 strcat(WC->summ[nummsgs-1].from, nodename);
01990 }
01991 }
01992
01993 WC->summ[nummsgs-1].date = datestamp;
01994
01995 #ifdef HAVE_ICONV
01996
01997 utf8ify_rfc822_string(WC->summ[nummsgs-1].from);
01998 #endif
01999 if (strlen(WC->summ[nummsgs-1].from) > 25) {
02000 strcpy(&WC->summ[nummsgs-1].from[22], "...");
02001 }
02002 }
02003 }
02004 }
02005 return (nummsgs);
02006 }
02007
02014 int longcmp_r(const void *s1, const void *s2) {
02015 long l1;
02016 long l2;
02017
02018 l1 = *(long *)s1;
02019 l2 = *(long *)s2;
02020
02021 if (l1 > l2) return(-1);
02022 if (l1 < l2) return(+1);
02023 return(0);
02024 }
02025
02026
02033 int summcmp_subj(const void *s1, const void *s2) {
02034 struct message_summary *summ1;
02035 struct message_summary *summ2;
02036
02037 summ1 = (struct message_summary *)s1;
02038 summ2 = (struct message_summary *)s2;
02039 return strcasecmp(summ1->subj, summ2->subj);
02040 }
02041
02048 int summcmp_rsubj(const void *s1, const void *s2) {
02049 struct message_summary *summ1;
02050 struct message_summary *summ2;
02051
02052 summ1 = (struct message_summary *)s1;
02053 summ2 = (struct message_summary *)s2;
02054 return strcasecmp(summ2->subj, summ1->subj);
02055 }
02056
02063 int summcmp_sender(const void *s1, const void *s2) {
02064 struct message_summary *summ1;
02065 struct message_summary *summ2;
02066
02067 summ1 = (struct message_summary *)s1;
02068 summ2 = (struct message_summary *)s2;
02069 return strcasecmp(summ1->from, summ2->from);
02070 }
02071
02078 int summcmp_rsender(const void *s1, const void *s2) {
02079 struct message_summary *summ1;
02080 struct message_summary *summ2;
02081
02082 summ1 = (struct message_summary *)s1;
02083 summ2 = (struct message_summary *)s2;
02084 return strcasecmp(summ2->from, summ1->from);
02085 }
02086
02093 int summcmp_date(const void *s1, const void *s2) {
02094 struct message_summary *summ1;
02095 struct message_summary *summ2;
02096
02097 summ1 = (struct message_summary *)s1;
02098 summ2 = (struct message_summary *)s2;
02099
02100 if (summ1->date < summ2->date) return -1;
02101 else if (summ1->date > summ2->date) return +1;
02102 else return 0;
02103 }
02104
02111 int summcmp_rdate(const void *s1, const void *s2) {
02112 struct message_summary *summ1;
02113 struct message_summary *summ2;
02114
02115 summ1 = (struct message_summary *)s1;
02116 summ2 = (struct message_summary *)s2;
02117
02118 if (summ1->date < summ2->date) return +1;
02119 else if (summ1->date > summ2->date) return -1;
02120 else return 0;
02121 }
02122
02123
02124
02130 void readloop(char *oper)
02131 {
02132 char cmd[256];
02133 char buf[SIZ];
02134 char old_msgs[SIZ];
02135 int a, b;
02136 int nummsgs;
02137 long startmsg;
02138 int maxmsgs;
02139 long *displayed_msgs = NULL;
02140 int num_displayed = 0;
02141 int is_summary = 0;
02142 int is_addressbook = 0;
02143 int is_singlecard = 0;
02144 int is_calendar = 0;
02145 int is_tasks = 0;
02146 int is_notes = 0;
02147 int is_bbview = 0;
02148 int lo, hi;
02149 int lowest_displayed = (-1);
02150 int highest_displayed = 0;
02151 struct addrbookent *addrbook = NULL;
02152 int num_ab = 0;
02153 char *sortby = NULL;
02154 char sortpref_name[128];
02155 char sortpref_value[128];
02156 char *subjsort_button;
02157 char *sendsort_button;
02158 char *datesort_button;
02159 int bbs_reverse = 0;
02160
02161 if (WC->wc_view == VIEW_WIKI) {
02162 sprintf(buf, "wiki?room=%s?page=home", WC->wc_roomname);
02163 http_redirect(buf);
02164 return;
02165 }
02166
02167 startmsg = atol(bstr("startmsg"));
02168 maxmsgs = atoi(bstr("maxmsgs"));
02169 is_summary = atoi(bstr("summary"));
02170 if (maxmsgs == 0) maxmsgs = DEFAULT_MAXMSGS;
02171
02172 snprintf(sortpref_name, sizeof sortpref_name, "sort %s", WC->wc_roomname);
02173 get_preference(sortpref_name, sortpref_value, sizeof sortpref_value);
02174
02175 sortby = bstr("sortby");
02176 if ( (strlen(sortby) > 0) && (strcasecmp(sortby, sortpref_value)) ) {
02177 set_preference(sortpref_name, sortby, 1);
02178 }
02179 if (strlen(sortby) == 0) sortby = sortpref_value;
02180
02182 if (strlen(sortby) == 0) sortby = "rdate";
02183
02185 if (!strcasecmp(sortby, "reverse")) {
02186 bbs_reverse = 1;
02187 }
02188 else {
02189 bbs_reverse = 0;
02190 }
02191
02192 output_headers(1, 1, 1, 0, 0, 0);
02193
02198 if (!strcmp(oper, "readnew")) {
02199 strcpy(cmd, "MSGS NEW");
02200 }
02201 else if (!strcmp(oper, "readold")) {
02202 strcpy(cmd, "MSGS OLD");
02203 }
02204 else if (!strcmp(oper, "do_search")) {
02205 sprintf(cmd, "MSGS SEARCH|%s", bstr("query"));
02206 }
02207 else {
02208 strcpy(cmd, "MSGS ALL");
02209 }
02210
02211 if ((WC->wc_view == VIEW_MAILBOX) && (maxmsgs > 1)) {
02212 is_summary = 1;
02213 if (!strcmp(oper, "do_search")) {
02214 sprintf(cmd, "MSGS SEARCH|%s", bstr("query"));
02215 }
02216 else {
02217 strcpy(cmd, "MSGS ALL");
02218 }
02219 }
02220
02221 if ((WC->wc_view == VIEW_ADDRESSBOOK) && (maxmsgs > 1)) {
02222 is_addressbook = 1;
02223 if (!strcmp(oper, "do_search")) {
02224 sprintf(cmd, "MSGS SEARCH|%s", bstr("query"));
02225 }
02226 else {
02227 strcpy(cmd, "MSGS ALL");
02228 }
02229 maxmsgs = 9999999;
02230 }
02231
02232 if (is_summary) {
02233 snprintf(cmd, sizeof cmd, "MSGS %s|%s||1",
02234 (!strcmp(oper, "do_search") ? "SEARCH" : "ALL"),
02235 (!strcmp(oper, "do_search") ? bstr("query") : "")
02236 );
02237 startmsg = 1;
02238 maxmsgs = 9999999;
02239 }
02240
02246 strcpy(old_msgs, "");
02247 if (is_summary) {
02248 serv_puts("GTSN");
02249 serv_getln(buf, sizeof buf);
02250 if (buf[0] == '2') {
02251 strcpy(old_msgs, &buf[4]);
02252 }
02253 }
02254
02255 is_singlecard = atoi(bstr("is_singlecard"));
02256
02257 if (WC->wc_default_view == VIEW_CALENDAR) {
02258 is_calendar = 1;
02259 strcpy(cmd, "MSGS ALL");
02260 maxmsgs = 32767;
02261 }
02262 if (WC->wc_default_view == VIEW_TASKS) {
02263 is_tasks = 1;
02264 strcpy(cmd, "MSGS ALL");
02265 maxmsgs = 32767;
02266 }
02267 if (WC->wc_default_view == VIEW_NOTES) {
02268 is_notes = 1;
02269 strcpy(cmd, "MSGS ALL");
02270 maxmsgs = 32767;
02271 }
02272
02273 if (is_notes) {
02274 wprintf("<div align=center>%s</div>\n", _("Click on any note to edit it."));
02275 wprintf("<div id=\"new_notes_here\"></div>\n");
02276 }
02277
02278 nummsgs = load_msg_ptrs(cmd, is_summary);
02279 if (nummsgs == 0) {
02280
02281 if ((!is_tasks) && (!is_calendar) && (!is_notes) && (!is_addressbook)) {
02282 wprintf("<div align=\"center\"><br /><em>");
02283 if (!strcmp(oper, "readnew")) {
02284 wprintf(_("No new messages."));
02285 } else if (!strcmp(oper, "readold")) {
02286 wprintf(_("No old messages."));
02287 } else {
02288 wprintf(_("No messages here."));
02289 }
02290 wprintf("</em><br /></div>\n");
02291 }
02292
02293 goto DONE;
02294 }
02295
02296 if (is_summary) {
02297 for (a = 0; a < nummsgs; ++a) {
02299 if (is_summary) {
02300 if (is_msg_in_mset(old_msgs, WC->msgarr[a])) {
02301 WC->summ[a].is_new = 0;
02302 }
02303 else {
02304 WC->summ[a].is_new = 1;
02305 }
02306 }
02307 }
02308 }
02309
02310 if (startmsg == 0L) {
02311 if (bbs_reverse) {
02312 startmsg = WC->msgarr[(nummsgs >= maxmsgs) ? (nummsgs - maxmsgs) : 0];
02313 }
02314 else {
02315 startmsg = WC->msgarr[0];
02316 }
02317 }
02318
02319 if (is_summary) {
02320 if (!strcasecmp(sortby, "subject")) {
02321 qsort(WC->summ, WC->num_summ,
02322 sizeof(struct message_summary), summcmp_subj);
02323 }
02324 else if (!strcasecmp(sortby, "rsubject")) {
02325 qsort(WC->summ, WC->num_summ,
02326 sizeof(struct message_summary), summcmp_rsubj);
02327 }
02328 else if (!strcasecmp(sortby, "sender")) {
02329 qsort(WC->summ, WC->num_summ,
02330 sizeof(struct message_summary), summcmp_sender);
02331 }
02332 else if (!strcasecmp(sortby, "rsender")) {
02333 qsort(WC->summ, WC->num_summ,
02334 sizeof(struct message_summary), summcmp_rsender);
02335 }
02336 else if (!strcasecmp(sortby, "date")) {
02337 qsort(WC->summ, WC->num_summ,
02338 sizeof(struct message_summary), summcmp_date);
02339 }
02340 else if (!strcasecmp(sortby, "rdate")) {
02341 qsort(WC->summ, WC->num_summ,
02342 sizeof(struct message_summary), summcmp_rdate);
02343 }
02344 }
02345
02346 if (!strcasecmp(sortby, "subject")) {
02347 subjsort_button = "<a href=\"readfwd?startmsg=1?maxmsgs=9999999?summary=1?sortby=rsubject\"><img border=\"0\" src=\"static/down_pointer.gif\" /></a>" ;
02348 }
02349 else if (!strcasecmp(sortby, "rsubject")) {
02350 subjsort_button = "<a href=\"readfwd?startmsg=1?maxmsgs=9999999?summary=1?sortby=subject\"><img border=\"0\" src=\"static/up_pointer.gif\" /></a>" ;
02351 }
02352 else {
02353 subjsort_button = "<a href=\"readfwd?startmsg=1?maxmsgs=9999999?summary=1?sortby=subject\"><img border=\"0\" src=\"static/sort_none.gif\" /></a>" ;
02354 }
02355
02356 if (!strcasecmp(sortby, "sender")) {
02357 sendsort_button = "<a href=\"readfwd?startmsg=1?maxmsgs=9999999?summary=1?sortby=rsender\"><img border=\"0\" src=\"static/down_pointer.gif\" /></a>" ;
02358 }
02359 else if (!strcasecmp(sortby, "rsender")) {
02360 sendsort_button = "<a href=\"readfwd?startmsg=1?maxmsgs=9999999?summary=1?sortby=sender\"><img border=\"0\" src=\"static/up_pointer.gif\" /></a>" ;
02361 }
02362 else {
02363 sendsort_button = "<a href=\"readfwd?startmsg=1?maxmsgs=9999999?summary=1?sortby=sender\"><img border=\"0\" src=\"static/sort_none.gif\" /></a>" ;
02364 }
02365
02366 if (!strcasecmp(sortby, "date")) {
02367 datesort_button = "<a href=\"readfwd?startmsg=1?maxmsgs=9999999?summary=1?sortby=rdate\"><img border=\"0\" src=\"static/down_pointer.gif\" /></a>" ;
02368 }
02369 else if (!strcasecmp(sortby, "rdate")) {
02370 datesort_button = "<a href=\"readfwd?startmsg=1?maxmsgs=9999999?summary=1?sortby=date\"><img border=\"0\" src=\"static/up_pointer.gif\" /></a>" ;
02371 }
02372 else {
02373 datesort_button = "<a href=\"readfwd?startmsg=1?maxmsgs=9999999?summary=1?sortby=rdate\"><img border=\"0\" src=\"static/sort_none.gif\" /></a>" ;
02374 }
02375
02376 if (is_summary) {
02377
02378 wprintf("<script language=\"javascript\" type=\"text/javascript\">"
02379 " document.onkeydown = CtdlMsgListKeyPress; "
02380 " if (document.layers) { "
02381 " document.captureEvents(Event.KEYPRESS); "
02382 " } "
02383 "</script>\n"
02384 );
02385
02387 wprintf("<div id=\"message_list_hdr\">"
02388 "<div class=\"fix_scrollbar_bug\">"
02389 "<table cellspacing=0 style=\"width:100%%\">"
02390 "<tr>"
02391 );
02392 wprintf("<th width=%d%%>%s %s</th>"
02393 "<th width=%d%%>%s %s</th>"
02394 "<th width=%d%%>%s %s"
02395 " "
02396 "<input type=\"submit\" name=\"delete_button\" id=\"delbutton\" "
02397 " onClick=\"CtdlDeleteSelectedMessages(event)\" "
02398 " value=\"%s\">"
02399 "</th>"
02400 "</tr>\n"
02401 ,
02402 SUBJ_COL_WIDTH_PCT,
02403 _("Subject"), subjsort_button,
02404 SENDER_COL_WIDTH_PCT,
02405 _("Sender"), sendsort_button,
02406 DATE_PLUS_BUTTONS_WIDTH_PCT,
02407 _("Date"), datesort_button,
02408 _("Delete")
02409 );
02410 wprintf("</table></div></div>\n");
02411
02412 wprintf("<div id=\"message_list\">"
02413
02414 "<div class=\"fix_scrollbar_bug\">\n"
02415
02416 "<table class=\"mailbox_summary\" id=\"summary_headers\" "
02417 "cellspacing=0 style=\"width:100%%;-moz-user-select:none;\">"
02418 );
02419 }
02420
02421 for (a = 0; a < nummsgs; ++a) {
02422 if ((WC->msgarr[a] >= startmsg) && (num_displayed < maxmsgs)) {
02423
02425 if (is_summary) {
02426 display_summarized(a);
02427 }
02428 else if (is_addressbook) {
02429 fetch_ab_name(WC->msgarr[a], buf);
02430 ++num_ab;
02431 addrbook = realloc(addrbook,
02432 (sizeof(struct addrbookent) * num_ab) );
02433 safestrncpy(addrbook[num_ab-1].ab_name, buf,
02434 sizeof(addrbook[num_ab-1].ab_name));
02435 addrbook[num_ab-1].ab_msgnum = WC->msgarr[a];
02436 }
02437 else if (is_calendar) {
02438 display_calendar(WC->msgarr[a]);
02439 }
02440 else if (is_tasks) {
02441 display_task(WC->msgarr[a]);
02442 }
02443 else if (is_notes) {
02444 display_note(WC->msgarr[a]);
02445 }
02446 else {
02447 if (displayed_msgs == NULL) {
02448 displayed_msgs = malloc(sizeof(long) *
02449 (maxmsgs<nummsgs ? maxmsgs : nummsgs));
02450 }
02451 displayed_msgs[num_displayed] = WC->msgarr[a];
02452 }
02453
02454 if (lowest_displayed < 0) lowest_displayed = a;
02455 highest_displayed = a;
02456
02457 ++num_displayed;
02458 }
02459 }
02460
02465 if ((!is_tasks) && (!is_calendar) && (!is_addressbook)
02466 && (!is_notes) && (!is_singlecard) && (!is_summary)) {
02467 is_bbview = 1;
02468 }
02469
02471 if (displayed_msgs != NULL) {
02472 if (bbs_reverse) {
02473 qsort(displayed_msgs, num_displayed, sizeof(long), longcmp_r);
02474 }
02475
02478 for (a=0; a<num_displayed; ++a) {
02479 read_message(displayed_msgs[a], 0, "");
02480 }
02481
02484 free(displayed_msgs);
02485 displayed_msgs = NULL;
02486 }
02487
02488 if (is_summary) {
02489 wprintf("</table>"
02490 "</div>\n");
02491 wprintf("</div>");
02494 wprintf("<div id=\"resize_msglist\" "
02495 "onMouseDown=\"CtdlResizeMsgListMouseDown(event)\">"
02496 "<div class=\"fix_scrollbar_bug\"> <hr>"
02497 "</div></div>\n"
02498 );
02499
02500 wprintf("<div id=\"preview_pane\">");
02501 }
02502
02507 ++lowest_displayed;
02508 ++highest_displayed;
02509
02514 if (is_bbview) {
02516 wprintf("<form name=\"msgomatic\">");
02517 wprintf(_("Reading #"), lowest_displayed, highest_displayed);
02518
02519 wprintf("<select name=\"whichones\" size=\"1\" "
02520 "OnChange=\"location.href=msgomatic.whichones.options"
02521 "[selectedIndex].value\">\n");
02522
02523 if (bbs_reverse) {
02524 for (b=nummsgs-1; b>=0; b = b - maxmsgs) {
02525 hi = b + 1;
02526 lo = b - maxmsgs + 2;
02527 if (lo < 1) lo = 1;
02528 wprintf("<option %s value="
02529 "\"%s"
02530 "?startmsg=%ld"
02531 "?maxmsgs=%d"
02532 "?summary=%d\">"
02533 "%d-%d</option> \n",
02534 ((WC->msgarr[lo-1] == startmsg) ? "selected" : ""),
02535 oper,
02536 WC->msgarr[lo-1],
02537 maxmsgs,
02538 is_summary,
02539 hi, lo);
02540 }
02541 }
02542 else {
02543 for (b=0; b<nummsgs; b = b + maxmsgs) {
02544 lo = b + 1;
02545 hi = b + maxmsgs + 1;
02546 if (hi > nummsgs) hi = nummsgs;
02547 wprintf("<option %s value="
02548 "\"%s"
02549 "?startmsg=%ld"
02550 "?maxmsgs=%d"
02551 "?summary=%d\">"
02552 "%d-%d</option> \n",
02553 ((WC->msgarr[b] == startmsg) ? "selected" : ""),
02554 oper,
02555 WC->msgarr[lo-1],
02556 maxmsgs,
02557 is_summary,
02558 lo, hi);
02559 }
02560 }
02561
02562 wprintf("<option value=\"%s?startmsg=%ld"
02563 "?maxmsgs=9999999?summary=%d\">"
02564 "ALL"
02565 "</option> ",
02566 oper,
02567 WC->msgarr[0], is_summary);
02568
02569 wprintf("</select> ");
02570 wprintf(_("of %d messages."), nummsgs);
02571
02573 wprintf(" <select name=\"direction\" size=\"1\" "
02574 "OnChange=\"location.href=msgomatic.direction.options"
02575 "[selectedIndex].value\">\n"
02576 );
02577
02578 wprintf("<option %s value=\"%s?sortby=forward\">oldest to newest</option>\n",
02579 (bbs_reverse ? "" : "selected"),
02580 oper
02581 );
02582
02583 wprintf("<option %s value=\"%s?sortby=reverse\">newest to oldest</option>\n",
02584 (bbs_reverse ? "selected" : ""),
02585 oper
02586 );
02587
02588 wprintf("</select></form>\n");
02590 }
02591
02592 DONE:
02593 if (is_tasks) {
02594 do_tasks_view();
02595 }
02596
02597 if (is_calendar) {
02598 do_calendar_view();
02599 }
02600
02601 if (is_addressbook) {
02602 do_addrbook_view(addrbook, num_ab);
02603 }
02604
02606 wDumpContent(1);
02607 if (addrbook != NULL) free(addrbook);
02608
02610 if (WC->summ != NULL) {
02611 free(WC->summ);
02612 WC->num_summ = 0;
02613 WC->summ = NULL;
02614 }
02615 wprintf("</div>\n");
02616 }
02617
02618
02623 void post_mime_to_server(void) {
02624 char boundary[SIZ];
02625 int is_multipart = 0;
02626 static int seq = 0;
02627 struct wc_attachment *att;
02628 char *encoded;
02629 size_t encoded_length;
02630
02632 serv_puts("MIME-Version: 1.0");
02633 serv_puts("X-Mailer: " SERVER);
02634
02636 if (WC->first_attachment != NULL) {
02637 is_multipart = 1;
02638 }
02639
02640 if (is_multipart) {
02641 sprintf(boundary, "Citadel--Multipart--%s--%04x--%04x",
02642 serv_info.serv_fqdn,
02643 getpid(),
02644 ++seq
02645 );
02646
02648 serv_printf("Content-type: multipart/mixed; "
02649 "boundary=\"%s\"\n", boundary);
02650 serv_printf("This is a multipart message in MIME format.\n");
02651 serv_printf("--%s", boundary);
02652 }
02653
02654 serv_puts("Content-type: text/html; charset=utf-8");
02655 serv_puts("Content-Transfer-Encoding: quoted-printable");
02656 serv_puts("");
02657 serv_puts("<html><body>\r\n");
02658 text_to_server_qp(bstr("msgtext"));
02659 serv_puts("</body></html>\r\n");
02660
02661 if (is_multipart) {
02662
02664 for (att = WC->first_attachment; att!=NULL; att=att->next) {
02665
02666 encoded_length = ((att->length * 150) / 100);
02667 encoded = malloc(encoded_length);
02668 if (encoded == NULL) break;
02669 CtdlEncodeBase64(encoded, att->data, att->length, 1);
02670
02671 serv_printf("--%s", boundary);
02672 serv_printf("Content-type: %s", att->content_type);
02673 serv_printf("Content-disposition: attachment; "
02674 "filename=\"%s\"", att->filename);
02675 serv_puts("Content-transfer-encoding: base64");
02676 serv_puts("");
02677 serv_write(encoded, strlen(encoded));
02678 serv_puts("");
02679 serv_puts("");
02680 free(encoded);
02681 }
02682 serv_printf("--%s--", boundary);
02683 }
02684
02685 serv_puts("000");
02686 }
02687
02688
02700 void post_message(void)
02701 {
02702 char buf[1024];
02703 char encoded_subject[1024];
02704 static long dont_post = (-1L);
02705 struct wc_attachment *att, *aptr;
02706 int is_anonymous = 0;
02707 char *display_name;
02708
02709 display_name = bstr("display_name");
02710 if (!strcmp(display_name, "__ANONYMOUS__")) {
02711 display_name = "";
02712 is_anonymous = 1;
02713 }
02714
02715 if (WC->upload_length > 0) {
02716
02717 lprintf(9, "%s:%d: we are uploading %d bytes\n", __FILE__, __LINE__, WC->upload_length);
02719 att = malloc(sizeof(struct wc_attachment));
02720 memset(att, 0, sizeof(struct wc_attachment));
02721 att->length = WC->upload_length;
02722 strcpy(att->content_type, WC->upload_content_type);
02723 strcpy(att->filename, WC->upload_filename);
02724 att->next = NULL;
02725
02727 if (WC->first_attachment == NULL) {
02728 WC->first_attachment = att;
02729 }
02730 else {
02731 aptr = WC->first_attachment;
02732 while (aptr->next != NULL) aptr = aptr->next;
02733 aptr->next = att;
02734 }
02735
02741 while (num_tokens(att->filename, '/') > 1) {
02742 remove_token(att->filename, 0, '/');
02743 }
02744 while (num_tokens(att->filename, '\\') > 1) {
02745 remove_token(att->filename, 0, '\\');
02746 }
02747
02752 att->data = WC->upload;
02753 WC->upload_length = 0;
02754 WC->upload = NULL;
02755 display_enter();
02756 return;
02757 }
02758
02759 if (strlen(bstr("cancel_button")) > 0) {
02760 sprintf(WC->ImportantMessage,
02761 _("Cancelled. Message was not posted."));
02762 } else if (strlen(bstr("attach_button")) > 0) {
02763 display_enter();
02764 return;
02765 } else if (atol(bstr("postseq")) == dont_post) {
02766 sprintf(WC->ImportantMessage,
02767 _("Automatically cancelled because you have already "
02768 "saved this message."));
02769 } else {
02770 rfc2047encode(encoded_subject, sizeof encoded_subject, bstr("subject"));
02771 sprintf(buf, "ENT0 1|%s|%d|4|%s|%s||%s|%s|%s|%s",
02772 bstr("recp"),
02773 is_anonymous,
02774 encoded_subject,
02775 display_name,
02776 bstr("cc"),
02777 bstr("bcc"),
02778 bstr("wikipage"),
02779 bstr("my_email_addr")
02780 );
02781 serv_puts(buf);
02782 serv_getln(buf, sizeof buf);
02783 if (buf[0] == '4') {
02784 post_mime_to_server();
02785 if ( (strlen(bstr("recp")) > 0)
02786 || (strlen(bstr("cc")) > 0)
02787 || (strlen(bstr("bcc")) > 0)
02788 ) {
02789 sprintf(WC->ImportantMessage, _("Message has been sent.\n"));
02790 }
02791 else {
02792 sprintf(WC->ImportantMessage, _("Message has been posted.\n"));
02793 }
02794 dont_post = atol(bstr("postseq"));
02795 } else {
02796 lprintf(9, "%s:%d: server post error: %s\n", __FILE__, __LINE__, buf);
02797 sprintf(WC->ImportantMessage, "%s", &buf[4]);
02798 display_enter();
02799 return;
02800 }
02801 }
02802
02803 free_attachments(WC);
02804
02809 if (strlen(bstr("return_to")) > 0) {
02810 http_redirect(bstr("return_to"));
02811 }
02815 else if (strlen(bstr("wikipage")) > 0) {
02816 snprintf(buf, sizeof buf, "wiki?page=%s", bstr("wikipage"));
02817 http_redirect(buf);
02818 }
02822 else {
02823 readloop("readnew");
02824 }
02825 }
02826
02827
02828
02829
02833 void display_enter(void)
02834 {
02835 char buf[SIZ];
02836 char ebuf[SIZ];
02837 long now;
02838 char *display_name;
02839 struct wc_attachment *att;
02840 int recipient_required = 0;
02841 int recipient_bad = 0;
02842 int i;
02843 int is_anonymous = 0;
02844 long existing_page = (-1L);
02845
02846 now = time(NULL);
02847
02848 if (strlen(bstr("force_room")) > 0) {
02849 gotoroom(bstr("force_room"));
02850 }
02851
02852 display_name = bstr("display_name");
02853 if (!strcmp(display_name, "__ANONYMOUS__")) {
02854 display_name = "";
02855 is_anonymous = 1;
02856 }
02857
02859 serv_puts("ENT0 0");
02860 serv_getln(buf, sizeof buf);
02861 if (!strncmp(buf, "570", 3)) {
02862 recipient_required = 1;
02863 }
02864 else if (buf[0] != '2') {
02865 sprintf(WC->ImportantMessage, "%s", &buf[4]);
02866 readloop("readnew");
02867 return;
02868 }
02869
02874 if (WC->wc_default_view == VIEW_ADDRESSBOOK) {
02875 do_edit_vcard(-1, "", "");
02876 return;
02877 }
02878
02879 #ifdef WEBCIT_WITH_CALENDAR_SERVICE
02880
02884 if (WC->wc_default_view == VIEW_CALENDAR) {
02885 display_edit_event();
02886 return;
02887 }
02888
02893 if (WC->wc_default_view == VIEW_TASKS) {
02894 display_edit_task();
02895 return;
02896 }
02897 #endif
02898
02903 output_headers(1, 1, 2, 0, 0, 0);
02904 wprintf("<div id=\"banner\">\n");
02905 embed_room_banner(NULL, navbar_none);
02906 wprintf("</div>\n");
02907 wprintf("<div id=\"content\">\n"
02908 "<div class=\"fix_scrollbar_bug message \">");
02909
02911 if (recipient_required) {
02912 sprintf(buf, "ENT0 0|%s|%d|0||%s||%s|%s|%s",
02913 bstr("recp"),
02914 is_anonymous,
02915 display_name,
02916 bstr("cc"), bstr("bcc"), bstr("wikipage"));
02917 serv_puts(buf);
02918 serv_getln(buf, sizeof buf);
02919
02920 if (!strncmp(buf, "570", 3)) {
02921 if (strlen(bstr("recp")) + strlen(bstr("cc")) + strlen(bstr("bcc")) > 0) {
02922 recipient_bad = 1;
02923 }
02924 }
02925 else if (buf[0] != '2') {
02926 wprintf("<em>%s</em><br />\n", &buf[4]);
02927 goto DONE;
02928 }
02929 }
02930
02934 wprintf("<form "
02935 "enctype=\"multipart/form-data\" "
02936 "method=\"POST\" "
02937 "accept-charset=\"UTF-8\" "
02938 "action=\"post\" "
02939 "name=\"enterform\""
02940 ">\n");
02941 wprintf("<input type=\"hidden\" name=\"postseq\" value=\"%ld\">\n", now);
02942 if (WC->wc_view == VIEW_WIKI) {
02943 wprintf("<input type=\"hidden\" name=\"wikipage\" value=\"%s\">\n", bstr("wikipage"));
02944 }
02945 wprintf("<input type=\"hidden\" name=\"return_to\" value=\"%s\">\n", bstr("return_to"));
02946
02949 wprintf("<img src=\"static/newmess3_24x.gif\" class=\"imgedit\">");
02950 wprintf(" ");
02951 fmt_date(buf, now, 0);
02952 wprintf("%s", buf);
02953 wprintf("\n");
02955 wprintf("<div>");
02956 wprintf("<label for=\"from_id\" > ");
02957 wprintf(_(" <I>from</I> "));
02958 wprintf("</label>");
02959
02960
02961
02962 wprintf("<select name=\"display_name\" size=1 id=\"from_id\">\n");
02963
02964 serv_puts("GVSN");
02965 serv_getln(buf, sizeof buf);
02966 if (buf[0] == '1') {
02967 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
02968 wprintf("<option %s value=\"",
02969 ((!strcasecmp(bstr("display_name"), buf)) ? "selected" : "")
02970 );
02971 escputs(buf);
02972 wprintf("\">");
02973 escputs(buf);
02974 wprintf("</option>\n");
02975 }
02976 }
02977
02978 if (WC->room_flags & QR_ANONOPT) {
02979 wprintf("<option %s value=\"__ANONYMOUS__\">%s</option>\n",
02980 ((!strcasecmp(bstr("__ANONYMOUS__"), WC->wc_fullname)) ? "selected" : ""),
02981 _("Anonymous")
02982 );
02983 }
02984
02985 wprintf("</select>\n");
02986
02987
02988
02989
02990 if (recipient_required) {
02991 serv_puts("GVEA");
02992 serv_getln(buf, sizeof buf);
02993 if (buf[0] == '1') {
02994 wprintf("<select name=\"my_email_addr\" size=1>\n");
02995 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
02996 wprintf("<option value=\"");
02997 escputs(buf);
02998 wprintf("\"><");
02999 escputs(buf);
03000 wprintf("></option>\n");
03001 }
03002 wprintf("</select>\n");
03003 }
03004 }
03005
03006 wprintf(_(" <I>in</I> "));
03007 escputs(WC->wc_roomname);
03008 wprintf("</div>");
03009
03010 if (recipient_required) {
03011
03012 wprintf("<div style=\"float: left;\"><label for=\"recp_id\"> ");
03013 wprintf(_("To:"));
03014 wprintf("</label>"
03015 "<input autocomplete=\"off\" type=\"text\" name=\"recp\" id=\"recp_id\" value=\"");
03016 escputs(bstr("recp"));
03017 wprintf("\" size=45 maxlength=1000 />");
03018 wprintf("<div class=\"auto_complete\" id=\"recp_name_choices\"></div>");
03019
03020
03021 wprintf("<br/><label for=\"cc_id\"> ");
03022 wprintf(_("CC:"));
03023 wprintf("</label>"
03024 "<input autocomplete=\"off\" type=\"text\" name=\"cc\" id=\"cc_id\" value=\"");
03025 escputs(bstr("cc"));
03026 wprintf("\" size=45 maxlength=1000 />");
03027 wprintf("<div class=\"auto_complete\" id=\"cc_name_choices\"></div>");
03028 wprintf("<br/><label for=\"bcc_id\"> ");
03029 wprintf(_("BCC:"));
03030 wprintf("</label>"
03031 "<input autocomplete=\"off\" type=\"text\" name=\"bcc\" id=\"bcc_id\" value=\"");
03032 escputs(bstr("bcc"));
03033 wprintf("\" size=45 maxlength=1000 />");
03034 wprintf("<div class=\"auto_complete\" id=\"bcc_name_choices\"></div>");
03035
03037 wprintf("<script type=\"text/javascript\"> \n"
03038 " activate_entmsg_autocompleters(); \n"
03039 "</script> \n"
03040 );
03041 wprintf("</div>");
03042
03044 wprintf(
03045 "<a href=\"javascript:PopOpenAddressBook('recp_id|%s|cc_id|%s|bcc_id|%s');\" "
03046 "title=\"%s\">"
03047 "<img align=middle border=0 width=24 height=24 src=\"static/viewcontacts_24x.gif\">"
03048 " %s</a>",
03049 _("To:"), _("CC:"), _("BCC:"),
03050 _("Contacts"), _("Contacts")
03051 );
03053 }
03054
03055 wprintf("<div style=\"clear: both;\"><label for=\"subject_id\" > ");
03056 if (recipient_required) {
03057 wprintf(_("Subject:"));
03058 }
03059 else {
03060 wprintf(_("Subject (optional):"));
03061 }
03062 wprintf("</label>"
03063 "<input type=\"text\" name=\"subject\" id=\"subject_id\" value=\" ");
03064 escputs(bstr("subject"));
03065 wprintf("\" size=45 maxlength=70>\n");
03066
03067 wprintf("</div>\n");
03068
03069 wprintf("<textarea name=\"msgtext\" cols=\"80\" rows=\"15\">");
03070
03072 msgescputs(bstr("msgtext"));
03073
03074
03075 if (atol(bstr("fwdquote")) > 0L) {
03076 wprintf("<br><div align=center><i>");
03077 wprintf(_("--- forwarded message ---"));
03078 wprintf("</i></div><br>");
03079 pullquote_message(atol(bstr("fwdquote")), 1, 1);
03080 }
03081
03083 else if (atol(bstr("replyquote")) > 0L) {
03084 wprintf("<br>"
03085 "<blockquote>");
03086 pullquote_message(atol(bstr("replyquote")), 0, 1);
03087 wprintf("</blockquote><br>");
03088 }
03089
03091 else if (WC->wc_view == VIEW_WIKI) {
03092 safestrncpy(buf, bstr("wikipage"), sizeof buf);
03093 str_wiki_index(buf);
03094 existing_page = locate_message_by_uid(buf);
03095 if (existing_page >= 0L) {
03096 pullquote_message(existing_page, 1, 0);
03097 }
03098 }
03099
03101 if ( (WC->is_mailbox) && (strcmp(bstr("sig_inserted"), "yes")) ) {
03102 get_preference("use_sig", buf, sizeof buf);
03103 if (!strcasecmp(buf, "yes")) {
03104 get_preference("signature", ebuf, sizeof ebuf);
03105 euid_unescapize(buf, ebuf);
03106 wprintf("<br>--<br>");
03107 for (i=0; i<strlen(buf); ++i) {
03108 if (buf[i] == '\n') {
03109 wprintf("<br>");
03110 }
03111 else if (buf[i] == '<') {
03112 wprintf("<");
03113 }
03114 else if (buf[i] == '>') {
03115 wprintf(">");
03116 }
03117 else if (buf[i] == '&') {
03118 wprintf("&");
03119 }
03120 else if (buf[i] == '\"') {
03121 wprintf(""");
03122 }
03123 else if (buf[i] == '\'') {
03124 wprintf("'");
03125 }
03126 else if (isprint(buf[i])) {
03127 wprintf("%c", buf[i]);
03128 }
03129 }
03130 }
03131 }
03132
03133 wprintf("</textarea>");
03134
03139 do_template("richedit");
03140
03142 wprintf("<div><img src=\"static/diskette_24x.gif\" border=0 ");
03143 wprintf(_("Attachments:"));
03144 wprintf(" ");
03145 wprintf("<select name=\"which_attachment\" size=1>");
03146 for (att = WC->first_attachment; att != NULL; att = att->next) {
03147 wprintf("<option value=\"");
03148 urlescputs(att->filename);
03149 wprintf("\">");
03150 escputs(att->filename);
03151
03152 wprintf("</option>\n");
03153 }
03154 wprintf("</select>");
03155
03157 wprintf(" ");
03158 wprintf(_("Attach file:"));
03159 wprintf(" <input name=\"attachfile\" "
03160 "size=16 type=\"file\">\n "
03161 "<input type=\"submit\" name=\"attach_button\" value=\"%s\">\n", _("Add"));
03162 wprintf("</div>");
03163
03164 wprintf("<div class=\"send_edit_msg\">");
03165 wprintf("<input type=\"submit\" name=\"send_button\" value=\"");
03166 if (recipient_required) {
03167 wprintf(_("Send message"));
03168 } else {
03169 wprintf(_("Post message"));
03170 }
03171 wprintf("\"> "
03172 "<input type=\"submit\" name=\"cancel_button\" value=\"%s\">\n", _("Cancel"));
03173 wprintf("</div>");
03174
03175
03177 if (strcmp(bstr("sig_inserted"), "yes")) {
03178 wprintf("<input type=\"hidden\" name=\"sig_inserted\" value=\"yes\">\n");
03179 }
03180
03181 wprintf("</form>\n");
03182 wprintf("</div></div>\n");
03183
03184 DONE: address_book_popup();
03185 wDumpContent(1);
03186 }
03187
03188
03192 void delete_msg(void)
03193 {
03194 long msgid;
03195 char buf[SIZ];
03196
03197 msgid = atol(bstr("msgid"));
03198
03199 if (WC->wc_is_trash) {
03200 serv_printf("DELE %ld", msgid);
03201 }
03202 else {
03203 serv_printf("MOVE %ld|_TRASH_|0", msgid);
03204 }
03205
03206 serv_getln(buf, sizeof buf);
03207 sprintf(WC->ImportantMessage, "%s", &buf[4]);
03208
03209 readloop("readnew");
03210 }
03211
03212
03216 void move_msg(void)
03217 {
03218 long msgid;
03219 char buf[SIZ];
03220
03221 msgid = atol(bstr("msgid"));
03222
03223 if (strlen(bstr("move_button")) > 0) {
03224 sprintf(buf, "MOVE %ld|%s", msgid, bstr("target_room"));
03225 serv_puts(buf);
03226 serv_getln(buf, sizeof buf);
03227 sprintf(WC->ImportantMessage, "%s", &buf[4]);
03228 } else {
03229 sprintf(WC->ImportantMessage, (_("The message was not moved.")));
03230 }
03231
03232 readloop("readnew");
03233 }
03234
03235
03236
03237
03238
03242 void confirm_move_msg(void)
03243 {
03244 long msgid;
03245 char buf[SIZ];
03246 char targ[SIZ];
03247
03248 msgid = atol(bstr("msgid"));
03249
03250
03251 output_headers(1, 1, 2, 0, 0, 0);
03252 wprintf("<div id=\"banner\">\n");
03253 wprintf("<TABLE WIDTH=100%% BORDER=0><TR><TD>");
03254 wprintf("<SPAN CLASS=\"titlebar\">");
03255 wprintf(_("Confirm move of message"));
03256 wprintf("</SPAN>\n");
03257 wprintf("</TD></TR></TABLE>\n");
03258 wprintf("</div>\n<div id=\"content\">\n");
03259
03260 wprintf("<CENTER>");
03261
03262 wprintf(_("Move this message to:"));
03263 wprintf("<br />\n");
03264
03265 wprintf("<form METHOD=\"POST\" action=\"move_msg\">\n");
03266 wprintf("<INPUT TYPE=\"hidden\" NAME=\"msgid\" VALUE=\"%s\">\n", bstr("msgid"));
03267
03268 wprintf("<SELECT NAME=\"target_room\" SIZE=5>\n");
03269 serv_puts("LKRA");
03270 serv_getln(buf, sizeof buf);
03271 if (buf[0] == '1') {
03272 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
03273 extract_token(targ, buf, 0, '|', sizeof targ);
03274 wprintf("<OPTION>");
03275 escputs(targ);
03276 wprintf("\n");
03277 }
03278 }
03279 wprintf("</SELECT>\n");
03280 wprintf("<br />\n");
03281
03282 wprintf("<INPUT TYPE=\"submit\" NAME=\"move_button\" VALUE=\"%s\">", _("Move"));
03283 wprintf(" ");
03284 wprintf("<INPUT TYPE=\"submit\" NAME=\"cancel_button\" VALUE=\"%s\">", _("Cancel"));
03285 wprintf("</form></CENTER>\n");
03286
03287 wprintf("</CENTER>\n");
03288 wDumpContent(1);
03289 }
03290
03291