/**************************** file: count.cpp Initially written by Keith Oxenrider October 25, 1998 For use on the web as a cgi program. Is activated by calling the program as an image, i.e., IMG SRC="/cgi-bin/count.cgi?countdatafile". to increment counter without having a visible display, invoke as follows: IMG SRC="/cgi-bin/count.cgi?countdatafile" HEIGHT="0" WIDTH="0" If the last character in the input string is an '!' then the counter will not be incremented, just displayed. The program will automagically create a new count file if the filename selected does not exist. There is a companion program called 'view_counts' that is used to look at all the counter stored along with the last access time. Modified to include date/time stamp on 3/1/1999. Security fix on 11/18/2003 to eliminate directory transversals. Converted on 03/06/2006 to C++ and to generate Microsoft's Bitmaps (DIB). ****************************/ #include #include #include #include #include #include #ifdef WIN32 //for Setting "stdout" to have binary mode #include #include #endif #include "mkBitMap.hpp" #define TRUE 1 #define FALSE 0 #define MAXLINELENGTH 1024 // hardcoded path to directory that contains data files #ifdef WIN32 char m_strPath[] = "countdata\\"; #else // presumed *nix char m_strPath[] = "countdata/"; #endif void dumpDigits(const char *numb){ CBitMap myBitMap(numb); printf("Content-type: image/x-ms-bmp\n\n"); #ifdef WIN32 // Set "stdout" to have binary mode: _setmode( _fileno( stdout ), _O_BINARY ); // no error checking/handling to simplify coding #endif myBitMap.Dump(stdout); exit(0); } /************************ * * main() * ************************/ int main () { unsigned long count; FILE *fin = NULL; char numb[MAXLINELENGTH], *input; int len, i, write, wipe; char filename[MAXLINELENGTH]; struct tm *time_date; time_t timer; input = getenv("QUERY_STRING"); if (input == NULL){// no file for counts dumpDigits("0100000000"); return 0; } len = strlen(input); // if input is too high, something is wrong, exit if (len >= MAXLINELENGTH){ dumpDigits("0200000000"); return 0; } // check for invalid characters (thanks infamous42md!) for (i=0; i10) // hard-coded for 10 digits, must change if you want more wipe = TRUE; if (wipe){ strcpy(numb, "0"); break; } } count = atol(numb); if (count >= LONG_MAX)//if the value rolls over, reset to zero (gives you 2^31, or 2,147,483,647 counts) count = 0; if (write){// write new counter data to file count++; FILE *fout = fopen(filename, "w"); if (fout){ fprintf(fout, "%ld", count); // get the time and format to look nice time(&timer); time_date = localtime(&timer); fprintf(fout, " %02d/%02d/%d %02d:%02d:%02d", time_date->tm_mon +1, time_date->tm_mday, time_date->tm_year+1900, time_date->tm_hour, time_date->tm_min, time_date->tm_sec); fclose(fout); }else{ perror("count file not open"); dumpDigits("0400000000"); } } sprintf(numb, "%ld", count); dumpDigits(numb); return 0;//should never get here, dumpDigits calls exit }