home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / analg211.zip / init.c < prev    next >
C/C++ Source or Header  |  1997-03-14  |  99KB  |  3,037 lines

  1. /*** analog 2.11 ***/
  2. /* Please read Readme.html, or http://www.statslab.cam.ac.uk/~sret1/analog/  */
  3.  
  4. /*** init.c; initialisation routines and declaration of global variables ***/
  5. /* See also init2.c */
  6.  
  7. #include "analhea2.h"
  8.  
  9. /*** First declare all global variables. We choose to declare them in this
  10.      file rather than analog.c because more are needed here. ***/
  11.  
  12. char monthname[12][12];
  13. char dayname[7][11];
  14. /* Note: month numbers run from 0 (Jan) to 11 (Dec) internally to this
  15.    program (though not where month numbers are needed in user input and
  16.    output) */
  17. char *lngstr[NOLNGSTRS];
  18. int dateoffset[12] = {0, 31, 59, 90, 120, 151, 181,
  19.             212, 243, 273, 304, 334};
  20. int monthlength[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  21.  
  22. char errs[NO_ERRS][MAXERRLENGTH] = {"Send timed out", "File does not exist",
  23. "No file matching URL", "User does not exist", "Send aborted",
  24. "Timed out waiting", "File permissions deny server access",
  25. "Read timed out", "Lost connection to client", "Cannot read directory",
  26. "Client denied by server configuration", "Malformed header from script",
  27. "Killing CGI process", "Could not get local address", "Will not follow link",
  28. "Could not get port number", "Script does not exist", "Script not found",
  29. "Unable to include", "Could not fork new process",
  30. "Unable to fork new process", "Invalid CGI ref",
  31. "Caught SIGTERM, shutting down", "Caught SIGSEGV, dumping core",
  32. "Caught SIGHUP, restarting", "SIGHUP received.  Attempting to restart",
  33. "Successful restart", "Resuming normal operations", "Starting",
  34. "Child error: pass failed", "Socket error: accept failed",
  35. "Child connection closed", "File open error", ""};
  36.       /* last must be "" */    
  37. int errors[NO_ERRS];   /* how many occurrences of each */
  38. int statusnos[NO_STATUS] = {200, 201, 202, 203, 204, 299, 301, 302, 303, 304,
  39. 399, 400, 401, 402, 403, 404, 499, 500, 501, 502, 503, 599};
  40. /* all status codes */
  41. char statusstrs[NO_STATUS][MAXSTATUSLENGTH] = {"OK", "Created",
  42. "Accepted for future processing", "Partial information",
  43. "OK, but nothing to send", "[Miscellaneous successes]", "Document moved",
  44. "Document found elsewhere", "Moved; use another request method",
  45. "Not modified since last retrieval", "[Miscellaneous redirections]",
  46. "Bad request", "Authorisation required", "Payment required", "Forbidden",
  47. "Document not found", "[Miscellaneous client/user errors]",
  48. "Internal server error", "Request type not supported",
  49. "Server overloaded", "Gateway timed out", "[Miscellaneous server errors]"};
  50. int status[NO_STATUS];   /* how many of each have been seen */
  51. int status7[NO_STATUS];  /* ditto in last 7 days */
  52.  
  53. char *outfile;
  54.  
  55. struct timestruct firsttime, lasttime, starttimec, oldtime, fromtime, totime;
  56. /* first and last log entries, now, a week before now, and
  57.    lower and upper bounds on time interval we want to consider */
  58.  
  59. struct monthly *firstm, *lastm;
  60.     /* pointers to the first and last years of monthly data */
  61. struct daily *firstD, *lastD;   /* ... months of daily data */
  62. struct hourly *firstH, *lastH;  /* ... days of hourly data */
  63. struct weekly *firstW, *lastW;  /* ... and to the first and last week */
  64.  
  65. int no_urls;               /* the number of distinct files found so far */
  66. int no_urls7;              /* the number used in the last 7 days */
  67. struct genstruct **rhead;  /* hash table of all files found */
  68. struct genstruct **ihead;  /* and one for all directories */
  69. struct genstruct **thead;  /* one for file types */
  70. struct domain **Ohead;     /* one for subdomains */
  71. struct domain *wildOhead;  /* and one for wild subdomains */
  72. struct domain *nwildOhead; /* and one for wild numerical subdomains */
  73. int no_hosts;              /* the number of hosts so far */
  74. int no_hosts7;             /* the number of all hosts in the last 7 days */
  75. int no_new_hosts7;         /* the number of new hosts in the last 7 days */
  76. struct genstruct **Shead;  /* and a record of all hosts */
  77. char *approxhostspace;     /* start of the space for approx host counting */
  78. char *approxhostspace7;    /* and a bit more for last 7 days accounting */
  79. size_t approxhostsize;     /* the size of those spaces, in bytes */
  80. struct domain **ohead;
  81. struct genstruct **fhead;
  82. struct genstruct **bhead;
  83. struct genstruct **Bhead;
  84. struct genstruct **Shead2; /* for filing pre-aliased filenames */
  85. struct genstruct **rhead2;
  86. struct genstruct **fhead2;
  87. size_t rhashsize, ihashsize, thashsize, Shashsize, fhashsize, bhashsize;
  88. size_t Bhashsize, Ohashsize;  /* sizes of the hash tables */
  89.  
  90. struct alias *filealiashead, *hostaliashead, *refaliashead, *browaliashead;
  91. struct alias *routaliashead, *ioutaliashead, *Soutaliashead, *foutaliashead;
  92. struct alias *boutaliashead, *toutaliashead, *subdomshead;
  93.     /* subdomshead is not really an alias, but it's the right shape */
  94. struct include *wantfilehead, *wanthosthead, *wantrefhead, *wantreqhead;
  95. struct include *linkhead, *reflinkhead, *ispagehead, *noexpandhead;
  96. struct include *refexpandhead;
  97.  
  98. int dreq[7], dpag[7];    /* requests and page requests for each day */
  99. int hreq[24], hpag[24];  /* ... and hour */
  100. double dbytes[7];        /* ... and bytes ditto */
  101. double hbytes[24];
  102.  
  103. /*** NB It often happens that families of variables have a one letter prefix
  104.      representing the different reports (usual letters, plus O = subdoms). ***/
  105. int rmaxreqs;     /* the max reqs for any file */
  106. int imaxreqs;     /* for any directory */
  107. int tmaxreqs;     /* for any file type */
  108. int Smaxreqs;     /* for any host */
  109. int omaxreqs;     /* for any domain */
  110. int fmaxreqs;     /* for any referrer */
  111. int bmaxreqs;     /* for any browser */
  112. int Bmaxreqs;     /* for any browser (full name) */
  113. /* Now the same for max pages and max bytes*/
  114. int rmaxpages, imaxpages, tmaxpages, Smaxpages, omaxpages, fmaxpages;
  115. int bmaxpages, Bmaxpages;
  116. double rmaxbytes, imaxbytes, tmaxbytes, Smaxbytes, omaxbytes, fmaxbytes;
  117. double bmaxbytes, Bmaxbytes;
  118.  
  119. int Smaxlength;     /* and the same for length of name */
  120.  
  121. char *dirsuffix;       /* e.g. index.html */
  122. int dirsufflength;     /* the length of dirsuffix */
  123. int onumber, Onumber;  /* the number of (sub)domains in the domain report */
  124. time_t starttime, stoptime;   /* the start and stop time of the program */
  125. struct tm *starttimetm;
  126. int total_succ_reqs, total_fail_reqs, total_other_reqs, total_page_reqs;
  127. int total_succ_reqs7, total_fail_reqs7, total_other_reqs7, total_page_reqs7;
  128. int total_good_brows, total_masked_brows, total_bad_brows;
  129. int total_good_refs, total_masked_refs, total_bad_refs;
  130. int total_ref_pages, total_brow_pages;
  131. double total_bytes, total_bytes7, total_ref_bytes, total_brow_bytes;
  132. int corrupt_lines;         /* the number of corrupt lines in the logfile */
  133.                              /* (Overlong lines, URLs with quotes in...) */
  134. int other_lines;           /* Lines masked out */
  135. int cachereqs, cachereqs7; /* The number of requests from cache */
  136. int cachepages, cachepages7; /* Page requests from cache */
  137. flag byq, refbyq, browbyq; /* whether we want to count bytes; always on until
  138.                   we find a line with no bytes information. */
  139. flag rawbytes;   /* whether bytes are quoted raw or in k notation */
  140. flag graphical;  /* whether to draw pretty graphs or just use ASCII art */
  141. flag filemaskq, hostmaskq, refmaskq;
  142. /* whether there is any masking of hosts, files or refs */
  143.  
  144. int weekbeginson;  /* which is the first day of the week? */
  145. char sepchar, repsepchar, decpoint;   /* chars as separators in numbers */
  146. char *presep;  /* string separating fields in PREFORMATTED */
  147.  
  148. char *commandname;  /* the name of the program, as called */
  149.  
  150. char *baseurl;         /* base for all URLs found */
  151. char rcols[7], icols[7], tcols[7], Scols[7], ocols[7], fcols[7], bcols[7];
  152. char Bcols[7], mcols[7], dcols[7], Dcols[7], Wcols[7], hcols[7], Hcols[7];
  153. char ccols[7], ecols[7];
  154. /* Columns appearing in each report */
  155.  
  156. struct loglist *logfilehead, *uncompresshead;
  157. /* uncompress is not really a loglist, but it's the right shape */
  158. struct stringlist *cachefilehead, *refloghead, *browloghead, *errloghead;
  159. char *domainsfile, *headerfile, *footerfile, *logourl, *imagedir;
  160. char reportorder[20];  /* the order in which reports occur (room for more) */
  161. /* NB if the size of this changes, so must it in case (REPORTORDER_): below */
  162. flag xq, mq, oq, iq, tq, rq, q7, dq, hq, Hq, Sq, Dq, Wq, fq, bq, Bq, cq, eq;
  163. int sq, aq;  /* a: output type     x->s: whether we want each type of report */
  164. #ifndef NODNS
  165. flag dnsq;            /* DNS lookup? */
  166. struct dnscache **dnshead;
  167. char *dnsfile;
  168. size_t dnshashsize;
  169. time_t dnsstaletime;  /* older than when the DNS information becomes stale */
  170. int dnsfreshhours;    /* how many hours it stays fresh for */
  171. #endif
  172. int lang;     /* language for output */
  173. char langfile[MAXSTRINGLENGTH];
  174. char oldlangfile[MAXSTRINGLENGTH];
  175. flag warnq, anywarns;  /* do we want warnings? any warnings issued? */
  176. flag html2;      /* if aq == HTML, whether output is guaranteed HTML2 */
  177. flag case_insensitive, stdin_used;
  178. char *ominreqstr, *Ominreqstr, *Sminreqstr, *iminreqstr, *rminreqstr;
  179. char *fminreqstr, *bminreqstr, *Bminreqstr, *tminreqstr;
  180. char *ominpagestr, *Ominpagestr, *Sminpagestr, *iminpagestr, *rminpagestr;
  181. char *fminpagestr, *bminpagestr, *Bminpagestr, *tminpagestr;
  182. char *ominbytestr, *Ominbytestr, *Sminbytestr, *iminbytestr, *rminbytestr;
  183. char *fminbytestr, *bminbytestr, *Bminbytestr, *tminbytestr;
  184. int eminreqs;
  185. int munit, Wunit, dunit, Dunit, hunit, Hunit;  /* the value of the mark */
  186. char mgraph, dgraph, Dgraph, hgraph, Hgraph, Wgraph;  /* R or B */
  187. flag mback, Dback, Wback, Hback;   /* backwards graphs? */
  188. int mrows, Drows, Wrows, Hrows, Wrowsdone;    /* max rows in each report */
  189. int osortby, isortby, tsortby, Ssortby, rsortby, fsortby, bsortby, Bsortby;
  190. int dirlevel, pagewidth;
  191. char markchar;
  192. char *hostname, *hosturl;
  193. int debug, progressfreq, no_configs = 0;
  194. flag vblesonly;
  195. flag formq;      /* commandline only. If ON, just make a form interface */
  196.  
  197. /* We also declare the following pointers here. They are used to keep track
  198.    of places in lists between functions in this file and init2.c */
  199.  
  200. struct alias *filealiasp, *hostaliasp, *refaliasp, *browaliasp, *routaliasp;
  201. struct alias *ioutaliasp, *Soutaliasp, *foutaliasp, *boutaliasp, *toutaliasp;
  202. struct alias *subdomp, *subdomtempp;
  203. struct include *wantfilep, *wanthostp, *wantrefp, *ispagep, *noexpandp;
  204. struct include *refexpandp, *wantreqp, *linkp, *reflinkp;
  205. struct loglist *logfilep, *uncompressp;
  206. struct stringlist *cachefilep, *reflogp, *browlogp, *errlogp;
  207.  
  208. /*** Now boring functions for initialisation of variables etc. ***/
  209.  
  210. void defaults(void)
  211. {
  212.   anywarns = OFF;
  213.   html2 = ON;
  214.   stdin_used = OFF;
  215.   domainsfile = (char *)xmalloc(MAXSTRINGLENGTH);
  216.   strncpy(domainsfile, DOMAINSFILE, MAXSTRINGLENGTH - 1);
  217.   domainsfile[MAXSTRINGLENGTH - 1] = '\0';
  218.   headerfile = (char *)xmalloc(MAXSTRINGLENGTH);
  219.   strncpy(headerfile, HEADERFILE, MAXSTRINGLENGTH - 1);
  220.   headerfile[MAXSTRINGLENGTH - 1] = '\0';
  221.   footerfile = (char *)xmalloc(MAXSTRINGLENGTH);
  222.   strncpy(footerfile, FOOTERFILE, MAXSTRINGLENGTH - 1);
  223.   footerfile[MAXSTRINGLENGTH - 1] = '\0';
  224.   outfile = (char *)xmalloc(MAXSTRINGLENGTH);
  225.   strncpy(outfile, OUTFILE, MAXSTRINGLENGTH - 1);
  226.   outfile[MAXSTRINGLENGTH - 1] = '\0';
  227. #ifndef NODNS
  228.   dnsfile = (char *)xmalloc(MAXSTRINGLENGTH);
  229.   strncpy(dnsfile, DNSFILE, MAXSTRINGLENGTH - 1);
  230.   dnsfile[MAXSTRINGLENGTH - 1] = '\0';
  231.   dnsq = NUMLOOKUP;
  232.   dnsfreshhours = DNSFRESHHOURS;
  233.   dnshashsize = DNSHASHSIZE;
  234. #endif
  235.   baseurl = (char *)xmalloc(MAXSTRINGLENGTH);
  236.   strncpy(baseurl, BASEURL, MAXSTRINGLENGTH - 1);
  237.   baseurl[MAXSTRINGLENGTH - 1] = '\0';
  238.   imagedir = (char *)xmalloc(MAXSTRINGLENGTH);
  239.   strncpy(imagedir, IMAGEDIR, MAXSTRINGLENGTH - 1);
  240.   imagedir[MAXSTRINGLENGTH - 1] = '\0';
  241.   dirsuffix = (char *)xmalloc(MAXSTRINGLENGTH);
  242.   strncpy(dirsuffix, DIRSUFFIX, MAXSTRINGLENGTH - 1);
  243.   dirsuffix[MAXSTRINGLENGTH - 1] = '\0';
  244.   strncpy(reportorder, REPORTORDER, 19);
  245.   reportorder[19] = '\0';
  246.   strncpy(ocols, DOMCOLS, 6);
  247.   ocols[6] = '\0';
  248.   strncpy(Scols, HOSTCOLS, 6);
  249.   Scols[6] = '\0';
  250.   strncpy(icols, DIRCOLS, 6);
  251.   icols[6] = '\0';
  252.   strncpy(tcols, TYPECOLS, 6);
  253.   tcols[6] = '\0';
  254.   strncpy(rcols, REQCOLS, 6);
  255.   rcols[6] = '\0';
  256.   strncpy(fcols, REFCOLS, 6);
  257.   fcols[6] = '\0';
  258.   strncpy(bcols, BROWCOLS, 6);
  259.   bcols[6] = '\0';
  260.   strncpy(Bcols, FULLBROWCOLS, 6);
  261.   Bcols[6] = '\0';
  262.   strncpy(mcols, MONTHCOLS, 6);
  263.   mcols[6] = '\0';
  264.   strncpy(dcols, DAYCOLS, 6);
  265.   dcols[6] = '\0';
  266.   strncpy(Dcols, FULLDAYCOLS, 6);
  267.   Dcols[6] = '\0';
  268.   strncpy(Wcols, WEEKCOLS, 6);
  269.   Wcols[6] = '\0';
  270.   strncpy(hcols, HOURCOLS, 6);
  271.   hcols[6] = '\0';
  272.   strncpy(Hcols, FULLHOURCOLS, 6);
  273.   Hcols[6] = '\0';
  274.   strcpy(ccols, "R");   /* for the moment */
  275.   strcpy(ecols, "R");
  276.   logourl = (char *)xmalloc(MAXSTRINGLENGTH);
  277.   strncpy(logourl, LOGOURL, MAXSTRINGLENGTH - 1);
  278.   logourl[MAXSTRINGLENGTH - 1] = '\0';
  279.   mq = MONTHLY;
  280.   Wq = WEEKLY;
  281.   dq = DAILY;
  282.   Dq = FULLDAILY;
  283.   hq = HOURLY;
  284.   Hq = FULLHOURLY;
  285.   oq = DOMAINREP;
  286.   iq = DIRECTORY;
  287.   tq = FILETYPE;
  288.   rq = REQUEST;
  289.   sq = COUNTHOSTS;
  290.   Sq = FULLHOSTS;
  291.   fq = REFERRER;
  292.   bq = BROWSER;
  293.   Bq = FULLBROWSER;
  294.   cq = STATUS;
  295.   eq = ERROR;
  296.   xq = GENERAL;
  297.   q7 = LASTSEVEN;
  298.   aq = OUTPUT;
  299.   lang = LANGUAGE;
  300.   warnq = WARNINGS;
  301.   progressfreq = PROGRESSFREQ;
  302.   graphical = GRAPHICAL;
  303.   case_insensitive = (CASE == INSENSITIVE);
  304.   munit = 0;
  305.   Wunit = 0;
  306.   hunit = 0;
  307.   Hunit = 0;
  308.   dunit = 0;
  309.   Dunit = 0;
  310.   mgraph = MONTHGRAPH;
  311.   dgraph = DAYGRAPH;
  312.   Dgraph = FULLDAYGRAPH;
  313.   hgraph = HOURGRAPH;
  314.   Hgraph = FULLHOURGRAPH;
  315.   Wgraph = WEEKGRAPH;
  316.   Hback = FULLHOURLYBACK;
  317.   Dback = FULLDAILYBACK;
  318.   Wback = WEEKLYBACK;
  319.   mback = MONTHLYBACK;
  320.   Wrows = WEEKROWS;
  321.   Drows = FULLDAYROWS;
  322.   mrows = MONTHROWS;
  323.   Hrows = FULLHOURROWS;
  324.   osortby = DOMSORTBY;
  325.   isortby = DIRSORTBY;
  326.   tsortby = TYPESORTBY;
  327.   rsortby = REQSORTBY;
  328.   Ssortby = HOSTSORTBY;
  329.   fsortby = REFSORTBY;
  330.   bsortby = BROWSORTBY;
  331.   Bsortby = FULLBROWSORTBY;
  332.   ominreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  333.   strncpy(ominreqstr, MIN_DOM_REQS, MAXSTRINGLENGTH - 1);
  334.   ominreqstr[MAXSTRINGLENGTH - 1] = '\0';
  335.   ominpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  336.   strncpy(ominpagestr, MIN_DOM_PAGES, MAXSTRINGLENGTH - 1);
  337.   ominpagestr[MAXSTRINGLENGTH - 1] = '\0';
  338.   ominbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  339.   strncpy(ominbytestr, MIN_DOM_BYTES, MAXSTRINGLENGTH - 1);
  340.   ominbytestr[MAXSTRINGLENGTH - 1] = '\0';
  341.   Ominreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  342.   strncpy(Ominreqstr, MIN_SUBDOM_REQS, MAXSTRINGLENGTH - 1);
  343.   Ominreqstr[MAXSTRINGLENGTH - 1] = '\0';
  344.   Ominpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  345.   strncpy(Ominpagestr, MIN_SUBDOM_PAGES, MAXSTRINGLENGTH - 1);
  346.   Ominpagestr[MAXSTRINGLENGTH - 1] = '\0';
  347.   Ominbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  348.   strncpy(Ominbytestr, MIN_SUBDOM_BYTES, MAXSTRINGLENGTH - 1);
  349.   Ominbytestr[MAXSTRINGLENGTH - 1] = '\0';
  350.   iminreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  351.   strncpy(iminreqstr, MIN_DIR_REQS, MAXSTRINGLENGTH - 1);
  352.   iminreqstr[MAXSTRINGLENGTH - 1] = '\0';
  353.   iminpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  354.   strncpy(iminpagestr, MIN_DIR_PAGES, MAXSTRINGLENGTH - 1);
  355.   iminpagestr[MAXSTRINGLENGTH - 1] = '\0';
  356.   iminbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  357.   strncpy(iminbytestr, MIN_DIR_BYTES, MAXSTRINGLENGTH - 1);
  358.   iminbytestr[MAXSTRINGLENGTH - 1] = '\0';
  359.   tminreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  360.   strncpy(tminreqstr, MIN_TYPE_REQS, MAXSTRINGLENGTH - 1);
  361.   tminreqstr[MAXSTRINGLENGTH - 1] = '\0';
  362.   tminpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  363.   strncpy(tminpagestr, MIN_TYPE_PAGES, MAXSTRINGLENGTH - 1);
  364.   tminpagestr[MAXSTRINGLENGTH - 1] = '\0';
  365.   tminbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  366.   strncpy(tminbytestr, MIN_TYPE_BYTES, MAXSTRINGLENGTH - 1);
  367.   tminbytestr[MAXSTRINGLENGTH - 1] = '\0';
  368.   Sminreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  369.   strncpy(Sminreqstr, MIN_HOST_REQS, MAXSTRINGLENGTH - 1);
  370.   Sminreqstr[MAXSTRINGLENGTH - 1] = '\0';
  371.   Sminpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  372.   strncpy(Sminpagestr, MIN_HOST_PAGES, MAXSTRINGLENGTH - 1);
  373.   Sminpagestr[MAXSTRINGLENGTH - 1] = '\0';
  374.   Sminbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  375.   strncpy(Sminbytestr, MIN_HOST_BYTES, MAXSTRINGLENGTH - 1);
  376.   Sminbytestr[MAXSTRINGLENGTH - 1] = '\0';
  377.   rminreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  378.   strncpy(rminreqstr, MIN_URL_REQS, MAXSTRINGLENGTH - 1);
  379.   rminreqstr[MAXSTRINGLENGTH - 1] = '\0';
  380.   rminpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  381.   strncpy(rminpagestr, MIN_URL_REQS, MAXSTRINGLENGTH - 1);  /* sic */
  382.   rminpagestr[MAXSTRINGLENGTH - 1] = '\0';
  383.   rminbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  384.   strncpy(rminbytestr, MIN_URL_BYTES, MAXSTRINGLENGTH - 1);
  385.   rminbytestr[MAXSTRINGLENGTH - 1] = '\0';
  386.   fminreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  387.   strncpy(fminreqstr, MIN_REF_REQS, MAXSTRINGLENGTH - 1);
  388.   fminreqstr[MAXSTRINGLENGTH - 1] = '\0';
  389.   fminpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  390.   strncpy(fminpagestr, MIN_REF_PAGES, MAXSTRINGLENGTH - 1);
  391.   fminpagestr[MAXSTRINGLENGTH - 1] = '\0';
  392.   fminbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  393.   strncpy(fminbytestr, MIN_REF_BYTES, MAXSTRINGLENGTH - 1);
  394.   fminbytestr[MAXSTRINGLENGTH - 1] = '\0';
  395.   bminreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  396.   strncpy(bminreqstr, MIN_BROW_REQS, MAXSTRINGLENGTH - 1);
  397.   bminreqstr[MAXSTRINGLENGTH - 1] = '\0';
  398.   bminpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  399.   strncpy(bminpagestr, MIN_BROW_PAGES, MAXSTRINGLENGTH - 1);
  400.   bminpagestr[MAXSTRINGLENGTH - 1] = '\0';
  401.   bminbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  402.   strncpy(bminbytestr, MIN_BROW_BYTES, MAXSTRINGLENGTH - 1);
  403.   bminbytestr[MAXSTRINGLENGTH - 1] = '\0';
  404.   Bminreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  405.   strncpy(Bminreqstr, MIN_FULLBROW_REQS, MAXSTRINGLENGTH - 1);
  406.   Bminreqstr[MAXSTRINGLENGTH - 1] = '\0';
  407.   Bminpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  408.   strncpy(Bminpagestr, MIN_FULLBROW_PAGES, MAXSTRINGLENGTH - 1);
  409.   Bminpagestr[MAXSTRINGLENGTH - 1] = '\0';
  410.   Bminbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  411.   strncpy(Bminbytestr, MIN_FULLBROW_BYTES, MAXSTRINGLENGTH - 1);
  412.   Bminbytestr[MAXSTRINGLENGTH - 1] = '\0';
  413.   eminreqs = MIN_ERR_OCCS;
  414.   dirlevel = DIRLEVEL;
  415.   pagewidth = PAGEWIDTH;
  416.   markchar = MARKCHAR;
  417.   rawbytes = RAWBYTES;
  418.   hostname = (char *)xmalloc(MAXSTRINGLENGTH);
  419.   strncpy(hostname, HOSTNAME, MAXSTRINGLENGTH - 1);
  420.   hostname[MAXSTRINGLENGTH - 1] = '\0';
  421.   hosturl = (char *)xmalloc(MAXSTRINGLENGTH);
  422.   strncpy(hosturl, HOSTURL, MAXSTRINGLENGTH - 1);
  423.   hosturl[MAXSTRINGLENGTH - 1] = '\0';
  424.   weekbeginson = WEEKBEGINSON;
  425.   sepchar = SEPCHAR;
  426.   repsepchar = REPSEPCHAR;
  427.   decpoint = DECPOINT;
  428.   presep = (char *)xmalloc(MAXSTRINGLENGTH);
  429.   strncpy(presep, PRESEP, MAXSTRINGLENGTH - 1);
  430.   presep[MAXSTRINGLENGTH - 1] = '\0';
  431.   vblesonly = OFF;
  432.   formq = OFF;
  433.   fromtime.code = -INFINITY;
  434.   totime.code = INFINITY;
  435.   approxhostsize = APPROXHOSTSIZE;
  436.   debug = DEBUG;
  437.   filemaskq = OFF;
  438.   hostmaskq = OFF;
  439.   refmaskq = OFF;
  440.   rhashsize = REQHASHSIZE;
  441.   ihashsize = DIRHASHSIZE;
  442.   thashsize = TYPEHASHSIZE;
  443.   Shashsize = HOSTHASHSIZE;
  444.   fhashsize = REFHASHSIZE;
  445.   bhashsize = BROWHASHSIZE;
  446.   Bhashsize = FULLBROWHASHSIZE;
  447.   Ohashsize = SUBDOMHASHSIZE;
  448. }
  449.  
  450. void init_structs(void)
  451. {
  452.   char tempstr[MAXSTRINGLENGTH];
  453.  
  454.   logfilehead = (struct loglist *)xmalloc(sizeof(struct loglist));
  455.   logfilep = logfilehead;
  456.   if (STREQ(LOGFILE, "none"))
  457.     logfilehead -> name[0] = '\0';
  458.   else {
  459.     strcpy(tempstr, LOGFILE);
  460.     addlogfile(&logfilep, tempstr, "", ON);
  461.   }
  462.   cachefilehead = (struct stringlist *)xmalloc(sizeof(struct stringlist));
  463.   cachefilep = cachefilehead;
  464.   if (STREQ(CACHEFILE, "none"))
  465.     cachefilehead -> name[0] = '\0';
  466.   else {
  467.     strcpy(tempstr, CACHEFILE);
  468.     configstrlist(tempstr, &cachefilep, (char *)NULL, (char *)NULL, 2, ON);
  469.   }
  470.   refloghead = (struct stringlist *)xmalloc(sizeof(struct stringlist));
  471.   reflogp = refloghead;
  472.   if (STREQ(REFERRER_LOG, "none"))
  473.     refloghead -> name[0] = '\0';
  474.   else{
  475.     strcpy(tempstr, REFERRER_LOG);
  476.     configstrlist(tempstr, &reflogp, (char *)NULL, (char *)NULL, 2, ON);
  477.   }
  478.   browloghead = (struct stringlist *)xmalloc(sizeof(struct stringlist));
  479.   browlogp = browloghead;
  480.   if (STREQ(BROWSER_LOG, "none"))
  481.     browloghead -> name[0] = '\0';
  482.   else {
  483.     strcpy(tempstr, BROWSER_LOG);
  484.     configstrlist(tempstr, &browlogp, (char *)NULL, (char *)NULL, 2, ON);
  485.   }
  486.   errloghead = (struct stringlist *)xmalloc(sizeof(struct stringlist));
  487.   errlogp = errloghead;
  488.   if (STREQ(ERROR_LOG, "none"))
  489.     errloghead -> name[0] = '\0';
  490.   else {
  491.     strcpy(tempstr, ERROR_LOG);
  492.     configstrlist(tempstr, &errlogp, (char *)NULL, (char *)NULL, 2, ON);
  493.   }
  494.   uncompresshead = (struct loglist *)xmalloc(sizeof(struct loglist));
  495.   uncompresshead -> name[0] = '\0';
  496.   uncompressp = uncompresshead;
  497.   filealiashead = (struct alias *)xmalloc(sizeof(struct alias));
  498.   filealiashead -> from[0] = '\0';
  499.   filealiasp = filealiashead;
  500.   hostaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  501.   hostaliashead -> from[0] = '\0';
  502.   hostaliasp = hostaliashead;
  503.   refaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  504.   refaliashead -> from[0] = '\0';
  505.   refaliasp = refaliashead;
  506.   browaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  507.   browaliashead -> from[0] = '\0';
  508.   browaliasp = browaliashead;
  509.   routaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  510.   routaliashead -> from[0] = '\0';
  511.   routaliasp = routaliashead;
  512.   ioutaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  513.   ioutaliashead -> from[0] = '\0';
  514.   ioutaliasp = ioutaliashead;
  515.   Soutaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  516.   Soutaliashead -> from[0] = '\0';
  517.   Soutaliasp = Soutaliashead;
  518.   foutaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  519.   foutaliashead -> from[0] = '\0';
  520.   foutaliasp = foutaliashead;
  521.   boutaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  522.   boutaliashead -> from[0] = '\0';
  523.   boutaliasp = boutaliashead;
  524.   toutaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  525.   toutaliashead -> from[0] = '\0';
  526.   toutaliasp = toutaliashead;
  527.   wantfilehead = (struct include *)xmalloc(sizeof(struct include));
  528.   wantfilehead -> in = UNSET;
  529.   wantfilep = wantfilehead;
  530.   wanthosthead = (struct include *)xmalloc(sizeof(struct include));
  531.   wanthosthead -> in = UNSET;
  532.   wanthostp = wanthosthead;
  533.   subdomshead = (struct alias *)xmalloc(sizeof(struct alias));
  534.   subdomshead -> from[0] = '\0';
  535.   subdomp = subdomshead;
  536.   wantrefhead = (struct include *)xmalloc(sizeof(struct include));
  537.   wantrefhead -> in = UNSET;
  538.   wantrefp = wantrefhead;
  539.   wantreqhead = (struct include *)xmalloc(sizeof(struct include));
  540.   wantreqhead -> in = UNSET;
  541.   wantreqp = wantreqhead;
  542.   linkhead = (struct include *)xmalloc(sizeof(struct include));
  543.   linkhead -> in = UNSET;
  544.   linkp = linkhead;
  545.   reflinkhead = (struct include *)xmalloc(sizeof(struct include));
  546.   reflinkhead -> in = UNSET;
  547.   reflinkp = reflinkhead;
  548.   noexpandhead = (struct include *)xmalloc(sizeof(struct include));
  549.   noexpandhead -> in = UNSET;
  550.   noexpandp = noexpandhead;
  551.   refexpandhead = (struct include *)xmalloc(sizeof(struct include));
  552.   refexpandhead -> in = UNSET;
  553.   refexpandp = refexpandhead;
  554.   ispagehead = (struct include *)xmalloc(sizeof(struct include));
  555.   ispagep = ispagehead;
  556.   strcpy(ispagep -> name, "*/");
  557.   ispagep -> in = TRUE;
  558.   ispagep -> next = (struct include *)xmalloc(sizeof(struct include));
  559.   ispagep = ispagep -> next;
  560.   strcpy(ispagep -> name, "*.html");
  561.   ispagep -> in = TRUE;
  562.   ispagep -> next = (struct include *)xmalloc(sizeof(struct include));
  563.   ispagep = ispagep -> next;
  564.   strcpy(ispagep -> name, "*.htm");
  565.   ispagep -> in = TRUE;
  566.   ispagep -> next = (struct include *)xmalloc(sizeof(struct include));
  567.   ispagep = ispagep -> next;
  568.   ispagep -> in = UNSET;
  569. }
  570.  
  571. void othervars(void)    /* vars initialised after command args and config */
  572. {
  573.   time_t oldtimeno;       /* the time 7 days ago */
  574.   struct tm *oldtimetm;
  575.  
  576.   int i;
  577.  
  578.   no_urls = 0;
  579.   no_urls7 = 0;
  580.   no_hosts = 0;
  581.   no_hosts7 = 0;
  582.   no_new_hosts7 = 0;
  583.   rmaxreqs = 0;
  584.   imaxreqs = 0;
  585.   tmaxreqs = 0;
  586.   Smaxreqs = 0;
  587.   fmaxreqs = 0;
  588.   bmaxreqs = 0;
  589.   Bmaxreqs = 0;
  590.   rmaxpages = 0;
  591.   imaxpages = 0;
  592.   tmaxpages = 0;
  593.   Smaxpages = 0;
  594.   fmaxpages = 0;
  595.   bmaxpages = 0;
  596.   Bmaxpages = 0;
  597.   rmaxbytes = 0.0;
  598.   imaxbytes = 0.0;
  599.   tmaxbytes = 0.0;
  600.   Smaxbytes = 0.0;
  601.   fmaxbytes = 0.0;
  602.   bmaxbytes = 0.0;
  603.   Bmaxbytes = 0.0;     /* omaxreqs, omaxpages and omaxbytes are set later */
  604.   Smaxlength = 0;
  605.   for (i = 0; i < NO_STATUS; i++) {
  606.     status[i] = 0;
  607.     status7[i] = 0;
  608.   }
  609.   total_succ_reqs = 0;
  610.   total_succ_reqs7 = 0;
  611.   total_page_reqs = 0;
  612.   total_page_reqs7 = 0;
  613.   total_fail_reqs = 0;
  614.   total_fail_reqs7 = 0;
  615.   total_other_reqs = 0;
  616.   total_other_reqs7 = 0;
  617.   total_good_refs = 0;
  618.   total_masked_refs = 0;
  619.   total_bad_refs = 0;
  620.   total_good_brows = 0;
  621.   total_masked_brows = 0;
  622.   total_bad_brows = 0;
  623.   total_bytes = 0.0;
  624.   total_bytes7 = 0.0;
  625.   total_ref_bytes = 0.0;
  626.   total_brow_bytes = 0.0;
  627.   corrupt_lines = 0;
  628.   other_lines = 0;
  629.   cachereqs = 0;
  630.   cachereqs7 = 0;
  631.   cachepages = 0;
  632.   cachepages7 = 0;
  633.   byq = ON;
  634.   refbyq = ON;
  635.   browbyq = ON;
  636.  
  637.   /* initialise the date structures */
  638.   if (mq) {
  639.     firstm = (struct monthly *)xmalloc(sizeof(struct monthly));
  640.     for (i = 0; i < 12; i++) {
  641.       firstm -> reqs[i] = 0;
  642.       firstm -> pages[i] = 0;
  643.       firstm -> bytes[i] = 0.0;
  644.     }
  645.     firstm -> next = NULL;
  646.     lastm = firstm;
  647.   }
  648.   if (Dq) {
  649.     firstD = (struct daily *)xmalloc(sizeof(struct daily));
  650.     for (i = 0; i < 31; i++) {
  651.       firstD -> reqs[i] = 0;
  652.       firstD -> pages[i] = 0;
  653.       firstD -> bytes[i] = 0.0;
  654.     }
  655.     firstD -> next = NULL;
  656.     lastD = firstD;
  657.   }
  658.   if (Hq) {
  659.     firstH = (struct hourly *)xmalloc(sizeof(struct hourly));
  660.     for (i = 0; i < 24; i++) {
  661.       firstH -> reqs[i] = 0;
  662.       firstH -> pages[i] = 0;
  663.       firstH -> bytes[i] = 0.0;
  664.     }
  665.     firstH -> next = NULL;
  666.     lastH = firstH;
  667.   }
  668.   if (Wq) {
  669.     firstW = (struct weekly *)xmalloc(sizeof(struct weekly));
  670.     firstW -> reqs = 0;
  671.     firstW -> pages = 0;
  672.     firstW -> bytes = 0;
  673.     firstW -> next = NULL;
  674.     lastW = firstW;
  675.   }
  676.   Wrowsdone = 1;
  677.   if (dq) {
  678.     for (i = 0; i < 7; i++) {
  679.       dreq[i] = 0;
  680.       dpag[i] = 0;
  681.       dbytes[i] = 0.0;
  682.     }
  683.   }
  684.   if (hq) {
  685.     for (i = 0; i < 24; i++) {
  686.       hreq[i] = 0;
  687.       hpag[i] = 0;
  688.       hbytes[i] = 0.0;
  689.     }
  690.   }
  691.  
  692. #ifndef NODNS
  693.   dnsstaletime = starttime - 3600 * dnsfreshhours;
  694. #endif
  695.  
  696.   if (q7) {   /* calculate the time 7 days ago */
  697.     if (starttimec.code <= totime.code) {
  698.       oldtimeno = starttime - 604800;        /* seconds in a week */
  699.       oldtimetm = localtime(&oldtimeno);
  700.       oldtime.year = 1900 + oldtimetm -> tm_year;
  701.       oldtime.date = oldtimetm -> tm_mday;
  702.       oldtime.monthno = oldtimetm -> tm_mon;
  703.       oldtime.hr = oldtimetm -> tm_hour;
  704.       oldtime.min = oldtimetm -> tm_min;
  705.     }
  706.     else {    /* totime is earlier than today; take 7 days before that */
  707.       oldtime.hr = 23;
  708.       oldtime.min = 59;
  709.       oldtime.year = totime.year;
  710.       oldtime.monthno = totime.monthno;
  711.       oldtime.date = totime.date - 7;
  712.       if (oldtime.date < 1) {
  713.     oldtime.monthno--;
  714.     if (oldtime.monthno < 0) {
  715.       oldtime.year--;
  716.       oldtime.monthno += 12;
  717.     }
  718.     oldtime.date += monthlength[oldtime.monthno] +
  719.       ISLEAPFEB(oldtime.monthno, oldtime.year);
  720.       }
  721.     }
  722.     oldtime.code = timecode(oldtime.date, oldtime.monthno, oldtime.year,
  723.                 oldtime.hr, oldtime.min);
  724.     if (oldtime.code < fromtime.code)
  725.       q7 = OFF;  /* FROM--TO is all in last 7 days */
  726.   }
  727.  
  728.   dirsufflength = (int)strlen(dirsuffix);
  729.     
  730.   if (rq || iq || tq) {
  731.     rhead = (struct genstruct **)xcalloc(rhashsize,
  732.                      sizeof(struct genstruct *));
  733.   }
  734.   rhead2 = (struct genstruct **)xcalloc(rhashsize, sizeof(struct genstruct *));
  735.   for (i = 0; i < rhashsize; i++) {
  736.     if (rq || iq || tq) {
  737.       rhead[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
  738.       rhead[i] -> name = NULL;
  739.     }
  740.     rhead2[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
  741.     rhead2[i] -> name = NULL;
  742.   }
  743.   if (iq) {
  744.     ihead = (struct genstruct **)xcalloc(ihashsize,
  745.                      sizeof(struct genstruct *));
  746.     for (i = 0; i < ihashsize; i++) {
  747.       ihead[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
  748.       ihead[i] -> name = NULL;
  749.     }
  750.   }
  751.   if (tq) {
  752.     thead = (struct genstruct **)xcalloc(thashsize,
  753.                      sizeof(struct genstruct *));
  754.     for (i = 0; i < thashsize; i++) {
  755.       thead[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
  756.       thead[i] -> name = NULL;
  757.     }
  758.   }
  759.   if (sq == ON) {
  760.     Shead = (struct genstruct **)xcalloc(Shashsize,
  761.                      sizeof(struct genstruct *));
  762.     Shead2 = (struct genstruct **)xcalloc(Shashsize,
  763.                       sizeof(struct genstruct *));
  764.     for (i = 0; i < Shashsize; i++) {
  765.       Shead[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
  766.       Shead[i] -> name = NULL;
  767.       Shead2[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
  768.       Shead2[i] -> name = NULL;
  769.     }
  770.   }
  771.   else if (sq == APPROX) {
  772.     approxhostspace = (char *) xcalloc(approxhostsize, 1);
  773.     if (q7)
  774.       approxhostspace7 = (char *) xcalloc(approxhostsize, 1);
  775.   }
  776.   if (fq) {
  777.     fhead = (struct genstruct **)xcalloc(fhashsize,
  778.                      sizeof(struct genstruct *));
  779.     fhead2 = (struct genstruct **)xcalloc(fhashsize,
  780.                       sizeof(struct genstruct *));
  781.     for (i = 0; i < fhashsize; i++) {
  782.       fhead[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
  783.       fhead[i] -> name = NULL;
  784.       fhead2[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
  785.       fhead2[i] -> name = NULL;
  786.     }
  787.   }
  788.   if (bq) {
  789.     bhead = (struct genstruct **)xcalloc(bhashsize,
  790.                      sizeof(struct genstruct *));
  791.     for (i = 0; i < bhashsize; i++) {
  792.       bhead[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
  793.       bhead[i] -> name = NULL;
  794.     }
  795.   }
  796.   if (Bq) {
  797.     Bhead = (struct genstruct **)xcalloc(Bhashsize,
  798.                      sizeof(struct genstruct *));
  799.     for (i = 0; i < Bhashsize; i++) {
  800.       Bhead[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
  801.       Bhead[i] -> name = NULL;
  802.     }
  803.   }
  804.   if (eq) {
  805.     for (i = 0; i < NO_ERRS; i++)
  806.       errors[i] = 0;
  807.   }
  808.   if (oq) {
  809.     ohead = (struct domain **)xcalloc(DOMHASHSIZE,
  810.                       sizeof(struct domain *));
  811.     for (i = 0; i < DOMHASHSIZE; i++) {
  812.       ohead[i] = (struct domain *)xmalloc(sizeof(struct domain));
  813.       ohead[i] -> name = NULL;
  814.     }
  815.     Ohead = (struct domain **)xcalloc(Ohashsize,
  816.                       sizeof(struct domain *));
  817.     for (i = 0; i < Ohashsize; i++) {
  818.       Ohead[i] = (struct domain *)xmalloc(sizeof(struct domain));
  819.       Ohead[i] -> name = NULL;
  820.     }
  821.     wildOhead = (struct domain *)xmalloc(sizeof(struct domain));
  822.     wildOhead -> id = NULL;
  823.     nwildOhead = (struct domain *)xmalloc(sizeof(struct domain));
  824.     nwildOhead -> id = NULL;
  825.  
  826.     domainscan();      /* read in all the domains */
  827.  
  828.   }   /* end if (oq) */
  829.  
  830. #ifndef NODNS
  831.   if (dnsq) {
  832.     dnshead = (struct dnscache **)xcalloc(dnshashsize,
  833.                       sizeof(struct dnscache *));
  834.     for (i = 0; i < dnshashsize; i++) {
  835.       dnshead[i] = (struct dnscache *)xmalloc(sizeof(struct dnscache));
  836.       dnshead[i] -> number = NULL;
  837.     }
  838.     dnscachescan();
  839.   }
  840. #endif
  841.  
  842. }
  843.  
  844. /*** Now for the functions that parse the configuration commands. ***/
  845.  
  846. void configline(char inputline[MAXLINELENGTH])  /* process one configline */
  847. {
  848.   enum {BADCOMMAND_, FILEALIAS_, HOSTALIAS_, REFALIAS_, BROWALIAS_,
  849.       REQOUTPUTALIAS_, DIROUTPUTALIAS_, HOSTOUTPUTALIAS_, REFOUTPUTALIAS_,
  850.       BROWOUTPUTALIAS_, TYPEOUTPUTALIAS_, FILEINCLUDE_, FILEEXCLUDE_,
  851.       FILEALLOW_, HOSTINCLUDE_, HOSTEXCLUDE_, HOSTALLOW_, REFINCLUDE_,
  852.       REFEXCLUDE_, REFALLOW_, REQINCLUDE_, REQEXCLUDE_, REQALLOW_,
  853.       LINKINCLUDE_,  LINKEXCLUDE_, LINKALLOW_, REFLINKINCLUDE_,
  854.       REFLINKEXCLUDE_, REFLINKALLOW_, FROM_, TO_, SUBDOMAIN_,
  855.       WEEKBEGINSON_, APPROXHOSTSIZE_, ISPAGE_, ISNOTPAGE_, SEPCHAR_,
  856.       REPSEPCHAR_, DECPOINT_, PRESEP_, REPORTORDER_, WITHARGS_,
  857.       WITHOUTARGS_, REFWITHARGS_, REFWITHOUTARGS_, NOTSUBDOMAIN_,
  858.       BASEURL_, DOMCOLS_, HOSTCOLS_, DIRCOLS_, TYPECOLS_, REQCOLS_,
  859.       REFCOLS_, BROWCOLS_,
  860.       FULLBROWCOLS_, MONTHCOLS_, DAYCOLS_, FULLDAYCOLS_, WEEKCOLS_,
  861.       HOURCOLS_, FULLHOURCOLS_, MONTHGRAPH_, DAYGRAPH_, FULLDAYGRAPH_,
  862.       HOURGRAPH_, FULLHOURGRAPH_, WEEKGRAPH_, GRAPHICAL_, LOGFILE_,
  863.       CACHEFILE_, REFLOG_, BROWLOG_, ERRLOG_, DOMAINSFILE_, HOSTNAME_,
  864.       HOSTURL_, HOSTMINREQS_, DOMMINREQS_, SUBDOMMINREQS_, DIRMINREQS_,
  865.       TYPEMINREQS_, REQMINREQS_, REFMINREQS_, BROWMINREQS_,
  866.       FULLBROWMINREQS_, HOSTMINPAGES_, DOMMINPAGES_, SUBDOMMINPAGES_,
  867.       DIRMINPAGES_, TYPEMINPAGES_, REQMINPAGES_, REFMINPAGES_,
  868.       BROWMINPAGES_, FULLBROWMINPAGES_, HOSTMINBYTES_, DOMMINBYTES_,
  869.       SUBDOMMINBYTES_, DIRMINBYTES_, TYPEMINBYTES_, REQMINBYTES_,
  870.       REFMINBYTES_, BROWMINBYTES_, FULLBROWMINBYTES_, ERRMINOCCS_,
  871.       REQSORTBY_, DOMSORTBY_, DIRSORTBY_, TYPESORTBY_, HOSTSORTBY_,
  872.       REFSORTBY_, BROWSORTBY_, FULLBROWSORTBY_, MARKCHAR_, PAGEWIDTH_,
  873.       ALLBACK_, MONTHLYBACK_, FULLHOURLYBACK_, FULLDAILYBACK_, WEEKLYBACK_,
  874.       MONTHROWS_, FULLHOURROWS_, FULLDAYROWS_, WEEKROWS_, MONTHLY_, DAILY_,
  875.       FULLDAILY_, WEEKLY_, HOURLY_, FULLHOURLY_, DOMAIN_, DIRECTORY_,
  876.       FILETYPE_, REQUEST_, FULLHOSTS_, REFERRER_, BROWSER_, FULLBROWSER_,
  877.       STATUS_, ERROR_, DIRLEVEL_, COUNTHOSTS_, LASTSEVEN_, WARNINGS_,
  878.       CASE_, IMAGEDIR_, DIRSUFFIX_, MONTHLYUNIT_, HOURLYUNIT_,
  879.       FULLHOURLYUNIT_, DAILYUNIT_, LOGOURL_, HEADERFILE_, FOOTERFILE_,
  880.       FULLDAILYUNIT_, WEEKLYUNIT_, ALL_, GENERAL_, OUTPUT_, LANGUAGE_,
  881.       LANGFILE_, DEBUG_, PROGRESSFREQ_, RAWBYTES_, UNCOMPRESS_,
  882.       REQHASHSIZE_, DIRHASHSIZE_, TYPEHASHSIZE_, HOSTHASHSIZE_,
  883.       REFHASHSIZE_, BROWHASHSIZE_, FULLBROWHASHSIZE_, SUBDOMHASHSIZE_,
  884. #ifndef NODNS
  885.       DNSHASHSIZE_, NUMLOOKUP_, DNSFILE_, DNSFRESHHOURS_,
  886. #endif
  887.       CONFIGFILE_, OUTFILE_, PRINTVARS_
  888. }
  889.   commandtype;   /* final '_'s to avoid clashes with #defines */
  890.  
  891.   char string1[MAXSTRINGLENGTH], string2[MAXSTRINGLENGTH],
  892.        string3[MAXSTRINGLENGTH];
  893.   int rc;
  894.   flag tempflag;
  895.  
  896.   rc = sscanf_config(inputline, string1, string2, string3);
  897.   if (rc > 0) {
  898.     commandtype = BADCOMMAND_;   /* pessimism :) */
  899.     strtoupper(string1);
  900.     /* Note: some of these else if's have been changed to just if's. This is
  901.        substantially less efficient but cures a bug in BSD/OS gcc; anyway this
  902.        portion takes ~0 time to run in the context of the whole program. */
  903.     if (STREQ(string1, "FILEALIAS"))
  904.       commandtype = FILEALIAS_;
  905.     else if (STREQ(string1, "HOSTALIAS"))
  906.       commandtype = HOSTALIAS_;
  907.     else if (STREQ(string1, "REFALIAS"))
  908.       commandtype = REFALIAS_;
  909.     else if (STREQ(string1, "BROWALIAS"))
  910.       commandtype = BROWALIAS_;
  911.     else if (STREQ(string1, "REQOUTPUTALIAS"))
  912.       commandtype = REQOUTPUTALIAS_;
  913.     else if (STREQ(string1, "DIROUTPUTALIAS"))
  914.       commandtype = DIROUTPUTALIAS_;
  915.     else if (STREQ(string1, "HOSTOUTPUTALIAS"))
  916.       commandtype = HOSTOUTPUTALIAS_;
  917.     else if (STREQ(string1, "REFOUTPUTALIAS"))
  918.       commandtype = REFOUTPUTALIAS_;
  919.     else if (STREQ(string1, "BROWOUTPUTALIAS"))
  920.       commandtype = BROWOUTPUTALIAS_;
  921.     else if (STREQ(string1, "TYPEOUTPUTALIAS"))
  922.       commandtype = TYPEOUTPUTALIAS_;
  923.     else if (STREQ(string1, "FILEINCLUDE"))
  924.       commandtype = FILEINCLUDE_;
  925.     else if (STREQ(string1, "FILEEXCLUDE"))
  926.       commandtype = FILEEXCLUDE_;
  927.     else if (STREQ(string1, "FILEALLOW"))
  928.       commandtype = FILEALLOW_;
  929.     else if (STREQ(string1, "HOSTINCLUDE"))
  930.       commandtype = HOSTINCLUDE_;
  931.     else if (STREQ(string1, "HOSTEXCLUDE"))
  932.       commandtype = HOSTEXCLUDE_;
  933.     else if (STREQ(string1, "HOSTALLOW"))
  934.       commandtype = HOSTALLOW_;
  935.     else if (STREQ(string1, "REFINCLUDE"))
  936.       commandtype = REFINCLUDE_;
  937.     else if (STREQ(string1, "REFEXCLUDE"))
  938.       commandtype = REFEXCLUDE_;
  939.     else if (STREQ(string1, "REFALLOW"))
  940.       commandtype = REFALLOW_;
  941.     else if (STREQ(string1, "REQINCLUDE"))
  942.       commandtype = REQINCLUDE_;
  943.     else if (STREQ(string1, "REQEXCLUDE"))
  944.       commandtype = REQEXCLUDE_;
  945.     else if (STREQ(string1, "REQALLOW"))
  946.       commandtype = REQALLOW_;
  947.     else if (STREQ(string1, "LINKINCLUDE"))
  948.       commandtype = LINKINCLUDE_;
  949.     else if (STREQ(string1, "LINKEXCLUDE"))
  950.       commandtype = LINKEXCLUDE_;
  951.     else if (STREQ(string1, "LINKALLOW"))
  952.       commandtype = LINKALLOW_;
  953.     else if (STREQ(string1, "REFLINKINCLUDE"))
  954.       commandtype = REFLINKINCLUDE_;
  955.     if (STREQ(string1, "REFLINKEXCLUDE"))
  956.       commandtype = REFLINKEXCLUDE_;
  957.     else if (STREQ(string1, "REFLINKALLOW"))
  958.       commandtype = REFLINKALLOW_;
  959.     else if (STREQ(string1, "FROM"))
  960.       commandtype = FROM_;
  961.     else if (STREQ(string1, "TO"))
  962.       commandtype = TO_;
  963.     else if (STREQ(string1, "SUBDOMAIN"))
  964.       commandtype = SUBDOMAIN_;
  965.     else if (STREQ(string1, "WEEKBEGINSON"))
  966.       commandtype = WEEKBEGINSON_;
  967.     else if (STREQ(string1, "APPROXHOSTSIZE"))
  968.       commandtype = APPROXHOSTSIZE_;
  969.     else if (STREQ(string1, "ISPAGE"))
  970.       commandtype = ISPAGE_;
  971.     else if (STREQ(string1, "ISNOTPAGE"))
  972.       commandtype = ISNOTPAGE_;
  973.     else if (STREQ(string1, "SEPCHAR"))
  974.       commandtype = SEPCHAR_;
  975.     else if (STREQ(string1, "REPSEPCHAR"))
  976.       commandtype = REPSEPCHAR_;
  977.     else if (STREQ(string1, "DECPOINT"))
  978.       commandtype = DECPOINT_;
  979.     else if (STREQ(string1, "PRESEP"))
  980.       commandtype = PRESEP_;
  981.     else if (STREQ(string1, "REPORTORDER"))
  982.       commandtype = REPORTORDER_;
  983.     else if (STREQ(string1, "WITHARGS"))
  984.       commandtype = WITHARGS_;
  985.     else if (STREQ(string1, "WITHOUTARGS"))
  986.       commandtype = WITHOUTARGS_;
  987.     else if (STREQ(string1, "REFWITHARGS"))
  988.       commandtype = REFWITHARGS_;
  989.     else if (STREQ(string1, "REFWITHOUTARGS"))
  990.       commandtype = REFWITHOUTARGS_;
  991.     else if (STREQ(string1, "NOTSUBDOMAIN"))
  992.       commandtype = NOTSUBDOMAIN_;
  993.     else if (STREQ(string1, "BASEURL"))
  994.       commandtype = BASEURL_;
  995.     else if (STREQ(string1, "DOMCOLS"))
  996.       commandtype = DOMCOLS_;
  997.     else if (STREQ(string1, "HOSTCOLS"))
  998.       commandtype = HOSTCOLS_;
  999.     else if (STREQ(string1, "DIRCOLS"))
  1000.       commandtype = DIRCOLS_;
  1001.     else if (STREQ(string1, "TYPECOLS"))
  1002.       commandtype = TYPECOLS_;
  1003.     else if (STREQ(string1, "REQCOLS"))
  1004.       commandtype = REQCOLS_;
  1005.     if (STREQ(string1, "REFCOLS"))
  1006.       commandtype = REFCOLS_;
  1007.     else if (STREQ(string1, "BROWCOLS"))
  1008.       commandtype = BROWCOLS_;
  1009.     else if (STREQ(string1, "FULLBROWCOLS"))
  1010.       commandtype = FULLBROWCOLS_;
  1011.     else if (STREQ(string1, "MONTHCOLS"))
  1012.       commandtype = MONTHCOLS_;
  1013.     else if (STREQ(string1, "DAYCOLS"))
  1014.       commandtype = DAYCOLS_;
  1015.     else if (STREQ(string1, "FULLDAYCOLS"))
  1016.       commandtype = FULLDAYCOLS_;
  1017.     else if (STREQ(string1, "WEEKCOLS"))
  1018.       commandtype = WEEKCOLS_;
  1019.     else if (STREQ(string1, "HOURCOLS"))
  1020.       commandtype = HOURCOLS_;
  1021.     else if (STREQ(string1, "FULLHOURCOLS"))
  1022.       commandtype = FULLHOURCOLS_;
  1023.     else if (STREQ(string1, "MONTHGRAPH"))
  1024.       commandtype = MONTHGRAPH_;
  1025.     else if (STREQ(string1, "DAYGRAPH"))
  1026.       commandtype = DAYGRAPH_;
  1027.     else if (STREQ(string1, "FULLDAYGRAPH"))
  1028.       commandtype = FULLDAYGRAPH_;
  1029.     else if (STREQ(string1, "HOURGRAPH"))
  1030.       commandtype = HOURGRAPH_;
  1031.     else if (STREQ(string1, "FULLHOURGRAPH"))
  1032.       commandtype = FULLHOURGRAPH_;
  1033.     else if (STREQ(string1, "WEEKGRAPH"))
  1034.       commandtype = WEEKGRAPH_;
  1035.     else if (STREQ(string1, "GRAPHICAL"))
  1036.       commandtype = GRAPHICAL_;
  1037.     else if (STREQ(string1, "LOGFILE"))
  1038.       commandtype = LOGFILE_;
  1039.     else if (STREQ(string1, "CACHEFILE"))
  1040.       commandtype = CACHEFILE_;
  1041.     else if (STREQ(string1, "REFLOG"))
  1042.       commandtype = REFLOG_;
  1043.     else if (STREQ(string1, "BROWLOG"))
  1044.       commandtype = BROWLOG_;
  1045.     else if (STREQ(string1, "ERRLOG"))
  1046.       commandtype = ERRLOG_;
  1047.     else if (STREQ(string1, "DOMAINSFILE"))
  1048.       commandtype = DOMAINSFILE_;
  1049.     else if (STREQ(string1, "HOSTNAME"))
  1050.       commandtype = HOSTNAME_;
  1051.     else if (STREQ(string1, "HOSTURL"))
  1052.       commandtype = HOSTURL_;
  1053.     else if (STREQ(string1, "HOSTMINREQS"))
  1054.       commandtype = HOSTMINREQS_;
  1055.     if (STREQ(string1, "DOMMINREQS"))
  1056.       commandtype = DOMMINREQS_;
  1057.     else if (STREQ(string1, "SUBDOMMINREQS"))
  1058.       commandtype = SUBDOMMINREQS_;
  1059.     else if (STREQ(string1, "DIRMINREQS"))
  1060.       commandtype = DIRMINREQS_;
  1061.     else if (STREQ(string1, "TYPEMINREQS"))
  1062.       commandtype = TYPEMINREQS_;
  1063.     else if (STREQ(string1, "REQMINREQS"))
  1064.       commandtype = REQMINREQS_;
  1065.     else if (STREQ(string1, "REFMINREQS"))
  1066.       commandtype = REFMINREQS_;
  1067.     else if (STREQ(string1, "BROWMINREQS"))
  1068.       commandtype = BROWMINREQS_;
  1069.     else if (STREQ(string1, "FULLBROWMINREQS"))
  1070.       commandtype = FULLBROWMINREQS_;
  1071.     else if (STREQ(string1, "HOSTMINPAGES"))
  1072.       commandtype = HOSTMINPAGES_;
  1073.     else if (STREQ(string1, "DOMMINPAGES"))
  1074.       commandtype = DOMMINPAGES_;
  1075.     else if (STREQ(string1, "SUBDOMMINPAGES"))
  1076.       commandtype = SUBDOMMINPAGES_;
  1077.     else if (STREQ(string1, "DIRMINPAGES"))
  1078.       commandtype = DIRMINPAGES_;
  1079.     else if (STREQ(string1, "TYPEMINPAGES"))
  1080.       commandtype = TYPEMINPAGES_;
  1081.     else if (STREQ(string1, "REQMINPAGES"))
  1082.       commandtype = REQMINPAGES_;
  1083.     else if (STREQ(string1, "REFMINPAGES"))
  1084.       commandtype = REFMINPAGES_;
  1085.     else if (STREQ(string1, "BROWMINPAGES"))
  1086.       commandtype = BROWMINPAGES_;
  1087.     else if (STREQ(string1, "FULLBROWMINPAGES"))
  1088.       commandtype = FULLBROWMINPAGES_;
  1089.     else if (STREQ(string1, "HOSTMINBYTES"))
  1090.       commandtype = HOSTMINBYTES_;
  1091.     else if (STREQ(string1, "DOMMINBYTES"))
  1092.       commandtype = DOMMINBYTES_;
  1093.     else if (STREQ(string1, "SUBDOMMINBYTES"))
  1094.       commandtype = SUBDOMMINBYTES_;
  1095.     else if (STREQ(string1, "DIRMINBYTES"))
  1096.       commandtype = DIRMINBYTES_;
  1097.     else if (STREQ(string1, "TYPEMINBYTES"))
  1098.       commandtype = TYPEMINBYTES_;
  1099.     else if (STREQ(string1, "REQMINBYTES"))
  1100.       commandtype = REQMINBYTES_;
  1101.     else if (STREQ(string1, "REFMINBYTES"))
  1102.       commandtype = REFMINBYTES_;
  1103.     else if (STREQ(string1, "BROWMINBYTES"))
  1104.       commandtype = BROWMINBYTES_;
  1105.     if (STREQ(string1, "FULLBROWMINBYTES"))
  1106.       commandtype = FULLBROWMINBYTES_;
  1107.     else if (STREQ(string1, "ERRMINOCCS"))
  1108.       commandtype = ERRMINOCCS_;
  1109.     else if (STREQ(string1, "REQSORTBY"))
  1110.       commandtype = REQSORTBY_;
  1111.     else if (STREQ(string1, "DOMSORTBY"))
  1112.       commandtype = DOMSORTBY_;
  1113.     else if (STREQ(string1, "DIRSORTBY"))
  1114.       commandtype = DIRSORTBY_;
  1115.     else if (STREQ(string1, "TYPESORTBY"))
  1116.       commandtype = TYPESORTBY_;
  1117.     else if (STREQ(string1, "HOSTSORTBY"))
  1118.       commandtype = HOSTSORTBY_;
  1119.     else if (STREQ(string1, "REFSORTBY"))
  1120.       commandtype = REFSORTBY_;
  1121.     else if (STREQ(string1, "BROWSORTBY"))
  1122.       commandtype = BROWSORTBY_;
  1123.     else if (STREQ(string1, "FULLBROWSORTBY"))
  1124.       commandtype = FULLBROWSORTBY_;
  1125.     else if (STREQ(string1, "MARKCHAR"))
  1126.       commandtype = MARKCHAR_;
  1127.     else if (STREQ(string1, "PAGEWIDTH"))
  1128.       commandtype = PAGEWIDTH_;
  1129.     else if (STREQ(string1, "ALLBACK"))
  1130.       commandtype = ALLBACK_;
  1131.     else if (STREQ(string1, "MONTHLYBACK"))
  1132.       commandtype = MONTHLYBACK_;
  1133.     else if (STREQ(string1, "FULLHOURLYBACK"))
  1134.       commandtype = FULLHOURLYBACK_;
  1135.     else if (STREQ(string1, "FULLDAILYBACK"))
  1136.       commandtype = FULLDAILYBACK_;
  1137.     else if (STREQ(string1, "WEEKLYBACK"))
  1138.       commandtype = WEEKLYBACK_;
  1139.     else if (STREQ(string1, "MONTHROWS"))
  1140.       commandtype = MONTHROWS_;
  1141.     else if (STREQ(string1, "FULLHOURROWS"))
  1142.       commandtype = FULLHOURROWS_;
  1143.     else if (STREQ(string1, "WEEKROWS"))
  1144.       commandtype = WEEKROWS_;
  1145.     else if (STREQ(string1, "FULLDAYROWS"))
  1146.       commandtype = FULLDAYROWS_;
  1147.     else if (STREQ(string1, "MONTHLY"))
  1148.       commandtype = MONTHLY_;
  1149.     else if (STREQ(string1, "DAILY"))
  1150.       commandtype = DAILY_;
  1151.     else if (STREQ(string1, "FULLDAILY"))
  1152.       commandtype = FULLDAILY_;
  1153.     else if (STREQ(string1, "WEEKLY"))
  1154.       commandtype = WEEKLY_;
  1155.     if (STREQ(string1, "HOURLY"))
  1156.       commandtype = HOURLY_;
  1157.     else if (STREQ(string1, "FULLHOURLY"))
  1158.       commandtype = FULLHOURLY_;
  1159.     else if (STREQ(string1, "DOMAIN"))
  1160.       commandtype = DOMAIN_;
  1161.     else if (STREQ(string1, "DIRECTORY"))
  1162.       commandtype = DIRECTORY_;
  1163.     else if (STREQ(string1, "FILETYPE"))
  1164.       commandtype = FILETYPE_;
  1165.     else if (STREQ(string1, "REQUEST"))
  1166.       commandtype = REQUEST_;
  1167.     else if (STREQ(string1, "FULLHOSTS"))
  1168.       commandtype = FULLHOSTS_;
  1169.     else if (STREQ(string1, "REFERRER") || STREQ(string1, "REFERER"))
  1170.       commandtype = REFERRER_;
  1171.     else if (STREQ(string1, "BROWSER"))
  1172.       commandtype = BROWSER_;
  1173.     else if (STREQ(string1, "FULLBROWSER"))
  1174.       commandtype = FULLBROWSER_;
  1175.     else if (STREQ(string1, "STATUS"))
  1176.       commandtype = STATUS_;
  1177.     else if (STREQ(string1, "ERROR"))
  1178.       commandtype = ERROR_;
  1179.     else if (STREQ(string1, "DIRLEVEL"))
  1180.       commandtype = DIRLEVEL_;
  1181.     else if (STREQ(string1, "COUNTHOSTS"))
  1182.       commandtype = COUNTHOSTS_;
  1183.     else if (STREQ(string1, "LASTSEVEN"))
  1184.       commandtype = LASTSEVEN_;
  1185.     else if (STREQ(string1, "WARNINGS"))
  1186.       commandtype = WARNINGS_;
  1187.     else if (STREQ(string1, "CASE"))
  1188.       commandtype = CASE_;
  1189.     else if (STREQ(string1, "IMAGEDIR"))
  1190.       commandtype = IMAGEDIR_;
  1191.     else if (STREQ(string1, "DIRSUFFIX"))
  1192.       commandtype = DIRSUFFIX_;
  1193.     else if (STREQ(string1, "MONTHLYUNIT"))
  1194.       commandtype = MONTHLYUNIT_;
  1195.     else if (STREQ(string1, "HOURLYUNIT"))
  1196.       commandtype = HOURLYUNIT_;
  1197.     else if (STREQ(string1, "FULLHOURLYUNIT"))
  1198.       commandtype = FULLHOURLYUNIT_;
  1199.     else if (STREQ(string1, "DAILYUNIT"))
  1200.       commandtype = DAILYUNIT_;
  1201.     else if (STREQ(string1, "FULLDAILYUNIT"))
  1202.       commandtype = FULLDAILYUNIT_;
  1203.     else if (STREQ(string1, "WEEKLYUNIT"))
  1204.       commandtype = WEEKLYUNIT_;
  1205.     if (STREQ(string1, "LOGOURL"))
  1206.       commandtype = LOGOURL_;
  1207.     else if (STREQ(string1, "HEADERFILE"))
  1208.       commandtype = HEADERFILE_;
  1209.     else if (STREQ(string1, "FOOTERFILE"))
  1210.       commandtype = FOOTERFILE_;
  1211.     else if (STREQ(string1, "ALL"))
  1212.       commandtype = ALL_;
  1213.     else if (STREQ(string1, "GENERAL"))
  1214.       commandtype = GENERAL_;
  1215.     else if (STREQ(string1, "OUTPUT"))
  1216.       commandtype = OUTPUT_;
  1217.     else if (STREQ(string1, "LANGUAGE"))
  1218.       commandtype = LANGUAGE_;
  1219.     else if (STREQ(string1, "LANGFILE"))
  1220.       commandtype = LANGFILE_;
  1221.     else if (STREQ(string1, "DEBUG"))
  1222.       commandtype = DEBUG_;
  1223.     else if (STREQ(string1, "PROGRESSFREQ"))
  1224.       commandtype = PROGRESSFREQ_;
  1225.     else if (STREQ(string1, "RAWBYTES"))
  1226.       commandtype = RAWBYTES_;
  1227.     else if (STREQ(string1, "UNCOMPRESS"))
  1228.       commandtype = UNCOMPRESS_;
  1229.     else if (STREQ(string1, "REQHASHSIZE"))
  1230.       commandtype = REQHASHSIZE_;
  1231.     else if (STREQ(string1, "DIRHASHSIZE"))
  1232.       commandtype = DIRHASHSIZE_;
  1233.     else if (STREQ(string1, "TYPEHASHSIZE"))
  1234.       commandtype = TYPEHASHSIZE_;
  1235.     else if (STREQ(string1, "HOSTHASHSIZE"))
  1236.       commandtype = HOSTHASHSIZE_;
  1237.     else if (STREQ(string1, "REFHASHSIZE"))
  1238.       commandtype = REFHASHSIZE_;
  1239.     else if (STREQ(string1, "BROWHASHSIZE"))
  1240.       commandtype = BROWHASHSIZE_;
  1241.     else if (STREQ(string1, "FULLBROWHASHSIZE"))
  1242.       commandtype = FULLBROWHASHSIZE_;
  1243.     else if (STREQ(string1, "SUBDOMHASHSIZE"))
  1244.       commandtype = SUBDOMHASHSIZE_;
  1245. #ifndef NODNS
  1246.     else if (STREQ(string1, "DNSHASHSIZE"))
  1247.       commandtype = DNSHASHSIZE_;
  1248.     else if (STREQ(string1, "NUMLOOKUP"))
  1249.       commandtype = NUMLOOKUP_;
  1250.     else if (STREQ(string1, "DNSFILE"))
  1251.       commandtype = DNSFILE_;
  1252.     else if (STREQ(string1, "DNSFRESHHOURS"))
  1253.       commandtype = DNSFRESHHOURS_;
  1254. #endif
  1255.     else if (STREQ(string1, "CONFIGFILE"))
  1256.       commandtype = CONFIGFILE_;
  1257.     else if (STREQ(string1, "OUTFILE"))
  1258.       commandtype = OUTFILE_;
  1259.     else if (STREQ(string1, "PRINTVARS"))
  1260.       commandtype = PRINTVARS_;
  1261.     
  1262.     switch(commandtype) {
  1263.     case (BADCOMMAND_):
  1264.       configwarning2(inputline);
  1265.       break;
  1266.     case (FILEALIAS_):
  1267.       configalias(string2, string3, &filealiasp, string1, inputline, rc);
  1268.       break;
  1269.     case (HOSTALIAS_):
  1270.       configalias(strtolower(string2), strtolower(string3), &hostaliasp,
  1271.           string1, inputline, rc);
  1272.       break;
  1273.     case (REFALIAS_):
  1274.       configalias(string2, string3, &refaliasp, string1, inputline, rc);
  1275.       break;
  1276.     case (BROWALIAS_):
  1277.       configalias(string2, string3, &browaliasp, string1, inputline, rc);
  1278.       break;
  1279.     case (REQOUTPUTALIAS_):
  1280.       configalias(string2, string3, &routaliasp, string1, inputline, rc);
  1281.       break;
  1282.     case (DIROUTPUTALIAS_):
  1283.       configalias(string2, string3, &ioutaliasp, string1, inputline, rc);
  1284.       break;
  1285.     case (HOSTOUTPUTALIAS_):
  1286.       configalias(string2, string3, &Soutaliasp, string1, inputline, rc);
  1287.       break;
  1288.     case (REFOUTPUTALIAS_):
  1289.       configalias(string2, string3, &foutaliasp, string1, inputline, rc);
  1290.       break;
  1291.     case (BROWOUTPUTALIAS_):
  1292.       configalias(string2, string3, &boutaliasp, string1, inputline, rc);
  1293.       break;
  1294.     case (TYPEOUTPUTALIAS_):
  1295.       configalias(string2, string3, &toutaliasp, string1, inputline, rc);
  1296.       break;
  1297.     case (FILEINCLUDE_):
  1298.       include(string2, &wantfilep, wantfilehead, TRUE, string1, inputline, rc,
  1299.           &filemaskq);
  1300.       break;
  1301.     case (FILEEXCLUDE_):
  1302.       include(string2, &wantfilep, wantfilehead, FALSE, string1, inputline,
  1303.           rc, &filemaskq);
  1304.       break;
  1305.     case (FILEALLOW_):
  1306.       include(string2, &wantfilep, wantfilehead, UNSET, string1, inputline, rc,
  1307.           &tempflag);
  1308.       break;
  1309.     case (HOSTINCLUDE_):
  1310.       include(strtolower(string2), &wanthostp, wanthosthead, TRUE, string1,
  1311.           inputline, rc, &hostmaskq);
  1312.       break;
  1313.     case (HOSTEXCLUDE_):
  1314.       include(strtolower(string2), &wanthostp, wanthosthead, FALSE, string1,
  1315.           inputline, rc, &hostmaskq);
  1316.       break;
  1317.     case (HOSTALLOW_):
  1318.       include(strtolower(string2), &wanthostp, wanthosthead, UNSET, string1,
  1319.           inputline, rc, &tempflag);
  1320.       break;
  1321.     case (REFINCLUDE_):
  1322.       include(string2, &wantrefp, wantrefhead, TRUE, string1, inputline, rc,
  1323.           &refmaskq);
  1324.       break;
  1325.     case (REFEXCLUDE_):
  1326.       include(string2, &wantrefp, wantrefhead, FALSE, string1, inputline, rc,
  1327.           &refmaskq);
  1328.       break;
  1329.     case (REFALLOW_):
  1330.       include(string2, &wantrefp, wantrefhead, UNSET, string1, inputline, rc,
  1331.           &tempflag);
  1332.       break;
  1333.     case (REQINCLUDE_):
  1334.       include(string2, &wantreqp, wantreqhead, TRUE, string1, inputline, rc,
  1335.           &tempflag);
  1336.       break;
  1337.     case (REQEXCLUDE_):
  1338.       include(string2, &wantreqp, wantreqhead, FALSE, string1, inputline, rc,
  1339.           &tempflag);
  1340.       break;
  1341.     case (REQALLOW_):
  1342.       include(string2, &wantreqp, wantreqhead, UNSET, string1, inputline, rc,
  1343.           &tempflag);
  1344.       break;
  1345.     case (LINKINCLUDE_):
  1346.       include(string2, &linkp, linkhead, TRUE, string1, inputline, rc,
  1347.           &tempflag);
  1348.       break;
  1349.     case (LINKEXCLUDE_):
  1350.       include(string2, &linkp, linkhead, FALSE, string1, inputline, rc,
  1351.           &tempflag);
  1352.       break;
  1353.     case (LINKALLOW_):
  1354.       include(string2, &linkp, linkhead, UNSET, string1, inputline, rc,
  1355.           &tempflag);
  1356.       break;
  1357.     case (REFLINKINCLUDE_):
  1358.       include(string2, &reflinkp, reflinkhead, TRUE, string1, inputline, rc,
  1359.           &tempflag);
  1360.       break;
  1361.     case (REFLINKEXCLUDE_):
  1362.       include(string2, &reflinkp, reflinkhead, FALSE, string1, inputline, rc,
  1363.           &tempflag);
  1364.       break;
  1365.     case (REFLINKALLOW_):
  1366.       include(string2, &reflinkp, reflinkhead, UNSET, string1, inputline, rc,
  1367.           &tempflag);
  1368.       break;
  1369.     case (FROM_):
  1370.       fromtodate(string2, &fromtime, TRUE, string1, inputline, rc);
  1371.       break;
  1372.     case (TO_):
  1373.       fromtodate(string2, &totime, FALSE, string1, inputline, rc);
  1374.       break;
  1375.     case (SUBDOMAIN_):
  1376.       if (string2[0] == '\0')
  1377.     configwarning2(inputline);
  1378.       else if (rc < 2)
  1379.     configwarning(string1, inputline);
  1380.       else {
  1381.     strtolower(string2);
  1382.     if (rc > 3 ||
  1383.         (rc == 3 && (string2[0] == '*' || 
  1384.              string2[(int)strlen(string2) - 1] == '*' ||
  1385.              string2[0] == '%')))
  1386.       configwarning3(string1, inputline);
  1387.     strcpy(subdomp -> from, string2);
  1388.     if (rc == 2 || string2[0] == '*' ||
  1389.         string2[(int)strlen(string2) - 1] == '*' || string2[0] == '%')
  1390.       strcpy(subdomp -> to, "?");
  1391.     else
  1392.       strcpy(subdomp -> to, string3);
  1393.     subdomp -> next =
  1394.       (struct alias *)xmalloc(sizeof(struct alias));
  1395.     subdomp = subdomp -> next;
  1396.     subdomp -> from[0] = '\0';
  1397.       }
  1398.       break;
  1399.     case (WEEKBEGINSON_):
  1400.       if (rc < 2)
  1401.     configwarning(string1, inputline);
  1402.       else {
  1403.     if (rc > 2)
  1404.       configwarning3(string1, inputline);
  1405.     strtoupper(string2);
  1406.     if (STREQ(string2, "SUNDAY"))
  1407.       weekbeginson = SUNDAY;
  1408.     else if (STREQ(string2, "MONDAY"))
  1409.       weekbeginson = MONDAY;
  1410.     else if (STREQ(string2, "TUESDAY"))
  1411.       weekbeginson = TUESDAY;
  1412.     else if (STREQ(string2, "WEDNESDAY"))
  1413.       weekbeginson = WEDNESDAY;
  1414.     else if (STREQ(string2, "THURSDAY"))
  1415.       weekbeginson = THURSDAY;
  1416.     else if (STREQ(string2, "FRIDAY"))
  1417.       weekbeginson = FRIDAY;
  1418.     else if (STREQ(string2, "SATURDAY"))
  1419.       weekbeginson = SATURDAY;
  1420.     else
  1421.       configwarning2(inputline);
  1422.       }
  1423.       break;
  1424.     case (APPROXHOSTSIZE_):
  1425.       if (rc < 2)
  1426.     configwarning(string1, inputline);
  1427.       else {
  1428.     if (rc > 2)
  1429.       configwarning3(string1, inputline);
  1430.     approxhostsize = atoi(string2);
  1431.     if (approxhostsize <= 0)
  1432.       configwarning2(inputline);
  1433.       }
  1434.       break;
  1435.     case (ISPAGE_):
  1436.       include(string2, &ispagep, ispagehead, TRUE, string1, inputline, rc,
  1437.           &tempflag);
  1438.       break;
  1439.     case (ISNOTPAGE_):
  1440.       include(string2, &ispagep, ispagehead, FALSE, string1, inputline, rc,
  1441.           &tempflag);
  1442.       break;
  1443.     case (SEPCHAR_):
  1444.       if (rc < 2)
  1445.     configwarning(string1, inputline);
  1446.       else {
  1447.     if (rc > 2 || (string2[0] != '\0' && string2[1] != '\0'))
  1448.       configwarning3(string1, inputline);
  1449.     sepchar = string2[0];
  1450.       }
  1451.       break;
  1452.     case (REPSEPCHAR_):
  1453.       if (rc < 2)
  1454.     configwarning(string1, inputline);
  1455.       else {
  1456.     if (rc > 2 || (string2[0] != '\0' && string2[1] != '\0'))
  1457.       configwarning3(string1, inputline);
  1458.     repsepchar = string2[0];
  1459.       }
  1460.       break;
  1461.     case (DECPOINT_):
  1462.       if (rc < 2 || string2[0] == '\0')
  1463.     configwarning(string1, inputline);
  1464.       else {
  1465.     if (rc > 2 || string2[1] != '\0')
  1466.       configwarning3(string1, inputline);
  1467.     decpoint = string2[0];
  1468.       }
  1469.       break;
  1470.     case (PRESEP_):
  1471.       configstr(string2, presep, string1, inputline, rc);
  1472.       break;
  1473.     case (REPORTORDER_):
  1474.       if (rc < 2)
  1475.     configwarning(string1, inputline);
  1476.       else {
  1477.     if (rc > 2 || (int)strlen(string2) > 19)
  1478.       configwarning3(string1, inputline);
  1479.     strncpy(reportorder, string2, 19);
  1480.       }
  1481.       break;
  1482.     case (WITHARGS_):
  1483.       include(string2, &noexpandp, noexpandhead, FALSE, string1, inputline,
  1484.           rc, &tempflag);
  1485.       break;
  1486.     case (WITHOUTARGS_):
  1487.       include(string2, &noexpandp, noexpandhead, TRUE, string1, inputline, rc,
  1488.           &tempflag);
  1489.       break;
  1490.     case (REFWITHARGS_):
  1491.       include(string2, &refexpandp, refexpandhead, TRUE, string1, inputline,
  1492.           rc, &tempflag);
  1493.       break;
  1494.     case (REFWITHOUTARGS_):
  1495.       include(string2, &refexpandp, refexpandhead, FALSE, string1, inputline,
  1496.           rc, &tempflag);
  1497.       break;
  1498.     case (NOTSUBDOMAIN_):
  1499.       if (rc < 2)
  1500.     configwarning(string1, inputline);
  1501.       else {
  1502.     strtolower(string2);
  1503.     if (rc > 2)
  1504.       configwarning3(string1, inputline);
  1505.     tempflag = OFF;
  1506.     for (subdomtempp = subdomshead; subdomtempp -> from[0] != '\0';
  1507.          subdomtempp = subdomtempp -> next) {
  1508.       if (STREQ(subdomtempp -> from, string2)) {
  1509.         subdomtempp -> from[0] = '?'; /* mark that we don't want it */
  1510.         tempflag = ON;
  1511.       }
  1512.     }
  1513.     if (!tempflag && warnq) {
  1514.       fprintf(stderr, "%s: Warning: NOTSUBDOMAIN command before corresponding SUBDOMAIN at\n", commandname);
  1515.       fprintf(stderr, "  %s", inputline);
  1516.       if (inputline[MAX(strlen(inputline) - 1, 0)] != '\n')
  1517.         fprintf(stderr, "\n");
  1518.       anywarns = ON;
  1519.     }
  1520.       }
  1521.       break;
  1522.     case (BASEURL_):
  1523.       configstr(string2, baseurl, string1, inputline, rc);
  1524.       break;
  1525.     case (DOMCOLS_):
  1526.       configcols(string2, ocols, string1, inputline, rc);
  1527.       break;
  1528.     case (HOSTCOLS_):
  1529.       configcols(string2, Scols, string1, inputline, rc);
  1530.       break;
  1531.     case (DIRCOLS_):
  1532.       configcols(string2, icols, string1, inputline, rc);
  1533.       break;
  1534.     case (TYPECOLS_):
  1535.       configcols(string2, tcols, string1, inputline, rc);
  1536.       break;
  1537.     case (REQCOLS_):
  1538.       configcols(string2, rcols, string1, inputline, rc);
  1539.       break;
  1540.     case (REFCOLS_):
  1541.       configcols(string2, fcols, string1, inputline, rc);
  1542.       break;
  1543.     case (BROWCOLS_):
  1544.       configcols(string2, bcols, string1, inputline, rc);
  1545.       break;
  1546.     case (FULLBROWCOLS_):
  1547.       configcols(string2, Bcols, string1, inputline, rc);
  1548.       break;
  1549.     case (MONTHCOLS_):
  1550.       configcols(string2, mcols, string1, inputline, rc);
  1551.       break;
  1552.     case (DAYCOLS_):
  1553.       configcols(string2, dcols, string1, inputline, rc);
  1554.       break;
  1555.     case (FULLDAYCOLS_):
  1556.       configcols(string2, Dcols, string1, inputline, rc);
  1557.       break;
  1558.     case (WEEKCOLS_):
  1559.       configcols(string2, Wcols, string1, inputline, rc);
  1560.       break;
  1561.     case (HOURCOLS_):
  1562.       configcols(string2, hcols, string1, inputline, rc);
  1563.       break;
  1564.     case (FULLHOURCOLS_):
  1565.       configcols(string2, Hcols, string1, inputline, rc);
  1566.       break;
  1567.     case (MONTHGRAPH_):
  1568.       configchar(string2, &mgraph, string1, inputline, rc);
  1569.       break;
  1570.     case (DAYGRAPH_):
  1571.       configchar(string2, &dgraph, string1, inputline, rc);
  1572.       break;
  1573.     case (FULLDAYGRAPH_):
  1574.       configchar(string2, &Dgraph, string1, inputline, rc);
  1575.       break;
  1576.     case (HOURGRAPH_):
  1577.       configchar(string2, &hgraph, string1, inputline, rc);
  1578.       break;
  1579.     case (FULLHOURGRAPH_):
  1580.       configchar(string2, &Hgraph, string1, inputline, rc);
  1581.       break;
  1582.     case (WEEKGRAPH_):
  1583.       configchar(string2, &Wgraph, string1, inputline, rc);
  1584.       break;
  1585.     case (GRAPHICAL_):
  1586.       onoff(string2, &graphical, string1, inputline, rc);
  1587.       break;
  1588.     case (LOGFILE_):
  1589.       if (rc < 2)
  1590.     configwarning(string1, inputline);
  1591.       else if (STREQ(string2, "none")) {
  1592.     logfilep = logfilehead;
  1593.     logfilehead -> name[0] = '\0';
  1594.       }
  1595.       else if (rc == 2)
  1596.     addlogfile(&logfilep, string2, "", ON);
  1597.       else {
  1598.     addlogfile(&logfilep, string2, string3, ON);
  1599.     if (rc > 3)
  1600.       configwarning3(string1, inputline);
  1601.       }
  1602.       break;
  1603.     case (CACHEFILE_):
  1604.       if (STREQ(string2, "none")) {
  1605.     cachefilep = cachefilehead;
  1606.     cachefilehead -> name[0] = '\0';
  1607.       }
  1608.       else
  1609.     configstrlist(string2, &cachefilep, string1, inputline, rc, ON);
  1610.       break;
  1611.     case (REFLOG_):
  1612.       if (STREQ(string2, "none")) {
  1613.     reflogp = refloghead;
  1614.     refloghead -> name[0] = '\0';
  1615.       }
  1616.       else
  1617.     configstrlist(string2, &reflogp, string1, inputline, rc, ON);
  1618.       break;
  1619.     case (BROWLOG_):
  1620.       if (STREQ(string2, "none")) {
  1621.     browlogp = browloghead;
  1622.     browloghead -> name[0] = '\0';
  1623.       }
  1624.       else
  1625.     configstrlist(string2, &browlogp, string1, inputline, rc, ON);
  1626.       break;
  1627.     case (ERRLOG_):
  1628.       if (STREQ(string2, "none")) {
  1629.     errlogp = errloghead;
  1630.     errloghead -> name[0] = '\0';
  1631.       }
  1632.       else
  1633.     configstrlist(string2, &errlogp, string1, inputline, rc, ON);
  1634.       break;
  1635.     case (DOMAINSFILE_):
  1636.       configstr(string2, domainsfile, string1, inputline, rc);
  1637.       break;
  1638.     case (HOSTNAME_):
  1639.       configstr(string2, hostname, string1, inputline, rc);
  1640.       break;
  1641.     case (HOSTURL_):
  1642.       configstr(string2, hosturl, string1, inputline, rc);
  1643.       break;
  1644.     case (HOSTMINREQS_):
  1645.       configstr(string2, Sminreqstr, string1, inputline, rc);
  1646.       break;
  1647.     case (DOMMINREQS_):
  1648.       configstr(string2, ominreqstr, string1, inputline, rc);
  1649.       break;
  1650.     case (SUBDOMMINREQS_):
  1651.       configstr(string2, Ominreqstr, string1, inputline, rc);
  1652.       break;
  1653.     case (DIRMINREQS_):
  1654.       configstr(string2, iminreqstr, string1, inputline, rc);
  1655.       break;
  1656.     case (TYPEMINREQS_):
  1657.       configstr(string2, tminreqstr, string1, inputline, rc);
  1658.       break;
  1659.     case (REQMINREQS_):
  1660.       configstr(string2, rminreqstr, string1, inputline, rc);
  1661.       break;
  1662.     case (REFMINREQS_):
  1663.       configstr(string2, fminreqstr, string1, inputline, rc);
  1664.       break;
  1665.     case (BROWMINREQS_):
  1666.       configstr(string2, bminreqstr, string1, inputline, rc);
  1667.       break;
  1668.     case (FULLBROWMINREQS_):
  1669.       configstr(string2, Bminreqstr, string1, inputline, rc);
  1670.       break;
  1671.     case (HOSTMINPAGES_):
  1672.       configstr(string2, Sminpagestr, string1, inputline, rc);
  1673.       break;
  1674.     case (DOMMINPAGES_):
  1675.       configstr(string2, ominpagestr, string1, inputline, rc);
  1676.       break;
  1677.     case (SUBDOMMINPAGES_):
  1678.       configstr(string2, Ominpagestr, string1, inputline, rc);
  1679.       break;
  1680.     case (DIRMINPAGES_):
  1681.       configstr(string2, iminpagestr, string1, inputline, rc);
  1682.       break;
  1683.     case (TYPEMINPAGES_):
  1684.       configstr(string2, tminpagestr, string1, inputline, rc);
  1685.       break;
  1686.     case (REQMINPAGES_):
  1687.       configstr(string2, rminpagestr, string1, inputline, rc);
  1688.       break;
  1689.     case (REFMINPAGES_):
  1690.       configstr(string2, fminpagestr, string1, inputline, rc);
  1691.       break;
  1692.     case (BROWMINPAGES_):
  1693.       configstr(string2, bminpagestr, string1, inputline, rc);
  1694.       break;
  1695.     case (FULLBROWMINPAGES_):
  1696.       configstr(string2, Bminpagestr, string1, inputline, rc);
  1697.       break;
  1698.     case (HOSTMINBYTES_):
  1699.       configstr(string2, Sminbytestr, string1, inputline, rc);
  1700.       break;
  1701.     case (DOMMINBYTES_):
  1702.       configstr(string2, ominbytestr, string1, inputline, rc);
  1703.       break;
  1704.     case (SUBDOMMINBYTES_):
  1705.       configstr(string2, Ominbytestr, string1, inputline, rc);
  1706.       break;
  1707.     case (DIRMINBYTES_):
  1708.       configstr(string2, iminbytestr, string1, inputline, rc);
  1709.       break;
  1710.     case (TYPEMINBYTES_):
  1711.       configstr(string2, tminbytestr, string1, inputline, rc);
  1712.       break;
  1713.     case (REQMINBYTES_):
  1714.       configstr(string2, rminbytestr, string1, inputline, rc);
  1715.       break;
  1716.     case (REFMINBYTES_):
  1717.       configstr(string2, fminbytestr, string1, inputline, rc);
  1718.       break;
  1719.     case (BROWMINBYTES_):
  1720.       configstr(string2, bminbytestr, string1, inputline, rc);
  1721.       break;
  1722.     case (FULLBROWMINBYTES_):
  1723.       configstr(string2, Bminbytestr, string1, inputline, rc);
  1724.       break;
  1725.     case (ERRMINOCCS_):
  1726.       configint(string2, &eminreqs, string1, inputline, rc);
  1727.       break;
  1728.     case (REQSORTBY_):
  1729.       configsortby(string2, &rsortby, string1, inputline, rc);
  1730.       break;
  1731.     case (DOMSORTBY_):
  1732.       configsortby(string2, &osortby, string1, inputline, rc);
  1733.       break;
  1734.     case (DIRSORTBY_):
  1735.       configsortby(string2, &isortby, string1, inputline, rc);
  1736.       break;
  1737.     case (TYPESORTBY_):
  1738.       configsortby(string2, &tsortby, string1, inputline, rc);
  1739.       break;
  1740.     case (HOSTSORTBY_):
  1741.       configsortby(string2, &Ssortby, string1, inputline, rc);
  1742.       break;
  1743.     case (REFSORTBY_):
  1744.       configsortby(string2, &fsortby, string1, inputline, rc);
  1745.       break;
  1746.     case (BROWSORTBY_):
  1747.       configsortby(string2, &bsortby, string1, inputline, rc);
  1748.       break;
  1749.     case (FULLBROWSORTBY_):
  1750.       configsortby(string2, &Bsortby, string1, inputline, rc);
  1751.       break;
  1752.     case (MARKCHAR_):
  1753.       if (rc < 2)
  1754.     configwarning(string1, inputline);
  1755.       else {
  1756.     if (rc > 2 || string2[1] != '\0')
  1757.       configwarning3(string1, inputline);
  1758.     markchar = string2[0];
  1759.       }
  1760.       break;
  1761.     case (PAGEWIDTH_):
  1762.       if (rc < 2)
  1763.     configwarning(string1, inputline);
  1764.       else {
  1765.     if (rc > 2)
  1766.       configwarning3(string1, inputline);
  1767.     pagewidth = atoi(string2);
  1768.     if (pagewidth < MINPAGEWIDTH || pagewidth > MAXPAGEWIDTH) {
  1769.       fprintf(stderr, "%s: Page width should be between %d and %d\n",
  1770.           commandname, MINPAGEWIDTH, MAXPAGEWIDTH);
  1771.       configwarning2(inputline);
  1772.       pagewidth = PAGEWIDTH;
  1773.     }
  1774.       }
  1775.       break;
  1776.     case (ALLBACK_):  /* onoff() extended */
  1777.       if (rc < 2)
  1778.     configwarning(string1, inputline);
  1779.       else {
  1780.     strtoupper(string2);
  1781.     if (STREQ(string2, "ON")) {
  1782.       mback = ON;
  1783.       Hback = ON;
  1784.       Wback = ON;
  1785.       Dback = ON;
  1786.     }
  1787.     else if (STREQ(string2, "OFF")) {
  1788.       mback = OFF;
  1789.       Hback = OFF;
  1790.       Wback = OFF;
  1791.       Dback = OFF;
  1792.     }
  1793.     else
  1794.       configwarning2(inputline);
  1795.       }
  1796.       break;
  1797.     case (MONTHLYBACK_):
  1798.       onoff(string2, &mback, string1, inputline, rc);
  1799.       break;
  1800.     case (FULLHOURLYBACK_):
  1801.       onoff(string2, &Hback, string1, inputline, rc);
  1802.       break;
  1803.     case (FULLDAILYBACK_):
  1804.       onoff(string2, &Dback, string1, inputline, rc);
  1805.       break;
  1806.     case (WEEKLYBACK_):
  1807.       onoff(string2, &Wback, string1, inputline, rc);
  1808.       break;
  1809.     case (MONTHROWS_):
  1810.       configint(string2, &mrows, string1, inputline, rc);
  1811.       break;
  1812.     case (FULLHOURROWS_):
  1813.       configint(string2, &Hrows, string1, inputline, rc);
  1814.       break;
  1815.     case (WEEKROWS_):
  1816.       configint(string2, &Wrows, string1, inputline, rc);
  1817.       break;
  1818.     case (FULLDAYROWS_):
  1819.       configint(string2, &Drows, string1, inputline, rc);
  1820.       break;
  1821.     case (MONTHLY_):
  1822.       onoff(string2, &mq, string1, inputline, rc);
  1823.       break;
  1824.     case (DAILY_):
  1825.       onoff(string2, &dq, string1, inputline, rc);
  1826.       break;
  1827.     case (FULLDAILY_):
  1828.       onoff(string2, &Dq, string1, inputline, rc);
  1829.       break;
  1830.     case (HOURLY_):
  1831.       onoff(string2, &hq, string1, inputline, rc);
  1832.       break;
  1833.     case (FULLHOURLY_):
  1834.       onoff(string2, &Hq, string1, inputline, rc);
  1835.       break;
  1836.     case (WEEKLY_):
  1837.       onoff(string2, &Wq, string1, inputline, rc);
  1838.       break;
  1839.     case (DOMAIN_):
  1840.       onoff(string2, &oq, string1, inputline, rc);
  1841.       break;
  1842.     case (FULLHOSTS_):
  1843.       onoff(string2, &Sq, string1, inputline, rc);
  1844.       break;
  1845.     case (DIRECTORY_):
  1846.       onoff(string2, &iq, string1, inputline, rc);
  1847.       break;
  1848.     case (FILETYPE_):
  1849.       onoff(string2, &tq, string1, inputline, rc);
  1850.       break;
  1851.     case (REQUEST_):
  1852.       onoff(string2, &rq, string1, inputline, rc);
  1853.       break;
  1854.     case (REFERRER_):
  1855.       onoff(string2, &fq, string1, inputline, rc);
  1856.       break;
  1857.     case (BROWSER_):
  1858.       onoff(string2, &bq, string1, inputline, rc);
  1859.       break;
  1860.     case (FULLBROWSER_):
  1861.       onoff(string2, &Bq, string1, inputline, rc);
  1862.       break;
  1863.     case (STATUS_):
  1864.       onoff(string2, &cq, string1, inputline, rc);
  1865.       break;
  1866.     case (ERROR_):
  1867.       onoff(string2, &eq, string1, inputline, rc);
  1868.       break;
  1869.     case (ALL_):
  1870.       if (rc < 2)
  1871.     configwarning(string1, inputline);
  1872.       else {
  1873.     strtoupper(string2);
  1874.     if (STREQ(string2, "ON")) {
  1875.       mq = ON;
  1876.       Wq = ON;
  1877.       dq = ON;
  1878.       Dq = ON;
  1879.       hq = ON;
  1880.       Hq = ON;
  1881.       oq = ON;
  1882.       Sq = ON;
  1883.       iq = ON;
  1884.       tq = ON;
  1885.       rq = ON;
  1886.       fq = ON;
  1887.       bq = ON;
  1888.       Bq = ON;
  1889.       cq = ON;
  1890.       eq = ON;
  1891.     }
  1892.     else if (STREQ(string2, "OFF"))  {
  1893.       mq = OFF;
  1894.       Wq = OFF;
  1895.       dq = OFF;
  1896.       Dq = OFF;
  1897.       hq = OFF;
  1898.       Hq = OFF;
  1899.       oq = OFF;
  1900.       Sq = OFF;
  1901.       iq = OFF;
  1902.       tq = OFF;
  1903.       rq = OFF;
  1904.       fq = OFF;
  1905.       bq = OFF;
  1906.       Bq = OFF;
  1907.       cq = OFF;
  1908.       eq = OFF;
  1909.     }
  1910.     else
  1911.       configwarning2(inputline);
  1912.       }
  1913.       break;
  1914.     case (GENERAL_):
  1915.       onoff(string2, &xq, string1, inputline, rc);
  1916.       break;
  1917.     case (DIRLEVEL_):
  1918.       configint(string2, &dirlevel, string1, inputline, rc);
  1919.       break;
  1920.     case (COUNTHOSTS_):
  1921.       if (rc < 2)
  1922.     configwarning(string1, inputline);
  1923.       else {
  1924.     strtoupper(string2);
  1925.     if (STREQ(string2, "ON"))
  1926.       sq = ON;
  1927.     else if (STREQ(string2, "OFF"))
  1928.       sq = OFF;
  1929.     else if (STREQ(string2, "APPROX"))
  1930.       sq = APPROX;
  1931.     else
  1932.       configwarning2(inputline);
  1933.       }
  1934.       break;
  1935.     case (LASTSEVEN_):
  1936.       onoff(string2, &q7, string1, inputline, rc);
  1937.       break;
  1938.     case (WARNINGS_):
  1939.       onoff(string2, &warnq, string1, inputline, rc);
  1940.       break;
  1941.     case (CASE_):
  1942.       if (rc < 2)
  1943.     configwarning(string1, inputline);
  1944.       else {
  1945.     strtoupper(string2);
  1946.     if (STREQ(string2, "SENSITIVE"))
  1947.       case_insensitive = OFF;
  1948.     else if (STREQ(string2, "INSENSITIVE"))
  1949.       case_insensitive = ON;
  1950.     else
  1951.       configwarning2(inputline);
  1952.       }
  1953.       break;
  1954.     case (IMAGEDIR_):
  1955.       configstr(string2, imagedir, string1, inputline, rc);
  1956.       break;
  1957.     case (DIRSUFFIX_):
  1958.       configstr(string2, dirsuffix, string1, inputline, rc);
  1959.       break;
  1960.     case (MONTHLYUNIT_):
  1961.       configint(string2, &munit, string1, inputline, rc);      
  1962.       break;
  1963.     case (HOURLYUNIT_):
  1964.       configint(string2, &hunit, string1, inputline, rc);      
  1965.       break;
  1966.     case (FULLHOURLYUNIT_):
  1967.       configint(string2, &Hunit, string1, inputline, rc);      
  1968.       break;
  1969.     case (DAILYUNIT_):
  1970.       configint(string2, &dunit, string1, inputline, rc);      
  1971.       break;
  1972.     case (FULLDAILYUNIT_):
  1973.       configint(string2, &Dunit, string1, inputline, rc);      
  1974.       break;
  1975.     case (WEEKLYUNIT_):
  1976.       configint(string2, &Wunit, string1, inputline, rc);      
  1977.       break;
  1978.     case (LOGOURL_):
  1979.       configstr(string2, logourl, string1, inputline, rc);
  1980.       break;
  1981.     case (HEADERFILE_):
  1982.       configstr(string2, headerfile, string1, inputline, rc);
  1983.       break;
  1984.     case (FOOTERFILE_):
  1985.       configstr(string2, footerfile, string1, inputline, rc);
  1986.       break;
  1987.     case (OUTPUT_):
  1988.       if (rc < 2)
  1989.     configwarning(string1, inputline);
  1990.       else {
  1991.     if (rc > 2)
  1992.       configwarning3(string1, inputline);
  1993.     strtoupper(string2);
  1994.     if (STREQ(string2, "ASCII"))
  1995.       aq = ASCII;
  1996.     else if (STREQ(string2, "HTML"))
  1997.       aq = HTML;
  1998.     else if (STREQ(string2, "CACHE"))
  1999.       aq = CACHE;
  2000.     else if (STREQ(string2, "PREFORMATTED"))
  2001.       aq = PREFORMATTED;
  2002.     else
  2003.       configwarning2(inputline);
  2004.       }
  2005.       break;
  2006.     case (LANGUAGE_):
  2007.       if (rc < 2)
  2008.     configwarning(string1, inputline);
  2009.       else {
  2010.     if (rc > 2)
  2011.       configwarning3(string1, inputline);
  2012.     strtoupper(string2);
  2013.     if (STREQ(string2, "ENGLISH"))
  2014.       lang = ENGLISH;
  2015.     else if (STREQ(string2, "US-ENGLISH"))
  2016.       lang = US_ENGLISH;
  2017.     else if (STREQ(string2, "FRENCH"))
  2018.       lang = FRENCH;
  2019.     else if (STREQ(string2, "GERMAN"))
  2020.       lang = GERMAN;
  2021.     else if (STREQ(string2, "ITALIAN"))
  2022.       lang = ITALIAN;
  2023.     else if (STREQ(string2, "SPANISH"))
  2024.       lang = SPANISH;
  2025.     else if (STREQ(string2, "DANISH"))
  2026.       lang = DANISH;
  2027.     else
  2028.       configwarning2(inputline);
  2029.       }
  2030.       break;
  2031.     case (LANGFILE_):
  2032.       configstr(string2, langfile, string1, inputline, rc);
  2033.       if (rc >= 2)
  2034.     lang = UNSET;
  2035.       break;
  2036.     case (DEBUG_):
  2037.       configint(string2, &debug, string1, inputline, rc);      
  2038.       break;
  2039.     case (PROGRESSFREQ_):
  2040.       configint(string2, &progressfreq, string1, inputline, rc);      
  2041.       break;
  2042.     case (RAWBYTES_):
  2043.       onoff(string2, &rawbytes, string1, inputline, rc);
  2044.       break;
  2045.     case (UNCOMPRESS_):
  2046.       if (rc < 3)
  2047.     configwarning(string1, inputline);
  2048.       else {
  2049.     addlogfile(&uncompressp, string2, string3, OFF);
  2050.     if (rc > 3)
  2051.       configwarning3(string1, inputline);
  2052.       }
  2053.       break;
  2054.     case (REQHASHSIZE_):
  2055.       configsizet(string2, &rhashsize, string1, inputline, rc);      
  2056.       break;
  2057.     case (DIRHASHSIZE_):
  2058.       configsizet(string2, &ihashsize, string1, inputline, rc);      
  2059.       break;
  2060.     case (TYPEHASHSIZE_):
  2061.       configsizet(string2, &thashsize, string1, inputline, rc);      
  2062.       break;
  2063.     case (HOSTHASHSIZE_):
  2064.       configsizet(string2, &Shashsize, string1, inputline, rc);      
  2065.       break;
  2066.     case (REFHASHSIZE_):
  2067.       configsizet(string2, &fhashsize, string1, inputline, rc);      
  2068.       break;
  2069.     case (BROWHASHSIZE_):
  2070.       configsizet(string2, &bhashsize, string1, inputline, rc);      
  2071.       break;
  2072.     case (FULLBROWHASHSIZE_):
  2073.       configsizet(string2, &Bhashsize, string1, inputline, rc);      
  2074.       break;
  2075.     case (SUBDOMHASHSIZE_):
  2076.       configsizet(string2, &Ohashsize, string1, inputline, rc);      
  2077.       break;
  2078. #ifndef NODNS
  2079.     case (DNSHASHSIZE_):
  2080.       configsizet(string2, &dnshashsize, string1, inputline, rc);      
  2081.       break;
  2082.     case (NUMLOOKUP_):
  2083.       onoff(string2, &dnsq, string1, inputline, rc);
  2084.       break;
  2085.     case (DNSFILE_):
  2086.       configstr(string2, dnsfile, string1, inputline, rc);
  2087.       break;
  2088.     case (DNSFRESHHOURS_):
  2089.       configint(string2, &dnsfreshhours, string1, inputline, rc);
  2090.       break;
  2091. #endif
  2092.     case (CONFIGFILE_):
  2093.       config(string2);
  2094.       break;
  2095.     case (OUTFILE_):
  2096.       configstr(string2, outfile, string1, inputline, rc);
  2097.       break;
  2098.     case (PRINTVARS_):
  2099.       onoff(string2, &vblesonly, string1, inputline, rc);
  2100.       break;
  2101.     }
  2102.   }
  2103. }
  2104.  
  2105. flag config(char *filename)
  2106. {
  2107.   FILE *cf;
  2108.   flag ispipe;
  2109.   char inputline[MAXLINELENGTH];
  2110.  
  2111.   if (STREQ(filename, "none"))
  2112.     return(0);
  2113.   else {
  2114.     no_configs++;
  2115.     if (no_configs > MAX_CONFIGS) {
  2116.       fprintf(stderr, "%s: Error: More than %d configuration files:\n",
  2117.           commandname, MAX_CONFIGS);
  2118.       fprintf(stderr, "  probably being called in circles: exiting\n");
  2119.       exit(ERR);
  2120.     }
  2121.     cf = fopenlog(filename, "configuration file", &ispipe);
  2122.     if (cf == NULL)
  2123.       return(1);
  2124.     else {  /* we can read the config. file */
  2125.       while (fgets(inputline, MAXLINELENGTH, cf) != NULL)
  2126.     configline(inputline);
  2127.       fcloselog(cf, filename, "configuration file", ispipe);
  2128.       return(0);
  2129.     }
  2130.   }
  2131. }
  2132.  
  2133. /*** Now the main commandline command ***/
  2134.  
  2135. void commandline(int argc, char **argv)
  2136. {
  2137.   int i;
  2138.  
  2139.   flag Gfound = FALSE;
  2140.   char tempstr1[MAXSTRINGLENGTH], tempstr2[MAXSTRINGLENGTH];
  2141.  
  2142.   /* First see whether to include the default config. file, by scanning
  2143.      backwards through the arguments looking for the (last) occurrence of
  2144.      +G or -G. We then run the config. file, then look at the other args. */
  2145.  
  2146.   for (i = argc - 1; i >= 1 && !Gfound; i--) {
  2147.     if (argv[i][1] == 'G') {
  2148.       if (argv[i][2] != '\0' && (argv[i][0] == '+' || argv[i][0] == '-')) {
  2149.     if (warnq) {
  2150.       fprintf(stderr,
  2151.           "%s: Warning: ignoring extra text after %cG option\n",
  2152.           commandname, argv[i][0]);
  2153.       anywarns = ON;
  2154.     }
  2155.       }
  2156.       if (argv[i][0] == '+') {
  2157.     Gfound = TRUE;
  2158.     config(DEFAULTCONFIGFILE);
  2159.       }
  2160.       else if (argv[i][0] == '-') {
  2161.     Gfound = TRUE;
  2162.       }
  2163.     }
  2164.   }
  2165.   if (!Gfound) {
  2166.     logfilep = logfilehead;
  2167.     cachefilep = cachefilehead;
  2168.     reflogp = refloghead;
  2169.     browlogp = browloghead;
  2170.     errlogp = errloghead;
  2171.     config(DEFAULTCONFIGFILE);
  2172.   }
  2173.  
  2174.   logfilep = logfilehead;  /* reset logfile pointers for over-write */
  2175.   cachefilep = cachefilehead;
  2176.   reflogp = refloghead;
  2177.   browlogp = browloghead;
  2178.   errlogp = errloghead;
  2179.  
  2180.   /* Now read the other arguments */
  2181.  
  2182.   for (i = 1; i < argc; i++) {
  2183.  
  2184.     if (argv[i][0] != '+' && argv[i][0] != '-') {
  2185.       if (STREQ(argv[i], "none")) {
  2186.     logfilep = logfilehead;
  2187.     logfilehead -> name[0] = '\0';
  2188.       }
  2189.       else
  2190.     addlogfile(&logfilep, argv[i], "", ON);
  2191.     }
  2192.     else switch (argv[i][1]) {
  2193.     case '\0':    /* read stdin */
  2194.       addlogfile(&logfilep, "stdin", "", ON);
  2195.       break;
  2196. #ifndef NODNS
  2197.     case '1':
  2198.       clflag(&dnsq, argv[i]);
  2199.       break;
  2200. #endif
  2201.     case '7':     /* stats for last 7 days */
  2202.       clflag(&q7, argv[i]);
  2203.       break;
  2204.     case 'a':     /* ASCII output */
  2205.       clflag(&aq, argv[i]);  /* This works because ON = ASCII, OFF = HTML */
  2206.       break;      
  2207.     case 'A':     /* all reports */
  2208.       if (argv[i][0] == '-')
  2209.     configline("ALL OFF");
  2210.       else
  2211.     configline("ALL ON");
  2212.       if (argv[i][2] != '\0' && warnq) {
  2213.     fprintf(stderr, "%s: Warning: ignoring extra text after %cA option\n",
  2214.         commandname, argv[i][0]);
  2215.     anywarns = ON;
  2216.       }
  2217.       break;
  2218.     case 'b':     /* browser summary */
  2219.       clgenrep(&bq, &bsortby, bminreqstr, bminpagestr, bminbytestr, argv[i]);
  2220.       break;
  2221.     case 'B':     /* browser report */
  2222.       clgenrep(&Bq, &Bsortby, Bminreqstr, Bminpagestr, Bminbytestr, argv[i]);
  2223.       break;
  2224.     case 'c':     /* status code report */
  2225.       clflag(&cq, argv[i]);
  2226.       break;
  2227.     case 'C':     /* configuration command */
  2228.       if (argv[i][2] == '\0') {
  2229.     if (warnq) {
  2230.       fprintf(stderr, "%s: Warning: no command supplied after +C option\n",
  2231.           commandname);
  2232.       fprintf(stderr, "  (or space left before command)\n");
  2233.       anywarns = ON;
  2234.     }
  2235.       }
  2236.       else
  2237.     configline(argv[i] + 2);
  2238.       break;
  2239.     case 'd':     /* daily summary */
  2240.       cldaterep(&dq, &dgraph, argv[i]);
  2241.       break;
  2242.     case 'D':     /* full daily report */
  2243.       cldaterep(&Dq, &Dgraph, argv[i]);
  2244.       break;
  2245.     case 'e':     /* error report */
  2246.       clflag(&eq, argv[i]);
  2247.       break;
  2248.     case 'f':     /* form */
  2249.       if (STREQ(argv[i] + 2, "orm"))
  2250.     formq = ON;
  2251.       else        /* referrer report */
  2252.     clgenrep(&fq, &fsortby, fminreqstr, fminpagestr, fminbytestr, argv[i]);
  2253.       break;
  2254.     case 'F':     /* FROM */
  2255.       if (argv[i][0] == '-') {
  2256.     configline("FROM OFF");
  2257.     if (argv[i][2] != '\0' && warnq) {
  2258.       fprintf(stderr, "%s: Warning: ignoring extra text after -F option\n",
  2259.           commandname);
  2260.       anywarns = ON;
  2261.     }
  2262.       }
  2263.       else if (argv[i][2] == '\0' && warnq) {
  2264.     fprintf(stderr, "%s: Warning: no date supplied after +F option\n",
  2265.         commandname);
  2266.     fprintf(stderr, "  (or space left before date)\n");
  2267.     anywarns = ON;
  2268.       }
  2269.       else {
  2270.     strcpy(tempstr2, "FROM ");
  2271.     strcat(tempstr2, argv[i] + 2);
  2272.     configline(tempstr2);
  2273.       }
  2274.       break;
  2275.     case 'g':     /* configuration file */
  2276.       if (argv[i][0] == '+') {
  2277.     if (argv[i][2] == '\0') {
  2278.       if (warnq) {
  2279.         fprintf(stderr,
  2280.             "%s: Warning: no filename supplied after +g option\n",
  2281.             commandname);
  2282.         fprintf(stderr, "  (or space left before filename)\n");
  2283.         anywarns = ON;
  2284.       }
  2285.     }
  2286.     else
  2287.       config(argv[i] + 2);
  2288.       }
  2289.       else {
  2290.     fprintf(stderr, "%s: Warning: Ignoring unknown option -g:\n",
  2291.         commandname);
  2292.     fprintf(stderr, "  see Readme.html for correct usage\n");
  2293.     fprintf(stderr,
  2294.         "  or go to http://www.statslab.cam.ac.uk/~sret1/analog/\n");
  2295.       }
  2296.       break;
  2297.     case 'G':     /* default configuration file: done already */
  2298.       break;
  2299.     case 'h':     /* help */
  2300.       if (STREQ(argv[i] + 2, "elp")) {
  2301.     fprintf(stderr, "For help see Readme.html, or ");
  2302.     fprintf(stderr, "http://www.statslab.cam.ac.uk/~sret1/analog/\n");
  2303.     exit(OK);
  2304.       }
  2305.       else        /* hourly summary */
  2306.     cldaterep(&hq, &hgraph, argv[i]);
  2307.       break;
  2308.     case 'H':     /* hourly report */
  2309.       cldaterep(&Hq, &Hgraph, argv[i]);
  2310.       break;
  2311.     case 'i':     /* directory report */
  2312.       clgenrep(&iq, &isortby, iminreqstr, iminpagestr, iminbytestr, argv[i]);
  2313.       break;
  2314.     case 'l':     /* 'level' of dir report */
  2315.       dirlevel = atoi(argv[i] + 2);
  2316.       break;
  2317.     case 'm':     /* monthly report */
  2318.       cldaterep(&mq, &mgraph, argv[i]);
  2319.       break;
  2320.     case 'n':     /* our host or organisation name */
  2321.       if (argv[i][2] == '\0') {
  2322.     if (warnq) {
  2323.       fprintf(stderr, "%s: Warning: no text supplied after %cn option\n",
  2324.           commandname, argv[i][0]);
  2325.       fprintf(stderr, "  (or space left before text)\n");
  2326.       anywarns = ON;
  2327.     }
  2328.       }
  2329.       else
  2330.     strncpy(hostname, argv[i] + 2, MAXSTRINGLENGTH - 1);
  2331.       break;
  2332.     case 'o':                 /* domain report */
  2333.       clgenrep(&oq, &osortby, ominreqstr, ominpagestr, ominbytestr, argv[i]);
  2334.       break;
  2335.     case 'O':     /* outfile */
  2336.       clfile(outfile, argv[i]);
  2337.       break;
  2338.     case 'p':    /* logo? */
  2339.       clfile(logourl, argv[i]);
  2340.       break;
  2341.     case 'q':    /* warnings? */
  2342.       clflag(&warnq, argv[i]);
  2343.       break;
  2344.     case 'r':    /* request report */
  2345.       clgenrep(&rq, &rsortby, rminreqstr, rminpagestr, rminbytestr, argv[i]);
  2346.       break;
  2347.     case 's':      /* count hosts? */
  2348.       if (argv[i][0] == '-')
  2349.     sq = OFF;
  2350.       else if (argv[i][2] == 's')
  2351.     sq = APPROX;
  2352.       else
  2353.     sq = ON;
  2354.       if (argv[i][2] == 's') {
  2355.     if (argv[i][3] != '\0' && warnq) {
  2356.       fprintf(stderr,
  2357.           "%s: Warning: ignoring extra text after %css option\n",
  2358.           commandname, argv[i][0]);
  2359.       anywarns = ON;
  2360.     }
  2361.       }
  2362.       else {  /* argv[i][2] != 's' */
  2363.     if (argv[i][2] != '\0' && warnq) {
  2364.       fprintf(stderr,
  2365.           "%s: Warning: ignoring extra text after %cs option\n",
  2366.           commandname, argv[i][0]);
  2367.       anywarns = ON;
  2368.     }
  2369.       }
  2370.       break;
  2371.     case 'S':      /* full hostname report */
  2372.       clgenrep(&Sq, &Ssortby, Sminreqstr, Sminpagestr, Sminbytestr, argv[i]);
  2373.       break;
  2374.     case 't':     /* file type report */
  2375.       clgenrep(&tq, &tsortby, tminreqstr, tminpagestr, tminbytestr, argv[i]);
  2376.       break;
  2377.     case 'T':     /* TO */
  2378.       if (argv[i][0] == '-') {
  2379.     configline("TO OFF");
  2380.     if (argv[i][2] != '\0' && warnq) {
  2381.       fprintf(stderr, "%s: Warning: ignoring extra text after -T option\n",
  2382.           commandname);
  2383.       anywarns = ON;
  2384.     }
  2385.       }
  2386.       else if (argv[i][2] == '\0' && warnq) {
  2387.     fprintf(stderr, "%s: Warning: no date supplied after +T option\n",
  2388.         commandname);
  2389.     fprintf(stderr, "  (or space left before date)\n");
  2390.     anywarns = ON;
  2391.       }
  2392.       else {
  2393.     strcpy(tempstr2, "TO ");
  2394.     strcat(tempstr2, argv[i] + 2);
  2395.     configline(tempstr2);
  2396.       }
  2397.       break;
  2398.     case 'u':     /* host URL */
  2399.       if (argv[i][2] == '\0') {
  2400.     if (warnq) {
  2401.       fprintf(stderr, "%s: Warning: no URL supplied after %cu option\n",
  2402.           commandname, argv[i][0]);
  2403.       fprintf(stderr, "  (or space left before URL)\n");
  2404.       anywarns = ON;
  2405.     }
  2406.       }
  2407.       else
  2408.     strncpy(hosturl, argv[i] + 2, MAXSTRINGLENGTH - 1);
  2409.       break;
  2410.     case 'U':      /* cache file */
  2411.       if(clfile(tempstr1, argv[i]) == OK) {
  2412.     strcpy(tempstr2, "CACHEFILE ");
  2413.     strncat(tempstr2, tempstr1, MAXSTRINGLENGTH - 11);
  2414.     configline(tempstr2);
  2415.       }
  2416.       break;
  2417.     case 'v':          /* print variables and exit */
  2418.       if (argv[i][2] != '\0' && warnq) {
  2419.     fprintf(stderr, "%s: Warning: ignoring extra text after %cv option\n",
  2420.         commandname, argv[i][0]);
  2421.     anywarns = ON;
  2422.       }
  2423.       vblesonly = ON;
  2424.       break;
  2425.     case 'V':          /* debugging info */
  2426.       if (argv[i][0] == '-') {
  2427.     debug = OFF;
  2428.     if (argv[i][2] != '\0' && warnq) {
  2429.       fprintf(stderr, "%s: Warning: ignoring extra text after -V option\n",
  2430.           commandname);
  2431.       anywarns = ON;
  2432.     }
  2433.       }
  2434.       else {
  2435.     if (argv[i][2] == '\0')
  2436.       debug = 1;
  2437.     else
  2438.       debug = atoi(argv[i] + 2);
  2439.       }
  2440.       break;
  2441.     case 'w':          /* pagewidth */
  2442.       pagewidth = atoi(argv[i] + 2);
  2443.       if (pagewidth < MINPAGEWIDTH || pagewidth > MAXPAGEWIDTH) {
  2444.     if (warnq) {
  2445.       fprintf(stderr,"%s: Warning: at option %s, page width should be between %d and %d\n", commandname, argv[i], MINPAGEWIDTH, MAXPAGEWIDTH);
  2446.       fprintf(stderr, "  Resetting to default value of %d\n", PAGEWIDTH);
  2447.       anywarns = ON;
  2448.     }
  2449.     pagewidth = PAGEWIDTH;
  2450.       }
  2451.       break;
  2452.     case 'W':           /* weekly report */
  2453.       cldaterep(&Wq, &Wgraph, argv[i]);
  2454.       break;
  2455.     case 'x':           /* general summary and gotos */
  2456.       clflag(&xq, argv[i]);
  2457.       break;
  2458.     default:
  2459.       fprintf(stderr, "%s: Warning: Ignoring unknown option %s:\n",
  2460.           commandname, argv[i]);
  2461.       fprintf(stderr, "  see Readme.html for correct usage\n");
  2462.       fprintf(stderr,
  2463.       "  or go to http://www.statslab.cam.ac.uk/~sret1/analog/\n");
  2464.     }
  2465.   }
  2466.  
  2467.   /* Finally, the mandatory config file */
  2468.   logfilep = logfilehead;  /* reset logfile pointers for over-write */
  2469.   cachefilep = cachefilehead;
  2470.   reflogp = refloghead;
  2471.   browlogp = browloghead;
  2472.   errlogp = errloghead;
  2473.  
  2474.   if (config(MANDATORYCONFIGFILE)) {
  2475.     fprintf(stderr,
  2476.     "%s: Error: Cannot ignore mandatory configuration file: exiting\n",
  2477.         commandname);
  2478.     exit(ERR);
  2479.   }
  2480.  
  2481. }
  2482.  
  2483. /*** The actual initialise() function ***/
  2484.  
  2485. void initialise(int argc, char **argv)
  2486. {
  2487.   FILE *outf;
  2488.   FILE *langf;
  2489.   flag ispipe;
  2490.   char templine[MAXLINELENGTH];
  2491.   int i;
  2492.  
  2493.   time(&starttime);
  2494.   starttimetm = localtime(&starttime);
  2495.   starttimec.year = 1900 + starttimetm -> tm_year;
  2496.   starttimec.date = starttimetm -> tm_mday;
  2497.   starttimec.monthno = starttimetm -> tm_mon;
  2498.   starttimec.hr = starttimetm -> tm_hour;
  2499.   starttimec.min = starttimetm -> tm_min;
  2500.   starttimec.code = timecode(starttimec.date, starttimec.monthno,
  2501.                  starttimec.year, starttimec.hr, starttimec.min);
  2502.  
  2503.   defaults();   /* enter the defaults for all the variables
  2504.            (before possibly changing them). */
  2505.  
  2506. #ifdef MAC_EVENTS
  2507.   commandname = (char *)xmalloc(7);
  2508.   strcpy(commandname, "analog");
  2509. #else
  2510.   commandname = (char *)xmalloc(strlen(argv[0]) + 1);
  2511.   strcpy(commandname, argv[0]);
  2512. #endif
  2513.  
  2514.   init_structs();   /* initialise all the structures (and pointers to them) */
  2515.  
  2516.   commandline(argc, argv);  /* parse commandline. This also parses all the
  2517.                    configuration files. */
  2518.  
  2519.   /* correct any variables for which wrong value given */
  2520.  
  2521.   if (fromtime.code > totime.code) {
  2522.     fprintf(stderr, "%s: Error: FROM and TO exclude all dates.\n",
  2523.         commandname);
  2524.     exit(ERR);
  2525.   }
  2526.  
  2527.   if (dirlevel == 0)
  2528.     dirlevel = 1;
  2529.  
  2530.   if (Sq)
  2531.     sq = ON;      /* +S implies +s */
  2532.  
  2533.   if (STREQ(baseurl, "none"))
  2534.     baseurl[0] = '\0';
  2535.   else if (baseurl[MAX(strlen(baseurl) - 1, 0)] == '/')
  2536.     baseurl[strlen(baseurl) - 1] = '\0';
  2537.  
  2538.   if (aq == CACHE) {
  2539.     configline("ALL OFF");
  2540.     xq = OFF;
  2541.     Hq = ON;
  2542.     Hback = OFF;
  2543.     Hrows = 0;
  2544.   }
  2545.  
  2546.   else if (aq == PREFORMATTED) {
  2547.     rawbytes = ON;
  2548.     lang = ENGLISH;  /* only affects days of the week */
  2549.     sepchar = '\0';
  2550.     repsepchar = '\0';
  2551.     decpoint = '.';  /* don't need this last one at the moment, but... */
  2552.   }
  2553.  
  2554.   if (rsortby == BYPAGES) {
  2555.     fprintf(stderr,
  2556.         "%s: Warning: Cannot sort request report by page requests:\n",
  2557.         commandname);
  2558.     fprintf(stderr, "  Sorting by requests instead.\n");
  2559.     rsortby = BYREQUESTS;
  2560.   }
  2561.  
  2562.   if (case_insensitive) {
  2563.     alias_to_lower(filealiashead);
  2564.     include_to_lower(wantfilehead);
  2565.     include_to_lower(wantreqhead);
  2566.     include_to_lower(linkhead);
  2567.     include_to_lower(ispagehead);
  2568.     include_to_lower(noexpandhead);
  2569.     strtolower(dirsuffix);
  2570.   }
  2571.  
  2572.   /* language support */
  2573.  
  2574.   if (lang != UNSET) {   /* otherwise langfile should already be set */
  2575.     strcpy(langfile, LANGDIR);
  2576.     if (lang == US_ENGLISH) {
  2577.       if (aq == HTML)
  2578.     strcat(langfile, "usengh.lng");
  2579.       else
  2580.     strcat(langfile, "usenga.lng");
  2581.     }
  2582.     else if (lang == DANISH) {
  2583.       if (aq == HTML)
  2584.     strcat(langfile, "danishh.lng");
  2585.       else
  2586.     strcat(langfile, "danisha.lng");
  2587.     }
  2588.     else if (lang == FRENCH) {
  2589.       if (aq == HTML)
  2590.     strcat(langfile, "frenchh.lng");
  2591.       else
  2592.     strcat(langfile, "frencha.lng");
  2593.     }
  2594.     else if (lang == GERMAN) {
  2595.       if (aq == HTML)
  2596.     strcat(langfile, "germanh.lng");
  2597.       else
  2598.     strcat(langfile, "germana.lng");
  2599.     }
  2600.     else if (lang == SPANISH) {
  2601.       if (aq == HTML)
  2602.     strcat(langfile, "spanishh.lng");
  2603.       else
  2604.     strcat(langfile, "spanisha.lng");
  2605.     }
  2606.     else if (lang == ITALIAN) {
  2607.       if (aq == HTML)
  2608.     strcat(langfile, "italianh.lng");
  2609.       else
  2610.     strcat(langfile, "italiana.lng");
  2611.     }
  2612.     else {  /* lang == ENGLISH */
  2613.       if (aq == HTML)
  2614.     strcat(langfile, "englishh.lng");
  2615.       else
  2616.     strcat(langfile, "englisha.lng");
  2617.     }
  2618.   }
  2619.   if (vblesonly) {
  2620.     strcpy(oldlangfile, langfile);  /* save for reporting */
  2621.     strcpy(langfile, LANGDIR "englisha.lng");  /* but read English instead */
  2622.   }
  2623.  
  2624.   if ((langf = fopenlog(langfile, "language file", &ispipe)) == NULL) {
  2625.     fprintf(stderr, "%s: Error: cannot ignore language file: exiting.\n",
  2626.           commandname);
  2627.     exit(ERR);
  2628.   }
  2629.  
  2630.   for (i = 0; i < 7; i++) {
  2631.     if (fscanf(langf, "%[^\n]%*[\n]", templine) != 1 ||
  2632.     ((templine[0] != '#' || templine[1] != '#') &&
  2633.      strlen(templine) >= 11)) {
  2634.       fprintf(stderr, "%s: Error: corrupt language file %s: exiting.\n",
  2635.           commandname, langfile);
  2636.       exit(ERR);
  2637.     }
  2638.     if (templine[0] == '#' && templine[1] == '#')
  2639.       i--;
  2640.     else
  2641.       strcpy(dayname[i], templine);  /* have checked it will fit above */
  2642.   }
  2643.   for (i = 0; i < 12; i++) {
  2644.     if (fscanf(langf, "%[^\n]%*[\n]", templine) != 1 ||
  2645.     ((templine[0] != '#' || templine[1] != '#') &&
  2646.      strlen(templine) >= 12)) {
  2647.       fprintf(stderr, "%s: Error: corrupt language file %s: exiting.\n",
  2648.           commandname, langfile);
  2649.       exit(ERR);
  2650.     }
  2651.     if (templine[0] == '#' && templine[1] == '#')
  2652.       i--;
  2653.     else
  2654.       strcpy(monthname[i], templine);
  2655.   }
  2656.   for (i = 0; i < NOLNGSTRS; i++) {
  2657.     if (fscanf(langf, "%[^\n]%*[\n]", templine) != 1 ||
  2658.     ((templine[0] != '#' || templine[1] != '#') &&
  2659.      strlen(templine) >= MAXSTRINGLENGTH)) {
  2660.       fprintf(stderr, "%s: Error: corrupt language file %s: exiting.\n",
  2661.           commandname, langfile);
  2662.       exit(ERR);
  2663.     }
  2664.     if (templine[0] == '#' && templine[1] == '#')
  2665.       i--;
  2666.     else {
  2667.       lngstr[i] = (char *)xmalloc(strlen(templine) + 1);
  2668.       strcpy(lngstr[i], templine);
  2669.     }
  2670.   }
  2671.  
  2672.   fcloselog(langf, langfile, "language file", ispipe);
  2673.  
  2674.   if (vblesonly)
  2675.     printvbles();    /* which also exits */
  2676.  
  2677.   if (!STREQ(outfile, "stdout")) {
  2678.     if ((outf = fopen(outfile, "w")) == NULL) {
  2679.       fprintf(stderr,
  2680.           "%s: Error: failed to open output file %s for writing.\n",
  2681.           commandname, outfile);
  2682.       exit(ERR);   /* test now so we don't do the processing THEN find out */
  2683.     }
  2684.     else
  2685.       fclose(outf);  /* no need to hold it open */
  2686.   }
  2687.  
  2688.   /* if we just want a form, generate that and exit */
  2689.  
  2690.   if (formq) {
  2691.     formgen();
  2692.     exit(OK);
  2693.   }
  2694.  
  2695.   othervars();
  2696.  
  2697. }   /* end initialise() */
  2698.  
  2699.  
  2700. /*** Finally, a boring function just to print variables and exit ***/
  2701.  
  2702. void printvbles(void)
  2703. {
  2704.   char *c;
  2705.  
  2706.   stdin_used = FALSE;
  2707.  
  2708.   printf("This is analog version %s\n", VERSION);
  2709.   printf("For more information on analog see Readme.html or\n");
  2710.   printf("http://www.statslab.cam.ac.uk/~sret1/analog/\n\n");
  2711.  
  2712.   if (formq) {
  2713.     printf("These options would construct form in %s; see that file for options set\n",
  2714.        outfile);
  2715.   }
  2716.   else {
  2717.     printf("Logfiles to analyse:\n");   /* as pvfilelist(), but for logfiles */
  2718.     if (logfilehead -> name[0] == '\0')
  2719.       printf("  none\n");
  2720.     for (logfilep = logfilehead; logfilep -> name[0] != '\0';
  2721.      logfilep = logfilep -> next) {
  2722.       printf("  %s", logfilep -> name);
  2723.       pvfiletest(logfilep -> name);
  2724.     }
  2725.  
  2726.     pvfilelist(cachefilehead, "Cache files");
  2727.  
  2728.     if (aq != CACHE) {
  2729.       pvfilelist(refloghead, "Referrer logs");
  2730.       pvfilelist(browloghead, "Browser logs");
  2731.       pvfilelist(errloghead, "Error logs");
  2732.     }
  2733.  
  2734.     if (uncompresshead -> name[0] != '\0') {
  2735.       printf("Files uncompressed by the following methods:\n");
  2736.       for (uncompressp = uncompresshead; uncompressp -> name[0] != '\0';
  2737.        uncompressp = uncompressp -> next)
  2738.     printf("  %s by %s\n", uncompressp -> name, uncompressp -> prefix);
  2739.     }
  2740.     printf("Filenames are case %s\n",
  2741.        (case_insensitive)?"insensitive":"sensitive");
  2742.     
  2743.     if (aq == CACHE)
  2744.       printf("\nOutputting cache file only.\n");
  2745.     else {
  2746.       printf("\nThe output will be in ");
  2747.       if (aq == HTML)
  2748.     printf("HTML\n");
  2749.       else if (aq == ASCII)
  2750.     printf("plain text\n");
  2751.       else /* aq == PREFORMATTED */
  2752.     printf("preformatted format\n");
  2753.       if (aq != PREFORMATTED) {
  2754.     if (lang != UNSET) {
  2755.       printf("The output language will be ");
  2756.       if (lang == ENGLISH)
  2757.         printf("English\n");
  2758.       else if (lang == US_ENGLISH)
  2759.         printf("US English\n");
  2760.       else if (lang == FRENCH)
  2761.         printf("French\n");
  2762.       else if (lang == GERMAN)
  2763.         printf("German\n");
  2764.       else if (lang == SPANISH)
  2765.         printf("Spanish\n");
  2766.       else if (lang == DANISH)
  2767.         printf("Danish\n");
  2768.       else /* (lang == ITALIAN) */
  2769.         printf("Italian\n");
  2770.     }
  2771.     printf("The language file will be %s", oldlangfile);
  2772.     pvfiletest(oldlangfile);
  2773.       }
  2774.  
  2775.       printf("The domains file is %s", domainsfile);
  2776.       pvfiletest(domainsfile);
  2777.  
  2778. #ifndef NODNS
  2779.       if (dnsq) {
  2780.     printf("DNS lookups performed with DNS cache file %s", dnsfile);
  2781.     pvfiletest(dnsfile);
  2782.     printf("Old DNS lookups will be rechecked if they are more than %d hours old\n", dnsfreshhours);
  2783.       }
  2784. #endif
  2785.  
  2786.       printf("The output file is %s\n", outfile);
  2787.       /* Don't check for being able to write as it will destroy the file */
  2788.  
  2789.       printf("\nReport order:\n");
  2790.       printf("General summary    %s\n", xq?"ON":"OFF");
  2791.       for (c = reportorder; *c != '\0'; c++) {
  2792.     switch(*c) {
  2793.     case 'b':
  2794.       pvgen(lngstr[browsum_], bq, bsortby, bminreqstr, bminpagestr,
  2795.         bminbytestr, bcols, lngstr[browgp_], lngstr[browgp_],
  2796.         lngstr[browgen_][0]);
  2797.       if (bq)
  2798.         pvalias(lngstr[browsum_], boutaliashead);
  2799.       break;
  2800.     case 'B':
  2801.       pvgen(lngstr[browrep_], Bq, Bsortby, Bminreqstr, Bminpagestr,
  2802.         Bminbytestr, Bcols, lngstr[browgs_], lngstr[browgp_],
  2803.         lngstr[browgen_][0]);
  2804.       break;
  2805.     case 'c':
  2806.       printf("%s %s\n", lngstr[statrep_], cq?"ON":"OFF");
  2807.       break;
  2808.     case 'd':
  2809.       pvtime(lngstr[daysum_], dq, dgraph, dunit, dcols, 0);
  2810.       break;
  2811.     case 'D':
  2812.       pvtime(lngstr[dayrep_], Dq, Dgraph, Dunit, Dcols, Drows);
  2813.       break;
  2814.     case 'e':
  2815.       printf("%s       %s\n", lngstr[errrep_], eq?"ON":"OFF");
  2816.       if (eminreqs == 0)
  2817.         printf("  %s, ", lngstr[allerrs_]);
  2818.       else if (eminreqs == 1)
  2819.         printf("%s,\n  ", lngstr[allerrs1_]);
  2820.       else {
  2821.         printf(lngstr[allerrsn_], eminreqs);
  2822.         printf("\n  ");
  2823.       }
  2824.       printf("%s.", lngstr[occsort_]);
  2825.       break;
  2826.     case 'f':
  2827.       pvgen(lngstr[refrep_], fq, fsortby, fminreqstr, fminpagestr,
  2828.         fminbytestr, fcols, lngstr[refgs_], lngstr[refgp_],
  2829.         lngstr[refgen_][0]);
  2830.       if (fq) {
  2831.         pvalias(lngstr[refrep_], foutaliashead);
  2832.         pvinout("as linked items", reflinkhead);
  2833.       }
  2834.       break;
  2835.     case 'h':
  2836.       pvtime(lngstr[hoursum_], hq, hgraph, hunit, hcols, 0);
  2837.       break;
  2838.     case 'H':
  2839.       pvtime(lngstr[hourrep_], Hq, Hgraph, Hunit, Hcols, Hrows);
  2840.       break;
  2841.     case 'i':
  2842.       pvgen(lngstr[dirrep_], iq, isortby, iminreqstr, iminpagestr,
  2843.         iminbytestr, icols, lngstr[dirgs_], lngstr[dirgp_],
  2844.         lngstr[dirgen_][0]);
  2845.       if (iq) {
  2846.         printf("  ");
  2847.         printf(lngstr[dirlevel_], dirlevel);
  2848.         printf(".\n");
  2849.         pvalias(lngstr[dirrep_], ioutaliashead);
  2850.       }
  2851.       break;
  2852.     case 'm':
  2853.       pvtime(lngstr[monthrep_], mq, mgraph, munit, mcols, mrows);
  2854.       break;
  2855.     case 'o':
  2856.       pvgen(lngstr[domrep_], oq, osortby, ominreqstr, ominpagestr,
  2857.         ominbytestr, ocols, lngstr[domgs_], lngstr[domgp_],
  2858.         lngstr[domgen_][0]);
  2859.       if (oq) {
  2860.         printf("  ");
  2861.         whatincluded(stdout, osortby, Ominreqstr, Ominpagestr, Ominbytestr,
  2862.              lngstr[subdomgs_], lngstr[subdomgp_], ON,
  2863.              lngstr[subdomgen_][0]);
  2864.       }
  2865.       break;
  2866.     case 'r':
  2867.       pvgen(lngstr[reqrep_], rq, rsortby, rminreqstr, rminpagestr,
  2868.         rminbytestr, rcols, lngstr[filegs_], lngstr[filegp_],
  2869.         lngstr[filegen_][0]);
  2870.       if (rq) {
  2871.         pvinout("in the report", wantreqhead);
  2872.         pvalias(lngstr[reqrep_], routaliashead);
  2873.         pvinout("as linked items", linkhead);
  2874.         if (baseurl[0] != '\0')
  2875.           printf("  (links prepended by %s)\n", baseurl);
  2876.       }
  2877.       break;
  2878.     case 'S':
  2879.       pvgen(lngstr[hostrep_], Sq, Ssortby, Sminreqstr, Sminpagestr,
  2880.         Sminbytestr, Scols, lngstr[hostgs_], lngstr[hostgp_],
  2881.         lngstr[hostgen_][0]);
  2882.       if (Sq)
  2883.         pvalias(lngstr[hostrep_], Soutaliashead);
  2884.       break;
  2885.     case 't':
  2886.       pvgen(lngstr[typerep_], tq, tsortby, tminreqstr, tminpagestr,
  2887.         tminbytestr, tcols, lngstr[extgs_], lngstr[extgp_],
  2888.         lngstr[extgen_][0]);
  2889.       if (tq)
  2890.         pvalias(lngstr[typerep_], toutaliashead);
  2891.       break;
  2892.     case 'W':
  2893.       pvtime(lngstr[weekrep_], Wq, Wgraph, Wunit, Wcols, Wrows);
  2894.       break;
  2895.     }  /* end switch c */
  2896.       }    /* end for c */
  2897.       
  2898.  
  2899.       if (sq == APPROX) {
  2900.     printf("\nApproximate hostname count ON\n");
  2901.     printf("  Space used for hostname count: ");
  2902.     int3printf(stdout, (int)approxhostsize, sepchar, 0);
  2903.     printf(" bytes\n");
  2904.       }
  2905.       else
  2906.     printf("\nHostname count     %s\n", (sq == ON)?"ON":"OFF");
  2907.  
  2908.       printf("Statistics for last 7 days %s\n", q7?"ON":"OFF");
  2909.  
  2910.       printf("Hash sizes are:\n");
  2911.       printf("  Requests        %6d\n", rhashsize);
  2912.       printf("  Directories     %6d\n", ihashsize);
  2913.       printf("  File types      %6d\n", thashsize);
  2914.       printf("  Hosts           %6d\n", Shashsize);
  2915.       printf("  Referrers       %6d\n", fhashsize);
  2916.       printf("  Browser summary %6d\n", bhashsize);
  2917.       printf("  Browser report  %6d\n", Bhashsize);
  2918.       printf("  Subdomains      %6d\n", Ohashsize);
  2919. #ifndef NODNS
  2920.       if (dnsq)
  2921.     printf("  DNS cache       %6d\n", dnshashsize);
  2922. #endif
  2923.       
  2924.       if (oq) {
  2925.     printf("\nRequested subdomains:\n");
  2926.     if (subdomshead -> from[0] == '\0')
  2927.       printf("  None\n");
  2928.     else for (subdomp = subdomshead; subdomp -> from[0] != '\0';
  2929.           subdomp = subdomp -> next) {
  2930.       if (subdomp -> from[0] == '?')  /* don't want it */
  2931.         ;
  2932.       else if (subdomp -> from[0] == '%')
  2933.         printf("  Numerical subdomains\n");
  2934.       else {
  2935.         printf("  %s", subdomp -> from);
  2936.         if (subdomp -> to[0] != '?')
  2937.           printf(" (%s)", subdomp -> to);
  2938.         printf("\n");
  2939.       }
  2940.     }
  2941.       }
  2942.     
  2943.       if (mq || dq || hq || Hq || Dq || Wq) {
  2944.     printf("\nThe character used in the graphs will be '%c'\n", markchar);
  2945.     printf("The page width is %d\n", pagewidth);
  2946.       }
  2947.  
  2948.       if (sepchar != '\0')
  2949.     printf("The character used as a separator in big numbers will be '%c'\n",
  2950.            sepchar);
  2951.       if (repsepchar != '\0')
  2952.     printf("The character used as a separator in big numbers within reports will be '%c'\n", repsepchar);
  2953.       printf("The character used as a decimal point will be '%c'\n", decpoint);
  2954.  
  2955.       if (Wq || Dq || dq) {
  2956.     printf("Weeks are taken to begin on ");
  2957.     switch(weekbeginson) {
  2958.     case (SUNDAY):
  2959.       printf("Sunday.\n");
  2960.       break;
  2961.     case (MONDAY):
  2962.       printf("Monday.\n");
  2963.       break;
  2964.     case (TUESDAY):
  2965.       printf("Tuesday.\n");
  2966.       break;
  2967.     case (WEDNESDAY):
  2968.       printf("Wednesday.\n");
  2969.       break;
  2970.     case (THURSDAY):
  2971.       printf("Thursday.\n");
  2972.       break;
  2973.     case (FRIDAY):
  2974.       printf("Friday.\n");
  2975.       break;
  2976.     case (SATURDAY):
  2977.       printf("Saturday.\n");
  2978.       break;
  2979.     }
  2980.       }
  2981.  
  2982.       printf("The following will be included in the output:\n");
  2983.  
  2984.       if (!aq)
  2985.     printf("Logo               %s\n",
  2986.            STREQ(logourl, "none")?logourl:"OFF");
  2987.       printf("Header file        %s",
  2988.          STREQ(headerfile, "none")?"OFF\n":headerfile);
  2989.       if (!STREQ(headerfile, "none")) {
  2990.     pvfiletest(headerfile);
  2991.       }
  2992.       printf("Footer file        %s",
  2993.          STREQ(footerfile, "none")?"OFF\n":footerfile);
  2994.       if (!STREQ(footerfile, "none"))
  2995.     pvfiletest(footerfile);
  2996.       printf("Organisation name  \"%s\"\n", hostname);
  2997.       if (!aq)
  2998.     printf("Name linked to URL %s\n\n", (hosturl[0]=='-')?"OFF":hosturl);
  2999.       
  3000.       pvinout("as pages", ispagehead);
  3001.       pvalias("File", filealiashead);
  3002.       pvalias("Host", hostaliashead);
  3003.       pvalias("Referrer", refaliashead);
  3004.       pvalias("Brower", browaliashead);
  3005.       
  3006.     }   /* end if aq != CACHE */
  3007.  
  3008.     if (filemaskq)
  3009.       pvinout("files", wantfilehead);
  3010.     if (hostmaskq)
  3011.       pvinout("hosts", wanthosthead);
  3012.     if (refmaskq && aq != CACHE)
  3013.       pvinout("referrers", wantrefhead);
  3014.     
  3015.     if (fromtime.code > -INFINITY || totime.code < INFINITY) {
  3016.       printf("\nExamining only times");
  3017.       if (fromtime.code > -INFINITY)
  3018.     printf(" from %02d/%s/%d", fromtime.date,
  3019.            monthname[fromtime.monthno], fromtime.year);
  3020.       if (totime.code < INFINITY)
  3021.     printf(" to %02d/%s/%d", totime.date,
  3022.            monthname[totime.monthno], totime.year);
  3023.       printf("\n");
  3024.     }
  3025.  
  3026.     printf("\nDebug level is %d\n", debug);
  3027.     printf("Warnings are %s\n", warnq?"ON":"OFF");
  3028.     if (progressfreq > 0)
  3029.       printf("Progress report every %d logfile lines\n", progressfreq);
  3030.     printf("\n");
  3031.  
  3032.   }  /* end not form */
  3033.  
  3034.   exit(OK);
  3035.  
  3036. }
  3037.