From 01feb53d65843a957635a16c3cccafe2b718777a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Sat, 9 Feb 2008 15:43:36 +0000 Subject: [PATCH] * UIMG and UOPN require the client to specify a Mimetype now. * the list file now contains this mimetype too, if there is no statement with a '/' in the expected place, we fallback to old notation and specify application/octetstream * adjust the client library. * in rooms.c list the [mimetype]. if s.b. doesn't like this notation, please change. --- citadel/citadel_ipc.c | 47 ++++++++++++++++++------- citadel/citadel_ipc.h | 4 +-- citadel/file_ops.c | 15 +++++--- citadel/room_ops.c | 80 ++++++++++++++++++++++++++----------------- citadel/rooms.c | 10 +++--- citadel/server.h | 2 ++ 6 files changed, 102 insertions(+), 56 deletions(-) diff --git a/citadel/citadel_ipc.c b/citadel/citadel_ipc.c index 96d5f1e79..004f8ad36 100644 --- a/citadel/citadel_ipc.c +++ b/citadel/citadel_ipc.c @@ -1326,14 +1326,18 @@ int CtdlIPCImageDownload(CtdlIPC *ipc, const char *filename, void **buf, /* UOPN */ -int CtdlIPCFileUpload(CtdlIPC *ipc, const char *save_as, const char *comment, - const char *path, +int CtdlIPCFileUpload(CtdlIPC *ipc, const char *save_as, const char *comment, + const char *path, void (*progress_gauge_callback) (CtdlIPC*, unsigned long, unsigned long), char *cret) { register int ret; char *aaa; + FILE *uploadFP; + char MimeTestBuf[64]; + const char *MimeType; + long len; if (!cret) return -1; if (!save_as) return -1; @@ -1342,15 +1346,24 @@ int CtdlIPCFileUpload(CtdlIPC *ipc, const char *save_as, const char *comment, if (!*path) return -1; if (ipc->uploading) return -1; + uploadFP = fopen(path, "r"); + if (!uploadFP) return -2; + + len = fread(&MimeTestBuf[0], 1, 64, uploadFP); + rewind (uploadFP); + if (len < 0) + return -3; + + MimeType = GuessMimeType(&MimeTestBuf[0], len); aaa = (char *)malloc(strlen(save_as) + strlen(comment) + 7); if (!aaa) return -1; - sprintf(aaa, "UOPN %s|%s", save_as, comment); + sprintf(aaa, "UOPN %s|%s|%s", save_as, MimeType, comment); ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret); free(aaa); if (ret / 100 == 2) { ipc->uploading = 1; - ret = CtdlIPCWriteUpload(ipc, path, progress_gauge_callback, cret); + ret = CtdlIPCWriteUpload(ipc, uploadFP, progress_gauge_callback, cret); ret = CtdlIPCEndUpload(ipc, (ret == -2 ? 1 : 0), cret); ipc->uploading = 0; } @@ -1366,7 +1379,11 @@ int CtdlIPCImageUpload(CtdlIPC *ipc, int for_real, const char *path, char *cret) { register int ret; + FILE *uploadFP; char *aaa; + char MimeTestBuf[64]; + const char *MimeType; + long len; if (!cret) return -1; if (!save_as) return -1; @@ -1377,12 +1394,21 @@ int CtdlIPCImageUpload(CtdlIPC *ipc, int for_real, const char *path, aaa = (char *)malloc(strlen(save_as) + 17); if (!aaa) return -1; - sprintf(aaa, "UIMG %d|%s", for_real, save_as); + uploadFP = fopen(path, "r"); + if (!uploadFP) return -2; + + len = fread(&MimeTestBuf[0], 1, 64, uploadFP); + rewind (uploadFP); + if (len < 0) + return -3; + MimeType = GuessMimeType(&MimeTestBuf[0], 64); + + sprintf(aaa, "UIMG %d|%s|%s", for_real, MimeType, save_as); ret = CtdlIPCGenericCommand(ipc, aaa, NULL, 0, NULL, NULL, cret); free(aaa); if (ret / 100 == 2 && for_real) { ipc->uploading = 1; - ret = CtdlIPCWriteUpload(ipc, path, progress_gauge_callback, cret); + ret = CtdlIPCWriteUpload(ipc, uploadFP, progress_gauge_callback, cret); ret = CtdlIPCEndUpload(ipc, (ret == -2 ? 1 : 0), cret); ipc->uploading = 0; } @@ -2347,7 +2373,7 @@ int CtdlIPCEndUpload(CtdlIPC *ipc, int discard, char *cret) /* WRIT */ -int CtdlIPCWriteUpload(CtdlIPC *ipc, const char *path, +int CtdlIPCWriteUpload(CtdlIPC *ipc, FILE *uploadFP, void (*progress_gauge_callback) (CtdlIPC*, unsigned long, unsigned long), char *cret) @@ -2357,15 +2383,10 @@ int CtdlIPCWriteUpload(CtdlIPC *ipc, const char *path, size_t bytes; char aaa[SIZ]; char buf[4096]; - FILE *fd; + FILE *fd = uploadFP; int ferr; if (!cret) return -1; - if (!path) return -1; - if (!*path) return -1; - - fd = fopen(path, "r"); - if (!fd) return -2; fseek(fd, 0L, SEEK_END); bytes = ftell(fd); diff --git a/citadel/citadel_ipc.h b/citadel/citadel_ipc.h index f7ee89f27..4254b6ef3 100644 --- a/citadel/citadel_ipc.h +++ b/citadel/citadel_ipc.h @@ -261,7 +261,7 @@ int CtdlIPCImageDownload(CtdlIPC *ipc, const char *filename, void **buf, void (*progress_gauge_callback)(CtdlIPC*, unsigned long, unsigned long), char *cret); int CtdlIPCFileUpload(CtdlIPC *ipc, const char *save_as, const char *comment, - const char *path, + const char *path, void (*progress_gauge_callback)(CtdlIPC*, unsigned long, unsigned long), char *cret); int CtdlIPCImageUpload(CtdlIPC *ipc, int for_real, const char *path, @@ -330,7 +330,7 @@ int CtdlIPCSendListing(CtdlIPC *ipc, const char *listing); size_t CtdlIPCPartialRead(CtdlIPC *ipc, void **buf, size_t offset, size_t bytes, char *cret); int CtdlIPCEndUpload(CtdlIPC *ipc, int discard, char *cret); -int CtdlIPCWriteUpload(CtdlIPC *ipc, const char *path, +int CtdlIPCWriteUpload(CtdlIPC *ipc, FILE *uploadFP, void (*progress_gauge_callback)(CtdlIPC*, unsigned long, unsigned long), char *cret); int CtdlIPCEndDownload(CtdlIPC *ipc, char *cret); diff --git a/citadel/file_ops.c b/citadel/file_ops.c index cc0e1afeb..daceb3be2 100644 --- a/citadel/file_ops.c +++ b/citadel/file_ops.c @@ -470,7 +470,8 @@ void cmd_uopn(char *cmdbuf) int a; extract_token(CC->upl_file, cmdbuf, 0, '|', sizeof CC->upl_file); - extract_token(CC->upl_comment, cmdbuf, 1, '|', sizeof CC->upl_comment); + extract_token(CC->upl_mimetype, cmdbuf, 1, '|', sizeof CC->upl_mimetype); + extract_token(CC->upl_comment, cmdbuf, 2, '|', sizeof CC->upl_comment); if (CtdlAccessCheck(ac_logged_in)) return; @@ -542,7 +543,8 @@ void cmd_uimg(char *cmdbuf) } is_this_for_real = extract_int(cmdbuf, 0); - extract_token(basenm, cmdbuf, 1, '|', sizeof basenm); + extract_token(CC->upl_mimetype, cmdbuf, 1, '|', sizeof CC->upl_mimetype); + extract_token(basenm, cmdbuf, 2, '|', sizeof basenm); if (CC->upload_fp != NULL) { cprintf("%d You already have an upload file open.\n", ERROR + RESOURCE_BUSY); @@ -682,15 +684,18 @@ void cmd_ucls(char *cmd) fp = fopen(CC->upl_filedir, "w"); } if (fp != NULL) { - fprintf(fp, "%s %s\n", CC->upl_file, + fprintf(fp, "%s %s %s\n", CC->upl_file, + CC->upl_mimetype, CC->upl_comment); fclose(fp); } /* put together an upload notice */ snprintf(upload_notice, sizeof upload_notice, - "NEW UPLOAD: '%s'\n %s\n", - CC->upl_file, CC->upl_comment); + "NEW UPLOAD: '%s'\n %s\n%s\n", + CC->upl_file, + CC->upl_comment, + CC->upl_mimetype); quickie_message(CC->curr_user, NULL, NULL, CC->room.QRname, upload_notice, 0, NULL); } else { diff --git a/citadel/room_ops.c b/citadel/room_ops.c index c2c5e2635..b82016ba5 100644 --- a/citadel/room_ops.c +++ b/citadel/room_ops.c @@ -1123,6 +1123,8 @@ void cmd_rdir(void) struct dirent *filedir_entry; int d_namelen; char buf2[SIZ]; + char mimebuf[64]; + long len; if (CtdlAccessCheck(ac_logged_in)) return; @@ -1139,48 +1141,62 @@ void cmd_rdir(void) cprintf("%d not here.\n", ERROR + HIGHER_ACCESS_REQUIRED); return; } - cprintf("%d %s|%s/%s\n", LISTING_FOLLOWS, config.c_fqdn, ctdl_file_dir, CC->room.QRdirname); - + snprintf(buf, sizeof buf, "%s/%s", ctdl_file_dir, CC->room.QRdirname); filedir = opendir (buf); - if (filedir) + + if (filedir == NULL) { + cprintf("%d not here.\n", ERROR + HIGHER_ACCESS_REQUIRED); + return; + } + cprintf("%d %s|%s/%s\n", LISTING_FOLLOWS, config.c_fqdn, ctdl_file_dir, CC->room.QRdirname); + + snprintf(buf, sizeof buf, "%s/%s/filedir", ctdl_file_dir, CC->room.QRdirname); + fd = fopen(buf, "r"); + if (fd == NULL) + fd = fopen("/dev/null", "r"); + while ((filedir_entry = readdir(filedir))) { - snprintf(buf, sizeof buf, "%s/%s/filedir", ctdl_file_dir, CC->room.QRdirname); - fd = fopen(buf, "r"); - if (fd == NULL) - fd = fopen("/dev/null", "r"); - while ((filedir_entry = readdir(filedir))) + if (strcasecmp(filedir_entry->d_name, "filedir") && filedir_entry->d_name[0] != '.') { - if (strcasecmp(filedir_entry->d_name, "filedir") && filedir_entry->d_name[0] != '.') - { #ifdef _DIRENT_HAVE_D_NAMELEN - d_namelen = filedir_entry->d_namelen; + d_namelen = filedir_entry->d_namelen; #else - d_namelen = strlen(filedir_entry->d_name); + d_namelen = strlen(filedir_entry->d_name); #endif - snprintf(buf, sizeof buf, "%s/%s/%s", ctdl_file_dir, CC->room.QRdirname, filedir_entry->d_name); - stat(buf, &statbuf); /* stat the file */ - if (!(statbuf.st_mode & S_IFREG)) - { - snprintf(buf2, sizeof buf2, "Command RDIR found something that is not a useable file. It should be cleaned up.\n RDIR found this non regular file:\n%s\n", buf); - aide_message(buf2, "RDIR found bad file"); - continue; /* not a useable file type so don't show it */ - } - safestrncpy(comment, "", sizeof comment); - fseek(fd, 0L, 0); /* rewind descriptions file */ - /* Get the description from the descriptions file */ - while ((fgets(buf, sizeof buf, fd) != NULL) && (IsEmptyStr(comment))) - { - buf[strlen(buf) - 1] = 0; - if ((!strncasecmp(buf, filedir_entry->d_name, d_namelen)) && (buf[d_namelen] == ' ')) - safestrncpy(comment, &buf[d_namelen + 1], sizeof comment); - } - cprintf("%s|%ld|%s\n", filedir_entry->d_name, (long)statbuf.st_size, comment); + snprintf(buf, sizeof buf, "%s/%s/%s", ctdl_file_dir, CC->room.QRdirname, filedir_entry->d_name); + stat(buf, &statbuf); /* stat the file */ + if (!(statbuf.st_mode & S_IFREG)) + { + snprintf(buf2, sizeof buf2, "Command RDIR found something that is not a useable file. It should be cleaned up.\n RDIR found this non regular file:\n%s\n", buf); + aide_message(buf2, "RDIR found bad file"); + continue; /* not a useable file type so don't show it */ + } + safestrncpy(comment, "", sizeof comment); + fseek(fd, 0L, 0); /* rewind descriptions file */ + /* Get the description from the descriptions file */ + while ((fgets(buf, sizeof buf, fd) != NULL) && (IsEmptyStr(comment))) + { + buf[strlen(buf) - 1] = 0; + if ((!strncasecmp(buf, filedir_entry->d_name, d_namelen)) && (buf[d_namelen] == ' ')) + safestrncpy(comment, &buf[d_namelen + 1], sizeof comment); + } + len = extract_token (mimebuf, comment, 0,' ', 64); + if ((len <0) || strchr(mimebuf, '/') == NULL) + { + snprintf (mimebuf, 64, "application/octetstream"); + len = 0; } + cprintf("%s|%ld|%s|%s\n", + filedir_entry->d_name, + (long)statbuf.st_size, + mimebuf, + &comment[len]); } - fclose(fd); - closedir(filedir); } + fclose(fd); + closedir(filedir); + cprintf("000\n"); } diff --git a/citadel/rooms.c b/citadel/rooms.c index 87d46f8bb..30edd1fe8 100644 --- a/citadel/rooms.c +++ b/citadel/rooms.c @@ -922,6 +922,7 @@ void roomdir(CtdlIPC *ipc) char flnm[256]; char flsz[32]; char comment[256]; + char mimetype[256]; char buf[256]; char *listing = NULL; /* Returned directory listing */ int r; @@ -942,12 +943,13 @@ void roomdir(CtdlIPC *ipc) extract_token(flnm, buf, 0, '|', sizeof flnm); extract_token(flsz, buf, 1, '|', sizeof flsz); - extract_token(comment, buf, 2, '|', sizeof comment); + extract_token(mimetype, buf, 2, '|', sizeof mimetype); + extract_token(comment, buf, 3, '|', sizeof comment); if (strlen(flnm) <= 14) - pprintf("%-14s %8s %s\n", flnm, flsz, comment); + pprintf("%-14s %8s %s [%s]\n", flnm, flsz, comment, mimetype); else - pprintf("%s\n%14s %8s %s\n", flnm, "", flsz, - comment); + pprintf("%s\n%14s %8s %s [%s]\n", flnm, "", flsz, + comment, mimetype); } if (listing) free(listing); } diff --git a/citadel/server.h b/citadel/server.h index 9f456c7f9..cfdea64cd 100644 --- a/citadel/server.h +++ b/citadel/server.h @@ -103,6 +103,7 @@ struct CitContext { char upl_path[PATH_MAX]; char upl_comment[256]; char upl_filedir[PATH_MAX]; + char upl_mimetype[64]; char dl_is_net; char upload_type; @@ -360,6 +361,7 @@ struct MetaData { int meta_refcount; /* Number of rooms pointing to this msg */ char meta_content_type[64]; /* Cached MIME content-type */ long meta_rfc822_length; /* Cache of RFC822-translated msg length */ + char mimetype[64]; /* if we were able to guess the mimetype for the data */ }; /* Calls to AdjRefCount() are queued and deferred, so the user doesn't -- 2.30.2