/*
 * Copyright (c) 1996-2007, OpenFWTK Development Group
 * All rights reserved. See LICENSE.
 */

/*
 *	(c) Marcus J. Ranum, the code is public domain 
 */

#include	<ctype.h>

#include	"firewall.h"

int
enargv(buf,av,avsiz,tobuf,bsiz)
char	*buf;
char	**av;
int	avsiz;
char	*tobuf;
int	bsiz;
{
	register	char	*ip = buf;
	register	char	*op = tobuf;
	register	char	*sp = 0;
	int		u_ac = 0;
	int		quot = 0;


	if(ip == (char *)0 || *ip == '\0') {
		av[0] = (char *)0;
		return(0);
	}
 	while(*ip && (isspace((unsigned char)*ip) ||
		     !isprint((unsigned char)*ip) ||
		     *ip == ','))
		ip++;

	while(*ip) {
		if(!isspace((unsigned char)*ip) && !isprint((unsigned char)*ip)) {
			ip++;
			continue;
		}

		if(!quot && (*ip == '\"' || *ip == '\'')) {
			quot = *ip++;

			if(sp == (char *)0)
				sp = op;
			if(bsiz - 1 < 0)
				return(-1);
			*op = '\0';
			continue;
		}
		if(isspace((unsigned char)*ip) && !quot) {
			if(--bsiz < 0)
				return(-1);
			*op++ = '\0';

			if(u_ac  + 1 >= avsiz)
				return(u_ac);

			av[u_ac++] = sp;
			sp = av[u_ac] = (char *)0;

		 	while(*ip && (isspace((unsigned char)*ip) ||
				     !isprint((unsigned char)*ip)))
				ip++;

			continue;
		}

		if(quot && *ip == quot) {
			quot = 0;
			ip++;
			continue;
		}

		if(*ip == '\\') {
			if(--bsiz < 0)
				return(-1);
			switch(*++ip) {
			case	'\0':
				continue;
			case	't':
				*op++ = '\t';
				break;

			case	'n':
				*op++ = '\n';
				break;

			default:
				*op++ = *ip;
			}
			ip++;
		}

		if(sp == (char *)0)
			sp = op;
		if(--bsiz < 0)
			return(-1);
		*op++ = *ip++;
	}

	if(sp != 0) {
		if(--bsiz < 0)
			return(-1);
		*op = '\0';

		if(u_ac  + 1 >= avsiz)
			return(u_ac);
		av[u_ac++] = sp;
		av[u_ac] = (char *)0;
	}
	av[u_ac] = (char *)0;
	return(u_ac);
}
