d282b1c0b5eb16ba843ff970eb36172594c5d6b0 hiram Wed Jun 1 10:57:16 2011 -0700 implement cgiApoptosis system diff --git src/hg/lib/web.c src/hg/lib/web.c index f60b50d..a9c381f 100644 --- src/hg/lib/web.c +++ src/hg/lib/web.c @@ -1107,97 +1107,113 @@ if ((retDb == NULL) || !hDbExists(retDb)) { retDb = hDefaultDb(); } /* If genomes don't match, then get the default db for that genome */ if (differentWord(genome, hGenome(retDb))) { retDb = hDefaultDbForGenome(genome); } return retDb; } /* phoneHome business */ -static void alarmExit(int status) -/* signal handler for SIGALRM for phoneHome function */ +static void cgiApoptosis(int status) +/* signal handler for SIGALRM for phoneHome function and CGI expiration */ { exit(0); } static void phoneHome() { static boolean beenHere = FALSE; if (beenHere) /* one at a time please */ return; beenHere = TRUE; +char *expireTime = cfgOptionDefault("browser.cgiExpireMinutes", "20"); +unsigned expireMinutes = sqlUnsigned(expireTime); +unsigned long expireSeconds = expireMinutes * 60; + char trashFile[PATH_LEN]; safef(trashFile, sizeof(trashFile), "%s/registration.txt", trashDir()); + +/* trashFile does not exist during command line execution */ if(fileExists(trashFile)) /* update access time for trashFile */ { struct utimbuf ut; struct stat mystat; ZeroVar(&mystat); if (stat(trashFile,&mystat)==0) { ut.actime = clock1(); ut.modtime = mystat.st_mtime; } else { ut.actime = ut.modtime = clock1(); } (void) utime(trashFile, &ut); + if (expireSeconds > 0) + { + (void) signal(SIGALRM, cgiApoptosis); + (void) alarm(expireSeconds); /* CGI timeout */ + } return; } char *scriptName = cgiScriptName(); char *ip = getenv("SERVER_ADDR"); if (scriptName && ip) /* will not be true from command line execution */ { FILE *f = fopen(trashFile, "w"); if (f) /* rigamarole only if we can get a trash file */ { time_t now = time(NULL); char *localTime; extern char *tzname[2]; struct tm *tm = localtime(&now); localTime = sqlUnixTimeToDate(&now,FALSE); /* FALSE == localtime */ fprintf(f, "%s, %s, %s %s, %s\n", scriptName, ip, localTime, tm->tm_isdst ? tzname[1] : tzname[0], trashFile); fclose(f); chmod(trashFile, 0666); pid_t pid0 = fork(); if (0 == pid0) /* in child */ { close(STDOUT_FILENO); /* do not hang up Apache finish for parent */ - (void) signal(SIGALRM, alarmExit); + (void) signal(SIGALRM, cgiApoptosis); (void) alarm(6); /* timeout here in 6 seconds */ #include "versionInfo.h" char url[1024]; safef(url, sizeof(url), "%s%s", "http://genomewiki.ucsc.edu/cgi-bin/useCount?version=browser.v", CGI_VERSION); /* 6 second alarm will exit this page fetch if it does not work */ (void) htmlPageGetWithCookies(url, NULL); /* ignore return */ exit(0); } /* child of fork has done exit(0) normally or via alarm */ } /* trash file open OK */ + if (expireSeconds > 0) + { + (void) signal(SIGALRM, cgiApoptosis); + (void) alarm(expireSeconds); /* CGI timeout */ + } } /* an actual CGI binary */ } /* phoneHome() */ /* phoneHome business */ void getDbGenomeClade(struct cart *cart, char **retDb, char **retGenome, char **retClade, struct hash *oldVars) /* Examine CGI and cart variables to determine which db, genome, or clade * has been selected, and then adjust as necessary so that all three are * consistent. Detect changes and reset db-specific cart variables. * Save db, genome and clade in the cart so it will be consistent hereafter. * The order of preference here is as follows: * If we got a request that explicitly names the db, that takes * highest priority, and we synch the organism to that db. * If we get a cgi request for a specific organism then we use that * organism to choose the DB. If just clade, go from there.