#include	<stdio.h>

#include	<stdlib.h>
#include	<ctype.h>
#include	<string.h>
#include	<stdio.h>

struct	valinfo
{
	unsigned	char	*name;
	unsigned	char	*text;
};

char    *getval(char *name);

static	int	gotvals=0;
static	int	nvals=0;
static	struct	valinfo	*vals;


/* =============== httpunescape =========== */

static unsigned char *httpunescape(unsigned char *sis)
{
/*
	Removes HTTP escapes typically found in an HTTP 
	query string. These are the use of '+' for ' '
	and the use of %xx notation for special characters
	where 'xx' is the hexadecimal equivalent of the
	bits of the character.

	Returns	either
	
	(1) The address of the original string which
		is modified in place.
	(2) NULL meaning that there is some sort of
		error. The string is not modified.

*/
	unsigned char *siptr;		/* input string pointer */
	unsigned char *soptr;		/* output string pointer */
	unsigned char *sos;		/* start of output string */
/*
	Allocate enough space for a copy of the string
*/
	sos = (unsigned char *)calloc(strlen(sis)+1,sizeof (unsigned char));
	if(sos == NULL)	return NULL;
	soptr = sos;
	siptr = sis;
/*
	Loop walks the input string
*/
	while(*siptr)
	{
		if(*siptr == '%')	/* start of hex escape */
		{
			char c, h;

			c = toupper(*++siptr);
			if(c >= '0' && c <= '9') c = c-'0';
			else	       c = c-'A'+10;
			h = toupper(*++siptr);
			if(h >= '0' && h <= '9') h = h-'0';
			else	       h = h-'A'+10;

			*soptr++ = (unsigned char) ((c << 4) + h);	
		} 
		else 
		if(*siptr == '+')	
			*soptr++ = ' ';
		else
			*soptr++ = *siptr;

		siptr++;
	}
/*
	Input string walk completed, terminate generated
	string and copy onto old string. Finally free
	dynamic space used for building of new string.
*/
	*soptr = '\0';
	strcpy(sis,sos);
	free(sos);
	return sis;
}

/* =============== getvals =================== */
static	int 	getvals(void)
{
/* 
	gets the values associated with the
	query part of the URL. 

	Returns the number of values, the
	actual values and names are in the static
	array 'vals'.

	Works for both 'post' and 'get'
	methods. The environment variable
	REQUEST_METHOD is used to determine
	the type of input.
*/

	int	i;
	int	vcnt = 0;	/* count of number of name/value pairs */
	unsigned char	*vstr;		/* points to location of received string */
	unsigned char	*vptr;		/* used for walking received string */
	unsigned char	*eptr;		/* location of next '=' in received string */
	unsigned char	*aptr;		/* location of next '&' in received string */

	vstr = getenv("REQUEST_METHOD");
	if(vstr == NULL)	return 0;
	if(strcmp(vstr,"POST") == 0)
	{
		int	l,cl;
		vstr = getenv("CONTENT_LENGTH");
		if(vstr == NULL || strlen(vstr) == 0)
			return 0;
		if((cl = atoi(vstr)) == 0)	return 0;
		vstr = (char *)malloc(cl+2);	/* get some space */
		if(vstr == NULL)	return 0;
		fgets(vstr,cl+1,stdin);	/* read in the data */
		l = strlen(vstr);
		if(vstr[l-1] == '\n')	vstr[l-1]='\0';
	}
	else
	{
		vstr = getenv("QUERY_STRING");
		if(vstr == NULL)	return 0;
	}
	vptr = vstr;

	/*
		now to count the number of values assuming
		they are separated by '&' characters as per CGI.
	*/

	while(*vptr)	if(*vptr++ == '&')	vcnt++;
	vcnt++;

	/*
		grab some space for the storage of name value 
		pairs
	*/
	
	vals = (struct valinfo *)calloc(vcnt,sizeof (struct valinfo));
	if(vals == NULL)	return 0;
	vptr = vstr;

	/*
		locate the actual name/value pairs in the
		input string assuming name and value are
		separated by '='. Strings are in-place
		unescaped at this stage - on the important
		assumption that unescaping will NOT increase
		the length of a string.
	*/

	for(i=0;i<vcnt;i++)
	{
		eptr = strchr(vptr,'=');	
		aptr = strchr(vptr,'&');
		if(eptr == NULL)		return 0;
		*eptr = '\0';
		vals[i].name = httpunescape(vptr);
		if(vals[i].name == NULL)	return 0;	
		if(aptr)
		{
			*aptr = '\0';
			vptr = aptr+1;
		}
		vals[i].text = httpunescape(eptr+1);
		if(vals[i].text == NULL)	return 0;
	}	
	return vcnt;
}

