X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fdownloads.c;fp=webcit%2Fdownloads.c;h=0000000000000000000000000000000000000000;hb=76a0f8571de023fe6bd20390174a2302e0a0b982;hp=6e6c9b981b5ebf0acf8bc46dc664fc9630956acd;hpb=50511759c152f4ca2e22fb39a9bf31fc9f9d916d;p=citadel.git diff --git a/webcit/downloads.c b/webcit/downloads.c deleted file mode 100644 index 6e6c9b981..000000000 --- a/webcit/downloads.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * 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[]; - -typedef struct _FileListStruct { - StrBuf *Filename; - long FileSize; - StrBuf *MimeType; - StrBuf *Comment; - int IsPic; - int Sequence; -} FileListStruct; - -void FreeFiles(void *vFile) -{ - FileListStruct *F = (FileListStruct*) vFile; - FreeStrBuf(&F->Filename); - FreeStrBuf(&F->MimeType); - FreeStrBuf(&F->Comment); - free(F); -} - -/* -------------------------------------------------------------------------------- */ -void tmplput_FILE_NAME(StrBuf *Target, WCTemplputParams *TP) -{ - FileListStruct *F = (FileListStruct*) CTX(CTX_FILELIST); - StrBufAppendTemplate(Target, TP, F->Filename, 0); -} -void tmplput_FILE_SIZE(StrBuf *Target, WCTemplputParams *TP) -{ - FileListStruct *F = (FileListStruct*) CTX(CTX_FILELIST); - StrBufAppendPrintf(Target, "%ld", F->FileSize); -} -void tmplput_FILEMIMETYPE(StrBuf *Target, WCTemplputParams *TP) -{ - FileListStruct *F = (FileListStruct*) CTX(CTX_FILELIST); - StrBufAppendTemplate(Target, TP, F->MimeType, 0); -} -void tmplput_FILE_COMMENT(StrBuf *Target, WCTemplputParams *TP) -{ - FileListStruct *F = (FileListStruct*) CTX(CTX_FILELIST); - StrBufAppendTemplate(Target, TP, F->Comment, 0); -} - -/* -------------------------------------------------------------------------------- */ - -int Conditional_FILE_ISPIC(StrBuf *Target, WCTemplputParams *TP) -{ - FileListStruct *F = (FileListStruct*) CTX(CTX_FILELIST); - return F->IsPic; -} - -/* -------------------------------------------------------------------------------- */ -int CompareFilelistByMime(const void *vFile1, const void *vFile2) -{ - FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1); - FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2); - - if (File1->IsPic != File2->IsPic) - return File1->IsPic > File2->IsPic; - return strcasecmp(ChrPtr(File1->MimeType), ChrPtr(File2->MimeType)); -} -int CompareFilelistByMimeRev(const void *vFile1, const void *vFile2) -{ - FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1); - FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2); - if (File1->IsPic != File2->IsPic) - return File1->IsPic < File2->IsPic; - return strcasecmp(ChrPtr(File2->MimeType), ChrPtr(File1->MimeType)); -} -int GroupchangeFilelistByMime(const void *vFile1, const void *vFile2) -{ - FileListStruct *File1 = (FileListStruct*) vFile1; - FileListStruct *File2 = (FileListStruct*) vFile2; - - if (File1->IsPic != File2->IsPic) - return File1->IsPic > File2->IsPic; - return strcasecmp(ChrPtr(File1->MimeType), ChrPtr(File2->MimeType)) != 0; -} - - -int CompareFilelistByName(const void *vFile1, const void *vFile2) -{ - FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1); - FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2); - - if (File1->IsPic != File2->IsPic) - return File1->IsPic > File2->IsPic; - return strcasecmp(ChrPtr(File1->Filename), ChrPtr(File2->Filename)); -} -int CompareFilelistByNameRev(const void *vFile1, const void *vFile2) -{ - FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1); - FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2); - if (File1->IsPic != File2->IsPic) - return File1->IsPic < File2->IsPic; - return strcasecmp(ChrPtr(File2->Filename), ChrPtr(File1->Filename)); -} -int GroupchangeFilelistByName(const void *vFile1, const void *vFile2) -{ - FileListStruct *File1 = (FileListStruct*) vFile1; - FileListStruct *File2 = (FileListStruct*) vFile2; - - return ChrPtr(File1->Filename)[0] != ChrPtr(File2->Filename)[0]; -} - - -int CompareFilelistBySize(const void *vFile1, const void *vFile2) -{ - FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1); - FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2); - if (File1->FileSize == File2->FileSize) - return 0; - return (File1->FileSize > File2->FileSize); -} -int CompareFilelistBySizeRev(const void *vFile1, const void *vFile2) -{ - FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1); - FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2); - if (File1->FileSize == File2->FileSize) - return 0; - return (File1->FileSize < File2->FileSize); -} -int GroupchangeFilelistBySize(const void *vFile1, const void *vFile2) -{ - return 0; -} - - -int CompareFilelistByComment(const void *vFile1, const void *vFile2) -{ - FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1); - FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2); - return strcasecmp(ChrPtr(File1->Comment), ChrPtr(File2->Comment)); -} -int CompareFilelistByCommentRev(const void *vFile1, const void *vFile2) -{ - FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1); - FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2); - return strcasecmp(ChrPtr(File2->Comment), ChrPtr(File1->Comment)); -} -int GroupchangeFilelistByComment(const void *vFile1, const void *vFile2) -{ - FileListStruct *File1 = (FileListStruct*) vFile1; - FileListStruct *File2 = (FileListStruct*) vFile2; - return ChrPtr(File1->Comment)[9] != ChrPtr(File2->Comment)[0]; -} - - -int CompareFilelistBySequence(const void *vFile1, const void *vFile2) -{ - FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1); - FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2); - return (File2->Sequence > File1->Sequence); -} -int GroupchangeFilelistBySequence(const void *vFile1, const void *vFile2) -{ - return 0; -} - -/* -------------------------------------------------------------------------------- */ -HashList* LoadFileList(StrBuf *Target, WCTemplputParams *TP) -{ - FileListStruct *Entry; - StrBuf *Buf; - HashList *Files; - int Done = 0; - int sequence = 0; - char buf[1024]; - CompareFunc SortIt; - int HavePic = 0; - WCTemplputParams SubTP; - - memset(&SubTP, 0, sizeof(WCTemplputParams)); - serv_puts("RDIR"); - serv_getln(buf, sizeof buf); - if (buf[0] != '1') return NULL; - - Buf = NewStrBuf(); - Files = NewHash(1, NULL); - while (!Done && (StrBuf_ServGetln(Buf)>=0)) { - if ( (StrLength(Buf)==3) && - !strcmp(ChrPtr(Buf), "000")) - { - Done = 1; - continue; - } - - Entry = (FileListStruct*) malloc(sizeof (FileListStruct)); - Entry->Filename = NewStrBufPlain(NULL, StrLength(Buf)); - Entry->MimeType = NewStrBufPlain(NULL, StrLength(Buf)); - Entry->Comment = NewStrBufPlain(NULL, StrLength(Buf)); - - Entry->Sequence = sequence++; - - StrBufExtract_token(Entry->Filename, Buf, 0, '|'); - Entry->FileSize = StrBufExtract_long(Buf, 1, '|'); - StrBufExtract_token(Entry->MimeType, Buf, 2, '|'); - StrBufExtract_token(Entry->Comment, Buf, 3, '|'); - - - - Entry->IsPic = (strstr(ChrPtr(Entry->MimeType), "image") != NULL); - if (Entry->IsPic) { - HavePic = 1; - } - Put(Files, SKEY(Entry->Filename), Entry, FreeFiles); - } - 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); - return Files; -} - -void display_mime_icon(void) -{ - char FileBuf[SIZ]; - const char *FileName; - char *MimeType; - size_t tlen; - - MimeType = xbstr("type", &tlen); - FileName = GetIconFilename(MimeType, tlen); - - if (FileName == NULL) - 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); -} - -void download_file(void) -{ - wcsession *WCC = WC; - StrBuf *Buf; - off_t bytes; - StrBuf *ContentType = NewStrBufPlain(HKEY("application/octet-stream")); - - /* Setting to nonzero forces a MIME type of application/octet-stream */ - int force_download = 1; - - 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"); - StrBuf_ServGetln(Buf); - } else { - 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"); - 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; - 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(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; - } - - while (bytes_transmitted < WCC->upload_length) - { - blocksize = 4096; - if (blocksize > (WCC->upload_length - bytes_transmitted)) - { - blocksize = (WCC->upload_length - bytes_transmitted); - } - serv_printf("WRIT %ld", 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"); - StrBuf_ServGetln(Line); - GetServerStatusMsg(Line, NULL, 1, 0); - RetMimeType = DoTemplate(HKEY("files"), NULL, &NoCtx); - http_transmit_thing(ChrPtr(RetMimeType), 0); - FreeStrBuf(&Line); -} - - - -/* - * When the browser requests an image file from the Citadel server, - * this function is called to transmit it. - */ -void output_image(void) -{ - StrBuf *Buf; - wcsession *WCC = WC; - off_t bytes; - const char *MimeType; - - Buf = NewStrBuf(); - serv_printf("OIMG %s|%s", bstr("name"), bstr("parm")); - StrBuf_ServGetln(Buf); - if (GetServerStatus(Buf, NULL) == 2) { - int rc; - StrBufCutLeft(Buf, 4); - bytes = StrBufExtract_long(Buf, 0, '|'); - - /** Read it from the server */ - - 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. - */ - StrBufPrintf (Buf, "%s%s", static_dirs[0], "/webcit_icons/blank.gif"); - output_static(ChrPtr(Buf)); - FreeStrBuf(&Buf); -} - -void -InitModule_DOWNLOAD -(void) -{ - RegisterCTX(CTX_FILELIST); - - RegisterIterator("ROOM:FILES", 0, NULL, LoadFileList, - NULL, DeleteHash, CTX_FILELIST, CTX_NONE, - IT_FLAG_DETECT_GROUPCHANGE); - - RegisterSortFunc(HKEY("filemime"), - NULL, 0, - CompareFilelistByMime, - CompareFilelistByMimeRev, - GroupchangeFilelistByMime, - CTX_FILELIST); - RegisterSortFunc(HKEY("filename"), - NULL, 0, - CompareFilelistByName, - CompareFilelistByNameRev, - GroupchangeFilelistByName, - CTX_FILELIST); - RegisterSortFunc(HKEY("filesize"), - NULL, 0, - CompareFilelistBySize, - CompareFilelistBySizeRev, - GroupchangeFilelistBySize, - CTX_FILELIST); - RegisterSortFunc(HKEY("filesubject"), - NULL, 0, - CompareFilelistByComment, - CompareFilelistByCommentRev, - GroupchangeFilelistByComment, - CTX_FILELIST); - RegisterSortFunc(HKEY("fileunsorted"), - NULL, 0, - CompareFilelistBySequence, - CompareFilelistBySequence, - GroupchangeFilelistBySequence, - 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("COND:FILE:ISPIC", 0, Conditional_FILE_ISPIC, CTX_FILELIST); - - 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); -}