X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fdownloads.c;h=600d89de0769cdf0c9196c02eb31293811725296;hb=5685e790de93f77083ea240f474a4870b194c550;hp=d3ffe37bb5f3fa399fc073b73f5432ab670dd886;hpb=a66cce670c39f513565011e93e7865c44806b501;p=citadel.git diff --git a/webcit/downloads.c b/webcit/downloads.c index d3ffe37bb..600d89de0 100644 --- a/webcit/downloads.c +++ b/webcit/downloads.c @@ -1,55 +1,270 @@ /* - * $Id: downloads.c 4849 2007-01-08 20:05:56Z ajc $ + * $Id$ */ #include "webcit.h" +#include "webserver.h" -void display_room_directory(void) +typedef struct _FileListStruct { + char Filename[256]; + int FilenameLen; + long FileSize; + char MimeType[64]; + int MimeTypeLen; + char Comment[512]; + int CommentLen; + int IsPic; + int Sequence; +}FileListStruct; + + +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(File1->MimeType, 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(File2->MimeType, File1->MimeType); +} + +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 CompareFilelistByComment(const void *vFile1, const void *vFile2) +{ + FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1); + FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2); + return strcasecmp(File1->Comment, 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); +} + +int CompareFilelistBySequence(const void *vFile1, const void *vFile2) +{ + FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1); + FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2); + return (File2->Sequence > File1->Sequence); +} + +HashList* LoadFileList(int *HavePic) +{ + FileListStruct *Entry; + HashList *Files; + int HavePics = 0; + int Order; + int sequence = 0; char buf[1024]; - char filename[256]; - char filesize[256]; - char comment[512]; - int bg = 0; + + 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; +} + +void FilePrintEntry(const char *FileName, void *vFile, int odd) +{ + FileListStruct *File = (FileListStruct*) vFile; + + wprintf("", (odd ? "DDDDDD" : "FFFFFF")); + wprintf("" + "Filename); + wprintf("\">\n", + File->MimeType); + escputs(File->Filename); wprintf(""); + wprintf("%ld", File->FileSize); + wprintf(""); escputs(File->MimeType); wprintf(""); + wprintf(""); escputs(File->Comment); wprintf(""); + wprintf("\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; + } + else return; + break; + case 2: /* SIZE*/ + return; + case 3: /*MIME*/ + return; /*TODO*/ + break; + case 4: /*COMM*/ + return; + default: + return; + } + + wprintf("%s", + (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("
\n" - "
" - ""); + wprintf("
\n"); + wprintf("

"); snprintf(title, sizeof title, _("Files available for download in %s"), WC->wc_roomname); escputs(title); - wprintf("" - "

