From 4802f475fa45ea1145a9f85bee789f637efa2866 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Mon, 3 Dec 2001 04:43:40 +0000 Subject: [PATCH] * Brought over an update of the MIME parser from Citadel. --- webcit/ChangeLog | 4 +- webcit/cookie_conversion.c | 8 +-- webcit/mime_parser.c | 142 ++++++++++++++++++++----------------- webcit/webcit.h | 1 + 4 files changed, 85 insertions(+), 70 deletions(-) diff --git a/webcit/ChangeLog b/webcit/ChangeLog index 10c1c5c94..dfcaf2db9 100644 --- a/webcit/ChangeLog +++ b/webcit/ChangeLog @@ -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 1998-12-03 Nathan Bryant * webserver.c: warning fix - diff --git a/webcit/cookie_conversion.c b/webcit/cookie_conversion.c index dd39f1bb1..83ae6ad8d 100644 --- a/webcit/cookie_conversion.c +++ b/webcit/cookie_conversion.c @@ -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); } } } diff --git a/webcit/mime_parser.c b/webcit/mime_parser.c index f6a3e79f3..2ada0e529 100644 --- a/webcit/mime_parser.c +++ b/webcit/mime_parser.c @@ -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) diff --git a/webcit/webcit.h b/webcit/webcit.h index 499f05850..940b34c43 100644 --- a/webcit/webcit.h +++ b/webcit/webcit.h @@ -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); -- 2.39.2