* UIMG and UOPN require the client to specify a Mimetype now.
authorWilfried Göesgens <willi@citadel.org>
Sat, 9 Feb 2008 15:43:36 +0000 (15:43 +0000)
committerWilfried Göesgens <willi@citadel.org>
Sat, 9 Feb 2008 15:43:36 +0000 (15:43 +0000)
* 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
citadel/citadel_ipc.h
citadel/file_ops.c
citadel/room_ops.c
citadel/rooms.c
citadel/server.h

index 96d5f1e7917e9b5a70567aa107d1282d9a0185a3..004f8ad36f597301cbb0aadb00c6ffb82af1059f 100644 (file)
@@ -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);
index f7ee89f2755db2ddda9a43e3b480abb5aa87fa20..4254b6ef3f89b44fca14624f21962d17a38b3bf7 100644 (file)
@@ -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);
index cc0e1afebf8c9271b94a99833edee49edc24a180..daceb3be24792b70c3f1d5bc6cca6825145a7d8b 100644 (file)
@@ -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 {
index c2c5e2635d83f12dcc0f00edf73a5d38c1274849..b82016ba558452923564cc482d870e7a943e6875 100644 (file)
@@ -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");
 }
 
index 87d46f8bb61a387614300496f5696671227f8378..30edd1fe845ee01a238a7851ab772bee7fa8e916 100644 (file)
@@ -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);
 }
index 9f456c7f9451d66f411d84983e465f72e449c388..cfdea64cd64e1043e0a74e5fa9069b20b1ffed7e 100644 (file)
@@ -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