7 typedef struct _FileListStruct {
20 int CompareFilelistByMime(const void *vFile1, const void *vFile2)
22 FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1);
23 FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2);
25 if (File1->IsPic != File2->IsPic)
26 return File1->IsPic > File2->IsPic;
27 return strcasecmp(File1->MimeType, File2->MimeType);
29 int CompareFilelistByMimeRev(const void *vFile1, const void *vFile2)
31 FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1);
32 FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2);
33 if (File1->IsPic != File2->IsPic)
34 return File1->IsPic < File2->IsPic;
35 return strcasecmp(File2->MimeType, File1->MimeType);
38 int CompareFilelistBySize(const void *vFile1, const void *vFile2)
40 FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1);
41 FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2);
42 if (File1->FileSize == File2->FileSize)
44 return (File1->FileSize > File2->FileSize);
47 int CompareFilelistBySizeRev(const void *vFile1, const void *vFile2)
49 FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1);
50 FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2);
51 if (File1->FileSize == File2->FileSize)
53 return (File1->FileSize < File2->FileSize);
56 int CompareFilelistByComment(const void *vFile1, const void *vFile2)
58 FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1);
59 FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2);
60 return strcasecmp(File1->Comment, File2->Comment);
62 int CompareFilelistByCommentRev(const void *vFile1, const void *vFile2)
64 FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1);
65 FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2);
66 return strcasecmp(File2->Comment, File1->Comment);
69 int CompareFilelistBySequence(const void *vFile1, const void *vFile2)
71 FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1);
72 FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2);
73 return (File2->Sequence > File1->Sequence);
76 HashList* LoadFileList(int *HavePic)
78 FileListStruct *Entry;
86 serv_getln(buf, sizeof buf);
88 Files = NewHash(1, NULL);
89 while (serv_getln(buf, sizeof buf), strcmp(buf, "000"))
91 Entry = (FileListStruct*) malloc(sizeof (FileListStruct));
93 Entry->FilenameLen = extract_token(
94 Entry->Filename, buf, 0, '|',
95 sizeof(Entry->Filename));
96 Entry->FileSize = extract_long(buf, 1);
97 Entry->MimeTypeLen = extract_token(
98 Entry->MimeType, buf, 2, '|',
99 sizeof(Entry->MimeType));
100 Entry->CommentLen = extract_token(
101 Entry->Comment, buf, 3, '|',
102 sizeof(Entry->Comment));
104 Entry->Sequence = sequence++;
105 Entry->IsPic = (strstr(Entry->MimeType, "image") != NULL);
106 if (!HavePics && Entry->IsPic) {
110 Put(Files, Entry->Filename,
114 Order = ibstr("SortOrder");
115 switch (ibstr("SortBy")){
117 SortByHashKey(Files,Order);
120 SortByPayload(Files, (Order)?
121 CompareFilelistBySize:
122 CompareFilelistBySizeRev);
125 SortByPayload(Files, (Order)?
126 CompareFilelistByMime:
127 CompareFilelistByMimeRev);
130 SortByPayload(Files, (Order)?
131 CompareFilelistByComment:
132 CompareFilelistByCommentRev);
135 SortByPayload(Files, CompareFilelistBySequence);
143 void FilePrintEntry(const char *FileName, void *vFile, int odd)
145 FileListStruct *File = (FileListStruct*) vFile;
147 wprintf("<tr bgcolor=\"#%s\">", (odd ? "DDDDDD" : "FFFFFF"));
149 "<a href=\"download_file/");
150 urlescputs(File->Filename);
151 wprintf("\"><img src=\"display_mime_icon?type=%s\" border=0 align=middle>\n",
153 escputs(File->Filename); wprintf("</a></td>");
154 wprintf("<td>%ld</td>", File->FileSize);
155 wprintf("<td>"); escputs(File->MimeType); wprintf("</td>");
156 wprintf("<td>"); escputs(File->Comment); wprintf("</td>");
160 void FilePrintTransition(void *vFile1, void *vFile2, int odd)
162 FileListStruct *File1 = (FileListStruct*) vFile1;
163 FileListStruct *File2 = (FileListStruct*) vFile2;
164 char StartChar[2] = "\0\0";
167 switch (ibstr("SortBy")){
169 if ((File2 != NULL) &&
171 (File1->Filename[0] != File2->Filename[0]))) {
172 StartChar[0] = File2->Filename[0];
173 SectionName = StartChar;
188 wprintf("<tr bgcolor=\"#%s\"><th colspan = 4>%s</th></tr>",
189 (odd ? "DDDDDD" : "FFFFFF"), SectionName);
193 void display_room_directory(void)
202 long SortDirections[5] = {2,2,2,2,2};
203 const char* SortIcons[3] = {
204 "static/up_pointer.gif",
205 "static/down_pointer.gif",
206 "static/sort_none.gif"};
209 RowNames[1] = _("Filename");
210 RowNames[2] = _("Size");
211 RowNames[3] = _("Content");
212 RowNames[4] = _("Description");
214 Files = LoadFileList (&havepics);
215 output_headers(1, 1, 2, 0, 0, 0);
216 wprintf("<div id=\"banner\">\n");
218 snprintf(title, sizeof title, _("Files available for download in %s"), WC->wc_roomname);
223 wprintf("<div id=\"content\" class=\"service\">\n");
225 wprintf("<div class=\"fix_scrollbar_bug\">"
226 "<table class=\"downloads_background\"><tr><td>\n");
229 Order = ibstr("SortOrder");
230 if (!havebstr("SortOrder") || Order > 2)
231 Order = 2; /* <- Unsorted... */
232 SortRow = ibstr("SortBy");
234 SortDirections[SortRow] = Order;
237 for (i = 1; i < 5; i++) {
238 switch (SortDirections[i]) {
252 " <a href=\"display_room_directory?SortOrder=%d&SortBy=%d\"> \n"
253 " <img src=\"%s\" border=\"0\"></a>\n"
257 SortIcons[SortDirections[i]]
262 //<th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n",
266 PrintHash(Files, FilePrintTransition, FilePrintEntry);
269 wprintf("</table>\n");
271 /** Now offer the ability to upload files... */
272 if (WC->room_flags & QR_UPLOAD)
276 "enctype=\"multipart/form-data\" "
278 "accept-charset=\"UTF-8\" "
279 "action=\"upload_file\" "
280 "name=\"upload_file_form\""
283 wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
285 wprintf(_("Upload a file:"));
286 wprintf(" <input NAME=\"filename\" SIZE=16 TYPE=\"file\"> \n");
287 wprintf(_("Description:"));
288 wprintf(" <input type=\"text\" name=\"description\" maxlength=\"64\" size=\"64\"> ");
289 wprintf("<input type=\"submit\" name=\"attach_button\" value=\"%s\">\n", _("Upload"));
291 wprintf("</form>\n");
296 wprintf("<div class=\"buttons\"><a href=\"display_pictureview&frame=1\">%s</a></div>", _("Slideshow"));
301 void display_pictureview(void)
312 if (lbstr("frame") == 1) {
314 output_headers(1, 1, 2, 0, 0, 0);
315 wprintf("<div id=\"banner\">\n");
317 snprintf(title, sizeof title, _("Pictures in %s"), WC->wc_roomname);
322 wprintf("<div id=\"content\" class=\"service\">\n");
324 wprintf("<div class=\"fix_scrollbar_bug\">"
325 "<table class=\"downloads_background\"><tr><td>\n");
329 wprintf("<script type=\"text/javascript\" language=\"JavaScript\" > \nvar fadeimages=new Array()\n");
332 serv_getln(buf, sizeof buf);
333 if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
334 extract_token(filename, buf, 0, '|', sizeof filename);
335 extract_token(filesize, buf, 1, '|', sizeof filesize);
336 extract_token(mimetype, buf, 2, '|', sizeof mimetype);
337 extract_token(comment, buf, 3, '|', sizeof comment);
338 if (strstr(mimetype, "image") != NULL) {
339 wprintf("fadeimages[%d]=[\"download_file/", n);
341 wprintf("\", \"\", \"\"]\n");
345 escputs(filename); wprintf("</a></td>");
346 wprintf("<td>"); escputs(filesize); wprintf("</td>");
347 wprintf("<td>"); escputs(mimetype); wprintf("</td>");
348 wprintf("<td>"); escputs(comment); wprintf("</td>");
354 wprintf("</script>\n");
355 wprintf("<tr><td><script type=\"text/javascript\" src=\"static/fadeshow.js\">\n</script>\n");
356 wprintf("<script type=\"text/javascript\" >\n");
357 wprintf("new fadeshow(fadeimages, 500, 400, 0, 3000, 1, \"R\");\n");
358 wprintf("</script></td><th>\n");
366 extern char* static_dirs[];
367 void display_mime_icon(void)
370 const char *FileName;
374 MimeType = xbstr("type", &tlen);
375 FileName = GetIconFilename(MimeType, tlen);
377 if (FileName == NULL)
378 snprintf (FileBuf, SIZ, "%s%s", static_dirs[0], "/diskette_24x.gif");
380 snprintf (FileBuf, SIZ, "%s%s", static_dirs[3], FileName);
381 output_static(FileBuf);
385 void download_file(void)
389 char content_type[256];
390 char *content = NULL;
392 /* Setting to nonzero forces a MIME type of application/octet-stream */
393 int force_download = 1;
395 safestrncpy(buf, ChrPtr(WC->UrlFragment2), sizeof buf);
397 serv_printf("OPEN %s", buf);
398 serv_getln(buf, sizeof buf);
400 bytes = extract_long(&buf[4], 0);
401 content = malloc(bytes + 2);
402 if (force_download) {
403 strcpy(content_type, "application/octet-stream");
406 extract_token(content_type, &buf[4], 3, '|', sizeof content_type);
408 output_headers(0, 0, 0, 0, 0, 0);
409 read_server_binary(WC->WBuf, bytes);
411 serv_getln(buf, sizeof buf);
412 http_transmit_thing(content_type, 0);
415 hprintf("HTTP/1.1 404 %s\n", &buf[4]);
416 output_headers(0, 0, 0, 0, 0, 0);
417 hprintf("Content-Type: text/plain\r\n");
418 wprintf(_("An error occurred while retrieving this file: %s\n"), &buf[4]);
426 void upload_file(void)
428 const char *MimeType;
430 long bytes_transmitted = 0;
432 wcsession *WCC = WC; /* stack this for faster access (WC is a function) */
434 MimeType = GuessMimeType(WCC->upload, WCC->upload_length);
435 serv_printf("UOPN %s|%s|%s", WCC->upload_filename, MimeType, bstr("description"));
436 serv_getln(buf, sizeof buf);
439 strcpy(WCC->ImportantMessage, &buf[4]);
440 display_room_directory();
444 while (bytes_transmitted < WCC->upload_length)
447 if (blocksize > (WCC->upload_length - bytes_transmitted))
449 blocksize = (WCC->upload_length - bytes_transmitted);
451 serv_printf("WRIT %ld", blocksize);
452 serv_getln(buf, sizeof buf);
455 blocksize = atoi(&buf[4]);
456 serv_write(&WCC->upload[bytes_transmitted], blocksize);
457 bytes_transmitted += blocksize;
462 serv_getln(buf, sizeof buf);
463 strcpy(WCC->ImportantMessage, &buf[4]);
464 display_room_directory();
470 * When the browser requests an image file from the Citadel server,
471 * this function is called to transmit it.
479 const char *MimeType;
481 serv_printf("OIMG %s|%s", bstr("name"), bstr("parm"));
482 serv_getln(buf, sizeof buf);
484 bytes = extract_long(&buf[4], 0);
486 /** Read it from the server */
488 if (read_server_binary(WCC->WBuf, bytes) > 0) {
490 serv_getln(buf, sizeof buf);
492 MimeType = GuessMimeType (ChrPtr(WCC->WBuf), StrLength(WCC->WBuf));
493 /** Write it to the browser */
494 if (!IsEmptyStr(MimeType))
496 http_transmit_thing(MimeType, 0);
500 /* hm... unknown mimetype? fallback to blank gif */
505 * Instead of an ugly 404, send a 1x1 transparent GIF
506 * when there's no such image on the server.
508 snprintf (blank_gif, SIZ, "%s%s", static_dirs[0], "/blank.gif");
509 output_static(blank_gif);
519 WebcitAddUrlHandler(HKEY("image"), output_image, 0);
520 WebcitAddUrlHandler(HKEY("display_mime_icon"), display_mime_icon , 0);
522 WebcitAddUrlHandler(HKEY("display_room_directory"), display_room_directory, 0);
523 WebcitAddUrlHandler(HKEY("display_pictureview"), display_pictureview, 0);
524 WebcitAddUrlHandler(HKEY("download_file"), download_file, NEED_URL);
525 WebcitAddUrlHandler(HKEY("upload_file"), upload_file, 0);