/*
 *  Copyright (C) 2002 Nigel Horne <njh@bandsman.co.uk>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *  MA 02110-1301, USA.
 *
 * $Log: text.c,v $
 * Revision 1.25  2007/02/12 20:46:09  njh
 * Various tidy
 *
 * Revision 1.24  2006/09/13 20:53:50  njh
 * Added debug
 *
 * Revision 1.23  2006/07/14 12:13:08  njh
 * Typo
 *
 * Revision 1.22  2006/07/01 21:03:36  njh
 * Better use of destroy mode
 *
 * Revision 1.21  2006/07/01 16:17:35  njh
 * Added destroy flag
 *
 * Revision 1.20  2006/07/01 03:47:50  njh
 * Don't loop if binhex runs out of memory
 *
 * Revision 1.19  2006/05/19 11:02:12  njh
 * Just include mbox.h
 *
 * Revision 1.18  2006/05/04 10:37:03  nigelhorne
 * Speed up scanning of clean files
 *
 * Revision 1.17  2006/05/03 09:36:40  nigelhorne
 * Pass full ctx into the mbox code
 *
 * Revision 1.16  2006/04/09 19:59:28  kojm
 * update GPL headers with new address for FSF
 *
 * Revision 1.15  2005/03/10 08:50:49  nigelhorne
 * Tidy
 *
 * Revision 1.14  2005/01/19 05:31:55  nigelhorne
 * Added textIterate
 *
 * Revision 1.13  2004/12/08 19:03:41  nigelhorne
 * Fix compilation error on Solaris
 *
 * Revision 1.12  2004/12/04 16:03:55  nigelhorne
 * Text/plain now handled as no encoding
 *
 * Revision 1.11  2004/11/27 21:54:26  nigelhorne
 * Tidy
 *
 * Revision 1.10  2004/08/22 10:34:24  nigelhorne
 * Use fileblob
 *
 * Revision 1.9  2004/08/21 11:57:57  nigelhorne
 * Use line.[ch]
 *
 * Revision 1.8  2004/07/20 14:35:29  nigelhorne
 * Some MYDOOM.I were getting through
 *
 * Revision 1.7  2004/06/22 04:08:02  nigelhorne
 * Optimise empty lines
 *
 * Revision 1.6  2004/05/05 09:37:52  nigelhorne
 * Removed textClean - not needed in clamAV
 *
 * Revision 1.5  2004/03/25 22:40:46  nigelhorne
 * Removed even more calls to realloc and some duplicated code
 *
 * Revision 1.4  2004/02/26 13:26:34  nigelhorne
 * Handle spaces at the end of uuencoded lines
 *
 */

static	char	const	rcsid[] = "$Id: text.c,v 1.25 2007/02/12 20:46:09 njh Exp $";

#if HAVE_CONFIG_H
#include "clamav-config.h"
#endif

#ifndef	CL_DEBUG
#define	NDEBUG	/* map CLAMAV debug onto standard */
#endif

#include <stdlib.h>
#ifdef	C_DARWIN
#include <sys/types.h>
#else
#ifdef HAVE_MALLOC_H /* tk: FreeBSD-CURRENT doesn't support malloc.h */
#ifndef	C_BSD	/* BSD now uses stdlib.h */
#include <malloc.h>
#endif
#endif
#endif
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <stdio.h>

#include "others.h"

#include "mbox.h"

static	text	*textCopy(const text *t_head);
static	text	*textAdd(text *t_head, const text *t);
static	void	addToFileblob(const line_t *line, void *arg);
static	void	getLength(const line_t *line, void *arg);
static	void	addToBlob(const line_t *line, void *arg);
static	void	*textIterate(text *t_text, void (*cb)(const line_t *line, void *arg), void *arg, int destroy);

void
textDestroy(text *t_head)
{
	while(t_head) {
		text *t_next = t_head->t_next;
		if(t_head->t_line)
			(void)lineUnlink(t_head->t_line);
		free(t_head);
		t_head = t_next;
	}
}

/* Clone the current object */
static text *
textCopy(const text *t_head)
{
	text *first = NULL, *last = NULL;

	while(t_head) {
		if(first == NULL)
			last = first = (text *)cli_malloc(sizeof(text));
		else {
			last->t_next = (text *)cli_malloc(sizeof(text));
			last = last->t_next;
		}

		if(last == NULL) {
			if(first)
				textDestroy(first);
			return NULL;
		}

		if(t_head->t_line)
			last->t_line = lineLink(t_head->t_line);
		else
			last->t_line = NULL;

		t_head = t_head->t_next;
	}

	if(first)
		last->t_next = NULL;

	return first;
}

/* Add a copy of a text to the end of the current object */
static text *
textAdd(text *t_head, const text *t)
{
	text *ret;
	int count;

	if(t_head == NULL) {
		if(t == NULL) {
			cli_errmsg("textAdd fails sanity check\n");
			return NULL;
		}
		return textCopy(t);
	}

	if(t == NULL)
		return t_head;

	ret = t_head;

	count = 0;
	while(t_head->t_next) {
		count++;
		t_head = t_head->t_next;
	}

	cli_dbgmsg("textAdd: count = %d\n", count);

	while(t) {
		t_head->t_next = (text *)cli_malloc(sizeof(text));
		t_head = t_head->t_next;

		assert(t_head != NULL);

		if(t->t_line)
			t_head->t_line = lineLink(t->t_line);
		else
			t_head->t_line = NULL;

		t = t->t_next;
	}

	t_head->t_next = NULL;

	return ret;
}

