126 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
** Copyright 1998 - 1999 Double Precision, Inc.  See COPYING for
 | 
						|
** distribution information.
 | 
						|
*/
 | 
						|
 | 
						|
#if	HAVE_CONFIG_H
 | 
						|
#include	"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
 | 
						|
#ifdef __WINDOWS__
 | 
						|
#define strncasecmp strnicmp
 | 
						|
#include <io.h>
 | 
						|
#define read _read
 | 
						|
#define lseek _lseek
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
/* $Id$ */
 | 
						|
 | 
						|
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, int fd)
 | 
						|
{
 | 
						|
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, fd)) != 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 (lseek(fd, p->startbody, SEEK_SET) == -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=read(fd, buf, cnt);
 | 
						|
		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, int fd, 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, fd);
 | 
						|
	if (boundary_chk_buf)	free(boundary_chk_buf);
 | 
						|
	return (n);
 | 
						|
}
 |