Integrated the DKIM signer into serv_smtpclient, but disabled it
[citadel.git] / webcit / downloads.c
index ea6ad4d9b218c5befe7c4233b394106bef2f51c2..9b7dde993c47f254174d3040a2540292ece34b3a 100644 (file)
@@ -1,8 +1,21 @@
 /*
- * $Id$
+ * 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, 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.
  */
+
 #include "webcit.h"
-#include "webserver.h"
+
+
+CtxType CTX_FILELIST = CTX_NONE;
+
+extern void output_static(const char* What);
 
 extern char* static_dirs[];
 
@@ -27,22 +40,22 @@ void FreeFiles(void *vFile)
 /* -------------------------------------------------------------------------------- */
 void tmplput_FILE_NAME(StrBuf *Target, WCTemplputParams *TP)
 {
-       FileListStruct *F = (FileListStruct*) CTX;
+       FileListStruct *F = (FileListStruct*) CTX(CTX_FILELIST);
        StrBufAppendTemplate(Target, TP, F->Filename, 0);
 }
 void tmplput_FILE_SIZE(StrBuf *Target, WCTemplputParams *TP)
 {
-       FileListStruct *F = (FileListStruct*) CTX;
+       FileListStruct *F = (FileListStruct*) CTX(CTX_FILELIST);
        StrBufAppendPrintf(Target, "%ld", F->FileSize);
 }
 void tmplput_FILEMIMETYPE(StrBuf *Target, WCTemplputParams *TP)
 {
-       FileListStruct *F = (FileListStruct*) CTX;
+       FileListStruct *F = (FileListStruct*) CTX(CTX_FILELIST);
        StrBufAppendTemplate(Target, TP, F->MimeType, 0);
 }
 void tmplput_FILE_COMMENT(StrBuf *Target, WCTemplputParams *TP)
 {
-       FileListStruct *F = (FileListStruct*) CTX;
+       FileListStruct *F = (FileListStruct*) CTX(CTX_FILELIST);
        StrBufAppendTemplate(Target, TP, F->Comment, 0);
 }
 
@@ -50,7 +63,7 @@ void tmplput_FILE_COMMENT(StrBuf *Target, WCTemplputParams *TP)
 
 int Conditional_FILE_ISPIC(StrBuf *Target, WCTemplputParams *TP)
 {
-       FileListStruct *F = (FileListStruct*) CTX;
+       FileListStruct *F = (FileListStruct*) CTX(CTX_FILELIST);
        return F->IsPic;
 }
 
@@ -172,10 +185,10 @@ HashList* LoadFileList(StrBuf *Target, WCTemplputParams *TP)
        int sequence = 0;
        char buf[1024];
        CompareFunc SortIt;
-       int HavePic;
+       int HavePic = 0;
        WCTemplputParams SubTP;
 
-       memset(&TP, 0, sizeof(WCTemplputParams));
+       memset(&SubTP, 0, sizeof(WCTemplputParams));
        serv_puts("RDIR");
        serv_getln(buf, sizeof buf);
        if (buf[0] != '1') return NULL;
@@ -210,14 +223,15 @@ HashList* LoadFileList(StrBuf *Target, WCTemplputParams *TP)
                }
                Put(Files, SKEY(Entry->Filename), Entry, FreeFiles);
        }
-       SubTP.ContextType = CTX_FILELIST;
-       SortIt = RetrieveSort(&SubTP, NULL, HKEY("fileunsorted"), 0);
+       if (HavePic)
+               putbstr("__HAVE_PIC", NewStrBufPlain(HKEY("1")));
+       SubTP.Filter.ContextType = CTX_FILELIST;
+       SortIt = RetrieveSort(&SubTP, NULL, 0, HKEY("fileunsorted"), 0);
        if (SortIt != NULL)
                SortByPayload(Files, SortIt);
        else 
                SortByPayload(Files, CompareFilelistBySequence);
        FreeStrBuf(&Buf);
