* Brought over an update of the MIME parser from Citadel.
authorArt Cancro <ajc@citadel.org>
Mon, 3 Dec 2001 04:43:40 +0000 (04:43 +0000)
committerArt Cancro <ajc@citadel.org>
Mon, 3 Dec 2001 04:43:40 +0000 (04:43 +0000)
webcit/ChangeLog
webcit/cookie_conversion.c
webcit/mime_parser.c
webcit/webcit.h

index 10c1c5c94f48b2afd04fbb3acb11085a4db7a961..dfcaf2db998848a9c4807298bc11d063f73ca1b0 100644 (file)
@@ -1,4 +1,7 @@
 $Log$
+Revision 301.13  2001/12/03 04:43:40  ajc
+* Brought over an update of the MIME parser from Citadel.
+
 Revision 301.12  2001/12/02 07:09:13  ajc
 * Turned the room editing page into a tabbed dialog
 * Started adding some of the room sharing stuff
@@ -647,4 +650,3 @@ Sun Dec  6 19:50:55 EST 1998 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
 
 1998-12-03 Nathan Bryant <bryant@cs.usm.maine.edu>
        * webserver.c: warning fix
-
index dd39f1bb10ca259fbb79fa859ba989693abbb63d..83ae6ad8dbc25960099ad004daf972c07d231b71 100644 (file)
@@ -91,7 +91,7 @@ void encode_base64(char *dest, char *source)
 
 
 
-void decode_base64(char *dest, char *source)
+int decode_base64(char *dest, char *source)
 {
     int i;
     int dpos = 0;
@@ -122,9 +122,9 @@ void decode_base64(char *dest, char *source)
 
            if (c == 0) {
                if (i > 0) {
-                   return;
+                   return(dpos);
                }
-               return;
+               return(dpos);
            }
            if (dtable[c] & 0x80) {
                /* Ignoring errors: discard invalid character. */
@@ -143,7 +143,7 @@ void decode_base64(char *dest, char *source)
        if (i>=3) dest[dpos++] = o[2];
        dest[dpos] = 0;
        if (i < 3) {
-           return;
+           return(dpos);
        }
     }
 }
index f6a3e79f3e257d5567f9941024bb1a7c2cc938d0..2ada0e5297ff6ca9c37d5380b8c33d03df34e07f 100644 (file)
@@ -54,6 +54,71 @@ char *fixed_partnum(char *supplied_partnum) {
 }
 
 
+
+/*
+ * Convert "quoted-printable" to binary.  Returns number of bytes decoded.
+ */
+int decode_quoted_printable(char *decoded, char *encoded, int sourcelen) {
+       char buf[SIZ];
+       int buf_length = 0;
+       int soft_line_break = 0;
+       int ch;
+       int decoded_length = 0;
+       int i;
+
+       decoded[0] = 0;
+       decoded_length = 0;
+       buf[0] = 0;
+       buf_length = 0;
+
+       for (i = 0; i < sourcelen; ++i) {
+
+               buf[buf_length++] = encoded[i];
+
+               if ( (encoded[i] == '\n')
+                  || (encoded[i] == 0)
+                  || (i == (sourcelen-1)) ) {
+                       buf[buf_length++] = 0;
+
+                       /*** begin -- process one line ***/
+
+                       if (buf[strlen(buf)-1] == '\n') {
+                               buf[strlen(buf)-1] = 0;
+                       }
+                       if (buf[strlen(buf)-1] == '\r') {
+                               buf[strlen(buf)-1] = 0;
+                       }
+                       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);
+                                       decoded[decoded_length++] = ch;
+                                       strcpy(buf, &buf[3]);
+                               } else {
+                                       decoded[decoded_length++] = buf[0];
+                                       strcpy(buf, &buf[1]);
+                               }
+                       }
+                       if (soft_line_break == 0) {
+                               decoded[decoded_length++] = '\r';
+                               decoded[decoded_length++] = '\n';
+                       }
+                       buf_length = 0;
+                       /*** end -- process one line ***/
+               }
+       }
+
+       decoded[decoded_length++] = 0;
+       return(decoded_length);
+}
+
 /*
  * Given a message or message-part body and a length, handle any necessary
  * decoding and pass the request up the stack.
@@ -99,16 +164,7 @@ void mime_decode(char *partnum,
 {
 
        char *decoded;
-       struct stat statbuf;
-       int sendpipe[2];
-       int recvpipe[2];
-       int childpid;
-       size_t bytes_sent = 0;
-       size_t bytes_recv = 0;
-       size_t blocksize;
-       int write_error = 0;
-
-       fprintf(stderr, "mime_decode() called\n");
+       size_t bytes_decoded = 0;
 
        /* Some encodings aren't really encodings */
        if (!strcasecmp(encoding, "7bit"))
