/*------------------------------------------------
//
// Module: counter.c
//
// Objet : compteur d'access par PATH_INFO
//
// ToDo  : 
//
//
//
// Maintenance :
//
//     Auteur  : Olivier Booklage
//     Version : V1.0
//     Date    : 20/04/1998
//     Remarq. :
//
//		modified by Ronald Andersson 1998.07.22
//		(see 'RA:' comments in code)
//
//-----------------------------------------------*/


/* ---       Includes externes       -- */

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

/* ---       Includes internes       -- */

/* --- Constantes globales internes --- */

/* --- Structures globales internes --- */

/* --- Variables globales  internes --- */

/* D‚finition bitmap des 10 chiffres */
/* Chaque chiffre est correspond a 8*16 points */

char *digits[] =
      {"0xff","0xff","0xff","0xc3","0x99","0x99","0x99","0x99",
           "0x99","0x99","0x99","0x99","0xc3","0xff","0xff","0xff",
           "0xff","0xff","0xff","0xcf","0xc7","0xcf","0xcf","0xcf",
           "0xcf","0xcf","0xcf","0xcf","0xcf","0xff","0xff","0xff",
           "0xff","0xff","0xff","0xc3","0x99","0x9f","0x9f","0xcf",
           "0xe7","0xf3","0xf9","0xf9","0x81","0xff","0xff","0xff",
           "0xff","0xff","0xff","0xc3","0x99","0x9f","0x9f","0xc7",
           "0x9f","0x9f","0x9f","0x99","0xc3","0xff","0xff","0xff",
           "0xff","0xff","0xff","0xcf","0xcf","0xc7","0xc7","0xcb",
           "0xcb","0xcd","0x81","0xcf","0x87","0xff","0xff","0xff",
           "0xff","0xff","0xff","0x81","0xf9","0xf9","0xf9","0xc1",
           "0x9f","0x9f","0x9f","0x99","0xc3","0xff","0xff","0xff",
           "0xff","0xff","0xff","0xc7","0xf3","0xf9","0xf9","0xc1",
           "0x99","0x99","0x99","0x99","0xc3","0xff","0xff","0xff",
           "0xff","0xff","0xff","0x81","0x99","0x9f","0x9f","0xcf",
           "0xcf","0xe7","0xe7","0xf3","0xf3","0xff","0xff","0xff",
           "0xff","0xff","0xff","0xc3","0x99","0x99","0x99","0xc3",
           "0x99","0x99","0x99","0x99","0xc3","0xff","0xff","0xff",
           "0xff","0xff","0xff","0xc3","0x99","0x99","0x99","0x99",
           "0x83","0x9f","0x9f","0xcf","0xe3","0xff","0xff","0xff"
           };

/* ---     Prototypage interne      --- */

int main (void);
static void servererr(char *msg);

/* ---         Fonctions            --- */

int main (void)
{
FILE *fp = NULL;
FILE *out = NULL;

char numb[8];				/* RA: old array size was 7 */
char hold[9]= "00000000";	/* RA: old array size was 8 */
/* since output is 7 digits, they should all work !!! */
/* and string termination is (as always) required !!! */

char cc[]= "0";
int x, y, c;
long num;	/* RA: was 'int' == not enough digits */
long len,i;
char *ref;

/* RA: Below is obviously the code that needs to be edited */
/*     to give more flexible path handling...              */

	ref=getenv("PATH_TRANSLATED");
	if((ref== NULL) || (!ref[0]))
		servererr("No PATH_INFO given. Please read the counter documentation.<P>");

/* Get the old count value, assuming 0 if no file */
	fp = fopen(ref,"r");
	if( fp !=NULL)
	{
		fgets(numb, 8, fp);
		fclose(fp);
		sscanf(numb,"%ld",&num);	/* RA: now uses long num */
		if ( num < 0 )
			num = 0;	/* RA: fix negative count to 0 */
	}
	else
		num = 0;	/* RA: fix missing file to 0 count */
	
/* Increment access counter by 1, but limit to 7 digits */
	if ( num < 9999999L )	/* RA: NEW: check size */
		num++;
	else
		num = 9999999L;		/* RA: NEW: lock at max value */

/* RA: Thanks to the changes the count is now guaranteed to */
/*     be in the range 0 through 9999999 in all code below. */
/*     Lacking this guarantee caused bugs previously.       */

/* Save/create a file with updated counter data */
	out = fopen(ref,"w");
	if( out !=NULL )
	{
		fprintf(out,"%ld",num);	/* RA: now uses long num */
		fclose(out);
	}
	else
	{
		fprintf(stderr,"\aCOUNTER:Unable to write <%s> file\n",ref);
		return(-1);
	}

/* RA: The old code used the pre-increment count below,  */
/*     which is incorrect, for a new page should start   */
/*     with a count of zero, but as soon as it is used   */
/*     the count returned should include the new access, */
/*     so we need to reconvert the new count to a string */

	ultoa( num, numb, 10);	/* RA: now 'numb' is updated */

/* A count of 1234 causes numb="1234" and hold="00001234" */
	len = strlen(numb);
	for (i=0; i<len; i++)
	{
		hold[8-len+i] = numb[i];
	}
/* NB: The above code makes the first byte of 'hold' useless */
/*     and must be a workaround to avoid the problems caused */
/*     by dimensioning 'numb' 1 byte too small earlier...    */
/*     It still works though, so I let it be.                */
/*     If changed, 2 similar changes are needed below too,   */
/*     on a line followed by an 'NB:' remark. */

/* Creation de l'entete de la sortie standard du script */

	printf ("Content-type: image/x-xbitmap%c%c",10,10);

/* Creation du corps */
	printf ("#define count_width 56\n");
	printf ("#define count_height 16\n");
	printf ("static char count_bits[] = {\n");

/* Le bitmap est ‚crit sur la sortie standard */
/* ligne par ligne */

/* NB: Here 'x' is pixel line index with 'y' being the character index  */
/*     so that their roles are switched around compared to the standard */
/*     terminology for x,y coordinates. No bug, but misleading...  ;-)  */

	for (x=0; x<16; x++)
	{
		for (y=1; y<8; y++)
/* NB: edit above line too for efficient 'hold' use */
		{
			cc[0]=hold[y];
			sscanf(cc,"%d",&c);
			printf(digits[((c*16)+x)]);
			if (y<7) { printf(", "); }
		}
		if (x==15) { printf("};");}{printf(",\n");}
	}
	printf("\n");

return(0);
}

static void servererr(char *msg)
{
	
		printf("Content-type: text/html%c%c",10,10);
		printf("<html><title>Counter Server Error</title>");
		printf("<body><h1>Counter Server Error</h1>");
		printf("This server encountered an error:<p>");
		printf("%s</body></html>", msg);

exit(0);
}

/* ---          EOF                 --- */
