Finalize vcard editing:
[citadel.git] / webcit / messages.c
index ebc4e41f8ff25ab96600991edf6bc49b5e8d3f4c..70cd85ab80c794c3e8fb68bde5073ff20a8371a1 100644 (file)
@@ -18,7 +18,6 @@
 #include "calendar.h"
 
 HashList *MsgHeaderHandler = NULL;
-HashList *MsgEvaluators = NULL;
 HashList *MimeRenderHandler = NULL;
 HashList *ReadLoopHandler = NULL;
 int dbg_analyze_msg = 0;
@@ -31,12 +30,6 @@ void jsonMessageListHdr(void);
 
 void display_enter(void);
 
-typedef void (*MsgPartEvaluatorFunc)(message_summary *Sum, StrBuf *Buf);
-
-typedef struct _MsgPartEvaluatorStruct {
-       MsgPartEvaluatorFunc f;
-} MsgPartEvaluatorStruct;
-
 void fixview()
 {
        /* workaround for json listview; its not useable directly */
@@ -495,50 +488,6 @@ void display_headers(void) {
 }
 
 
-message_summary *ReadOneMessageSummary(StrBuf *RawMessage, const char *DefaultSubject, long MsgNum) 
-{
-       void                 *vEval;
-       MsgPartEvaluatorStruct  *Eval;
-       message_summary      *Msg;
-       StrBuf *Buf;
-       const char *buf;
-       const char *ebuf;
-       int nBuf;
-       long len;
-       
-       Buf = NewStrBuf();
-
-       serv_printf("MSG0 %ld|1", MsgNum);      /* ask for headers only */
-       
-       StrBuf_ServGetln(Buf);
-       if (GetServerStatus(Buf, NULL) == 1) {
-               FreeStrBuf(&Buf);
-               return NULL;
-       }
-
-       Msg = (message_summary*)malloc(sizeof(message_summary));
-       memset(Msg, 0, sizeof(message_summary));
-       while (len = StrBuf_ServGetln(Buf),
-              (len >= 0) && 
-              ((len != 3)  ||
-               strcmp(ChrPtr(Buf), "000")))
-       {
-               buf = ChrPtr(Buf);
-               ebuf = strchr(ChrPtr(Buf), '=');
-               nBuf = ebuf - buf;
-               if (GetHash(MsgEvaluators, buf, nBuf, &vEval) && vEval != NULL) {
-                       Eval = (MsgPartEvaluatorStruct*) vEval;
-                       StrBufCutLeft(Buf, nBuf + 1);
-                       Eval->f(Msg, Buf);
-               }
-               else syslog(LOG_INFO, "Don't know how to handle Message Headerline [%s]", ChrPtr(Buf));
-       }
-       return Msg;
-}
-
-
-
-
 
 /*
  * load message pointers from the server for a "read messages" operation
@@ -650,10 +599,11 @@ int load_msg_ptrs(const char *servcmd,
  * \param MatchMSet MSet we want to flag
  * \param FlagToSet Flag to set on each BasicMsgStruct->Flags if in MSet
  */
-void SetFlagsFromMSet(HashList *ScanMe, MSet *MatchMSet, int FlagToSet, int Reverse)
+long SetFlagsFromMSet(HashList *ScanMe, MSet *MatchMSet, int FlagToSet, int Reverse)
 {
        const char *HashKey;
        long HKLen;
+       long count = 0;
        HashPos *at;
        void *vMsg;
        message_summary *Msg;
@@ -664,17 +614,21 @@ void SetFlagsFromMSet(HashList *ScanMe, MSet *MatchMSet, int FlagToSet, int Reve
                Msg = (message_summary*) vMsg;
                if (Reverse && IsInMSetList(MatchMSet, Msg->msgnum)) {
                        Msg->Flags = Msg->Flags | FlagToSet;
+                       count++;
                }
                else if (!Reverse && !IsInMSetList(MatchMSet, Msg->msgnum)) {
                        Msg->Flags = Msg->Flags | FlagToSet;
+                       count++;
                }
        }
        DeleteHashPos(&at);
+       return count;
 }
 
 
-void load_seen_flags(void)
+long load_seen_flags(void)
 {
+       long count = 0;
        StrBuf *OldMsg;
        wcsession *WCC = WC;
        MSet *MatchMSet;
@@ -687,15 +641,16 @@ void load_seen_flags(void)
        }
        else {
                FreeStrBuf(&OldMsg);
-               return;
+               return 0;
        }
 
        if (ParseMSet(&MatchMSet, OldMsg))
        {
-               SetFlagsFromMSet(WCC->summ, MatchMSet, MSGFLAG_READ, 0);
+               count = SetFlagsFromMSet(WCC->summ, MatchMSet, MSGFLAG_READ, 0);
        }
        DeleteMSet(&MatchMSet);
        FreeStrBuf(&OldMsg);
+       return count;
 }
 
 extern readloop_struct rlid[];
