/**************************************************************************/
/**                                                                      **/
/**               WWW HTML General Form Retrieval                        **/
/**                                                                      **/
/**               (c) 1994 Takoyaki Software Ltd.                        **/
/**                                                                      **/
/**                        ------------                                  **/
/**                                                                      **/
/**  Idea, programming, and magic are the personal copyright of          **/
/**  Dylan Cuthbert (dylan@takoyaki.demon.co.uk)                         **/
/**                                                                      **/
/**************************************************************************/
/* Version modifications                                                  */
/* v0.5 - first version                                                   */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <time.h>
#ifdef __GO32__
#include <osfcn.h>
#endif


#define VERSION "v0.5"

/** Allow up to 10000 entries in a form (a little over the top maybe?) **/

#define MAX_ENTRIES 10000

#define STARTCHAR '['
#define STOPCHAR ']'

/** if an entry can't be found return an empty string with this macro **/

#define entry(num,label) (((num)==-1)?"":entries[(num)].label)

/** structure for form entries received from the client **/

typedef struct {
    char *name;
    char *val;
} entry;

/** routines in util.c (public domain) **/

char *makeword(char *line, char stop);
char *fmakeword(FILE *f, char stop, int *len);
char x2c(char *what);
void unescape_url(char *url);
void plustospace(char *str);

entry entries[MAX_ENTRIES];
int max;

char wordbuf[10240];


/**********************************************/
/** Search through the FORM contents for a   **/
/** label of the specified name              **/

int findname(char *s)
	{
	int n;

	for (n=0;n<max;n++)
		if (stricmp(entries[n].name,s)==0) return n;

	return -1;
	}


/**********************************************/
void copyfile(char *backupname,char *fn)
	{
	FILE *out,*in;

	if (out = fopen(backupname,"w"))
		{
		if (in = fopen(fn,"r"))
			{

			while (!feof(in))
				fputc(fgetc(in),out);

			fclose(in);
			}
		fclose(out);
		}
	}


/*************************************************/
/** get a line of text from the file            **/
/** the line is separated by special characters **/
/** defined as STOPCHAR                         **/

char *fgetline(FILE *fp,char STARTchar, char STOPchar)
	{
	char *w=wordbuf;

	if (STARTchar)
		while(!feof(fp) && fgetc(fp)!=STARTchar)
			;

	while(!feof(fp) && (w-wordbuf)<10240-1)
		{
		*w++ = fgetc(fp);
		if (w[-1] == STOPchar)
			{
			w[-1] = '\0';
			break;
			}
		}
	w[0] = '\0';
	return wordbuf;
	}

/**********************************************/
/** get a word from the file                 **/

char *fgetword(FILE *fp)
	{
	char *w=wordbuf;
	char c;

	while(!feof(fp))
		{
		c = fgetc(fp);
		if (isalpha(c)) break;
		}

	if (isalpha(c)) *w++ = c;

	while(!feof(fp))
		{
		*w++ = fgetc(fp);
		if (w[-1] == ' ' || !isalpha(w[-1]))
			{
			w[-1] = '\0';
			break;
			}
		}
	*w = '\0';
	return wordbuf;
	}


/**********************************************/
void fhtmlchar(char c,FILE *fp)
	{
	if (c=='<' || c=='>' || c=='&' || c == 0x0d || (c<32 && c!='\t' && c!=0x0a))
		{
		switch(c)
			{
			case '<':
				fprintf(fp,"&lt;");
				break;
			case '&':
				fprintf(fp,"&amp;");
				break;
			case '>':
				fprintf(fp,"&gt;");
				break;
			default:
				break;
			}
		}
	else fprintf(fp,"%c",c);
	return;
	}


/**********************************************/
void htmlchar(char c)
	{
	fhtmlchar(c,stdout);
	}


/**********************************************/
void filterfile(char *file)
	{
	FILE *fp;
	char c;
#ifdef MODDATEPREFIX
	char modstr[]=MODDATEPREFIX;
#endif
	int hits=0,n;

	if (fp=fopen(file,"r"))
		{
		while (!feof(fp))
			{
			c = fgetc(fp);
#ifdef MODDATEPREFIX
			if (c==modstr[hits])
				{
				while (c == modstr[hits] && !feof(fp) && hits<strlen(modstr))
					{
					hits++;
					c = fgetc(fp);
					}

				if (hits==strlen(modstr))
					{
/* ok.. its the last modified string so delete everything up until the '.' */
/* by delete I mean just don't output it                                   */

					while (c!='.' && !feof(fp))
						c = fgetc(fp);

					hits = 0;
					continue;
					}
				else
					{
					for (n=0;n<hits;n++)
						htmlchar(modstr[n]);
					hits = 0;
					}
				}
#endif

			htmlchar(c);
			}
		fclose(fp);
		}
	}

