]> code.citadel.org Git - citadel.git/commitdiff
Finished the mime parser, but there's a bug in it somewhere...
authorArt Cancro <ajc@citadel.org>
Sun, 31 Jan 1999 22:37:21 +0000 (22:37 +0000)
committerArt Cancro <ajc@citadel.org>
Sun, 31 Jan 1999 22:37:21 +0000 (22:37 +0000)
citadel/Makefile.in
citadel/mime_parser.c
citadel/msgbase.c
citadel/qpdecode.c [new file with mode: 0644]

index 150d6bc4428ea3135dc5f7f4c6732de404b7696b..be239d27c25614b5ada9464d3f0e268615565649 100644 (file)
@@ -23,7 +23,8 @@ SERVER_TARGETS=citserver setup
 SERV_MODULES=modules/serv_chat.so \
        modules/serv_upgrade.so modules/serv_expire.so
 UTIL_TARGETS=aidepost netmailer netproc netsetup msgform readlog rcit \
-       stats citmail netpoll mailinglist userlist sendcommand base64
+       stats citmail netpoll mailinglist userlist sendcommand \
+       base64 qpdecode
 PROXY_TARGETS=proxy
 
 prefix=@prefix@
@@ -57,7 +58,7 @@ SOURCES=aidepost.c citadel.c citmail.c citserver.c client_chat.c commands.c \
        room_ops.c rooms.c routines.c routines2.c serv_chat.c \
        serv_info.c serv_test.c serv_upgrade.c setup.c snprintf.c stats.c \
        support.c sysdep.c tools.c user_ops.c userlist.c serv_expire.c \
-       whobbs.c sendcommand.c mime_parser.c base64.c
+       whobbs.c sendcommand.c mime_parser.c base64.c qpdecode.c
 
 DEP_FILES=$(SOURCES:.c=.d)
 
@@ -160,6 +161,9 @@ sendcommand: sendcommand.o ipc_c_tcp.o tools.o config.o $(SNPRINTF)
        $(CC) sendcommand.o ipc_c_tcp.o tools.o config.o \
         $(SNPRINTF) $(LDFLAGS) -o sendcommand
 
+qpdecode: qpdecode.o
+       $(CC) qpdecode.o $(LDFLAGS) -o qpdecode
+
 base64: base64.o
        $(CC) base64.o $(LDFLAGS) -o base64
 
