#include "common.h" #include "Base.h" bool CGI::Base::initialize() { nRequests = 0; tStart = ::time(0); pid = ::getpid(); const char* sDirectory = ::getenv("RECORD_TO"); if (!sDirectory) { sDirectory = ::getenv("TEMP"); if (!sDirectory) { sDirectory = "/tmp"; } } sRecordDirectory = sDirectory; sRecordDirectory.strcat("/"); ::mkdir(sRecordDirectory,0777); const char* s = ::getenv("RECORD_ON"); wantRecord = (s && *s && (0 < atoi(s))); fRequest = ::fopen("/dev/null","r"); fResponse = ::fopen("/dev/null","w"); return true; } extern char** environ; static int countEnviron() { int n = 0; for (; environ[n]; ++n) { } return n; } static int compareEnviron(const void* a,const void* b) { const char* s1 = *(const char**)a; const char* s2 = *(const char**)b; int v = ::strcmp(s1,s2); //printf("compare '%s' to '%s' returns %d\n",s1,s2,v); return v; } static void sortEnviron() { int n = countEnviron(); ::qsort(environ,n,sizeof(char*),compareEnviron); } void CGI::Base::writeResponse(FILE* f) { fprintf(f,"Content-Type: text/html\n\n<html><title>CGI %s</title><h3>CGI %s</h3>",getName(),getName()); fprintf(f,"<table border=1 cellspacing=0 cellpadding=4><tr><th>argument<th>value\n"); fprintf(f,"</table>\n"); fprintf(f,"<h4>environment values</h4>\n<pre>"); sortEnviron(); for (int i = 0; environ[i]; ++i) { fprintf(f,"%s\n",environ[i]); } fprintf(f,"</pre>\n"); if (!sScriptFilename) { fprintf(f,"<p>SCRIPT_FILENAME not set.</p>\n"); } else { fprintf(f,"<p>Could not run script: '%s'</p>\n",sScriptFilename); if (0 < ::strlen(sLastError)) { fprintf(f,"<code>%s</code>\n",sLastError.getBuffer()); } } } void CGI::Base::handleRequest() { sLastError = ""; sScriptFilename = ::getenv("SCRIPT_FILENAME"); if (!sScriptFilename) { writeResponse(fResponse); nameRecord(); recordResponse(); fprintf(fResponse,"<p>SCRIPT_FILENAME not set.</p>\n"); return; } if (!runScript()) { writeResponse(fResponse); } if (wantRecord) { nameRecord(); recordResponse(); } } void CGI::Base::nameRecord() { ++nRequests; time_t t = time(0); struct tm* p = ::localtime(&t); static const char sFormat[] = "%sCGI.%04d-%02d-%02d-%02d-%02d-%02d.%08lx.%d.log"; int n = ::strlen(sRecordDirectory) + ::strlen(sFormat) + 10; sprintf(sRecordName.getBuffer(n),sFormat, // sRecordDirectory.getBuffer(), // 1900 + p->tm_year, // 1 + p->tm_mon, // p->tm_mday, // p->tm_hour, // p->tm_min, // p->tm_sec, // (long) pid,nRequests); } void CGI::Base::recordResponse() { fprintf(fResponse,"<p>recorded to: '%s'</p>\n",sRecordName.getBuffer()); FILE* log = fopen(sRecordName,"w"); if (!log) { fprintf(fResponse,"<p>error: '%s'</p>\n",::strerror(errno)); return; } writeResponse(log); fclose(log); } bool CGI::Base::runScript() { return false; }