Began fixing http://uncensored.citadel.org/wiki?page=stefan2012mar07?go=exterminate
[citadel.git] / webcit / messages.c
index 5dcc5c9d3d02ece4944d3720842ebd6c7ffa8538..f990c8700b09d1e358e502181194cccc5ec5c045 100644 (file)
@@ -1,26 +1,20 @@
 /*
  * Functions which deal with the fetching and displaying of messages.
  *
- * Copyright (c) 1996-2011 by the citadel.org team
+ * Copyright (c) 1996-2012 by the citadel.org team
  *
  * This program is open source software.  You can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 3 of the
- * License, or (at your option) any later version.
+ * modify it under the terms of the GNU General Public License, version 3.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include "webcit.h"
 #include "webserver.h"
-#include "groupdav.h"
+#include "dav.h"
 #include "calendar.h"
 
 HashList *MsgHeaderHandler = NULL;
@@ -529,7 +523,8 @@ message_summary *ReadOneMessageSummary(StrBuf *RawMessage, const char *DefaultSu
  *
  * servcmd:            the citadel command to send to the citserver
  */
-int load_msg_ptrs(const char *servcmd, 
+int load_msg_ptrs(const char *servcmd,
+                 const char *filter,
                  SharedMessageStatus *Stat, 
                  load_msg_ptrs_detailheaders LH)
 {
@@ -540,6 +535,7 @@ int load_msg_ptrs(const char *servcmd,
        int n;
        int skipit;
        const char *Ptr = NULL;
+       int StatMajor;
 
        Stat->lowest_found = LONG_MAX;
        Stat->highest_found = LONG_MIN;
@@ -552,7 +548,21 @@ int load_msg_ptrs(const char *servcmd,
        Buf = NewStrBuf();
        serv_puts(servcmd);
        StrBuf_ServGetln(Buf);
-       if (GetServerStatus(Buf, NULL) != 1) {
+       StatMajor = GetServerStatus(Buf, NULL);
+       switch (StatMajor) {
+       case 1:
+               break;
+       case 8:
+               if (filter != NULL) {
+                       serv_puts(filter);
+                        serv_puts("000");
+                       break;
+               }
+               /* fall back to empty filter in case of we were fooled... */
+               serv_puts("");
+               serv_puts("000");
+               break;
+       default:
                FreeStrBuf(&Buf);
                return (Stat->nummsgs);
        }
@@ -672,6 +682,8 @@ typedef struct _RoomRenderer{
        int RoomType;
 
        GetParamsGetServerCall_func GetParamsGetServerCall;
+       
+       PrintViewHeader_func PrintPageHeader;
        PrintViewHeader_func PrintViewHeader;
        LoadMsgFromServer_func LoadMsgFromServer;
        RenderView_or_Tail_func RenderView_or_Tail;
@@ -692,6 +704,7 @@ void readloop(long oper, eCustomRoomRenderer ForceRenderer)
        void *vMsg;
        message_summary *Msg;
        char cmd[256] = "";
+       char filter[256] = "";
        int i, r;
        wcsession *WCC = WC;
        HashPos *at;
@@ -705,18 +718,8 @@ void readloop(long oper, eCustomRoomRenderer ForceRenderer)
                WCC->CurRoom.view = VIEW_MAILBOX;
        }
 
-       if (havebstr("is_ajax") && (1 == (ibstr("is_ajax")))) {
-               WCC->is_ajax = 1;
-       }
-
-       if ((oper == do_search) && (WCC->CurRoom.view == VIEW_WIKI)) {
-               display_wiki_pagelist();
-               return;
-       }
-
-       if (WCC->CurRoom.view == VIEW_WIKI) {
-               http_redirect("wiki?page=home");
-               return;
+       if (havebstr("view")) {
+               WCC->CurRoom.view = ibstr("view");
        }
 
        memset(&Stat, 0, sizeof(SharedMessageStatus));
@@ -736,22 +739,23 @@ void readloop(long oper, eCustomRoomRenderer ForceRenderer)
        }
 
        ViewMsg = (RoomRenderer*) vViewMsg;
-       if (!WCC->is_ajax) {
+       if (ViewMsg->PrintPageHeader == NULL)
                output_headers(1, 1, 1, 0, 0, 0);
-       } else if (WCC->CurRoom.view == VIEW_MAILBOX) {
-               jsonMessageListHdr();
-       }
+       else 
+               ViewMsg->PrintPageHeader(&Stat, ViewSpecific);
 
        if (ViewMsg->GetParamsGetServerCall != NULL) {
                r = ViewMsg->GetParamsGetServerCall(
                       &Stat,
                       &ViewSpecific,
                       oper,
-                      cmd, sizeof(cmd)
+                      cmd, sizeof(cmd),
+                      filter, sizeof(filter)
                );
        } else {
                r = 0;
        }
+
        switch(r)
        {
        case 400:
@@ -764,8 +768,12 @@ void readloop(long oper, eCustomRoomRenderer ForceRenderer)
        default:
                break;
        }
-       if (!IsEmptyStr(cmd))
-               Stat.nummsgs = load_msg_ptrs(cmd, &Stat, ViewMsg->LHParse);
+       if (!IsEmptyStr(cmd)) {
+               const char *p = NULL;
+               if (!IsEmptyStr(filter))
+                       p = filter;
+               Stat.nummsgs = load_msg_ptrs(cmd, p, &Stat, ViewMsg->LHParse);
+       }
 
        if (Stat.sortit) {
                CompareFunc SortIt;
@@ -1003,14 +1011,14 @@ void post_message(void)
                StrBuf *Recp = NULL; 
                StrBuf *Cc = NULL;
                StrBuf *Bcc = NULL;
-               const StrBuf *Wikipage = NULL;
+               char *wikipage = NULL;
                const StrBuf *my_email_addr = NULL;
                StrBuf *CmdBuf = NULL;
                StrBuf *references = NULL;
                int saving_to_drafts = 0;
                long HeaderLen = 0;
 
-               saving_to_drafts = !strcasecmp(bstr("submit_action"), "drafts");
+               saving_to_drafts = !strcasecmp(bstr("submit_action"), "draft");
                Buf = NewStrBuf();
 
                if (saving_to_drafts) {
@@ -1058,14 +1066,15 @@ void post_message(void)
                FreeStrBuf(&EmailAddress);
                FreeStrBuf(&EncBuf);
 
-               Wikipage = sbstr("page");
+               wikipage = strdup(bstr("page"));
+               str_wiki_index(wikipage);
                my_email_addr = sbstr("my_email_addr");
                
                HeaderLen = StrLength(Recp) + 
                        StrLength(encoded_subject) +
                        StrLength(Cc) +
                        StrLength(Bcc) + 
-                       StrLength(Wikipage) +
+                       strlen(wikipage) +
                        StrLength(my_email_addr) + 
                        StrLength(references);
                CmdBuf = NewStrBufPlain(NULL, sizeof (CMD) + HeaderLen);
@@ -1077,11 +1086,12 @@ void post_message(void)
                             ChrPtr(display_name),
                             saving_to_drafts?"":ChrPtr(Cc),
                             saving_to_drafts?"":ChrPtr(Bcc),
-                            ChrPtr(Wikipage),
+                            wikipage,
                             ChrPtr(my_email_addr),
                             ChrPtr(references));
                FreeStrBuf(&references);
                FreeStrBuf(&encoded_subject);
+               free(wikipage);
 
                if ((HeaderLen + StrLength(sbstr("msgtext")) < 10) && 
                    (GetCount(WCC->attachments) == 0)){
@@ -1113,7 +1123,7 @@ void post_message(void)
                                if (saving_to_drafts) {
                                        AppendImportantMessage(_("Message has been saved to Drafts.\n"), -1);
                                        gotoroom(WCC->CurRoom.name);
-                                       display_enter();
+                                       readloop(readnew, eUseDefault);
                                        FreeStrBuf(&Buf);
                                        return;
                                } else if (  (havebstr("recp"))
@@ -1322,7 +1332,9 @@ void display_enter(void)
                is_anonymous = 1;
        }
 
-       /* First test to see whether this is a room that requires recipients to be entered */
+       /*
+        * First, do we have permission to enter messages in this room at all?
+        */
        Line = NewStrBuf();
        serv_puts("ENT0 0");
        StrBuf_ServGetln(Line);
@@ -1563,14 +1575,15 @@ void display_enter(void)
                const StrBuf *Recp = NULL; 
                const StrBuf *Cc = NULL;
                const StrBuf *Bcc = NULL;
-               const StrBuf *Wikipage = NULL;
+               char *wikipage = NULL;
                StrBuf *CmdBuf = NULL;
                const char CMD[] = "ENT0 0|%s|%d|0||%s||%s|%s|%s";
                
                Recp = sbstr("recp");
                Cc = sbstr("cc");
                Bcc = sbstr("bcc");
-               Wikipage = sbstr("page");
+               wikipage = strdup(bstr("page"));
+               str_wiki_index(wikipage);
                
                CmdBuf = NewStrBufPlain(NULL, 
                                        sizeof (CMD) + 
@@ -1578,7 +1591,7 @@ void display_enter(void)
                                        StrLength(display_name) +
                                        StrLength(Cc) +
                                        StrLength(Bcc) + 
-                                       StrLength(Wikipage));
+                                       strlen(wikipage));
 
                StrBufPrintf(CmdBuf, 
                             CMD,
@@ -1587,9 +1600,11 @@ void display_enter(void)
                             ChrPtr(display_name),
                             ChrPtr(Cc), 
                             ChrPtr(Bcc), 
-                            ChrPtr(Wikipage));
+                            wikipage
+               );
                serv_puts(ChrPtr(CmdBuf));
                StrBuf_ServGetln(CmdBuf);
+               free(wikipage);
 
                rc = GetServerStatusMsg(CmdBuf, &Result, 0, 0);
 
@@ -1719,6 +1734,7 @@ void postpart(StrBuf *partnum, StrBuf *filename, int force_download)
 void mimepart(int force_download)
 {
        long msgnum;
+       long ErrorDetail;
        StrBuf *att;
        wcsession *WCC = WC;
        StrBuf *Buf;
@@ -1732,7 +1748,7 @@ void mimepart(int force_download)
 
        serv_printf("OPNA %ld|%s", msgnum, ChrPtr(att));
        StrBuf_ServGetln(Buf);
-       if (GetServerStatus(Buf, NULL) == 2) {
+       if (GetServerStatus(Buf, &ErrorDetail) == 2) {
                StrBufCutLeft(Buf, 4);
                bytes = StrBufExtract_long(Buf, 0, '|');
                if (!force_download) {
@@ -1756,7 +1772,23 @@ void mimepart(int force_download)
                http_transmit_thing(CT, 0);
        } else {
                StrBufCutLeft(Buf, 4);
-               hprintf("HTTP/1.1 404 %s\n", ChrPtr(Buf));
+               switch (ErrorDetail) {
+               default:
+               case ERROR + MESSAGE_NOT_FOUND:
+                       hprintf("HTTP/1.1 404 %s\n", ChrPtr(Buf));
+                       break;
+               case ERROR + NOT_LOGGED_IN:
+                       hprintf("HTTP/1.1 401 %s\n", ChrPtr(Buf));
+                       break;
+
+               case ERROR + HIGHER_ACCESS_REQUIRED:
+                       hprintf("HTTP/1.1 403 %s\n", ChrPtr(Buf));
+                       break;
+               case ERROR + INTERNAL_ERROR:
+               case ERROR + TOO_BIG:
+                       hprintf("HTTP/1.1 500 %s\n", ChrPtr(Buf));
+                       break;
+               }
                output_headers(0, 0, 0, 0, 0, 0);
                hprintf("Content-Type: text/plain\r\n");
                begin_burst();
@@ -1875,31 +1907,23 @@ void h_do_search(void) { readloop(do_search, eUseDefault);}
 void h_readgt(void) { readloop(readgt, eUseDefault);}
 void h_readlt(void) { readloop(readlt, eUseDefault);}
 
-void jsonMessageListHdr(void) 
-{
-       /* TODO: make a generic function */
-       hprintf("HTTP/1.1 200 OK\r\n");
-       hprintf("Content-type: application/json; charset=utf-8\r\n");
-       hprintf("Server: %s / %s\r\n", PACKAGE_STRING, ChrPtr(WC->serv_info->serv_software));
-       hprintf("Connection: close\r\n");
-       hprintf("Pragma: no-cache\r\nCache-Control: no-store\r\nExpires:-1\r\n");
-       begin_burst();
-}
 
 
 /* Output message list in JSON format */
 void jsonMessageList(void) {
+       StrBuf *View = NewStrBuf();
        const StrBuf *room = sbstr("room");
        long oper = (havebstr("query")) ? do_search : readnew;
-       WC->is_ajax = 1; 
+       StrBufPrintf(View, "%d", VIEW_JSON_LIST);
+       putbstr("view", View);; 
        gotoroom(room);
        readloop(oper, eUseDefault);
-       WC->is_ajax = 0;
 }
 
 void RegisterReadLoopHandlerset(
        int RoomType,
        GetParamsGetServerCall_func GetParamsGetServerCall,
+       PrintViewHeader_func PrintPageHeader,
        PrintViewHeader_func PrintViewHeader,
        load_msg_ptrs_detailheaders LH,
        LoadMsgFromServer_func LoadMsgFromServer,
@@ -1913,6 +1937,7 @@ void RegisterReadLoopHandlerset(
 
        Handler->RoomType = RoomType;
        Handler->GetParamsGetServerCall = GetParamsGetServerCall;
+       Handler->PrintPageHeader = PrintPageHeader;
        Handler->PrintViewHeader = PrintViewHeader;
        Handler->LoadMsgFromServer = LoadMsgFromServer;
        Handler->RenderView_or_Tail = RenderView_or_Tail;