index 12c775512eaf9abe48d4390da0a0266e7aaa854f..2b0d70710a07f451c850f22635d63cd38f90ab89 100644 (file)
@@ -99,6 +99,13 @@ void mime_decode(char *partnum,
        size_t blocksize;
        int write_error = 0;
 
+       lprintf(9, "mime_decode() called\n");
+
+       /* Some encodings aren't really encodings */
+       if (!strcasecmp(encoding, "7bit"))      strcpy(encoding, "");
+       if (!strcasecmp(encoding, "8bit"))      strcpy(encoding, "");
+       if (!strcasecmp(encoding, "binary"))    strcpy(encoding, "");
+
        /* If this part is not encoded, send as-is */
        if (strlen(encoding)==0) {
                CallBack(name, filename, partnum, disposition, part_start,
@@ -107,7 +114,7 @@ void mime_decode(char *partnum,
                }
 
        if ( (strcasecmp(encoding, "base64"))
-            && (strcasecmp(encoding, "7bit"))  ) {
+            && (strcasecmp(encoding, "quoted-printable"))  ) {
                lprintf(5, "ERROR: unknown MIME encoding '%s'\n", encoding);
                return;
                }
@@ -127,7 +134,6 @@ void mime_decode(char *partnum,
        if (pipe(recvpipe) != 0) return;
 
        childpid = fork();
-       lprintf(9, "fork() returned %d\n", childpid);
        if (childpid < 0) {
                phree(decoded);
                return;
@@ -142,8 +148,8 @@ void mime_decode(char *partnum,
                close(recvpipe[0]);
                if (!strcasecmp(encoding, "base64"))
                   execlp("./base64", "base64", "-d", NULL);
-               else if (!strcasecmp(encoding, "7bit")) /* just a test */
-                  execlp("/bin/dd", "dd", NULL);
+               else if (!strcasecmp(encoding, "quoted-printable"))
+                  execlp("./qpdecode", "qpdecode", NULL);
                lprintf(5, "ERROR: cannot exec decoder for %s\n", encoding);
                exit(1);
                }
@@ -151,8 +157,6 @@ void mime_decode(char *partnum,
        close(sendpipe[0]);      /* Close the ends we're not using  */
        close(recvpipe[1]);
 
-       lprintf(9, "ready to send %d bytes\n", length);
-
        while ( (bytes_sent < length) && (write_error == 0) ) {
                /* Empty the input pipe FIRST */
                while (fstat(recvpipe[0], &statbuf), (statbuf.st_size > 0) ) {
@@ -180,8 +184,6 @@ void mime_decode(char *partnum,
                bytes_recv = bytes_recv + blocksize;
                }
 
-       lprintf(9, "Decoded length = %d\n", bytes_recv);
-
        if (bytes_recv > 0)
                CallBack(name, filename, partnum, disposition, decoded,
                        content_type, bytes_recv);
@@ -224,6 +226,7 @@ void the_mime_parser(char *partnum,
        size_t length;
        char nested_partnum[256];
 
+       lprintf(9, "the_mime_parser() called\n");
        ptr = content_start;
        memset(boundary, 0, sizeof boundary);
        memset(content_type, 0, sizeof content_type);
@@ -331,5 +334,6 @@ void mime_parser(char *content_start, char *content_end,
                        size_t cblength)
                ) {
 
+       lprintf(9, "mime_parser() called\n");
        the_mime_parser("1", content_start, content_end, CallBack);
        }
index 3a53416dd71be0023af5e66c0f61fb79cfa805dc..5fb3c4b6c6229eab92d54ddf388560332778d1a2 100644 (file)
@@ -336,8 +336,9 @@ FMTEND:     cprintf("\n");
 
 
 /*
+ * Callback function for mime parser that simply lists the part
  */
-void part_handler(char *name, char *filename, char *partnum, char *disp,
+void list_this_part(char *name, char *filename, char *partnum, char *disp,
                         void *content, char *cbtype, size_t length) {
 
        cprintf("part=%s|%s|%s|%s|%s|%d\n",
@@ -345,6 +346,20 @@ void part_handler(char *name, char *filename, char *partnum, char *disp,
        }
 
 
+/*
+ * Callback function for mime parser that wants to display text
+ */
+void fixed_output(char *name, char *filename, char *partnum, char *disp,
+                        void *content, char *cbtype, size_t length) {
+
+       if (!strcasecmp(cbtype, "text/plain")) {
+               client_write(content, length);
+               }
+       else {
+               cprintf("Part %s: %s (%s) (%d bytes)\n",
+                       partnum, filename, cbtype, length);
+               }
+       }
 
 
 /*
@@ -551,7 +566,7 @@ time_t output_message(char *msgid, int mode, int headers_only) {
 
        /* do some sort of MIME output */
        if ( (mode == MT_MIME) && (format_type == 4) ) {
-               mime_parser(mptr, NULL, *part_handler);
+               mime_parser(mptr, NULL, *list_this_part);
                cprintf("000\n");
                cdb_free(dmsgtext);
                return(xtime);
@@ -575,10 +590,9 @@ time_t output_message(char *msgid, int mode, int headers_only) {
 
        /* If the format type on disk is 1 (fixed-format), then we want
         * everything to be output completely literally ... regardless of
-        * what message transfer format is in use.  Format type 4 is 
-        * temporarily being output this way as well.
+        * what message transfer format is in use.
         */
-       if ( (format_type == 1) || (format_type == 4)) {
+       if (format_type == 1) {
                strcpy(buf, "");
                while(ch = *mptr++, ch>0) {
                        if (ch == 13) ch = 10;
@@ -603,7 +617,14 @@ time_t output_message(char *msgid, int mode, int headers_only) {
        if (format_type == 0) {
                memfmout(80,mptr,0);
                }
-
+       /* If the message on disk is format 4 (MIME), we've gotta hand it
+        * off to the MIME parser.  The client has already been told that
+        * this message is format 1 (fixed format), so the callback function
+        * we use will display those parts as-is.
+        */
+       if (format_type == 4) {
+               mime_parser(mptr, NULL, *fixed_output);
+               }
 
        /* now we're done */
        cprintf("000\n");
diff --git a/citadel/qpdecode.c b/citadel/qpdecode.c
new file mode 100644 (file)
index 0000000..ba01e12
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Convert "quoted printable" encoding to binary (stdin to stdout)
+ * Copyright (C) 1999 by Art Cancro
+ * Distributed under the terms of the GNU General Public License.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+int main(int argc, char *argv[]) {
+       char buf[80];
+       int soft_line_break = 0;
+       int ch;
+
+       while (fgets(buf, 80, stdin) != NULL) {
+               while (isspace(buf[strlen(buf)-1]))
+                       buf[strlen(buf)-1] = 0;
+               soft_line_break = 0;
+
+               while (strlen(buf) > 0) {
+                       if (!strcmp(buf, "=")) {
+                               soft_line_break = 1;
+                               strcpy(buf, "");
+                       } else if ( (strlen(buf)>=3) && (buf[0]=='=') ) {
+                               sscanf(&buf[1], "%02x", &ch);
+                               putc(ch, stdout);
+                               strcpy(buf, &buf[3]);
+                       } else {
+                               putc(buf[0], stdout);
+                               strcpy(buf, &buf[1]);
+                       }
+               }
+               if (soft_line_break == 0) printf("\r\n");
+       }
+       exit(0);
+}