/**********************************************/
void writefile(char *file, char *data)
	{
	FILE *fp;
	time_t tim;
	char buf[100];

	if (fp=fopen(file,"w"))
		{
	
		fwrite(data,strlen(data),1,fp);

#ifdef MODDATEPREFIX
		time(&tim);
		strftime(buf,100,"%y/%m/%d at %I:%M%p (JST)",localtime(&tim));
		fprintf(fp,"%s%s</I>.",MODDATEPREFIX,buf);
#endif

		fclose(fp);
		}
	}
/**********************************************/
int scanfile(char *fn,char *s)
	{
	int n=0;
	char c;
	FILE *fp;

	if (s[0]=='\0') return 1;

	if (fp = fopen(fn,"r"))
		{

		while (!feof(fp))
			{
			c = fgetc(fp);
			if (s[n] == c)
				{
				n++;
				if (s[n]=='\0')
					{
					c = fgetc(fp);
					fclose(fp);
					if (isalpha(c)) return 0;
					return 1;
					}
				}
			else n=0;
			}
		fclose(fp);
		}
	else return 0;

	return 0;
	}

/**********************************************/
/*  Process the template                      */

int Template(char *template)
	{
	FILE *fp,*op;
	char *on,c;
	char name[100];
	int n,m;

	if (fp = fopen(template,"r"))
		{
		on = fgetline(fp,STARTCHAR,STOPCHAR);
		
		if (op = fopen(on,"a"))
			{

			while (!feof(fp))
				{
				c = fgetc(fp);
				if (c == STARTCHAR)
					{
					c = fgetc(fp);
					if (c == STARTCHAR) fputc(c,op);
					else
						{
						name[0] = c;
						strcpy(name+1,fgetline(fp,0,STOPchar));
#ifdef __GO32__
						fprintf(op,"[%s]",name);
#else
						if ((n = findname(name))!=-1)
							{
							for (m=0;m<strlen(entry(n,val));m++)
								{
								fhtmlchar(entry(n,val)[m],op);
								}
							}
#endif
						}
					}
				else fputc(c,op);
				}

			fclose(op);
			}
		else { fclose(fp) ; return 0; }
		fclose(fp);
		}
	else return 0;
	return 1;
	}


/**********************************************/
/* the starting point of life as we know it   */

main(int argc, char *argv[]) {
	register int x,m=0,n;
	int cl;
	FILE *fp;
	char *cl2;

/* this is a header to say we are going to give Mosaic a html doc */

/* go to the src directory */

	Template("template.tst");
	exit(0);

/*********************************************************/
/**  Deal with GET requests                             **/
/**                                                     **/
/*********************************************************/

/* Check if its a GET or a POST request */

	if (strcmp(getenv("REQUEST_METHOD"),"POST"))
		{
/* if a GET request the data is sent as an environment variable */

		cl2 = getenv("QUERY_STRING");
		if(cl2 == NULL)
			{
			max = 0;
			}
		else
			{

/* pull the data out of the environment variable */
			cl2 = strdup(cl2);
			for(x=0;cl2[0] != '\0';x++) {
				m=x;
				entries[x].val = makeword(cl2,'&');
				plustospace(entries[x].val);
				unescape_url(entries[x].val);
				entries[x].name = makeword(entries[x].val,'=');
				}
			max = m+1;
			}

		return;
		}

/* now to deal with METHOD=POST type requests */

/* make sure the content type is readable by us */

	if(strcmp(getenv("CONTENT_TYPE"),"application/x-www-form-urlencoded")) {
		printf("<HR>There has been an error in the sending of the data.<BR>");
		printf("Please go back to the page and re-send.<HR>");
		printf("If the problem persists contact: <ADDRESS>dylan@takoyaki.demon.co.uk</ADDRESS>");
		exit(1);
		}

/* get the amount of data sent */

	cl = atoi(getenv("CONTENT_LENGTH"));

/* read in each item */

	for(x=0;cl && (!feof(stdin));x++) {
		m=x;
		entries[x].val = fmakeword(stdin,'&',&cl);
		plustospace(entries[x].val);
		unescape_url(entries[x].val);
		entries[x].name = makeword(entries[x].val,'=');
		}
	max = m+1;

/**********************************************************************/
/*  METHOD=POST data manipulation                                     */
/*                                                                    */
/**********************************************************************/

	printf("Content-type: text/html%c%c",10,10);

	if (findname("TEMPLATE")!=-1)
		{
		if (!Template(entry(findname("TEMPLATE"),val)))
			printf("<H1>Error: Non-existant Template!</H1>");
		}
	else
		{
		printf("<H1>Error: Non-existant Template!</H1>");
		}
	


}

/* LE FIN */