@@ -144,72 +200,28 @@ void mime_decode(char *partnum,
                fprintf(stderr, "ERROR: cannot allocate memory.\n");
                return;
        }
-       if (pipe(sendpipe) != 0)
-               return;
-       if (pipe(recvpipe) != 0)
-               return;
 
-       childpid = fork();
-       if (childpid < 0) {
-               free(decoded);
-               return;
+       if (!strcasecmp(encoding, "base64")) {
+               bytes_decoded = decode_base64(decoded, part_start);
        }
-       if (childpid == 0) {
-               close(2);
-               /* send stdio to the pipes */
-               if (dup2(sendpipe[0], 0) < 0)
-                       fprintf(stderr, "ERROR dup2()\n");
-               if (dup2(recvpipe[1], 1) < 0)
-                       fprintf(stderr, "ERROR dup2()\n");
-               close(sendpipe[1]);     /* Close the ends we're not using */
-               close(recvpipe[0]);
-               if (!strcasecmp(encoding, "base64"))
-                       execlp("./base64", "base64", "-d", NULL);
-               else if (!strcasecmp(encoding, "quoted-printable"))
-                       execlp("./qpdecode", "qpdecode", NULL);
-               fprintf(stderr, "ERROR: cannot exec decoder for %s\n", encoding);
-               exit(1);
-       }
-       close(sendpipe[0]);     /* Close the ends we're not using  */
-       close(recvpipe[1]);
-
-       while ((bytes_sent < length) && (write_error == 0)) {
-               /* Empty the input pipe FIRST */
-               while (fstat(recvpipe[0], &statbuf), (statbuf.st_size > 0)) {
-                       blocksize = read(recvpipe[0], &decoded[bytes_recv],
-                                        statbuf.st_size);
-                       if (blocksize < 0)
-                               fprintf(stderr, "ERROR: cannot read from pipe\n");
-                       else
-                               bytes_recv = bytes_recv + blocksize;
-               }
-               /* Then put some data into the output pipe */
-               blocksize = length - bytes_sent;
-               if (blocksize > 2048)
-                       blocksize = 2048;
-               if (write(sendpipe[1], &part_start[bytes_sent], blocksize) < 0) {
-                       fprintf(stderr, "ERROR: cannot write to pipe: %s\n",
-                               strerror(errno));
-                       write_error = 1;
-               }
-               bytes_sent = bytes_sent + blocksize;
-       }
-       close(sendpipe[1]);
-       /* Empty the input pipe */
-       while ((blocksize = read(recvpipe[0], &decoded[bytes_recv], 1)),
-              (blocksize > 0)) {
-               bytes_recv = bytes_recv + blocksize;
+       else if (!strcasecmp(encoding, "quoted-printable")) {
+               bytes_decoded = decode_quoted_printable(decoded,
+                                                       part_start, length);
        }
 
-       if (bytes_recv > 0) if (CallBack != NULL) {
+       if (bytes_decoded > 0) if (CallBack != NULL) {
                CallBack(name, filename, fixed_partnum(partnum),
                        disposition, decoded,
-                       content_type, bytes_recv, "binary", userdata);
+                       content_type, bytes_decoded, "binary", userdata);
        }
 
        free(decoded);
 }
 
+
+
+
+
 /*
  * Break out the components of a multipart message
  * (This function expects to be fed HEADERS + CONTENT)
index 499f05850f7ae9881b61248bf5702be00d183b38..940b34c434414149d2215767826529ee20c57b29 100644 (file)
@@ -283,3 +283,4 @@ char *memreadline(char *start, char *buf, int maxlen);
 int num_tokens (char *source, char tok);
 void extract_token(char *dest, char *source, int parmnum, char separator);
 void remove_token(char *source, int parmnum, char separator);
+int decode_base64(char *dest, char *source);