/*
 * Add a message's content to the end of the current object
 */
text *
textAddMessage(text *aText, message *aMessage)
{
	assert(aMessage != NULL);

	if(messageGetEncoding(aMessage) == NOENCODING)
		return textAdd(aText, messageGetBody(aMessage));
	else {
		text *anotherText = messageToText(aMessage);

		if(aText)
			return textMove(aText, anotherText);
		return anotherText;
	}
}

/*
 * Put the contents of the given text at the end of the current object.
 * The given text emptied; it can be used again if needed, though be warned that
 * it will have an empty line at the start.
 */
text *
textMove(text *t_head, text *t)
{
	text *ret;

	if(t_head == NULL) {
		if(t == NULL) {
			cli_errmsg("textMove fails sanity check\n");
			return NULL;
		}
		t_head = (text *)cli_malloc(sizeof(text));
		if(t_head == NULL)
			return NULL;
		t_head->t_line = t->t_line;
		t_head->t_next = t->t_next;
		t->t_line = NULL;
		t->t_next = NULL;
		return t_head;
	}

	if(t == NULL)
		return t_head;

	ret = t_head;

	while(t_head->t_next)
		t_head = t_head->t_next;

	/*
	 * Move the first line manually so that the caller is left clean but
	 * empty, the rest is moved by a simple pointer reassignment
	 */
	t_head->t_next = (text *)cli_malloc(sizeof(text));
	if(t_head->t_next == NULL)
		return NULL;
	t_head = t_head->t_next;

	assert(t_head != NULL);

	if(t->t_line) {
		t_head->t_line = t->t_line;
		t->t_line = NULL;
	} else
		t_head->t_line = NULL;

	t_head->t_next = t->t_next;
	t->t_next = NULL;

	return ret;
}

/*
 * Transfer the contents of the text into a blob
 * The caller must free the returned blob if b is NULL
 */
blob *
textToBlob(text *t, blob *b, int destroy)
{
	size_t s;
	blob *bin;

	if(t == NULL)
		return NULL;

	s = 0;

	(void)textIterate(t, getLength, &s, 0);

	if(s == 0)
		return b;

	/*
	 * copy b. If b is NULL and an error occurs we know we need to free
	 *	before returning
	 */
	bin = b;
	if(b == NULL) {
		b = blobCreate();

		if(b == NULL)
			return NULL;
	}

	if(blobGrow(b, s) != CL_SUCCESS) {
		cli_warnmsg("Couldn't grow the blob: we may be low on memory\n");
#if	0
		if(!destroy) {
			if(bin == NULL)
				blobDestroy(b);
			return NULL;
		}
		/*
		 * We may be able to recover enough memory as we destroy to
		 * create the blob
		 */
#else
		if(bin == NULL)
			blobDestroy(b);
		return NULL;
#endif
	}

	(void)textIterate(t, addToBlob, b, destroy);

	if(destroy && t->t_next) {
		textDestroy(t->t_next);
		t->t_next = NULL;
	}

	blobClose(b);

	return b;
}

fileblob *
textToFileblob(text *t, fileblob *fb, int destroy)
{
	assert(fb != NULL);
	assert(t != NULL);

	if(fb == NULL) {
		cli_dbgmsg("textToFileBlob, destroy = %d\n", destroy);
		fb = fileblobCreate();

		if(fb == NULL)
			return NULL;
	} else {
		cli_dbgmsg("textToFileBlob to %s, destroy = %d\n",
			fileblobGetFilename(fb), destroy);

		fb->ctx = NULL;	/* no need to scan */
	}

	fb = textIterate(t, addToFileblob, fb, destroy);
	if(destroy && t->t_next) {
		textDestroy(t->t_next);
		t->t_next = NULL;
	}
	return fb;
}

static void
getLength(const line_t *line, void *arg)
{
	size_t *length = (size_t *)arg;

	if(line)
		*length += strlen(lineGetData(line)) + 1;
	else
		(*length)++;
}

static void
addToBlob(const line_t *line, void *arg)
{
	blob *b = (blob *)arg;

	if(line) {
		const char *l = lineGetData(line);

		blobAddData(b, (const unsigned char *)l, strlen(l));
	}
	blobAddData(b, (const unsigned char *)"\n", 1);
}

static void
addToFileblob(const line_t *line, void *arg)
{
	fileblob *fb = (fileblob *)arg;

	if(line) {
		const char *l = lineGetData(line);

		fileblobAddData(fb, (const unsigned char *)l, strlen(l));
	}
	fileblobAddData(fb, (const unsigned char *)"\n", 1);
}

static void *
textIterate(text *t_text, void (*cb)(const line_t *item, void *arg), void *arg, int destroy)
{
	/*
	 * Have two loops rather than one, so that we're not checking the
	 * value of "destroy" lots and lots of times
	 */
#if	0
	while(t_text) {
		(*cb)(t_text->t_line, arg);

		if(destroy && t_text->t_line) {
			lineUnlink(t_text->t_line);
			t_text->t_line = NULL;
		}

		t_text = t_text->t_next;
	}
#else
	if(destroy)
		while(t_text) {
			(*cb)(t_text->t_line, arg);

			if(t_text->t_line) {
				lineUnlink(t_text->t_line);
				t_text->t_line = NULL;
			}

			t_text = t_text->t_next;
		}
	else
		while(t_text) {
			(*cb)(t_text->t_line, arg);

			t_text = t_text->t_next;
		}
#endif
	return arg;
}
