X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fdownloads.c;h=60783c5685cad880b94c1f877dc821c473891218;hb=fb6f6fa4ec4e3277e30d84326d48e6850822d318;hp=ed78c74c6bdfc07a188b45bbcea8440230d5ac6f;hpb=67917357773bfa5975de311d325dd3414c720a09;p=citadel.git diff --git a/webcit/downloads.c b/webcit/downloads.c index ed78c74c6..60783c568 100644 --- a/webcit/downloads.c +++ b/webcit/downloads.c @@ -1,9 +1,20 @@ /* - * $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" +extern void output_static(const char* What); + extern char* static_dirs[]; typedef struct _FileListStruct { @@ -25,32 +36,32 @@ void FreeFiles(void *vFile) } /* -------------------------------------------------------------------------------- */ -void tmplput_FILE_NAME(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType) +void tmplput_FILE_NAME(StrBuf *Target, WCTemplputParams *TP) { - FileListStruct *F = (FileListStruct*) Context; - StrBufAppendTemplate(Target, nArgs, Tokens, Context, ContextType, F->Filename, 0); + FileListStruct *F = (FileListStruct*) CTX; + StrBufAppendTemplate(Target, TP, F->Filename, 0); } -void tmplput_FILE_SIZE(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType) +void tmplput_FILE_SIZE(StrBuf *Target, WCTemplputParams *TP) { - FileListStruct *F = (FileListStruct*) Context; + FileListStruct *F = (FileListStruct*) CTX; StrBufAppendPrintf(Target, "%ld", F->FileSize); } -void tmplput_FILEMIMETYPE(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType) +void tmplput_FILEMIMETYPE(StrBuf *Target, WCTemplputParams *TP) { - FileListStruct *F = (FileListStruct*) Context; - StrBufAppendTemplate(Target, nArgs, Tokens, Context, ContextType, F->MimeType, 0); + FileListStruct *F = (FileListStruct*) CTX; + StrBufAppendTemplate(Target, TP, F->MimeType, 0); } -void tmplput_FILE_COMMENT(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType) +void tmplput_FILE_COMMENT(StrBuf *Target, WCTemplputParams *TP) { - FileListStruct *F = (FileListStruct*) Context; - StrBufAppendTemplate(Target, nArgs, Tokens, Context, ContextType, F->Comment, 0); + FileListStruct *F = (FileListStruct*) CTX; + StrBufAppendTemplate(Target, TP, F->Comment, 0); } /* -------------------------------------------------------------------------------- */ -int Conditional_FILE_ISPIC(WCTemplateToken *Tokens, void *Context, int ContextType) +int Conditional_FILE_ISPIC(StrBuf *Target, WCTemplputParams *TP) { - FileListStruct *F = (FileListStruct*) Context; + FileListStruct *F = (FileListStruct*) CTX; return F->IsPic; } @@ -163,7 +174,7 @@ int GroupchangeFilelistBySequence(const void *vFile1, const void *vFile2) } /* -------------------------------------------------------------------------------- */ -HashList* LoadFileList(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType) +HashList* LoadFileList(StrBuf *Target, WCTemplputParams *TP) { FileListStruct *Entry; StrBuf *Buf; @@ -172,8 +183,10 @@ HashList* LoadFileList(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void int sequence = 0; char buf[1024]; CompareFunc SortIt; - int HavePic; + int HavePic = 0; + WCTemplputParams SubTP; + memset(&SubTP, 0, sizeof(WCTemplputParams)); serv_puts("RDIR"); serv_getln(buf, sizeof buf); if (buf[0] != '1') return NULL; @@ -208,13 +221,15 @@ HashList* LoadFileList(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void } Put(Files, SKEY(Entry->Filename), Entry, FreeFiles); } - SortIt = RetrieveSort(CTX_FILELIST, 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; } @@ -229,7 +244,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); @@ -237,59 +252,88 @@ 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"); + 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, '|'); + if (!force_download) { + StrBufExtract_token(ContentType, Buf, 3, '|'); } - 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); + serv_read_binary(WCC->WBuf, bytes, Buf); serv_puts("CLOS"); - serv_getln(buf, sizeof buf); - http_transmit_thing(content_type, 0); - free(content); + StrBuf_ServGetln(Buf); + http_transmit_thing(ChrPtr(ContentType), 0); } 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; } @@ -301,19 +345,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); } @@ -324,41 +371,49 @@ 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)) { 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. */ - snprintf (blank_gif, SIZ, "%s%s", static_dirs[0], "/blank.gif"); - output_static(blank_gif); + StrBufPrintf (Buf, "%s%s", static_dirs[0], "/webcit_icons/blank.gif"); + output_static(ChrPtr(Buf)); + FreeStrBuf(&Buf); } void @@ -401,15 +456,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); - 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); }