]> code.citadel.org Git - citadel.git/commitdiff
* mime_parser.c: now uses built-in functions to decode base64 and
authorArt Cancro <ajc@citadel.org>
Mon, 3 Dec 2001 04:28:03 +0000 (04:28 +0000)
committerArt Cancro <ajc@citadel.org>
Mon, 3 Dec 2001 04:28:03 +0000 (04:28 +0000)
  quoted-printable attachments, instead of piping data to outboard programs.

citadel/ChangeLog
citadel/Makefile.in
citadel/mime_parser.c
citadel/qpdecode.c [deleted file]
citadel/tools.c
citadel/tools.h

index 56fb591f92a63c1011b013b38bdc5d5b8d3e753e..3e31842791baea0e3184025d8d1448a9b4d55c56 100644 (file)
@@ -1,4 +1,8 @@
  $Log$
+ Revision 580.89  2001/12/03 04:28:02  ajc
+ * mime_parser.c: now uses built-in functions to decode base64 and
+   quoted-printable attachments, instead of piping data to outboard programs.
+
  Revision 580.88  2001/12/03 02:45:46  ajc
  * Began implementing some code to handle multiple recipients (but #define'd
    it all out because we're approaching a release)
@@ -2912,4 +2916,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import 
-
index 743b819b5bce9a5d32d9d0911f96117171b7af5f..fb1eb45ba2734c86958c2af656c14edde76dafbc 100644 (file)
@@ -42,7 +42,7 @@ SERV_MODULES=modules/libchat.la modules/libvcard.la \
        modules/libical.la
 UTIL_TARGETS=aidepost netsetup msgform readlog \
        stats citmail userlist sendcommand \
-       base64 qpdecode migratenet
+       base64 migratenet
 
 prefix=@prefix@
 srcdir=@srcdir@
@@ -88,7 +88,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 setup.c snprintf.c stats.c serv_vcard.c \
        support.c sysdep.c tools.c user_ops.c userlist.c serv_expire.c \
-       whobbs.c sendcommand.c mime_parser.c base64.c qpdecode.c getutline.c \
+       whobbs.c sendcommand.c mime_parser.c base64.c getutline.c \
        auth.c chkpwd.c html.c vcard.c serv_upgrade.c serv_vandelay.c \
        serv_smtp.c serv_pop3.c internet_addressing.c parsedate.c genstamp.c \
        $(DOMAIN) clientsocket.c serv_inetcfg.c serv_rwho.c serv_bio.c \
@@ -231,9 +231,6 @@ sendcommand: sendcommand.o ipc_c_tcp.o libcitserver.la $(LIBOBJS)
        $(LIBTOOL) $(CC) sendcommand.o ipc_c_tcp.o libcitserver.la \
         $(LIBOBJS) $(LDFLAGS) -o sendcommand $(NETLIBS)
 
-qpdecode: qpdecode.o
-       $(CC) qpdecode.o $(LDFLAGS) -o qpdecode
-
 base64: base64.o
        $(CC) base64.o $(LDFLAGS) -o base64
 
index 62f0397d43610cfce65a74b6643035ffba9a90ee..1dfd751d166f1221d394d012bc6ad8e15914fb06 100644 (file)
@@ -61,6 +61,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.
@@ -106,14 +171,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;
+       size_t bytes_decoded = 0;
 
        lprintf(9, "mime_decode() called\n");
 
@@ -146,75 +204,27 @@ void mime_decode(char *partnum,
         * assumption with base64, uuencode, and quoted-printable.  Just to
         * be safe, we still pad the buffer a bit.
         */
-       decoded = malloc(length + 1024);
+       decoded = mallok(length + 1024);
        if (decoded == NULL) {
                lprintf(9, "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 (childpid == 0) {
-               close(2);
-               /* send stdio to the pipes */
-               if (dup2(sendpipe[0], 0) < 0)
-                       lprintf(9, "ERROR dup2()\n");
-               if (dup2(recvpipe[1], 1) < 0)
-                       lprintf(9, "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);
-               lprintf(9, "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)
-                               lprintf(9, "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) {
-                       lprintf(9, "ERROR: cannot write to pipe: %s\n",
-                               strerror(errno));
-                       write_error = 1;
-               }
-               bytes_sent = bytes_sent + blocksize;
+       if (!strcasecmp(encoding, "base64")) {
+               bytes_decoded = decode_base64(decoded, part_start);
        }
-       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);
+       phree(decoded);
 }
 
 /*
diff --git a/citadel/qpdecode.c b/citadel/qpdecode.c
deleted file mode 100644 (file)
index 9468653..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * $Id$ 
- *
- * 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);
-}
index 8ff62786d6ce9fb41a8ceee9dc27442558a6c28e..c37b521429dff7e8d36995f254e61b14dc7a5280 100644 (file)
@@ -243,8 +243,10 @@ void encode_base64(char *dest, char *source)
 }
 
 
-
-void decode_base64(char *dest, char *source)
+/* 
+ * Convert base64-encoded to binary.  Returns the length of the decoded data.
+ */
+int decode_base64(char *dest, char *source)
 {
     int i;
     int dpos = 0;
@@ -275,9 +277,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. */
@@ -296,7 +298,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 bc3871e15a372fe640e39c1a609a76097f2e9875..d2fc6cf7fd3be244cafbae96b11d00a28d4893dd 100644 (file)
@@ -5,7 +5,7 @@ void extract_token(char *dest, char *source, int parmnum, char separator);
 int extract_int (char *source, int parmnum);
 long int extract_long (char *source, long int parmnum);
 void encode_base64(char *dest, char *source);
-void decode_base64(char *dest, char *source);
+int decode_base64(char *dest, char *source);
 void striplt(char *);
 int haschar(char *st, int ch);
 int collapsed_strcmp(char *s1, char *s2);