@@ -734,7 +689,7 @@ void readloop(long oper, eCustomRoomRenderer ForceRenderer)
        long HKLen;
        WCTemplputParams SubTP;
        SharedMessageStatus Stat;
-       void *ViewSpecific;
+       void *ViewSpecific = NULL;
 
        if (havebstr("is_summary") && (1 == (ibstr("is_summary")))) {
                WCC->CurRoom.view = VIEW_MAILBOX;
@@ -814,7 +769,7 @@ void readloop(long oper, eCustomRoomRenderer ForceRenderer)
                Stat.startmsg =  0;
        }
 
-       if (Stat.load_seen) load_seen_flags();
+       if (Stat.load_seen) Stat.numNewmsgs = load_seen_flags();
        
         /*
         * Print any inforation above the message list...
@@ -832,9 +787,13 @@ void readloop(long oper, eCustomRoomRenderer ForceRenderer)
                
                Foo = NewStrBuf ();
                StrBufPrintf(Foo, "%ld", Stat.nummsgs);
-               PutBstr(HKEY("__READLOOP:TOTALMSGS"), NewStrBufDup(Foo));
+               PutBstr(HKEY("__READLOOP:TOTALMSGS"), NewStrBufDup(Foo)); // keep Foo!
+
+               StrBufPrintf(Foo, "%ld", Stat.numNewmsgs);
+               PutBstr(HKEY("__READLOOP:NEWMSGS"), NewStrBufDup(Foo)); // keep Foo!
+
                StrBufPrintf(Foo, "%ld", Stat.startmsg);
-               PutBstr(HKEY("__READLOOP:STARTMSG"), Foo);
+               PutBstr(HKEY("__READLOOP:STARTMSG"), Foo); // store Foo elsewhere, descope it here.
        }
 
        /*
@@ -930,6 +889,7 @@ void post_mime_to_server(void) {
 
        /* Remember, serv_printf() appends an extra newline */
        if (include_text_alt) {
+               StrBuf *Buf;
                serv_printf("Content-type: multipart/alternative; "
                        "boundary=\"%s\"\n", alt_boundary);
                serv_printf("This is a multipart message in MIME format.\n");
@@ -939,18 +899,30 @@ void post_mime_to_server(void) {
                serv_puts("Content-Transfer-Encoding: quoted-printable");
                serv_puts("");
                txtmail = html_to_ascii(bstr("msgtext"), 0, 80, 0);
-               text_to_server_qp(txtmail);     /* Transmit message in quoted-printable encoding */
+               Buf = NewStrBufPlain(txtmail, -1);
                free(txtmail);
 
+               text_to_server_qp(Buf);     /* Transmit message in quoted-printable encoding */
+               FreeStrBuf(&Buf);
                serv_printf("\n--%s", alt_boundary);
        }
 
-       serv_puts("Content-type: text/html; charset=utf-8");
-       serv_puts("Content-Transfer-Encoding: quoted-printable");
-       serv_puts("");
-       serv_puts("<html><body>\r\n");
-       text_to_server_qp(bstr("msgtext"));     /* Transmit message in quoted-printable encoding */
-       serv_puts("</body></html>\r\n");
+       if (havebstr("markdown"))
+       {
+               serv_puts("Content-type: text/x-markdown; charset=utf-8");
+               serv_puts("Content-Transfer-Encoding: quoted-printable");
+               serv_puts("");
+               text_to_server_qp(sbstr("msgtext"));    /* Transmit message in quoted-printable encoding */
+       }
+       else
+       {
+               serv_puts("Content-type: text/html; charset=utf-8");
+               serv_puts("Content-Transfer-Encoding: quoted-printable");
+               serv_puts("");
+               serv_puts("<html><body>\r\n");
+               text_to_server_qp(sbstr("msgtext"));    /* Transmit message in quoted-printable encoding */
+               serv_puts("</body></html>\r\n");
+       }
 
        if (include_text_alt) {
                serv_printf("--%s--", alt_boundary);
@@ -1219,24 +1191,40 @@ void upload_attachment(void) {
        long newnlen;
        void *v;
        wc_mime_attachment *att;
+       const StrBuf *Tmpl = sbstr("template");
+       const StrBuf *MimeType = NULL;
+       const StrBuf *UID;
 
+       begin_burst();
        syslog(LOG_DEBUG, "upload_attachment()\n");
-       wc_printf("upload_attachment()<br>\n");
+       if (!Tmpl) wc_printf("upload_attachment()<br>\n");
 
        if (WCC->upload_length <= 0) {
                syslog(LOG_DEBUG, "ERROR no attachment was uploaded\n");
-               wc_printf("ERROR no attachment was uploaded<br>\n");
+               if (Tmpl)
+               {
+                       putlbstr("UPLOAD_ERROR", 1);
+                       MimeType = DoTemplate(SKEY(Tmpl), NULL, &NoCtx);
+               }
+               else      wc_printf("ERROR no attachment was uploaded<br>\n");
+               http_transmit_thing(ChrPtr(MimeType), 0);
+
                return;
        }
 
        syslog(LOG_DEBUG, "Client is uploading %d bytes\n", WCC->upload_length);
-       wc_printf("Client is uploading %d bytes<br>\n", WCC->upload_length);
-       att = malloc(sizeof(wc_mime_attachment));
+       if (Tmpl) putlbstr("UPLOAD_LENGTH", WCC->upload_length);
+       else wc_printf("Client is uploading %d bytes<br>\n", WCC->upload_length);
+
+       att = (wc_mime_attachment*)malloc(sizeof(wc_mime_attachment));
        memset(att, 0, sizeof(wc_mime_attachment ));
        att->length = WCC->upload_length;
        att->ContentType = NewStrBufPlain(WCC->upload_content_type, -1);
        att->FileName = NewStrBufDup(WCC->upload_filename);
-       
+       UID = sbstr("qquuid");
+       if (UID)
+               att->PartNum = NewStrBufDup(UID);
+
        if (WCC->attachments == NULL) {
                WCC->attachments = NewHash(1, Flathash);
        }
@@ -1271,6 +1259,9 @@ void upload_attachment(void) {
        att->Data = WCC->upload;
        WCC->upload = NULL;
        WCC->upload_length = 0;
+       
+       if (Tmpl) MimeType = DoTemplate(SKEY(Tmpl), NULL, &NoCtx);
+       http_transmit_thing(ChrPtr(MimeType), 0);
 }
 
 
@@ -1287,26 +1278,35 @@ void remove_attachment(void) {
        StrBuf *WhichAttachment;
        HashPos *at;
        long len;
+       int found=0;
        const char *key;
 
        WhichAttachment = NewStrBufDup(sbstr("which_attachment"));
+       if (ChrPtr(WhichAttachment)[0] == '/')
+               StrBufCutLeft(WhichAttachment, 1);
        StrBufUnescape(WhichAttachment, 0);
        at = GetNewHashPos(WCC->attachments, 0);
        do {
+               vAtt = NULL;
                GetHashPos(WCC->attachments, at, &len, &key, &vAtt);
-       
+
                att = (wc_mime_attachment*) vAtt;
-               if ((att != NULL) && 
-                   (strcmp(ChrPtr(WhichAttachment), 
-                           ChrPtr(att->FileName)   ) == 0))
+               if ((att != NULL) &&
+                   (
+                           !strcmp(ChrPtr(WhichAttachment), ChrPtr(att->FileName)) ||
+                   ((att->PartNum != NULL) &&
+                    !strcmp(ChrPtr(WhichAttachment), ChrPtr(att->PartNum)))
+                           ))
                {
                        DeleteEntryFromHash(WCC->attachments, at);
+                       found=1;
                        break;
                }
        }
        while (NextHashPos(WCC->attachments, at));
+
        FreeStrBuf(&WhichAttachment);
-       wc_printf("remove_attachment() completed\n");
+       wc_printf("remove_attachment(%d) completed\n", found);
 }
 
 
@@ -1695,7 +1695,10 @@ void display_enter(void)
 
        begin_burst();
        output_headers(1, 0, 0, 0, 1, 0);
-       DoTemplate(HKEY("edit_message"), NULL, &NoCtx);
+       if (WCC->CurRoom.defview == VIEW_WIKIMD) 
+               DoTemplate(HKEY("edit_markdown_epic"), NULL, &NoCtx);
+       else
+               DoTemplate(HKEY("edit_message"), NULL, &NoCtx);
        end_burst();
 
        return;
@@ -1803,6 +1806,7 @@ void postpart(StrBuf *partnum, StrBuf *filename, int force_download)
  */
 void mimepart(int force_download)
 {
+       int detect_mime = 0;
        long msgnum;
        long ErrorDetail;
        StrBuf *att;
@@ -1821,25 +1825,32 @@ void mimepart(int force_download)
        if (GetServerStatus(Buf, &ErrorDetail) == 2) {
                StrBufCutLeft(Buf, 4);
                bytes = StrBufExtract_long(Buf, 0, '|');
-               if (!force_download) {
-                       StrBufExtract_token(ContentType, Buf, 3, '|');
+               StrBufExtract_token(ContentType, Buf, 3, '|');
+               CheckGZipCompressionAllowed (SKEY(ContentType));
+               if (force_download)
+               {
+                       FlushStrBuf(ContentType);
+                       detect_mime = 0;
                }
-
-               serv_read_binary(WCC->WBuf, bytes, Buf);
-               serv_puts("CLOS");
-               StrBuf_ServGetln(Buf);
-               CT = ChrPtr(ContentType);
-
-               if (!force_download) {
-                       if (!strcasecmp(ChrPtr(ContentType), "application/octet-stream")) {
+               else
+               {
+                       if (!strcasecmp(ChrPtr(ContentType), "application/octet-stream"))
+                       {
                                StrBufExtract_token(Buf, WCC->Hdr->HR.ReqLine, 2, '/');
                                CT = GuessMimeByFilename(SKEY(Buf));
+                               StrBufPlain(ContentType, CT, -1);
                        }
-                       if (!strcasecmp(ChrPtr(ContentType), "application/octet-stream")) {
-                               CT = GuessMimeType(SKEY(WCC->WBuf));
+                       if (!strcasecmp(ChrPtr(ContentType), "application/octet-stream"))
+                       {
+                               detect_mime = 1;
                        }
                }
-               http_transmit_thing(CT, 0);
+               serv_read_binary_to_http(ContentType, bytes, 0, detect_mime);
+
+               serv_read_binary(WCC->WBuf, bytes, Buf);
+               serv_puts("CLOS");
+               StrBuf_ServGetln(Buf);
+               CT = ChrPtr(ContentType);
        } else {
                StrBufCutLeft(Buf, 4);
                switch (ErrorDetail) {
@@ -1859,7 +1870,12 @@ void mimepart(int force_download)
                        hprintf("HTTP/1.1 500 %s\n", ChrPtr(Buf));
                        break;
                }
-               output_headers(0, 0, 0, 0, 0, 0);
+
+               hprintf("Pragma: no-cache\r\n"
+                       "Cache-Control: no-store\r\n"
+                       "Expires: -1\r\n"
+               );
+
                hprintf("Content-Type: text/plain\r\n");
                begin_burst();
                wc_printf(_("An error occurred while retrieving this part: %s\n"),