/**************************************************************************/
/**                                                                      **/
/**               WWW HTML general search system                         **/
/**                                                                      **/
/**               (c) 1994 Takoyaki Software Ltd.                        **/
/**                                                                      **/
/**                        ------------                                  **/
/**                                                                      **/
/**  Idea, programming, and magic are the personal copyright of          **/
/**  Dylan Cuthbert (dylan@takoyaki.demon.co.uk)                         **/
/**                                                                      **/
/**************************************************************************/
/* __PASSLOCK=wombat                                                      */

#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.1"

#define CONFIGFILE "/home/vinz/htsearch.conf"

#define WWWPAGES "/home/vinz/www"

/** Allow up to 10000 entries in a form (a little over the top maybe?) **/

#define MAX_ENTRIES 10000

#define STOPCHAR 0x07

/** 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);
		}
	}

/**********************************************/
char *makebackupname(char *fn)
	{
	static char backupname[128];

	if (strlen(fn)>100) fn[100]='\0';

	strcpy(backupname,fn);

	if (strrchr(backupname,'.'))
		strcpy(strrchr(backupname,'.')+1,"bak");
	else strcpy(backupname+strlen(backupname),".bak");

	return backupname;
	}

/**********************************************/
void makebackup(char *fn)
	{

	copyfile(makebackupname(fn),fn);
	}



/*************************************************/
/** get a line of text from the file            **/
/** the line is separated by special characters **/
/** defined as STOPCHAR                         **/

char *fgetline(FILE *fp)
	{
	char *w=wordbuf;

	while(!feof(fp) && fgetc(fp)!=STOPCHAR)
		;

	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 filterfile(char *file)
	{
	FILE *fp;
	char c;
	if (fp=fopen(file,"r"))
		{
		while (!feof(fp))
			{
			c = fgetc(fp);
			if (c=='<' || c=='>' || c=='&' || c == 0x0d || (c<32 && c!='\t' && c!=0x0a))
				{
				switch(c)
					{
					case '<':
						printf("&lt;");
						break;
					case '&':
						printf("&amp;");
						break;
					case '>':
						printf("&gt;");
						break;
					default:
						break;
					}
				}
			else printf("%c",c);
			}
		fclose(fp);
		}
	}


/**********************************************/
void writefile(char *file, char *data)
	{
	FILE *fp;

	makebackup(file);

	if (fp=fopen(file,"w"))
		{
	
		fwrite(data,strlen(data),1,fp);
		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')
					{
					fclose(fp);
					return 1;
					}
				}
			else n=0;
			}
		fclose(fp);
		}
	else return 0;

	return 0;
	}



/**********************************************/
int checkpass(char *fn, char *pass)
	{
	char buf[128];

/* add a little more security here   */
/* only allow one '/' in the file    */
/* this is because this program is   */
/* run with root access so you       */
/* could edit any file on the system */
/* this limits the range             */

		if (stricmp(CONFIGFILE,fn))
			if (strchr(fn,'/'))
				if (strchr(strchr(fn,'/'),'/')) return 0;

	if (strlen(pass)>100) pass[100]='\0';

	sprintf(buf,"*admin-override: %s",pass);
	if (scanfile(CONFIGFILE,buf))
		{

		return 1;
		}

	sprintf(buf,"*%s: %s",fn,pass);
	return scanfile(CONFIGFILE,buf);
	}


/**********************************************/
/* 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 */

	printf("Content-type: text/html%c%c",10,10);

/* go to the src directory */

	chdir(WWWPAGES);

/*********************************************************/
/**  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;
			}


		if ((findname("STRING")!=-1) && (findname("FILE")!=-1))
			searchfile(entry(findname("STRING"),val),entry(findname("STRING"),val));
		else if (findname("FILE")!=-1)
			searchrequest(entry(findname("FILE"),val));
		return;
		}

/* now to deal with METHOD=POST type requests */
/* basically there shouldn't be any           */


		}

}

/* LE FIN */

