messages.c

00001 /*
00002  * $Id: messages.c 5217 2007-06-13 19:38:02Z ajc $
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                 /* vcard_n_prettyize(storename); */
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("&nbsp;");
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                                 /* ignore */
00536                         }
00537                         else if (!strcasecmp(firsttoken, "rev")) {
00538                                 /* ignore */
00539                         }
00540                         else if (!strcasecmp(firsttoken, "label")) {
00541                                 /* ignore */
00542                         }
00543                         else {
00544 
00545                                 /*** Don't show extra fields.  They're ugly.
00546                                 if (pass == 2) {
00547                                         wprintf("<TR><TD>");
00548                                         escputs(thisname);
00549                                         wprintf("</TD><TD>");
00550                                         escputs(thisvalue);
00551                                         wprintf("</TD></TR>\n");
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&gt; ", &buf[5]);
00765                 }
00766                 if (!strncasecmp(buf, "rfca=", 5)) {
00767                         strcpy(rfca, &buf[5]);
00768                         wprintf("&lt;");
00769                         escputs(rfca);
00770                         wprintf("&gt; ");
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&gt; ", &buf[5]);
01368                         }
01369                         if (!strncasecmp(buf, "rfca=", 5)) {
01370                                 strcpy(rfca, &buf[5]);
01371                                 wprintf("&lt;");
01372                                 msgescputs(rfca);
01373                                 wprintf("&gt; ");
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         /* Boring old 80-column fixed format text gets handled this way... */
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          * If there were attachments, we have to download them and insert them
01542          * into the attachment chain for the forwarded message we are composing.
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                          * tracing  ... uncomment if necessary
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                                 /* Create an attachment struct from this mime part... */
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                                 /* And add it to the list. */
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);       /* brief */
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);     /* ask for headers only */
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                         /* Grab the name off the card */
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&nbsp;-&nbsp;%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) {       /* New tab */
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                         "&nbsp;"
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("&nbsp;<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         /* Allow the user to select any of his valid screen names */
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         /* If this is an email (not a post), allow the user to select any of his
02988          * valid email addresses.
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("\">&lt;");
02999                                 escputs(buf);
03000                                 wprintf("&gt;</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                         "&nbsp;%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         /* If we're forwarding a message, insert it here... */
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("&lt;");
03113                                 }
03114                                 else if (buf[i] == '>') {
03115                                         wprintf("&gt;");
03116                                 }
03117                                 else if (buf[i] == '&') {
03118                                         wprintf("&amp;");
03119                                 }
03120                                 else if (buf[i] == '\"') {
03121                                         wprintf("&quot;");
03122                                 }
03123                                 else if (buf[i] == '\'') {
03124                                         wprintf("&#39;");
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                 /* wprintf(" (%s, %d bytes)",att->content_type,att->length); */
03152                 wprintf("</option>\n");
03153         }
03154         wprintf("</select>");
03155 
03157         wprintf("&nbsp;&nbsp;&nbsp;");
03158         wprintf(_("Attach file:"));
03159         wprintf(" <input name=\"attachfile\" "
03160                 "size=16 type=\"file\">\n&nbsp;&nbsp;"
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("\">&nbsp;"
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("&nbsp;");
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 

Generated on Wed Jun 20 23:13:09 2007 for webcit by  doxygen 1.5.2