/* =============== getval ================= */

char	*getval(char *name)
{
/*
	Returns a pointer to the value
	associated with the string 'name'.
	As a side effect the values are
	obtained and unescaped if this
	has not already been done.

	Returns NULL if no value available or	
	an error has occured whilst processing
	the string from the remote browser.

*/
	int	i;
	if(!gotvals)
	{
		nvals = getvals();
		gotvals = 1;
	}
	if(nvals == 0)	return NULL;

/* 
	linear search of saved name/value
	pairs looking for name match 
*/
	for(i=0;i<nvals;i++)
	{
		if(strcmp(name,vals[i].name)==0)
			return vals[i].text;
	}
	return NULL;
}


main()
{
	int	x,y;
	char	*recipient, *header, *title;
	char	*realname, *email, *matricula;
	char	*q01, *q02, *q03, *q04, *q05, *q06, *q07, *q08, *q09, *q10;
	char	*comentarios;
	FILE	*arq;

        recipient = getval("recipient");
        header = getval("header");
        title = getval("title");

	realname = getval ("realname");
	email = getval ("email");
	matricula = getval ("matricula");

        q01 = getval("q01");
        q02 = getval("q02");
        q03 = getval("q03");
        q04 = getval("q04");
        q05 = getval("q05");
        q06 = getval("q06");
	q07 = getval("q07");
        q08 = getval("q08");
        q09 = getval("q09");
        q10 = getval("q10");
        comentarios = getval("comentarios");

	printf("Content-type: text/html\n\n");
	printf("<html><head><title>%s</title></head>\n", title);
	printf("<body><h2>%s</h2>\n", header);

	printf ("Nome:      %s<p>\n", realname);
	printf ("Email:     %s<p>\n", email);
	printf ("Matricula: %s<p>\n", matricula);

	if ((arq = fopen ("/home/antonio2/provas", "a")) == NULL)
	{
		printf ("Problemas: arquivo n&atilde;o pode ser enviado<br>");
		printf("</body></html>\n");
		exit (0);
	}

	printf ("Destino    : %s\n", recipient);
	printf ("Nome       : %s\n", realname);
	printf ("Email      : %s\n", email);
	printf ("Matricula  : %s\n", matricula);
	printf ("q01: %s<br>\n", q01);
	printf ("q02: %s<br>\n", q02);
	printf ("q03: %s<br>\n", q03);
	printf ("q04: %s<br>\n", q04);
	printf ("q05: %s<br>\n", q05);
	printf ("q06: %s<br>\n", q06);
	printf ("q07: %s<br>\n", q07);
	printf ("q08: %s<br>\n", q08);
	printf ("q09: %s<br>\n", q09);
	printf ("q10: %s<br>\n", q10);
	printf ("comentarios: %s<br>\n", comentarios);
	printf("</body></html>\n");

	fprintf (arq, "Destino    : %s\n", recipient);
	fprintf (arq, "Nome       : %s\n", realname);
	fprintf (arq, "Email      : %s\n", email);
	fprintf (arq, "Matricula  : %s\n", matricula);
	fprintf (arq, "q01        : %s\n", q01);
	fprintf (arq, "q02        : %s\n", q02);
	fprintf (arq, "q03        : %s\n", q03);
	fprintf (arq, "q04        : %s\n", q04);
	fprintf (arq, "q05        : %s\n", q05);
	fprintf (arq, "q06        : %s\n", q06);
	fprintf (arq, "q07        : %s\n", q07);
	fprintf (arq, "q08        : %s\n", q08);
	fprintf (arq, "q09        : %s\n", q09);
	fprintf (arq, "q10        : %s\n", q10);
	fprintf (arq, "comentarios: %s\n", comentarios);
	fprintf (arq, "------------------------------------------\n");
	fclose (arq);

}

