libclamav/uuencode.c
4c7e38d5
 /*
2023340a
  *  Copyright (C) 2007-2008 Sourcefire, Inc.
  *
  *  Authors: Nigel Horne
4c7e38d5
  *
  *  This program is free software; you can redistribute it and/or modify
2023340a
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
4c7e38d5
  *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
48b7b4a7
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  *  MA 02110-1301, USA.
4c7e38d5
  */
2023340a
 
155a1c63
 static	char	const	rcsid[] = "$Id: uuencode.c,v 1.8 2006/12/11 11:55:11 njh Exp $";
4c7e38d5
 
 #include "clamav.h"
 
a8efe447
 #if	HAVE_CONFIG_H
4c7e38d5
 #include "clamav-config.h"
 #endif
 
a8efe447
 #ifdef	HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 
4c7e38d5
 #include <stdio.h>
 #include <memory.h>
 #include <sys/stat.h>
155a1c63
 #ifdef	HAVE_STRINGS_H
 #include <strings.h>
 #endif
4c7e38d5
 #include "others.h"
d4a7dd82
 #include "str.h"
 
4c7e38d5
 #include "mbox.h"
 #include "uuencode.h"
 
 /* Maximum line length according to RFC821 */
 #define	RFC2821LENGTH	1000
 
 int
49cc1e3c
 cli_uuencode(const char *dir, fmap_t *map)
4c7e38d5
 {
 	message *m;
 	char buffer[RFC2821LENGTH + 1];
ee1b2a6c
 	size_t at = 0;
4c7e38d5
 
6761ac0a
 	if(!fmap_gets(map, buffer, &at, sizeof(buffer) - 1)) {
4c7e38d5
 		/* empty message */
 		return CL_CLEAN;
 	}
 	if(!isuuencodebegin(buffer)) {
f2d79ab3
 		cli_dbgmsg("Message is not in uuencoded format\n");
4c7e38d5
 		return CL_EFORMAT;
 	}
 
 	m = messageCreate();
 	if(m == NULL) {
 		return CL_EMEM;
 	}
 
 	cli_dbgmsg("found uuencode file\n");
 
ee1b2a6c
 	if(uudecodeFile(m, buffer, dir, map, &at) < 0) {
4c7e38d5
 		messageDestroy(m);
f2d79ab3
 		cli_dbgmsg("Message is not in uuencoded format\n");
4c7e38d5
 		return CL_EFORMAT;
 	}
 	messageDestroy(m);
 
 	return CL_CLEAN;	/* a lie - but it gets things going */
 }
 
 /*
  * Save the uuencoded part of the file as it is read in since there's no need
  * to include it in the parse tree. Saves memory and parse time.
  * Return < 0 for failure
  */
 int
49cc1e3c
 uudecodeFile(message *m, const char *firstline, const char *dir, fmap_t *map, size_t *at)
4c7e38d5
 {
 	fileblob *fb;
 	char buffer[RFC2821LENGTH + 1];
 	char *filename = cli_strtok(firstline, 2, " ");
 
 	if(filename == NULL)
 		return -1;
 
 	fb = fileblobCreate();
 	if(fb == NULL) {
 		free(filename);
 		return -1;
 	}
 
 	fileblobSetFilename(fb, dir, filename);
 	cli_dbgmsg("uudecode %s\n", filename);
 	free(filename);
 
ee1b2a6c
 	while(fmap_gets(map, buffer, at, sizeof(buffer) - 1)) {
4c7e38d5
 		unsigned char data[1024];
 		const unsigned char *uptr;
 		size_t len;
 
 		cli_chomp(buffer);
 		if(strcasecmp(buffer, "end") == 0)
 			break;
 		if(buffer[0] == '\0')
 			break;
 
 		uptr = decodeLine(m, UUENCODE, buffer, data, sizeof(data));
 		if(uptr == NULL)
 			break;
 
 		len = (size_t)(uptr - data);
 		if((len > 62) || (len == 0))
 			break;
 
 		if(fileblobAddData(fb, data, len) < 0)
 			break;
 	}
 
 	fileblobDestroy(fb);
 
 	return 1;
 }