Back to index

courier  0.68.2
rfc2045tryboundary.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 1998 - 1999 Double Precision, Inc.  See COPYING for
00003 ** distribution information.
00004 */
00005 
00006 #if    HAVE_CONFIG_H
00007 #include "rfc2045_config.h"
00008 #endif
00009 #include      "rfc2045.h"
00010 #if    HAVE_UNISTD_H
00011 #include      <unistd.h>
00012 #endif
00013 #include      <stdio.h>
00014 #include      <stdlib.h>
00015 #include       <string.h>
00016 #if    HAVE_STRINGS_H
00017 #include       <strings.h>
00018 #endif
00019 
00020 
00021 
00022 extern void rfc2045_add_buf( char **, size_t *, size_t *,
00023        const char *, size_t);
00024 
00025 static const char *boundary_chk_val;
00026 static size_t boundary_chk_val_len;
00027 static char *boundary_chk_buf;
00028 static size_t boundary_chk_bufsize, boundary_chk_buflen;
00029 static int boundary_chk_flag;
00030 
00031 static void boundary_chk_add(const char *p, size_t l)
00032 {
00033        if (boundary_chk_buflen < boundary_chk_val_len+20)
00034               rfc2045_add_buf( &boundary_chk_buf,
00035                      &boundary_chk_bufsize,
00036                      &boundary_chk_buflen, p, l);
00037 }
00038 
00039 static int boundary_chk(const char *p, size_t l, void *ptr)
00040 {
00041 static size_t i, j;
00042 
00043        for (j=i=0; i<l; i++)
00044        {
00045               if (p[i] == '\n')
00046               {
00047                      boundary_chk_add(p+j, i-j);
00048 
00049                      if (boundary_chk_buflen >= boundary_chk_val_len+2 &&
00050                             boundary_chk_buf[0] == '-' &&
00051                             boundary_chk_buf[1] == '-' &&
00052                             strncasecmp(boundary_chk_val,
00053                                    boundary_chk_buf+2,
00054                                    boundary_chk_val_len) == 0)
00055                                    boundary_chk_flag=1;
00056                                    
00057                      boundary_chk_buflen=0;
00058                      j=i+1;
00059               }
00060        }
00061        boundary_chk_add(p+j, l-j);
00062        return (0);
00063 }
00064 
00065 static int try_boundary(struct rfc2045 *p, struct rfc2045src *src)
00066 {
00067 int    rc;
00068 char   buf[512];
00069 int    n, cnt;
00070 off_t  ps;
00071 
00072        if (p->firstpart)
00073        {
00074               for (p=p->firstpart; p; p=p->next)
00075                      if ((rc=try_boundary(p, src)) != 0)
00076                             return (rc);
00077               return (0);
00078        }
00079 
00080        if (p->content_transfer_encoding &&
00081               strcmp(p->content_transfer_encoding, "base64") == 0)
00082               return (0);
00083 
00084        boundary_chk_flag=0;
00085        boundary_chk_buflen=0;
00086 
00087        if ((*src->seek_func)(p->startbody, src->arg) == -1)    return (-1);
00088        rfc2045_cdecode_start(p, boundary_chk, 0);
00089 
00090        ps=p->startbody;
00091        while (ps < p->endbody)
00092        {
00093               if (p->endbody - ps < sizeof(buf))
00094                      cnt=p->endbody-ps;
00095               else   cnt=sizeof(buf);
00096               n=(*src->read_func)(buf, cnt, src->arg);
00097               if (n <= 0)   return (-1);
00098               rfc2045_cdecode(p, buf, n);
00099               ps += n;
00100               if (boundary_chk_flag)      break;
00101        }
00102        rfc2045_cdecode_end(p);
00103        if (boundary_chk_buflen)
00104               boundary_chk("\n", 1, 0);   /* Flush out partial line */
00105        return (boundary_chk_flag);
00106 }
00107 
00108 int rfc2045_try_boundary(struct rfc2045 *p, struct rfc2045src *src,
00109                       const char *boundary)
00110 {
00111 int    n;
00112 
00113        boundary_chk_val_len=strlen(boundary_chk_val=boundary);
00114        boundary_chk_buf=0;
00115        boundary_chk_bufsize=0;
00116        n=try_boundary(p, src);
00117        if (boundary_chk_buf)       free(boundary_chk_buf);
00118        return (n);
00119 }