/*
- * $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[];
+
typedef struct _FileListStruct {
- char Filename[256];
- int FilenameLen;
+ StrBuf *Filename;
long FileSize;
- char MimeType[64];
- int MimeTypeLen;
- char Comment[512];
- int CommentLen;
+ StrBuf *MimeType;
+ StrBuf *Comment;
int IsPic;
int Sequence;
-}FileListStruct;
+} 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);
if (File1->IsPic != File2->IsPic)
return File1->IsPic > File2->IsPic;
- return strcasecmp(File1->MimeType, File2->MimeType);
+ return strcasecmp(ChrPtr(File1->MimeType), ChrPtr(File2->MimeType));
}
int CompareFilelistByMimeRev(const void *vFile1, const void *vFile2)
{
FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2);
if (File1->IsPic != File2->IsPic)
return File1->IsPic < File2->IsPic;
- return strcasecmp(File2->MimeType, File1->MimeType);
+ 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);
return 0;
return (File1->FileSize > File2->FileSize);
}
-
int CompareFilelistBySizeRev(const void *vFile1, const void *vFile2)
{
FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1);
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(File1->Comment, File2->Comment);
+ 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(File2->Comment, File1->Comment);
+ 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 *File2 = (FileListStruct*) GetSearchPayload(vFile2);
return (File2->Sequence > File1->Sequence);
}
+int GroupchangeFilelistBySequence(const void *vFile1, const void *vFile2)
+{
+ return 0;
+}
-HashList* LoadFileList(int *HavePic)
+/* -------------------------------------------------------------------------------- */
+HashList* LoadFileList(StrBuf *Target, WCTemplputParams *TP)
{
FileListStruct *Entry;
+ StrBuf *Buf;
HashList *Files;
- int HavePics = 0;
- int Order;
+ 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') {
- Files = NewHash(1, NULL);
- while (serv_getln(buf, sizeof buf), strcmp(buf, "000"))
- {
- Entry = (FileListStruct*) malloc(sizeof (FileListStruct));
-
- Entry->FilenameLen = extract_token(
- Entry->Filename, buf, 0, '|',
- sizeof(Entry->Filename));
- Entry->FileSize = extract_long(buf, 1);
- Entry->MimeTypeLen = extract_token(
- Entry->MimeType, buf, 2, '|',
- sizeof(Entry->MimeType));
- Entry->CommentLen = extract_token(
- Entry->Comment, buf, 3, '|',
- sizeof(Entry->Comment));
-
- Entry->Sequence = sequence++;
- Entry->IsPic = (strstr(Entry->MimeType, "image") != NULL);
- if (!HavePics && Entry->IsPic) {
- HavePics = 1;
- *HavePic = 1;
- }
- Put(Files, Entry->Filename,
- Entry->FilenameLen,
- Entry, NULL);
- }
- Order = ibstr("SortOrder");
- switch (ibstr("SortBy")){
- case 1: /*NAME*/
- SortByHashKey(Files,Order);
- break;
- case 2: /* SIZE*/
- SortByPayload(Files, (Order)?
- CompareFilelistBySize:
- CompareFilelistBySizeRev);
- break;
- case 3: /*MIME*/
- SortByPayload(Files, (Order)?
- CompareFilelistByMime:
- CompareFilelistByMimeRev);
- break;
- case 4: /*COMM*/
- SortByPayload(Files, (Order)?
- CompareFilelistByComment:
- CompareFilelistByCommentRev);
- break;
- default:
- SortByPayload(Files, CompareFilelistBySequence);
- }
- return Files;
- }
- else
- return NULL;
-}
+ if (buf[0] != '1') return NULL;
-void FilePrintEntry(const char *FileName, void *vFile, int odd)
-{
- FileListStruct *File = (FileListStruct*) vFile;
-
- wprintf("<tr bgcolor=\"#%s\">", (odd ? "DDDDDD" : "FFFFFF"));
- wprintf("<td>"
- "<a href=\"download_file/");
- urlescputs(File->Filename);
- wprintf("\"><img src=\"display_mime_icon?type=%s\" border=0 align=middle>\n",
- File->MimeType);
- escputs(File->Filename); wprintf("</a></td>");
- wprintf("<td>%ld</td>", File->FileSize);
- wprintf("<td>"); escputs(File->MimeType); wprintf("</td>");
- wprintf("<td>"); escputs(File->Comment); wprintf("</td>");
- wprintf("</tr>\n");
-}
-
-void FilePrintTransition(void *vFile1, void *vFile2, int odd)
-{
- FileListStruct *File1 = (FileListStruct*) vFile1;
- FileListStruct *File2 = (FileListStruct*) vFile2;
- char StartChar[2] = "\0\0";
- char *SectionName;
-
- switch (ibstr("SortBy")){
- case 1: /*NAME*/
- if ((File2 != NULL) &&
- ((File1 == NULL) ||
- (File1->Filename[0] != File2->Filename[0]))) {
- StartChar[0] = File2->Filename[0];
- SectionName = StartChar;
+ Buf = NewStrBuf();
+ Files = NewHash(1, NULL);
+ while (!Done && (StrBuf_ServGetln(Buf)>=0)) {
+ if ( (StrLength(Buf)==3) &&
+ !strcmp(ChrPtr(Buf), "000"))
+ {
+ Done = 1;
+ continue;
}
- else return;
- break;
- case 2: /* SIZE*/
- return;
- case 3: /*MIME*/
- return; /*TODO*/
- break;
- case 4: /*COMM*/
- return;
- default:
- return;
- }
-
- wprintf("<tr bgcolor=\"#%s\"><th colspan = 4>%s</th></tr>",
- (odd ? "DDDDDD" : "FFFFFF"), SectionName);
-}
-
-
-void display_room_directory(void)
-{
- char title[256];
- int havepics = 0;
- HashList *Files;
- int Order;
- int SortRow;
- int i;
-
- long SortDirections[5] = {2,2,2,2,2};
- const char* SortIcons[3] = {
- "static/up_pointer.gif",
- "static/down_pointer.gif",
- "static/sort_none.gif"};
- char *RowNames[5] = {"",
- _("Filename"),
- _("Size"),
- _("Content"),
- _("Description")};
-
- Files = LoadFileList (&havepics);
- output_headers(1, 1, 2, 0, 0, 0);
- wprintf("<div id=\"banner\">\n");
- wprintf("<h1>");
- snprintf(title, sizeof title, _("Files available for download in %s"), WC->wc_roomname);
- escputs(title);
- wprintf("</h1>");
- wprintf("</div>\n");
-
- wprintf("<div id=\"content\" class=\"service\">\n");
-
- wprintf("<div class=\"fix_scrollbar_bug\">"
- "<table class=\"downloads_background\"><tr><td>\n");
-
-
- Order = ibstr("SortOrder");
- if (!havebstr("SortOrder") || Order > 2)
- Order = 2; /* <- Unsorted... */
- SortRow = ibstr("SortBy");
-
- SortDirections[SortRow] = Order;
-
- wprintf("<tr>\n");
- for (i = 1; i < 5; i++) {
- switch (SortDirections[i]) {
- default:
- case 0:
- Order = 2;
- break;
- case 1:
- Order = 0;
- break;
- case 2:
- Order = 1;
- break;
- }
-
- wprintf(" <th>%s \n"
- " <a href=\"display_room_directory?SortOrder=%d&SortBy=%d\"> \n"
- " <img src=\"%s\" border=\"0\"></a>\n"
- " </th>\n",
- RowNames[i],
- Order, i,
- SortIcons[SortDirections[i]]
- );
-
- }
- wprintf("</tr>\n");
-//<th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n",
- //);
-
- if (Files != NULL) {
- PrintHash(Files, FilePrintTransition, FilePrintEntry);
- DeleteHash(&Files);
- }
- wprintf("</table>\n");
- /** Now offer the ability to upload files... */
- if (WC->room_flags & QR_UPLOAD)
- {
- wprintf("<hr>");
- wprintf("<form "
- "enctype=\"multipart/form-data\" "
- "method=\"POST\" "
- "accept-charset=\"UTF-8\" "
- "action=\"upload_file\" "
- "name=\"upload_file_form\""
- ">\n"
- );
- wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
-
- wprintf(_("Upload a file:"));
- wprintf(" <input NAME=\"filename\" SIZE=16 TYPE=\"file\"> \n");
- wprintf(_("Description:"));
- wprintf(" <input type=\"text\" name=\"description\" maxlength=\"64\" size=\"64\"> ");
- wprintf("<input type=\"submit\" name=\"attach_button\" value=\"%s\">\n", _("Upload"));
-
- wprintf("</form>\n");
- }
+ Entry = (FileListStruct*) malloc(sizeof (FileListStruct));
+ Entry->Filename = NewStrBufPlain(NULL, StrLength(Buf));
+ Entry->MimeType = NewStrBufPlain(NULL, StrLength(Buf));
+ Entry->Comment = NewStrBufPlain(NULL, StrLength(Buf));
- wprintf("</div>\n");
- if (havepics)
- wprintf("<div class=\"buttons\"><a href=\"display_pictureview&frame=1\">%s</a></div>", _("Slideshow"));
- wDumpContent(1);
-}
+ 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, '|');
-void display_pictureview(void)
-{
- char buf[1024];
- char filename[256];
- char filesize[256];
- char mimetype[64];
- char comment[512];
- char title[256];
- int n = 0;
-
- if (lbstr("frame") == 1) {
- output_headers(1, 1, 2, 0, 0, 0);
- wprintf("<div id=\"banner\">\n");
- wprintf("<h1>");
- snprintf(title, sizeof title, _("Pictures in %s"), WC->wc_roomname);
- escputs(title);
- wprintf("</h1>");
- wprintf("</div>\n");
-
- wprintf("<div id=\"content\" class=\"service\">\n");
-
- wprintf("<div class=\"fix_scrollbar_bug\">"
- "<table class=\"downloads_background\"><tr><td>\n");
-
-
-
- wprintf("<script type=\"text/javascript\" language=\"JavaScript\" > \nvar fadeimages=new Array()\n");
-
- serv_puts("RDIR");
- serv_getln(buf, sizeof buf);
- if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
- extract_token(filename, buf, 0, '|', sizeof filename);
- extract_token(filesize, buf, 1, '|', sizeof filesize);
- extract_token(mimetype, buf, 2, '|', sizeof mimetype);
- extract_token(comment, buf, 3, '|', sizeof comment);
- if (strstr(mimetype, "image") != NULL) {
- wprintf("fadeimages[%d]=[\"download_file/", n);
- escputs(filename);
- wprintf("\", \"\", \"\"]\n");
-
- /*
- //mimetype);
- escputs(filename); wprintf("</a></td>");
- wprintf("<td>"); escputs(filesize); wprintf("</td>");
- wprintf("<td>"); escputs(mimetype); wprintf("</td>");
- wprintf("<td>"); escputs(comment); wprintf("</td>");
- wprintf("</tr>\n");
- */
- n++;
- }
- }
- wprintf("</script>\n");
- wprintf("<tr><td><script type=\"text/javascript\" src=\"static/fadeshow.js\">\n</script>\n");
- wprintf("<script type=\"text/javascript\" >\n");
- wprintf("new fadeshow(fadeimages, 500, 400, 0, 3000, 1, \"R\");\n");
- wprintf("</script></td><th>\n");
- wprintf("</div>\n");
+ Entry->IsPic = (strstr(ChrPtr(Entry->MimeType), "image") != NULL);
+ if (Entry->IsPic) {
+ HavePic = 1;
+ }
+ Put(Files, SKEY(Entry->Filename), Entry, FreeFiles);
}
- wDumpContent(1);
-
-
+ 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;
}
-extern char* static_dirs[];
void display_mime_icon(void)
{
char FileBuf[SIZ];
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);
-
}
-void download_file(char *filename)
+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, filename, 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);
+ 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, '|');
}
- output_headers(0, 0, 0, 0, 0, 0);
- read_server_binary(content, bytes);
+ serv_read_binary(WCC->WBuf, bytes, Buf);
serv_puts("CLOS");
- serv_getln(buf, sizeof buf);
- http_transmit_thing(content, bytes, content_type, 0);
- free(content);
+ StrBuf_ServGetln(Buf);
+ http_transmit_thing(ChrPtr(ContentType), 0);
} else {
- wprintf("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);
- wprintf("Content-Type: text/plain\r\n");
- wprintf("\r\n");
- wprintf(_("An error occurred while retrieving this file: %s\n"), &buf[4]);
+ 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;
- char buf[1024];
- size_t bytes_transmitted = 0;
- size_t blocksize;
- struct 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]);
- display_room_directory();
+ 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;
}
{
blocksize = (WCC->upload_length - bytes_transmitted);
}
- serv_printf("WRIT %d", blocksize);
- serv_getln(buf, sizeof buf);
- if (buf[0] == '7')
- {
- blocksize = atoi(&buf[4]);
- serv_write(&WCC->upload[bytes_transmitted], blocksize);
+ 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");
- serv_getln(buf, sizeof buf);
- strcpy(WCC->ImportantMessage, &buf[4]);
- display_room_directory();
+ 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))
+ {
+ 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);
}