1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
/*
** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for
** distribution information.
*/
#if HAVE_CONFIG_H
#include "rfc2045_config.h"
#endif
#include "rfc2045.h"
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if HAVE_STRINGS_H
#include <strings.h>
#endif
extern void rfc2045_add_buf( char **, size_t *, size_t *,
const char *, size_t);
static const char *boundary_chk_val;
static size_t boundary_chk_val_len;
static char *boundary_chk_buf;
static size_t boundary_chk_bufsize, boundary_chk_buflen;
static int boundary_chk_flag;
static void boundary_chk_add(const char *p, size_t l)
{
if (boundary_chk_buflen < boundary_chk_val_len+20)
rfc2045_add_buf( &boundary_chk_buf,
&boundary_chk_bufsize,
&boundary_chk_buflen, p, l);
}
static int boundary_chk(const char *p, size_t l, void *ptr)
{
static size_t i, j;
for (j=i=0; i<l; i++)
{
if (p[i] == '\n')
{
boundary_chk_add(p+j, i-j);
if (boundary_chk_buflen >= boundary_chk_val_len+2 &&
boundary_chk_buf[0] == '-' &&
boundary_chk_buf[1] == '-' &&
strncasecmp(boundary_chk_val,
boundary_chk_buf+2,
boundary_chk_val_len) == 0)
boundary_chk_flag=1;
boundary_chk_buflen=0;
j=i+1;
}
}
boundary_chk_add(p+j, l-j);
return (0);
}
static int try_boundary(struct rfc2045 *p, struct rfc2045src *src)
{
int rc;
char buf[512];
int n, cnt;
off_t ps;
if (p->firstpart)
{
for (p=p->firstpart; p; p=p->next)
if ((rc=try_boundary(p, src)) != 0)
return (rc);
return (0);
}
if (p->content_transfer_encoding &&
strcmp(p->content_transfer_encoding, "base64") == 0)
return (0);
boundary_chk_flag=0;
boundary_chk_buflen=0;
if ((*src->seek_func)(p->startbody, src->arg) == -1) return (-1);
rfc2045_cdecode_start(p, boundary_chk, 0);
ps=p->startbody;
while (ps < p->endbody)
{
if (p->endbody - ps < sizeof(buf))
cnt=p->endbody-ps;
else cnt=sizeof(buf);
n=(*src->read_func)(buf, cnt, src->arg);
if (n <= 0) return (-1);
rfc2045_cdecode(p, buf, n);
ps += n;
if (boundary_chk_flag) break;
}
rfc2045_cdecode_end(p);
if (boundary_chk_buflen)
boundary_chk("\n", 1, 0); /* Flush out partial line */
return (boundary_chk_flag);
}
int rfc2045_try_boundary(struct rfc2045 *p, struct rfc2045src *src,
const char *boundary)
{
int n;
boundary_chk_val_len=strlen(boundary_chk_val=boundary);
boundary_chk_buf=0;
boundary_chk_bufsize=0;
n=try_boundary(p, src);
if (boundary_chk_buf) free(boundary_chk_buf);
return (n);
}
|