/*-------------------------------------------------------------------------*
 * title        : neurocounter                                             *
 * version      : v0.97                                                    *
 * programmer   : nam tran [neuropunk]                                     *
 * programmed   : december 1999                                            *
 * affiliations : neuropunk productions && neuronetwork                    *
 * urls	        : neuropunk.com && neuronetwork.cx                         *
 * e-mail       : neuroticism@hotmail.com                                  *
 * description  : This is a simple text based SSI counter. The story is    *
 *              : pretty funny. I was planning to implement file locking   *
 *              : but I couldn't find any functions that would actually    *
 *              : work under my win32 client and my compiler [lcc]. So     *
 *              : I came up w/ one of my "neuropunk's famous hacks" :)     *
 *              : Basically, two files are created, a *.chk and a *.dat    *
 *              : file. The *.chk tells the status of the *.dat, file and  *
 *              : whether or not it can be edited. I'm sure there will be  *
 *              : some some errors in this logic [at that split second...] *
 *              : but the same could also be said about the "true" file    *
 *              : locking functions. Oh yeah, this thing can support       *
 *              : infinite users, since it creates a new set of files for  *
 *              : every user, so I suggest you put this in a different     *
 *              : directory. syntax is: whatever/neurocnt.exe?name         *
 *-------------------------------------------------------------------------*/


/*--------------*
 * header files *
 *--------------*/
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>


/*------------------*
 * global variables *
 *------------------*/
 int MAX_N = 256;      //the max # of elements in an array


/*---------------------*
 * function prototypes *
 *---------------------*/
 void zero_one(FILE *chk); //converts 0 to 1, and closes the chk file
 void one_zero(FILE *chk); //converts 1 to 0, and closes the chk file



/*----------------------*
 * start of the program *
 *----------------------*/
 void main(int argc, char *argv[])
 {
	FILE *dat;         //points to actual hits
	FILE *chk;         //neuropunk's hack of a "lock" :)
	char *n_dat;       //used in construction of file name
	char *n_chk;       //used in construction of file name
	int status = 1;    //status of chk file, 1 means files are being used
	int cnt = 0;       //current count of data file

/*
	if(argc != 2)
	{
		printf("\n\n:incorrect arguments, exiting\n\n");
		exit(1);
	}
*/

	//MEMORY ALLOCATION
	n_dat = (char *) malloc(MAX_N * sizeof(char));
	n_chk = (char *) malloc(MAX_N * sizeof(char));
	if((n_dat==NULL)||(n_chk==NULL))
	{
		printf("\n\n:error allocatin memory, exiting\n\n");
		exit(1);
	}

	//CREATING THE FILE NAMES
	strcpy(n_dat, getenv("QUERY_STRING")); //should be the info after "?"
	strcat(n_dat, ".dat");
	strcpy(n_chk, getenv("QUERY_STRING"));
	strcat(n_chk, ".chk");



	//checking to see if the file even exists (by doing a read), if not
	//a *.dat and a *.chk file will be created.

	//by theory, if *.chk doesn't exist, then *.dat shouldn't exist either
	//i can't think of an instance when one would exist and the other
	//wouldn't



	//if check file doesn't exist, creating the *.dat and *.chk files
	//what happens if a chk file already exists? look past this
	//huge ass if statement

	if((chk = fopen(n_chk, "r+")) == NULL)	//if the *.chk file doesn't exist
	{
		dat = fopen(n_dat, "w+");
		chk = fopen(n_chk, "w+");

		if((dat==NULL)||(chk==NULL))
		{
			printf("\n\n:error creating file, exiting\n\n");
			exit(1);
		}

		//you have file, isn't ready for other's access [hence the 1], and
		//you have one hit. going to call a function to convert the
		//1 to a 0, meaning the file will be ready for access laters


		fprintf(chk, "1");
		fprintf(dat, "1"); //your first hit, so no reading previous data

		fclose(dat);       //hit file closed, but can't edit
		one_zero(chk);     //now the data file can be edited again

		//printing to web browser....
		printf("Content-type: text/html\n\n");
		printf("1");


		return;
	}


	while(status == 1)	//this is saying that a *.chk DOES exist
	{
		if((chk = fopen(n_chk, "r+")) == NULL)
		{
			printf("\n\n:error opening file, exiting\n\n");
			exit(1);
		}


		fscanf(chk, "%d", &status); //trying to pick up status...

		if(status == 1)
		{
			fclose(chk);	//so we can start again...
		}

		if(status == 0) //KICK ASS!!!
		{
			zero_one(chk);

			//i have to open the chk file again, because zero_one closes
			//the file, and when one_zero tries to edit the file...

			if((chk = fopen(n_chk, "r+")) == NULL)
			{
				printf("\n\n:error opening file, exiting\n\n");
				exit(1);
			}

			if((dat = fopen(n_dat, "r+")) == NULL)
			{
				printf("\n\n:error opening file, exiting\n\n");
				exit(1);
			}


			fscanf(dat, "%d", &cnt);
			cnt++;
			fseek(dat, 0, SEEK_SET);
			fprintf(dat, "%d", cnt);

			fclose(dat);   //can't edit the data file yet
			one_zero(chk); //now you can

			printf("Content-type: text/html\n\n");
			printf("%d", cnt);
		}
	}



	free(n_dat);
	free(n_chk);
 }



/*-------------------------------------------------------------------------*
 * name     : zero_one                                                     *
 * purpose  : converts a zero to a one and closes the file                 *
 * accepts  : FILE *                                                       *
 * returns  : void                                                         *
 * comments : none                                                         *
 *-------------------------------------------------------------------------*/
 void zero_one(FILE *chk)
 {
	fseek(chk, 0, SEEK_SET);
	fprintf(chk, "1");
	fclose(chk);
 }



/*-------------------------------------------------------------------------*
 * name     : one_zero                                                     *
 * purpose  : converts a one to a zero and closes the file                 *
 * accepts  : FILE *                                                       *
 * returns  : void                                                         *
 * comments : none                                                         *
 *-------------------------------------------------------------------------*/
 void one_zero(FILE *chk)
 {
	fseek(chk, 0, SEEK_SET);
	fseek(chk, 0, SEEK_SET);
	fprintf(chk, "0");
	fclose(chk);
 }