-       svputlong("FILE:HAVEPICS", HavePic);
        return Files;
 }
 
@@ -232,7 +246,7 @@ void display_mime_icon(void)
        FileName = GetIconFilename(MimeType, tlen);
 
        if (FileName == NULL)
-               snprintf (FileBuf, SIZ, "%s%s", static_dirs[0], "/diskette_24x.gif");
+               snprintf (FileBuf, SIZ, "%s%s", static_dirs[0], "/webcit_icons/essen/16x16/file.png");
        else
                snprintf (FileBuf, SIZ, "%s%s", static_dirs[3], FileName);
        output_static(FileBuf);
@@ -240,59 +254,90 @@ void display_mime_icon(void)
 
 void download_file(void)
 {
-       char buf[256];
+       wcsession *WCC = WC;
+       StrBuf *Buf;
        off_t bytes;
-       char content_type[256];
-       char *content = NULL;
+       StrBuf *ContentType = NewStrBufPlain(HKEY("application/octet-stream"));
 
        /* Setting to nonzero forces a MIME type of application/octet-stream */
        int force_download = 1;
        
-       safestrncpy(buf, ChrPtr(WC->UrlFragment2), sizeof buf);
-       unescape_input(buf);
-       serv_printf("OPEN %s", buf);
-       serv_getln(buf, sizeof buf);
-       if (buf[0] == '2') {
-               bytes = extract_long(&buf[4], 0);
-               content = malloc(bytes + 2);
-               if (force_download) {
-                       strcpy(content_type, "application/octet-stream");
-               }
-               else {
-                       extract_token(content_type, &buf[4], 3, '|', sizeof content_type);
-               }
-               output_headers(0, 0, 0, 0, 0, 0);
-               read_server_binary(WC->WBuf, bytes);
+       Buf = NewStrBuf();
+       StrBufExtract_token(Buf, WCC->Hdr->HR.ReqLine, 0, '/');
+       StrBufUnescape(Buf, 1);
+       serv_printf("OPEN %s", ChrPtr(Buf));
+       StrBuf_ServGetln(Buf);
+       if (GetServerStatus(Buf, NULL) == 2) {
+               StrBufCutLeft(Buf, 4);
+               bytes = StrBufExtract_long(Buf, 0, '|');
+               StrBufExtract_token(ContentType, Buf, 3, '|');
+
+               CheckGZipCompressionAllowed (SKEY(ContentType));
+               if (force_download)
+                       FlushStrBuf(ContentType);
+
+               serv_read_binary_to_http(ContentType, bytes, 0, 0);
                serv_puts("CLOS");
-               serv_getln(buf, sizeof buf);
-               http_transmit_thing(content_type, 0);
-               free(content);
+               StrBuf_ServGetln(Buf);
        } else {
-               hprintf("HTTP/1.1 404 %s\n", &buf[4]);
+               StrBufCutLeft(Buf, 4);
+               hprintf("HTTP/1.1 404 %s\n", ChrPtr(Buf));
                output_headers(0, 0, 0, 0, 0, 0);
                hprintf("Content-Type: text/plain\r\n");
-               wprintf(_("An error occurred while retrieving this file: %s\n"), &buf[4]);
+               wc_printf(_("An error occurred while retrieving this file: %s\n"), 
+                       ChrPtr(Buf));
                end_burst();
        }
+       FreeStrBuf(&ContentType);
+       FreeStrBuf(&Buf);
+}
+
+
+
+void delete_file(void)
+{
+       const StrBuf *MimeType;
+       StrBuf *Line;
+       char buf[256];
+       
+       safestrncpy(buf, bstr("file"), sizeof buf);
+       unescape_input(buf);
+       serv_printf("DELF %s", buf);
+
+       StrBuf_ServGetln(Line);
+       GetServerStatusMsg(Line, NULL, 1, 0);
+
+       MimeType = DoTemplate(HKEY("files"), NULL, &NoCtx);
+       http_transmit_thing(ChrPtr(MimeType), 0);
+       FreeStrBuf(&Line);
 }
 
 
 
 void upload_file(void)
 {
+       const StrBuf *RetMimeType;
        const char *MimeType;
-       char buf[1024];
+       StrBuf *Line;
        long bytes_transmitted = 0;
        long blocksize;
+       const StrBuf *Desc;
        wcsession *WCC = WC;     /* stack this for faster access (WC is a function) */
 
-       MimeType = GuessMimeType(WCC->upload, WCC->upload_length); 
-       serv_printf("UOPN %s|%s|%s", WCC->upload_filename, MimeType, bstr("description"));
-       serv_getln(buf, sizeof buf);
-       if (buf[0] != '2')
-       {
-               strcpy(WCC->ImportantMessage, &buf[4]);
-               do_template("files", NULL);
+       MimeType = GuessMimeType(ChrPtr(WCC->upload), WCC->upload_length); 
+
+               Desc = sbstr("description");
+
+       serv_printf("UOPN %s|%s|%s", 
+                   ChrPtr(WCC->upload_filename), 
+                   MimeType, 
+                   ChrPtr(Desc));
+       Line = NewStrBuf();
+       StrBuf_ServGetln(Line);
+       if (GetServerStatusMsg(Line, NULL, 1, 2) != 2) {
+               RetMimeType = DoTemplate(HKEY("files"), NULL, &NoCtx);
+               http_transmit_thing(ChrPtr(RetMimeType), 0);
+               FreeStrBuf(&Line);
                return;
        }
 
@@ -304,19 +349,22 @@ void upload_file(void)
                        blocksize = (WCC->upload_length - bytes_transmitted);
                }
                serv_printf("WRIT %ld", blocksize);
-               serv_getln(buf, sizeof buf);
-               if (buf[0] == '7')
-               {
-                       blocksize = atoi(&buf[4]);
-                       serv_write(&WCC->upload[bytes_transmitted], blocksize);
+               StrBuf_ServGetln(Line);
+               if (GetServerStatusMsg(Line, NULL, 0, 0) == 7) {
+                       blocksize = atoi(ChrPtr(Line) + 4);
+                       serv_write(&ChrPtr(WCC->upload)[bytes_transmitted], blocksize);
                        bytes_transmitted += blocksize;
                }
+               else
+                       break;
        }
 
        serv_puts("UCLS 1");
-       serv_getln(buf, sizeof buf);
-       strcpy(WCC->ImportantMessage, &buf[4]);
-       do_template("files", CTX_NONE);
+       StrBuf_ServGetln(Line);
+       GetServerStatusMsg(Line, NULL, 1, 0);
+       RetMimeType = DoTemplate(HKEY("files"), NULL, &NoCtx);
+       http_transmit_thing(ChrPtr(RetMimeType), 0);
+       FreeStrBuf(&Line);
 }
 
 
@@ -327,47 +375,56 @@ void upload_file(void)
  */
 void output_image(void)
 {
-       char blank_gif[SIZ];
+       StrBuf *Buf;
        wcsession *WCC = WC;
-       char buf[SIZ];
        off_t bytes;
        const char *MimeType;
        
+       Buf = NewStrBuf();
        serv_printf("OIMG %s|%s", bstr("name"), bstr("parm"));
-       serv_getln(buf, sizeof buf);
-       if (buf[0] == '2') {
-               bytes = extract_long(&buf[4], 0);
+       StrBuf_ServGetln(Buf);
+       if (GetServerStatus(Buf, NULL) == 2) {
+               int rc;
+               StrBufCutLeft(Buf, 4);
+               bytes = StrBufExtract_long(Buf, 0, '|');
 
                /** Read it from the server */
                
-               if (read_server_binary(WCC->WBuf, bytes) > 0) {
-                       serv_puts("CLOS");
-                       serv_getln(buf, sizeof buf);
+               rc = serv_read_binary(WCC->WBuf, bytes, Buf);
+               serv_puts("CLOS");
+               StrBuf_ServGetln(Buf);
                
+               if (rc > 0) {
                        MimeType = GuessMimeType (ChrPtr(WCC->WBuf), StrLength(WCC->WBuf));
                        /** Write it to the browser */
                        if (!IsEmptyStr(MimeType))
                        {
+                               CheckGZipCompressionAllowed (MimeType, strlen(MimeType));
                                http_transmit_thing(MimeType, 0);
+                               FreeStrBuf(&Buf);
                                return;
                        }
                }
                /* hm... unknown mimetype? fallback to blank gif */
-       } 
+       }
+       else { 
+               syslog(LOG_DEBUG, "OIMG failed: %s", ChrPtr(Buf));
+       }
 
        
        /*
         * Instead of an ugly 404, send a 1x1 transparent GIF
-        * when there's no such image on the server.
+        * when there's no such image on the server display blank
         */
-       snprintf (blank_gif, SIZ, "%s%s", static_dirs[0], "/blank.gif");
-       output_static(blank_gif);
+       output_static(NULL);
+       FreeStrBuf(&Buf);
 }
 
 void 
 InitModule_DOWNLOAD
 (void)
 {
+       RegisterCTX(CTX_FILELIST);
 
        RegisterIterator("ROOM:FILES", 0, NULL, LoadFileList,
                         NULL, DeleteHash, CTX_FILELIST, CTX_NONE, 
@@ -404,15 +461,16 @@ InitModule_DOWNLOAD
                         GroupchangeFilelistBySequence,
                         CTX_FILELIST);
 
-       RegisterNamespace("FILE:NAME", 0, 2, tmplput_FILE_NAME, CTX_FILELIST);
-       RegisterNamespace("FILE:SIZE", 0, 1, tmplput_FILE_SIZE, CTX_FILELIST);
-       RegisterNamespace("FILE:MIMETYPE", 0, 2, tmplput_FILEMIMETYPE, CTX_FILELIST);
-       RegisterNamespace("FILE:COMMENT", 0, 2, tmplput_FILE_COMMENT, CTX_FILELIST);
+       RegisterNamespace("FILE:NAME", 0, 2, tmplput_FILE_NAME, NULL, CTX_FILELIST);
+       RegisterNamespace("FILE:SIZE", 0, 1, tmplput_FILE_SIZE, NULL, CTX_FILELIST);
+       RegisterNamespace("FILE:MIMETYPE", 0, 2, tmplput_FILEMIMETYPE, NULL, CTX_FILELIST);
+       RegisterNamespace("FILE:COMMENT", 0, 2, tmplput_FILE_COMMENT, NULL, CTX_FILELIST);
 
-       RegisterConditional(HKEY("COND:FILE:ISPIC"), 0, Conditional_FILE_ISPIC, CTX_FILELIST);
+       RegisterConditional("COND:FILE:ISPIC", 0, Conditional_FILE_ISPIC, CTX_FILELIST);
 
-       WebcitAddUrlHandler(HKEY("image"), output_image, 0);
-       WebcitAddUrlHandler(HKEY("display_mime_icon"), display_mime_icon , 0);
-       WebcitAddUrlHandler(HKEY("download_file"), download_file, NEED_URL);
-       WebcitAddUrlHandler(HKEY("upload_file"), upload_file, 0);
+       WebcitAddUrlHandler(HKEY("image"), "", 0, output_image, ANONYMOUS);
+       WebcitAddUrlHandler(HKEY("display_mime_icon"), "", 0, display_mime_icon , ANONYMOUS);
+       WebcitAddUrlHandler(HKEY("download_file"), "", 0, download_file, NEED_URL);
+       WebcitAddUrlHandler(HKEY("delete_file"), "", 0, delete_file, NEED_URL);
+       WebcitAddUrlHandler(HKEY("upload_file"), "", 0, upload_file, 0);
 }