\n" - "
\n
\n" - ); + wprintf(""); + wprintf("
\n"); + + wprintf("
\n"); wprintf("
" "\n", - _("Filename"), - _("Size"), - _("Description") - ); - 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(comment, buf, 2, '|', sizeof comment); - bg = 1 - bg; - wprintf("", (bg ? "DDDDDD" : "FFFFFF")); - wprintf(""); - wprintf(""); - wprintf(""); - wprintf("\n"); + + Order = ibstr("SortOrder"); + if (!havebstr("SortOrder") || Order > 2) + Order = 2; /* <- Unsorted... */ + SortRow = ibstr("SortBy"); + + SortDirections[SortRow] = Order; + + wprintf("\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(" \n", + RowNames[i], + Order, i, + SortIcons[SortDirections[i]] + ); + } + wprintf("\n"); +//\n", + //); + if (Files != NULL) { + PrintHash(Files, FilePrintTransition, FilePrintEntry); + DeleteHash(&Files); + } wprintf("
\n"); - wprintf("
%s%s%s
" - "\n"); - escputs(filename); wprintf(""); escputs(filesize); wprintf(""); escputs(comment); wprintf("
%s \n" + " \n" + " \n" + "
%s%s%s%s
\n"); /** Now offer the ability to upload files... */ @@ -64,6 +279,7 @@ void display_room_directory(void) "name=\"upload_file_form\"" ">\n" ); + wprintf("\n", WC->nonce); wprintf(_("Upload a file:")); wprintf("  \n"); @@ -75,12 +291,99 @@ void display_room_directory(void) } wprintf("
\n"); + if (havepics) + wprintf("
%s
", _("Slideshow")); wDumpContent(1); } -void download_file(char *filename) +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("
\n"); + wprintf("

"); + snprintf(title, sizeof title, _("Pictures in %s"), WC->wc_roomname); + escputs(title); + wprintf("

"); + wprintf("
\n"); + + wprintf("
\n"); + + wprintf("
" + "
\n"); + + + + wprintf("\n"); + wprintf("
\n"); + wprintf("\n"); + wprintf("\n"); + } + wDumpContent(1); + + +} + +extern char* static_dirs[]; +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], "/diskette_24x.gif"); + else + snprintf (FileBuf, SIZ, "%s%s", static_dirs[3], FileName); + output_static(FileBuf); + +} + +void download_file(void) +{ + StrBuf *Buf; char buf[256]; off_t bytes; char content_type[256]; @@ -89,7 +392,7 @@ void download_file(char *filename) /* Setting to nonzero forces a MIME type of application/octet-stream */ int force_download = 1; - safestrncpy(buf, filename, sizeof buf); + safestrncpy(buf, ChrPtr(WC->UrlFragment1), sizeof buf); unescape_input(buf); serv_printf("OPEN %s", buf); serv_getln(buf, sizeof buf); @@ -103,17 +406,17 @@ void download_file(char *filename) extract_token(content_type, &buf[4], 3, '|', sizeof content_type); } output_headers(0, 0, 0, 0, 0, 0); - read_server_binary(content, bytes); + Buf = read_server_binary(bytes); serv_puts("CLOS"); serv_getln(buf, sizeof buf); - http_transmit_thing(content, bytes, content_type, 0); + http_transmit_thing(Buf, content_type, 0); free(content); } else { - wprintf("HTTP/1.1 404 %s\n", &buf[4]); + hprintf("HTTP/1.1 404 %s\n", &buf[4]); output_headers(0, 0, 0, 0, 0, 0); - wprintf("Content-Type: text/plain\r\n"); - wprintf("\r\n"); + hprintf("Content-Type: text/plain\r\n"); wprintf(_("An error occurred while retrieving this file: %s\n"), &buf[4]); + end_burst(); } } @@ -122,38 +425,51 @@ void download_file(char *filename) void upload_file(void) { + 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) */ - serv_printf("UOPN %s|%s", WC->upload_filename, bstr("description")); + 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(WC->ImportantMessage, &buf[4]); + strcpy(WCC->ImportantMessage, &buf[4]); display_room_directory(); return; } - while (bytes_transmitted < WC->upload_length) + while (bytes_transmitted < WCC->upload_length) { blocksize = 4096; - if (blocksize > (WC->upload_length - bytes_transmitted)) + if (blocksize > (WCC->upload_length - bytes_transmitted)) { - blocksize = (WC->upload_length - bytes_transmitted); + 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(&WC->upload[bytes_transmitted], blocksize); + serv_write(&WCC->upload[bytes_transmitted], blocksize); bytes_transmitted += blocksize; } } serv_puts("UCLS 1"); serv_getln(buf, sizeof buf); - strcpy(WC->ImportantMessage, &buf[4]); + strcpy(WCC->ImportantMessage, &buf[4]); display_room_directory(); } + +void +InitModule_DOWNLOAD +(void) +{ + WebcitAddUrlHandler(HKEY("display_room_directory"), display_room_directory, 0); + WebcitAddUrlHandler(HKEY("display_pictureview"), display_pictureview, 0); + WebcitAddUrlHandler(HKEY("download_file"), download_file, NEED_URL); + WebcitAddUrlHandler(HKEY("upload_file"), upload_file, 0); +}