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);
							 | 
						||
| 
								 | 
							
								}
							 |