ftp.nice.ch/pub/next/unix/network/www/Analog.2.0.NIHS.bs.tar.gz#/Analog.2.0/init.c

This is init.c in view mode; [Download] [Up]

/*** analog 2.0 ***/
/* Please read Readme.html, or http://www.statslab.cam.ac.uk/~sret1/analog/  */

/*** init.c; initialisation routines and declaration of global variables ***/
/* See also init2.c */

#include "analhea2.h"

/*** First declare all global variables. We choose to declare them in this
     file rather than analog.c because more are needed here. ***/

/* lang: need new dayname and monthname here, possibly in HTML and non-HTML
   versions. */
char endayname[7][11] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
char frdayname[7][11] = {"Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"};
char dedayname[7][11] = {"Son", "Mon", "Die", "Mit", "Don", "Fre", "Sam"};
char itdayname[7][11] = {"Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"};
char esdayname[7][11] = {"Dom", "Lun", "Mar", "Mie", "Jue", "Vie", "Sab"};
char dkhtmldayname[7][11] = {"søn", "man", "tir", "ons", "tor", "fre",
				 "lør"};
char dkdayname[7][11] = {"son", "man", "tir", "ons", "tor", "fre",
				 "lor"};
char enmonthname[12][12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
			      "Aug", "Sep", "Oct", "Nov", "Dec"};
char frmonthname[12][12] = {"Janv", "Fevr", "Mars", "Avri", " Mai", "Juin",
			      "Juil", "Aout", "Sept", "Octo", "Nove", "Dece"};
char frhtmlmonthname[12][12] = {"Janv", "Févr", "Mars", "Avri", " Mai",
				  "Juin", "Juil", "Août", "Sept", "Octo",
				  "Nove", "Déce"};
char demonthname[12][12] = {"Jan", "Feb", "Mar", "Apr", "Mai", "Jun", "Jul",
			      "Aug", "Sep", "Okt", "Nov", "Dez"};
char dehtmlmonthname[12][12] = {"Jan", "Feb", "Mär", "Apr", "Mai", "Jun",
				  "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"};
char itmonthname[12][12] = {"Gen", "Feb", "Mar", "Apr", "Mag", "Giu",
			      "Lug", "Ago", "Set", "Ott", "Nov", "Dic"};
char esmonthname[12][12] = {"Ene", "Feb", "Mar", "Abr", "May", "Jun",
			      "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"};
char dkmonthname[12][12] = {"jan", "feb", "mar", "apr", "maj", "jun",
			      "jul", "aug", "sep", "okt", "nov", "dec"};
char monthname[12][12];     /* set to whichever is appropriate */
char dayname[7][11];
/* Note: month numbers run from 0 (Jan) to 11 (Dec) internally to this
   program (though not where month numbers are needed in user input and
   output) */
int dateoffset[12] = {0, 31, 59, 90, 120, 151, 181,
			212, 243, 273, 304, 334};
int monthlength[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

char errs[NO_ERRS][MAXERRLENGTH] =
/* all error messages */
         {
/* 01 */   "Send timed out",
/* 02 */   "File does not exist",
/* 03 */   "No file matching URL",
/* 04 */   "User does not exist",
/* 05 */   "Send aborted",
/* 06 */   "Timed out waiting",
/* 07 */   "File permissions deny server access",
/* 08 */   "Read timed out",
/* 09 */   "Lost connection to client",
/* 10 */   "Cannot read directory",
/* 11 */   "Client denied by server configuration",
/* 12 */   "Malformed header from script",
/* 13 */   "Killing CGI process",
/* 14 */   "Could not get local address",
/* 15 */   "Will not follow link",
/* 16 */   "Could not get port number",
/* 17 */   "Script does not exist",
/* 18 */   "Script not found",
/* 19 */   "Unable to include",
/* 20 */   "Could not fork new process",
/* 21 */   "Unable to fork new process",
/* 22 */   "Invalid CGI ref",
/* 23 */   "Caught SIGTERM, shutting down",
/* 24 */   "Caught SIGSEGV, dumping core",
/* 25 */   "Caught SIGHUP, restarting",
/* 26 */   "SIGHUP received.  Attempting to restart",
/* 27 */   "Successful restart",
/* 28 */   "Resuming normal operations",
/* 29 */   "Starting",
/* 30 */   "Child error: pass failed",
/* 31 */   "Socket error: accept failed",
/* 32 */   "Child connection closed",
/* 33 */   "File open error",
/* 34 */   "Failed before entering app",
/* 35 */   "Unable to change uid",
/* 36 */   "Malformed response header from app",
/* 37 */   "Duplicate CGI response header",
/* 38 */   "Directive for requested file",
/* 39 */   "Could not connect to application",
/* 40 */   "AppClass",
/* 41 */   "ExternalAppClass",
/* 42 */   "FastCgiIpcDir",
/* 43 */   ""     /* last must be "" */ 
         };

int errors[NO_ERRS];   /* how many occurrences of each */

int statusnos[NO_STATUS] =
/* all status codes */
         {
/* 01 */   200,
/* 02 */   201,
/* 03 */   202,
/* 04 */   203,
/* 05 */   204,
/* 06 */   299,
/* 07 */   301,
/* 08 */   302,
/* 09 */   303,
/* 10 */   304,
/* 11 */   399,
/* 12 */   400,
/* 13 */   401,
/* 14 */   402,
/* 15 */   403,
/* 16 */   404,
/* 17 */   499,
/* 18 */   500,
/* 19 */   501,
/* 20 */   502,
/* 21 */   503,
/* 22 */   599
         };

char statusstrs[NO_STATUS][MAXSTATUSLENGTH] =
/* all status messages */
         {
/* 01 */   "OK",
/* 02 */   "Created",
/* 03 */   "Accepted for future processing",
/* 04 */   "Partial information",
/* 05 */   "OK, but nothing to send",
/* 06 */   "[Miscellaneous successes]",
/* 07 */   "Document moved",
/* 08 */   "Document found elsewhere",
/* 09 */   "Moved; use another request method",
/* 10 */   "Not modified since last retrieval",
/* 11 */   "[Miscellaneous redirections]",
/* 12 */   "Bad request",
/* 13 */   "Authorisation required",
/* 14 */   "Payment required",
/* 15 */   "Forbidden",
/* 16 */   "Document not found",
/* 17 */   "[Miscellaneous client/user errors]",
/* 18 */   "Internal server error",
/* 19 */   "Request type not supported",
/* 20 */   "Server overloaded",
/* 21 */   "Gateway timed out",
/* 22 */   "[Miscellaneous server errors]"
         };

int status[NO_STATUS];   /* how many of each have been seen */
int status7[NO_STATUS];  /* ditto in last 7 days */

char *outfile;

struct timestruct firsttime, lasttime, starttimec, oldtime, fromtime, totime;
/* first and last log entries, now, a week before now, and
   lower and upper bounds on time interval we want to consider */

struct monthly *firstm, *lastm;
    /* pointers to the first and last years of monthly data */
struct daily *firstD, *lastD;   /* ... months of daily data */
struct hourly *firstH, *lastH;  /* ... days of hourly data */
struct weekly *firstW, *lastW;  /* ... and to the first and last week */

int no_urls;               /* the number of distinct files found so far */
int no_urls7;              /* the number used in the last 7 days */
struct genstruct **rhead;  /* hash table of all files found */
struct genstruct **ihead;  /* and one for all directories */
struct genstruct **thead;  /* one for file types */
struct domain **Ohead;     /* one for subdomains */
struct domain *wildOhead;  /* and one for wild subdomains */
struct domain *nwildOhead; /* and one for wild numerical subdomains */
int no_hosts;              /* the number of hosts so far */
int no_hosts7;             /* the number of all hosts in the last 7 days */
int no_new_hosts7;         /* the number of new hosts in the last 7 days */
struct genstruct **Shead;  /* and a record of all hosts */
char *approxhostspace;     /* start of the space for approx host counting */
char *approxhostspace7;    /* and a bit more for last 7 days accounting */
size_t approxhostsize;     /* the size of those spaces, in bytes */
struct domain **ohead;
struct genstruct **fhead;
struct genstruct **bhead;
struct genstruct **Bhead;
struct genstruct **Shead2; /* for filing pre-aliased filenames */
struct genstruct **rhead2;
struct genstruct **fhead2;
size_t rhashsize, ihashsize, thashsize, Shashsize, fhashsize, bhashsize;
size_t Bhashsize, Ohashsize;  /* sizes of the hash tables */

struct alias *filealiashead, *hostaliashead, *refaliashead, *browaliashead;
struct alias *routaliashead, *ioutaliashead, *Soutaliashead, *foutaliashead;
struct alias *boutaliashead, *toutaliashead, *subdomshead;
    /* subdomshead is not really an alias, but it's the right shape */
struct include *wantfilehead, *wanthosthead, *wantrefhead, *wantreqhead;
struct include *linkhead, *reflinkhead, *ispagehead, *noexpandhead;
struct include *refexpandhead;

int dreq[7], dpag[7];    /* requests and page requests for each day */
int hreq[24], hpag[24];  /* ... and hour */
double dbytes[7];        /* ... and bytes ditto */
double hbytes[24];

/*** NB It often happens that families of variables have a one letter prefix
     representing the different reports (usual letters, plus O = subdoms). ***/
int rmaxreqs;     /* the max reqs for any file */
int imaxreqs;     /* for any directory */
int tmaxreqs;     /* for any file type */
int Smaxreqs;     /* for any host */
int omaxreqs;     /* for any domain */
int fmaxreqs;     /* for any referrer */
int bmaxreqs;     /* for any browser */
int Bmaxreqs;     /* for any browser (full name) */
/* Now the same for max pages and max bytes*/
int rmaxpages, imaxpages, tmaxpages, Smaxpages, omaxpages, fmaxpages;
int bmaxpages, Bmaxpages;
double rmaxbytes, imaxbytes, tmaxbytes, Smaxbytes, omaxbytes, fmaxbytes;
double bmaxbytes, Bmaxbytes;

int Smaxlength;     /* and the same for length of name */

char *dirsuffix;       /* e.g. index.html */
int dirsufflength;     /* the length of dirsuffix */
int onumber, Onumber;  /* the number of (sub)domains in the domain report */
time_t starttime, stoptime;   /* the start and stop time of the program */
struct tm *starttimetm;
int total_succ_reqs, total_fail_reqs, total_other_reqs, total_page_reqs;
int total_succ_reqs7, total_fail_reqs7, total_other_reqs7, total_page_reqs7;
int total_good_brows, total_masked_brows, total_bad_brows;
int total_good_refs, total_masked_refs, total_bad_refs;
int total_ref_pages, total_brow_pages;
double total_bytes, total_bytes7, total_ref_bytes, total_brow_bytes;
int corrupt_lines;         /* the number of corrupt lines in the logfile */
                             /* (Overlong lines, URLs with quotes in...) */
int other_lines;           /* Lines masked out */
int cachereqs, cachereqs7; /* The number of requests from cache */
int cachepages, cachepages7; /* Page requests from cache */
flag byq, refbyq, browbyq; /* whether we want to count bytes; always on until
			      we find a line with no bytes information. */
flag rawbytes;   /* whether bytes are quoted raw or in k notation */
flag graphical;  /* whether to draw pretty graphs or just use ASCII art */
flag filemaskq, hostmaskq, refmaskq;
/* whether there is any masking of hosts, files or refs */

int weekbeginson;  /* which is the first day of the week? */
char sepchar, repsepchar, decpoint;   /* chars as separators in numbers */
char *presep;  /* string separating fields in PREFORMATTED */

char *commandname;  /* the name of the program, as called */

char *baseurl;         /* base for all URLs found */
char rcols[7], icols[7], tcols[7], Scols[7], ocols[7], fcols[7], bcols[7];
char Bcols[7], mcols[7], dcols[7], Dcols[7], Wcols[7], hcols[7], Hcols[7];
char ccols[7], ecols[7];
/* Columns appearing in each report */

struct loglist *logfilehead, *uncompresshead;
/* uncompress is not really a loglist, but it's the right shape */
struct stringlist *cachefilehead, *refloghead, *browloghead, *errloghead;
char *domainsfile, *headerfile, *footerfile, *logourl, *imagedir;
char reportorder[20];  /* the order in which reports occur (room for more) */
/* NB if the size of this changes, so must it in case (REPORTORDER_): below */
flag xq, mq, oq, iq, tq, rq, q7, dq, hq, Hq, Sq, Dq, Wq, fq, bq, Bq, cq, eq;
int sq, aq;  /* a: output type     x->s: whether we want each type of report */
#ifndef NODNS
flag dnsq;            /* DNS lookup? */
struct dnscache **dnshead;
char *dnsfile;
size_t dnshashsize;
time_t dnsstaletime;  /* older than when the DNS information becomes stale */
int dnsfreshhours;    /* how many hours it stays fresh for */
#endif
int lang, dialect;     /* language for output */
flag warnq, anywarns;  /* do we want warnings? any warnings issued? */
flag html2;      /* if aq == HTML, whether output is guaranteed HTML2 */
flag case_insensitive, stdin_used;
char *ominreqstr, *Ominreqstr, *Sminreqstr, *iminreqstr, *rminreqstr;
char *fminreqstr, *bminreqstr, *Bminreqstr, *tminreqstr;
char *ominpagestr, *Ominpagestr, *Sminpagestr, *iminpagestr, *rminpagestr;
char *fminpagestr, *bminpagestr, *Bminpagestr, *tminpagestr;
char *ominbytestr, *Ominbytestr, *Sminbytestr, *iminbytestr, *rminbytestr;
char *fminbytestr, *bminbytestr, *Bminbytestr, *tminbytestr;
int eminreqs;
int munit, Wunit, dunit, Dunit, hunit, Hunit;  /* the value of the mark */
char mgraph, dgraph, Dgraph, hgraph, Hgraph, Wgraph;  /* R or B */
flag mback, Dback, Wback, Hback;   /* backwards graphs? */
int mrows, Drows, Wrows, Hrows, Wrowsdone;    /* max rows in each report */
int osortby, isortby, tsortby, Ssortby, rsortby, fsortby, bsortby, Bsortby;
int dirlevel, pagewidth;
char markchar;
char *hostname, *hosturl;
int debug, progressfreq, no_configs = 0;

flag vblesonly;  /* commandline only. If ON, just print variables and exit */
flag formq;      /* commandline only. If ON, just make a form interface */

/* We also declare the following pointers here. They are used to keep track
   of places in lists between functions in this file and init2.c */

struct alias *filealiasp, *hostaliasp, *refaliasp, *browaliasp, *routaliasp;
struct alias *ioutaliasp, *Soutaliasp, *foutaliasp, *boutaliasp, *toutaliasp;
struct alias *subdomp, *subdomtempp;
struct include *wantfilep, *wanthostp, *wantrefp, *ispagep, *noexpandp;
struct include *refexpandp, *wantreqp, *linkp, *reflinkp;
struct loglist *logfilep, *uncompressp;
struct stringlist *cachefilep, *reflogp, *browlogp, *errlogp;

/*** Now boring functions for initialisation of variables etc. ***/

void defaults(void)
{
  anywarns = OFF;
/*
  html2 = ON;
*/
  html2 = OFF;
  stdin_used = OFF;
  domainsfile = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(domainsfile, DOMAINSFILE, MAXSTRINGLENGTH - 1);
  domainsfile[MAXSTRINGLENGTH - 1] = '\0';
  headerfile = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(headerfile, HEADERFILE, MAXSTRINGLENGTH - 1);
  headerfile[MAXSTRINGLENGTH - 1] = '\0';
  footerfile = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(footerfile, FOOTERFILE, MAXSTRINGLENGTH - 1);
  footerfile[MAXSTRINGLENGTH - 1] = '\0';
  outfile = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(outfile, OUTFILE, MAXSTRINGLENGTH - 1);
  outfile[MAXSTRINGLENGTH - 1] = '\0';
#ifndef NODNS
  dnsfile = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(dnsfile, DNSFILE, MAXSTRINGLENGTH - 1);
  dnsfile[MAXSTRINGLENGTH - 1] = '\0';
  dnsq = NUMLOOKUP;
  dnsfreshhours = DNSFRESHHOURS;
  dnshashsize = DNSHASHSIZE;
#endif
  baseurl = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(baseurl, BASEURL, MAXSTRINGLENGTH - 1);
  baseurl[MAXSTRINGLENGTH - 1] = '\0';
  imagedir = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(imagedir, IMAGEDIR, MAXSTRINGLENGTH - 1);
  imagedir[MAXSTRINGLENGTH - 1] = '\0';
  dirsuffix = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(dirsuffix, DIRSUFFIX, MAXSTRINGLENGTH - 1);
  dirsuffix[MAXSTRINGLENGTH - 1] = '\0';
  strncpy(reportorder, REPORTORDER, 19);
  reportorder[19] = '\0';
  strncpy(ocols, DOMCOLS, 6);
  ocols[6] = '\0';
  strncpy(Scols, HOSTCOLS, 6);
  Scols[6] = '\0';
  strncpy(icols, DIRCOLS, 6);
  icols[6] = '\0';
  strncpy(tcols, TYPECOLS, 6);
  tcols[6] = '\0';
  strncpy(rcols, REQCOLS, 6);
  rcols[6] = '\0';
  strncpy(fcols, REFCOLS, 6);
  fcols[6] = '\0';
  strncpy(bcols, BROWCOLS, 6);
  bcols[6] = '\0';
  strncpy(Bcols, FULLBROWCOLS, 6);
  Bcols[6] = '\0';
  strncpy(mcols, MONTHCOLS, 6);
  mcols[6] = '\0';
  strncpy(dcols, DAYCOLS, 6);
  dcols[6] = '\0';
  strncpy(Dcols, FULLDAYCOLS, 6);
  Dcols[6] = '\0';
  strncpy(Wcols, WEEKCOLS, 6);
  Wcols[6] = '\0';
  strncpy(hcols, HOURCOLS, 6);
  hcols[6] = '\0';
  strncpy(Hcols, FULLHOURCOLS, 6);
  Hcols[6] = '\0';
  strcpy(ccols, "R");   /* for the moment */
  strcpy(ecols, "R");
  logourl = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(logourl, LOGOURL, MAXSTRINGLENGTH - 1);
  logourl[MAXSTRINGLENGTH - 1] = '\0';
  mq = MONTHLY;
  Wq = WEEKLY;
  dq = DAILY;
  Dq = FULLDAILY;
  hq = HOURLY;
  Hq = FULLHOURLY;
  oq = DOMAINREP;
  iq = DIRECTORY;
  tq = FILETYPE;
  rq = REQUEST;
  sq = COUNTHOSTS;
  Sq = FULLHOSTS;
  fq = REFERRER;
  bq = BROWSER;
  Bq = FULLBROWSER;
  cq = STATUS;
  eq = ERROR;
  xq = GENERAL;
  q7 = LASTSEVEN;
  aq = OUTPUT;
  lang = LANGUAGE;
  dialect = NONE;
  warnq = WARNINGS;
  progressfreq = PROGRESSFREQ;
  graphical = GRAPHICAL;
  case_insensitive = (CASE == INSENSITIVE);
  munit = 0;
  Wunit = 0;
  hunit = 0;
  Hunit = 0;
  dunit = 0;
  Dunit = 0;
  mgraph = MONTHGRAPH;
  dgraph = DAYGRAPH;
  Dgraph = FULLDAYGRAPH;
  hgraph = HOURGRAPH;
  Hgraph = FULLHOURGRAPH;
  Wgraph = WEEKGRAPH;
  Hback = FULLHOURLYBACK;
  Dback = FULLDAILYBACK;
  Wback = WEEKLYBACK;
  mback = MONTHLYBACK;
  Wrows = WEEKROWS;
  Drows = FULLDAYROWS;
  mrows = MONTHROWS;
  Hrows = FULLHOURROWS;
  osortby = DOMSORTBY;
  isortby = DIRSORTBY;
  tsortby = TYPESORTBY;
  rsortby = REQSORTBY;
  Ssortby = HOSTSORTBY;
  fsortby = REFSORTBY;
  bsortby = BROWSORTBY;
  Bsortby = FULLBROWSORTBY;
  ominreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(ominreqstr, MIN_DOM_REQS, MAXSTRINGLENGTH - 1);
  ominreqstr[MAXSTRINGLENGTH - 1] = '\0';
  ominpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(ominpagestr, MIN_DOM_PAGES, MAXSTRINGLENGTH - 1);
  ominpagestr[MAXSTRINGLENGTH - 1] = '\0';
  ominbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(ominbytestr, MIN_DOM_BYTES, MAXSTRINGLENGTH - 1);
  ominbytestr[MAXSTRINGLENGTH - 1] = '\0';
  Ominreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(Ominreqstr, MIN_SUBDOM_REQS, MAXSTRINGLENGTH - 1);
  Ominreqstr[MAXSTRINGLENGTH - 1] = '\0';
  Ominpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(Ominpagestr, MIN_SUBDOM_PAGES, MAXSTRINGLENGTH - 1);
  Ominpagestr[MAXSTRINGLENGTH - 1] = '\0';
  Ominbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(Ominbytestr, MIN_SUBDOM_BYTES, MAXSTRINGLENGTH - 1);
  Ominbytestr[MAXSTRINGLENGTH - 1] = '\0';
  iminreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(iminreqstr, MIN_DIR_REQS, MAXSTRINGLENGTH - 1);
  iminreqstr[MAXSTRINGLENGTH - 1] = '\0';
  iminpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(iminpagestr, MIN_DIR_PAGES, MAXSTRINGLENGTH - 1);
  iminpagestr[MAXSTRINGLENGTH - 1] = '\0';
  iminbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(iminbytestr, MIN_DIR_BYTES, MAXSTRINGLENGTH - 1);
  iminbytestr[MAXSTRINGLENGTH - 1] = '\0';
  tminreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(tminreqstr, MIN_TYPE_REQS, MAXSTRINGLENGTH - 1);
  tminreqstr[MAXSTRINGLENGTH - 1] = '\0';
  tminpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(tminpagestr, MIN_TYPE_PAGES, MAXSTRINGLENGTH - 1);
  tminpagestr[MAXSTRINGLENGTH - 1] = '\0';
  tminbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(tminbytestr, MIN_TYPE_BYTES, MAXSTRINGLENGTH - 1);
  tminbytestr[MAXSTRINGLENGTH - 1] = '\0';
  Sminreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(Sminreqstr, MIN_HOST_REQS, MAXSTRINGLENGTH - 1);
  Sminreqstr[MAXSTRINGLENGTH - 1] = '\0';
  Sminpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(Sminpagestr, MIN_HOST_PAGES, MAXSTRINGLENGTH - 1);
  Sminpagestr[MAXSTRINGLENGTH - 1] = '\0';
  Sminbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(Sminbytestr, MIN_HOST_BYTES, MAXSTRINGLENGTH - 1);
  Sminbytestr[MAXSTRINGLENGTH - 1] = '\0';
  rminreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(rminreqstr, MIN_URL_REQS, MAXSTRINGLENGTH - 1);
  rminreqstr[MAXSTRINGLENGTH - 1] = '\0';
  rminpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(rminpagestr, MIN_URL_REQS, MAXSTRINGLENGTH - 1);  /* sic */
  rminpagestr[MAXSTRINGLENGTH - 1] = '\0';
  rminbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(rminbytestr, MIN_URL_BYTES, MAXSTRINGLENGTH - 1);
  rminbytestr[MAXSTRINGLENGTH - 1] = '\0';
  fminreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(fminreqstr, MIN_REF_REQS, MAXSTRINGLENGTH - 1);
  fminreqstr[MAXSTRINGLENGTH - 1] = '\0';
  fminpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(fminpagestr, MIN_REF_PAGES, MAXSTRINGLENGTH - 1);
  fminpagestr[MAXSTRINGLENGTH - 1] = '\0';
  fminbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(fminbytestr, MIN_REF_BYTES, MAXSTRINGLENGTH - 1);
  fminbytestr[MAXSTRINGLENGTH - 1] = '\0';
  bminreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(bminreqstr, MIN_BROW_REQS, MAXSTRINGLENGTH - 1);
  bminreqstr[MAXSTRINGLENGTH - 1] = '\0';
  bminpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(bminpagestr, MIN_BROW_PAGES, MAXSTRINGLENGTH - 1);
  bminpagestr[MAXSTRINGLENGTH - 1] = '\0';
  bminbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(bminbytestr, MIN_BROW_BYTES, MAXSTRINGLENGTH - 1);
  bminbytestr[MAXSTRINGLENGTH - 1] = '\0';
  Bminreqstr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(Bminreqstr, MIN_FULLBROW_REQS, MAXSTRINGLENGTH - 1);
  Bminreqstr[MAXSTRINGLENGTH - 1] = '\0';
  Bminpagestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(Bminpagestr, MIN_FULLBROW_PAGES, MAXSTRINGLENGTH - 1);
  Bminpagestr[MAXSTRINGLENGTH - 1] = '\0';
  Bminbytestr = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(Bminbytestr, MIN_FULLBROW_BYTES, MAXSTRINGLENGTH - 1);
  Bminbytestr[MAXSTRINGLENGTH - 1] = '\0';
  eminreqs = MIN_ERR_OCCS;
  dirlevel = DIRLEVEL;
  pagewidth = PAGEWIDTH;
  markchar = MARKCHAR;
  rawbytes = RAWBYTES;
  hostname = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(hostname, HOSTNAME, MAXSTRINGLENGTH - 1);
  hostname[MAXSTRINGLENGTH - 1] = '\0';
  hosturl = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(hosturl, HOSTURL, MAXSTRINGLENGTH - 1);
  hosturl[MAXSTRINGLENGTH - 1] = '\0';
  weekbeginson = WEEKBEGINSON;
  sepchar = SEPCHAR;
  repsepchar = REPSEPCHAR;
  decpoint = DECPOINT;
  presep = (char *)xmalloc(MAXSTRINGLENGTH);
  strncpy(presep, PRESEP, MAXSTRINGLENGTH - 1);
  presep[MAXSTRINGLENGTH - 1] = '\0';
  vblesonly = OFF;
  formq = OFF;
  fromtime.code = -INFINITY;
  totime.code = INFINITY;
  approxhostsize = APPROXHOSTSIZE;
  debug = DEBUG;
  filemaskq = OFF;
  hostmaskq = OFF;
  refmaskq = OFF;
  rhashsize = REQHASHSIZE;
  ihashsize = DIRHASHSIZE;
  thashsize = TYPEHASHSIZE;
  Shashsize = HOSTHASHSIZE;
  fhashsize = REFHASHSIZE;
  bhashsize = BROWHASHSIZE;
  Bhashsize = FULLBROWHASHSIZE;
  Ohashsize = SUBDOMHASHSIZE;
}

void init_structs(void)
{
  char tempstr[MAXSTRINGLENGTH];

  logfilehead = (struct loglist *)xmalloc(sizeof(struct loglist));
  logfilep = logfilehead;
  if (STREQ(LOGFILE, "none"))
    logfilehead -> name[0] = '\0';
  else {
    strcpy(tempstr, LOGFILE);
    addlogfile(&logfilep, tempstr, "", ON);
  }
  cachefilehead = (struct stringlist *)xmalloc(sizeof(struct stringlist));
  cachefilep = cachefilehead;
  if (STREQ(CACHEFILE, "none"))
    cachefilehead -> name[0] = '\0';
  else {
    strcpy(tempstr, CACHEFILE);
    configstrlist(tempstr, &cachefilep, (char *)NULL, (char *)NULL, 2, ON);
  }
  refloghead = (struct stringlist *)xmalloc(sizeof(struct stringlist));
  reflogp = refloghead;
  if (STREQ(REFERRER_LOG, "none"))
    refloghead -> name[0] = '\0';
  else{
    strcpy(tempstr, REFERRER_LOG);
    configstrlist(tempstr, &reflogp, (char *)NULL, (char *)NULL, 2, ON);
  }
  browloghead = (struct stringlist *)xmalloc(sizeof(struct stringlist));
  browlogp = browloghead;
  if (STREQ(BROWSER_LOG, "none"))
    browloghead -> name[0] = '\0';
  else {
    strcpy(tempstr, BROWSER_LOG);
    configstrlist(tempstr, &browlogp, (char *)NULL, (char *)NULL, 2, ON);
  }
  errloghead = (struct stringlist *)xmalloc(sizeof(struct stringlist));
  errlogp = errloghead;
  if (STREQ(ERROR_LOG, "none"))
    errloghead -> name[0] = '\0';
  else {
    strcpy(tempstr, ERROR_LOG);
    configstrlist(tempstr, &errlogp, (char *)NULL, (char *)NULL, 2, ON);
  }
  uncompresshead = (struct loglist *)xmalloc(sizeof(struct loglist));
  uncompresshead -> name[0] = '\0';
  uncompressp = uncompresshead;
  filealiashead = (struct alias *)xmalloc(sizeof(struct alias));
  filealiashead -> from[0] = '\0';
  filealiasp = filealiashead;
  hostaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  hostaliashead -> from[0] = '\0';
  hostaliasp = hostaliashead;
  refaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  refaliashead -> from[0] = '\0';
  refaliasp = refaliashead;
  browaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  browaliashead -> from[0] = '\0';
  browaliasp = browaliashead;
  routaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  routaliashead -> from[0] = '\0';
  routaliasp = routaliashead;
  ioutaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  ioutaliashead -> from[0] = '\0';
  ioutaliasp = ioutaliashead;
  Soutaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  Soutaliashead -> from[0] = '\0';
  Soutaliasp = Soutaliashead;
  foutaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  foutaliashead -> from[0] = '\0';
  foutaliasp = foutaliashead;
  boutaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  boutaliashead -> from[0] = '\0';
  boutaliasp = boutaliashead;
  toutaliashead = (struct alias *)xmalloc(sizeof(struct alias));
  toutaliashead -> from[0] = '\0';
  toutaliasp = toutaliashead;
  wantfilehead = (struct include *)xmalloc(sizeof(struct include));
  wantfilehead -> in = UNSET;
  wantfilep = wantfilehead;
  wanthosthead = (struct include *)xmalloc(sizeof(struct include));
  wanthosthead -> in = UNSET;
  wanthostp = wanthosthead;
  subdomshead = (struct alias *)xmalloc(sizeof(struct alias));
  subdomshead -> from[0] = '\0';
  subdomp = subdomshead;
  wantrefhead = (struct include *)xmalloc(sizeof(struct include));
  wantrefhead -> in = UNSET;
  wantrefp = wantrefhead;
  wantreqhead = (struct include *)xmalloc(sizeof(struct include));
  wantreqhead -> in = UNSET;
  wantreqp = wantreqhead;
  linkhead = (struct include *)xmalloc(sizeof(struct include));
  linkhead -> in = UNSET;
  linkp = linkhead;
  reflinkhead = (struct include *)xmalloc(sizeof(struct include));
  reflinkhead -> in = UNSET;
  reflinkp = reflinkhead;
  noexpandhead = (struct include *)xmalloc(sizeof(struct include));
  noexpandhead -> in = UNSET;
  noexpandp = noexpandhead;
  refexpandhead = (struct include *)xmalloc(sizeof(struct include));
  refexpandhead -> in = UNSET;
  refexpandp = refexpandhead;
  ispagehead = (struct include *)xmalloc(sizeof(struct include));
  ispagep = ispagehead;
  strcpy(ispagep -> name, "*/");
  ispagep -> in = TRUE;
  ispagep -> next = (struct include *)xmalloc(sizeof(struct include));
  ispagep = ispagep -> next;
  strcpy(ispagep -> name, "*.html");
  ispagep -> in = TRUE;
  ispagep -> next = (struct include *)xmalloc(sizeof(struct include));
  ispagep = ispagep -> next;
  strcpy(ispagep -> name, "*.htm");
  ispagep -> in = TRUE;
  ispagep -> next = (struct include *)xmalloc(sizeof(struct include));
  ispagep = ispagep -> next;
  ispagep -> in = UNSET;
}

void othervars(void)    /* vars initialised after command args and config */
{
  time_t oldtimeno;       /* the time 7 days ago */
  struct tm *oldtimetm;

  int i;

  no_urls = 0;
  no_urls7 = 0;
  no_hosts = 0;
  no_hosts7 = 0;
  no_new_hosts7 = 0;
  rmaxreqs = 0;
  imaxreqs = 0;
  tmaxreqs = 0;
  Smaxreqs = 0;
  fmaxreqs = 0;
  bmaxreqs = 0;
  Bmaxreqs = 0;
  rmaxpages = 0;
  imaxpages = 0;
  tmaxpages = 0;
  Smaxpages = 0;
  fmaxpages = 0;
  bmaxpages = 0;
  Bmaxpages = 0;
  rmaxbytes = 0.0;
  imaxbytes = 0.0;
  tmaxbytes = 0.0;
  Smaxbytes = 0.0;
  fmaxbytes = 0.0;
  bmaxbytes = 0.0;
  Bmaxbytes = 0.0;     /* omaxreqs, omaxpages and omaxbytes are set later */
  Smaxlength = 0;
  for (i = 0; i < NO_STATUS; i++) {
    status[i] = 0;
    status7[i] = 0;
  }
  total_succ_reqs = 0;
  total_succ_reqs7 = 0;
  total_page_reqs = 0;
  total_page_reqs7 = 0;
  total_fail_reqs = 0;
  total_fail_reqs7 = 0;
  total_other_reqs = 0;
  total_other_reqs7 = 0;
  total_good_refs = 0;
  total_masked_refs = 0;
  total_bad_refs = 0;
  total_good_brows = 0;
  total_masked_brows = 0;
  total_bad_brows = 0;
  total_bytes = 0.0;
  total_bytes7 = 0.0;
  total_ref_bytes = 0.0;
  total_brow_bytes = 0.0;
  corrupt_lines = 0;
  other_lines = 0;
  cachereqs = 0;
  cachereqs7 = 0;
  cachepages = 0;
  cachepages7 = 0;
  byq = ON;
  refbyq = ON;
  browbyq = ON;

  /* initialise the date structures */
  if (mq) {
    firstm = (struct monthly *)xmalloc(sizeof(struct monthly));
    for (i = 0; i < 12; i++) {
      firstm -> reqs[i] = 0;
      firstm -> pages[i] = 0;
      firstm -> bytes[i] = 0.0;
    }
    firstm -> next = NULL;
    lastm = firstm;
  }
  if (Dq) {
    firstD = (struct daily *)xmalloc(sizeof(struct daily));
    for (i = 0; i < 31; i++) {
      firstD -> reqs[i] = 0;
      firstD -> pages[i] = 0;
      firstD -> bytes[i] = 0.0;
    }
    firstD -> next = NULL;
    lastD = firstD;
  }
  if (Hq) {
    firstH = (struct hourly *)xmalloc(sizeof(struct hourly));
    for (i = 0; i < 24; i++) {
      firstH -> reqs[i] = 0;
      firstH -> pages[i] = 0;
      firstH -> bytes[i] = 0.0;
    }
    firstH -> next = NULL;
    lastH = firstH;
  }
  if (Wq) {
    firstW = (struct weekly *)xmalloc(sizeof(struct weekly));
    firstW -> reqs = 0;
    firstW -> pages = 0;
    firstW -> bytes = 0;
    firstW -> next = NULL;
    lastW = firstW;
  }
  Wrowsdone = 1;
  if (dq) {
    for (i = 0; i < 7; i++) {
      dreq[i] = 0;
      dpag[i] = 0;
      dbytes[i] = 0.0;
    }
  }
  if (hq) {
    for (i = 0; i < 24; i++) {
      hreq[i] = 0;
      hpag[i] = 0;
      hbytes[i] = 0.0;
    }
  }

#ifndef NODNS
  dnsstaletime = starttime - 3600 * dnsfreshhours;
#endif

  if (q7) {   /* calculate the time 7 days ago */
    if (starttimec.code <= totime.code) {
      oldtimeno = starttime - 604800;        /* seconds in a week */
      oldtimetm = localtime(&oldtimeno);
      oldtime.year = 1900 + oldtimetm -> tm_year;
      oldtime.date = oldtimetm -> tm_mday;
      oldtime.monthno = oldtimetm -> tm_mon;
      oldtime.hr = oldtimetm -> tm_hour;
      oldtime.min = oldtimetm -> tm_min;
    }
    else {    /* totime is earlier than today; take 7 days before that */
      oldtime.hr = 23;
      oldtime.min = 59;
      oldtime.year = totime.year;
      oldtime.monthno = totime.monthno;
      oldtime.date = totime.date - 7;
      if (oldtime.date < 1) {
	oldtime.monthno--;
	if (oldtime.monthno < 0) {
	  oldtime.year--;
	  oldtime.monthno += 12;
	}
	oldtime.date += monthlength[oldtime.monthno] +
	  ISLEAPFEB(oldtime.monthno, oldtime.year);
      }
    }
    oldtime.code = timecode(oldtime.date, oldtime.monthno, oldtime.year,
			    oldtime.hr, oldtime.min);
    if (oldtime.code < fromtime.code)
      q7 = OFF;  /* FROM--TO is all in last 7 days */
  }

  if (lang == ENGLISH) {
    for (i = 0; i < 12; i++)
      strcpy(monthname[i], enmonthname[i]);
    for (i = 0; i < 7; i++)
      strcpy(dayname[i], endayname[i]);
  }
  else if (lang == FRENCH) {
    for (i = 0; i < 7; i++)
      strcpy(dayname[i], frdayname[i]);
    if (aq == HTML)
      for (i = 0; i < 12; i++)
        strcpy(monthname[i], frhtmlmonthname[i]);
    else
      for (i = 0; i < 12; i++)
        strcpy(monthname[i], frmonthname[i]);
  }
  else if (lang == GERMAN) {
    for (i = 0; i < 7; i++)
      strcpy(dayname[i], dedayname[i]);
    if (aq == HTML)
      for (i = 0; i < 12; i++)
        strcpy(monthname[i], dehtmlmonthname[i]);
    else
      for (i = 0; i < 12; i++)
        strcpy(monthname[i], demonthname[i]);
  }
  else if (lang == SPANISH) {
    for (i = 0; i < 7; i++)
      strcpy(dayname[i], esdayname[i]);
    for (i = 0; i < 12; i++)
      strcpy(monthname[i], esmonthname[i]);
  }
  else if (lang == DANISH) {
    if (aq == HTML)
      for (i = 0; i < 7; i++)
	strcpy(dayname[i], dkhtmldayname[i]);
    else
      for (i = 0; i < 7; i++)
	strcpy(dayname[i], dkdayname[i]);
    for (i = 0; i < 12; i++)
      strcpy(monthname[i], dkmonthname[i]);
  }
  else {  /* lang == ITALIAN */
    for (i = 0; i < 7; i++)
      strcpy(dayname[i], itdayname[i]);
    for (i = 0; i < 12; i++)
      strcpy(monthname[i], itmonthname[i]);
  }

  dirsufflength = (int)strlen(dirsuffix);
    
  if (rq || iq || tq) {
    rhead = (struct genstruct **)xcalloc(rhashsize,
					 sizeof(struct genstruct *));
  }
  rhead2 = (struct genstruct **)xcalloc(rhashsize, sizeof(struct genstruct *));
  for (i = 0; i < rhashsize; i++) {
    if (rq || iq || tq) {
      rhead[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
      rhead[i] -> name = NULL;
    }
    rhead2[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
    rhead2[i] -> name = NULL;
  }
  if (iq) {
    ihead = (struct genstruct **)xcalloc(ihashsize,
					 sizeof(struct genstruct *));
    for (i = 0; i < ihashsize; i++) {
      ihead[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
      ihead[i] -> name = NULL;
    }
  }
  if (tq) {
    thead = (struct genstruct **)xcalloc(thashsize,
					 sizeof(struct genstruct *));
    for (i = 0; i < thashsize; i++) {
      thead[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
      thead[i] -> name = NULL;
    }
  }
  if (sq == ON) {
    Shead = (struct genstruct **)xcalloc(Shashsize,
					 sizeof(struct genstruct *));
    Shead2 = (struct genstruct **)xcalloc(Shashsize,
					  sizeof(struct genstruct *));
    for (i = 0; i < Shashsize; i++) {
      Shead[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
      Shead[i] -> name = NULL;
      Shead2[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
      Shead2[i] -> name = NULL;
    }
  }
  else if (sq == APPROX) {
    approxhostspace = (char *) xcalloc(approxhostsize, 1);
    if (q7)
      approxhostspace7 = (char *) xcalloc(approxhostsize, 1);
  }
  if (fq) {
    fhead = (struct genstruct **)xcalloc(fhashsize,
					 sizeof(struct genstruct *));
    fhead2 = (struct genstruct **)xcalloc(fhashsize,
					  sizeof(struct genstruct *));
    for (i = 0; i < fhashsize; i++) {
      fhead[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
      fhead[i] -> name = NULL;
      fhead2[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
      fhead2[i] -> name = NULL;
    }
  }
  if (bq) {
    bhead = (struct genstruct **)xcalloc(bhashsize,
					 sizeof(struct genstruct *));
    for (i = 0; i < bhashsize; i++) {
      bhead[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
      bhead[i] -> name = NULL;
    }
  }
  if (Bq) {
    Bhead = (struct genstruct **)xcalloc(Bhashsize,
					 sizeof(struct genstruct *));
    for (i = 0; i < Bhashsize; i++) {
      Bhead[i] = (struct genstruct *)xmalloc(sizeof(struct genstruct));
      Bhead[i] -> name = NULL;
    }
  }
  if (eq) {
    for (i = 0; i < NO_ERRS; i++)
      errors[i] = 0;
  }
  if (oq) {
    ohead = (struct domain **)xcalloc(DOMHASHSIZE,
				      sizeof(struct domain *));
    for (i = 0; i < DOMHASHSIZE; i++) {
      ohead[i] = (struct domain *)xmalloc(sizeof(struct domain));
      ohead[i] -> name = NULL;
    }
    Ohead = (struct domain **)xcalloc(Ohashsize,
				      sizeof(struct domain *));
    for (i = 0; i < Ohashsize; i++) {
      Ohead[i] = (struct domain *)xmalloc(sizeof(struct domain));
      Ohead[i] -> name = NULL;
    }
    wildOhead = (struct domain *)xmalloc(sizeof(struct domain));
    wildOhead -> id = NULL;
    nwildOhead = (struct domain *)xmalloc(sizeof(struct domain));
    nwildOhead -> id = NULL;

    domainscan();      /* read in all the domains */

  }   /* end if (oq) */

#ifndef NODNS
  if (dnsq) {
    dnshead = (struct dnscache **)xcalloc(dnshashsize,
					  sizeof(struct dnscache *));
    for (i = 0; i < dnshashsize; i++) {
      dnshead[i] = (struct dnscache *)xmalloc(sizeof(struct dnscache));
      dnshead[i] -> number = NULL;
    }
    dnscachescan();
  }
#endif
}

/*** Now for the functions that parse the configuration commands. ***/

void configline(char inputline[MAXLINELENGTH])  /* process one configline */
{
  enum {BADCOMMAND_, FILEALIAS_, HOSTALIAS_, REFALIAS_, BROWALIAS_,
	  REQOUTPUTALIAS_, DIROUTPUTALIAS_, HOSTOUTPUTALIAS_, REFOUTPUTALIAS_,
	  BROWOUTPUTALIAS_, TYPEOUTPUTALIAS_, FILEINCLUDE_, FILEEXCLUDE_,
	  FILEALLOW_, HOSTINCLUDE_, HOSTEXCLUDE_, HOSTALLOW_, REFINCLUDE_,
	  REFEXCLUDE_, REFALLOW_, REQINCLUDE_, REQEXCLUDE_, REQALLOW_,
	  LINKINCLUDE_,  LINKEXCLUDE_, LINKALLOW_, REFLINKINCLUDE_,
	  REFLINKEXCLUDE_, REFLINKALLOW_, FROM_, TO_, SUBDOMAIN_,
	  WEEKBEGINSON_, APPROXHOSTSIZE_, ISPAGE_, ISNOTPAGE_, SEPCHAR_,
	  REPSEPCHAR_, DECPOINT_, PRESEP_, REPORTORDER_, WITHARGS_,
	  WITHOUTARGS_, REFWITHARGS_, REFWITHOUTARGS_, NOTSUBDOMAIN_,
	  BASEURL_, DOMCOLS_, HOSTCOLS_, DIRCOLS_, TYPECOLS_, REQCOLS_,
	  REFCOLS_, BROWCOLS_,
	  FULLBROWCOLS_, MONTHCOLS_, DAYCOLS_, FULLDAYCOLS_, WEEKCOLS_,
	  HOURCOLS_, FULLHOURCOLS_, MONTHGRAPH_, DAYGRAPH_, FULLDAYGRAPH_,
	  HOURGRAPH_, FULLHOURGRAPH_, WEEKGRAPH_, GRAPHICAL_, LOGFILE_,
	  CACHEFILE_, REFLOG_, BROWLOG_, ERRLOG_, DOMAINSFILE_, HOSTNAME_,
	  HOSTURL_, HOSTMINREQS_, DOMMINREQS_, SUBDOMMINREQS_, DIRMINREQS_,
	  TYPEMINREQS_, REQMINREQS_, REFMINREQS_, BROWMINREQS_,
	  FULLBROWMINREQS_, HOSTMINPAGES_, DOMMINPAGES_, SUBDOMMINPAGES_,
	  DIRMINPAGES_, TYPEMINPAGES_, REQMINPAGES_, REFMINPAGES_,
	  BROWMINPAGES_, FULLBROWMINPAGES_, HOSTMINBYTES_, DOMMINBYTES_,
	  SUBDOMMINBYTES_, DIRMINBYTES_, TYPEMINBYTES_, REQMINBYTES_,
	  REFMINBYTES_, BROWMINBYTES_, FULLBROWMINBYTES_, ERRMINOCCS_,
	  REQSORTBY_, DOMSORTBY_, DIRSORTBY_, TYPESORTBY_, HOSTSORTBY_,
	  REFSORTBY_, BROWSORTBY_, FULLBROWSORTBY_, MARKCHAR_, PAGEWIDTH_,
	  ALLBACK_, MONTHLYBACK_, FULLHOURLYBACK_, FULLDAILYBACK_, WEEKLYBACK_,
	  MONTHROWS_, FULLHOURROWS_, FULLDAYROWS_, WEEKROWS_, MONTHLY_, DAILY_,
	  FULLDAILY_, WEEKLY_, HOURLY_, FULLHOURLY_, DOMAIN_, DIRECTORY_,
	  FILETYPE_, REQUEST_, FULLHOSTS_, REFERRER_, BROWSER_, FULLBROWSER_,
	  STATUS_, ERROR_, DIRLEVEL_, COUNTHOSTS_, LASTSEVEN_, WARNINGS_,
	  CASE_, IMAGEDIR_, DIRSUFFIX_, MONTHLYUNIT_, HOURLYUNIT_,
	  FULLHOURLYUNIT_, DAILYUNIT_, LOGOURL_, HEADERFILE_, FOOTERFILE_,
	  FULLDAILYUNIT_, WEEKLYUNIT_, ALL_, GENERAL_, OUTPUT_, LANGUAGE_,
	  DEBUG_, PROGRESSFREQ_, RAWBYTES_, UNCOMPRESS_, REQHASHSIZE_,
	  DIRHASHSIZE_, TYPEHASHSIZE_, HOSTHASHSIZE_, REFHASHSIZE_,
	  BROWHASHSIZE_, FULLBROWHASHSIZE_, SUBDOMHASHSIZE_,
#ifndef NODNS
	  DNSHASHSIZE_, NUMLOOKUP_, DNSFILE_, DNSFRESHHOURS_,
#endif
	  CONFIGFILE_, OUTFILE_
}
  commandtype;   /* final '_'s to avoid clashes with #defines */

  char string1[MAXSTRINGLENGTH], string2[MAXSTRINGLENGTH],
       string3[MAXSTRINGLENGTH];
  int rc;
  flag tempflag;

  rc = sscanf_config(inputline, string1, string2, string3);
  if (rc > 0) {
    commandtype = BADCOMMAND_;   /* pessimism :) */
    strtoupper(string1);
    /* Note: some of these else if's have been changed to just if's. This is
       substantially less efficient but cures a bug in BSD/OS gcc; anyway this
       portion takes ~0 time to run in the context of the whole program. */
    if (STREQ(string1, "FILEALIAS"))
      commandtype = FILEALIAS_;
    else if (STREQ(string1, "HOSTALIAS"))
      commandtype = HOSTALIAS_;
    else if (STREQ(string1, "REFALIAS"))
      commandtype = REFALIAS_;
    else if (STREQ(string1, "BROWALIAS"))
      commandtype = BROWALIAS_;
    else if (STREQ(string1, "REQOUTPUTALIAS"))
      commandtype = REQOUTPUTALIAS_;
    else if (STREQ(string1, "DIROUTPUTALIAS"))
      commandtype = DIROUTPUTALIAS_;
    else if (STREQ(string1, "HOSTOUTPUTALIAS"))
      commandtype = HOSTOUTPUTALIAS_;
    else if (STREQ(string1, "REFOUTPUTALIAS"))
      commandtype = REFOUTPUTALIAS_;
    else if (STREQ(string1, "BROWOUTPUTALIAS"))
      commandtype = BROWOUTPUTALIAS_;
    else if (STREQ(string1, "TYPEOUTPUTALIAS"))
      commandtype = TYPEOUTPUTALIAS_;
    else if (STREQ(string1, "FILEINCLUDE"))
      commandtype = FILEINCLUDE_;
    else if (STREQ(string1, "FILEEXCLUDE"))
      commandtype = FILEEXCLUDE_;
    else if (STREQ(string1, "FILEALLOW"))
      commandtype = FILEALLOW_;
    else if (STREQ(string1, "HOSTINCLUDE"))
      commandtype = HOSTINCLUDE_;
    else if (STREQ(string1, "HOSTEXCLUDE"))
      commandtype = HOSTEXCLUDE_;
    else if (STREQ(string1, "HOSTALLOW"))
      commandtype = HOSTALLOW_;
    else if (STREQ(string1, "REFINCLUDE"))
      commandtype = REFINCLUDE_;
    else if (STREQ(string1, "REFEXCLUDE"))
      commandtype = REFEXCLUDE_;
    else if (STREQ(string1, "REFALLOW"))
      commandtype = REFALLOW_;
    else if (STREQ(string1, "REQINCLUDE"))
      commandtype = REQINCLUDE_;
    else if (STREQ(string1, "REQEXCLUDE"))
      commandtype = REQEXCLUDE_;
    else if (STREQ(string1, "REQALLOW"))
      commandtype = REQALLOW_;
    else if (STREQ(string1, "LINKINCLUDE"))
      commandtype = LINKINCLUDE_;
    else if (STREQ(string1, "LINKEXCLUDE"))
      commandtype = LINKEXCLUDE_;
    else if (STREQ(string1, "LINKALLOW"))
      commandtype = LINKALLOW_;
    else if (STREQ(string1, "REFLINKINCLUDE"))
      commandtype = REFLINKINCLUDE_;
    if (STREQ(string1, "REFLINKEXCLUDE"))
      commandtype = REFLINKEXCLUDE_;
    else if (STREQ(string1, "REFLINKALLOW"))
      commandtype = REFLINKALLOW_;
    else if (STREQ(string1, "FROM"))
      commandtype = FROM_;
    else if (STREQ(string1, "TO"))
      commandtype = TO_;
    else if (STREQ(string1, "SUBDOMAIN"))
      commandtype = SUBDOMAIN_;
    else if (STREQ(string1, "WEEKBEGINSON"))
      commandtype = WEEKBEGINSON_;
    else if (STREQ(string1, "APPROXHOSTSIZE"))
      commandtype = APPROXHOSTSIZE_;
    else if (STREQ(string1, "ISPAGE"))
      commandtype = ISPAGE_;
    else if (STREQ(string1, "ISNOTPAGE"))
      commandtype = ISNOTPAGE_;
    else if (STREQ(string1, "SEPCHAR"))
      commandtype = SEPCHAR_;
    else if (STREQ(string1, "REPSEPCHAR"))
      commandtype = REPSEPCHAR_;
    else if (STREQ(string1, "DECPOINT"))
      commandtype = DECPOINT_;
    else if (STREQ(string1, "PRESEP"))
      commandtype = PRESEP_;
    else if (STREQ(string1, "REPORTORDER"))
      commandtype = REPORTORDER_;
    else if (STREQ(string1, "WITHARGS"))
      commandtype = WITHARGS_;
    else if (STREQ(string1, "WITHOUTARGS"))
      commandtype = WITHOUTARGS_;
    else if (STREQ(string1, "REFWITHARGS"))
      commandtype = REFWITHARGS_;
    else if (STREQ(string1, "REFWITHOUTARGS"))
      commandtype = REFWITHOUTARGS_;
    else if (STREQ(string1, "NOTSUBDOMAIN"))
      commandtype = NOTSUBDOMAIN_;
    else if (STREQ(string1, "BASEURL"))
      commandtype = BASEURL_;
    else if (STREQ(string1, "DOMCOLS"))
      commandtype = DOMCOLS_;
    else if (STREQ(string1, "HOSTCOLS"))
      commandtype = HOSTCOLS_;
    else if (STREQ(string1, "DIRCOLS"))
      commandtype = DIRCOLS_;
    else if (STREQ(string1, "TYPECOLS"))
      commandtype = TYPECOLS_;
    else if (STREQ(string1, "REQCOLS"))
      commandtype = REQCOLS_;
    if (STREQ(string1, "REFCOLS"))
      commandtype = REFCOLS_;
    else if (STREQ(string1, "BROWCOLS"))
      commandtype = BROWCOLS_;
    else if (STREQ(string1, "FULLBROWCOLS"))
      commandtype = FULLBROWCOLS_;
    else if (STREQ(string1, "MONTHCOLS"))
      commandtype = MONTHCOLS_;
    else if (STREQ(string1, "DAYCOLS"))
      commandtype = DAYCOLS_;
    else if (STREQ(string1, "FULLDAYCOLS"))
      commandtype = FULLDAYCOLS_;
    else if (STREQ(string1, "WEEKCOLS"))
      commandtype = WEEKCOLS_;
    else if (STREQ(string1, "HOURCOLS"))
      commandtype = HOURCOLS_;
    else if (STREQ(string1, "FULLHOURCOLS"))
      commandtype = FULLHOURCOLS_;
    else if (STREQ(string1, "MONTHGRAPH"))
      commandtype = MONTHGRAPH_;
    else if (STREQ(string1, "DAYGRAPH"))
      commandtype = DAYGRAPH_;
    else if (STREQ(string1, "FULLDAYGRAPH"))
      commandtype = FULLDAYGRAPH_;
    else if (STREQ(string1, "HOURGRAPH"))
      commandtype = HOURGRAPH_;
    else if (STREQ(string1, "FULLHOURGRAPH"))
      commandtype = FULLHOURGRAPH_;
    else if (STREQ(string1, "WEEKGRAPH"))
      commandtype = WEEKGRAPH_;
    else if (STREQ(string1, "GRAPHICAL"))
      commandtype = GRAPHICAL_;
    else if (STREQ(string1, "LOGFILE"))
      commandtype = LOGFILE_;
    else if (STREQ(string1, "CACHEFILE"))
      commandtype = CACHEFILE_;
    else if (STREQ(string1, "REFLOG"))
      commandtype = REFLOG_;
    else if (STREQ(string1, "BROWLOG"))
      commandtype = BROWLOG_;
    else if (STREQ(string1, "ERRLOG"))
      commandtype = ERRLOG_;
    else if (STREQ(string1, "DOMAINSFILE"))
      commandtype = DOMAINSFILE_;
    else if (STREQ(string1, "HOSTNAME"))
      commandtype = HOSTNAME_;
    else if (STREQ(string1, "HOSTURL"))
      commandtype = HOSTURL_;
    else if (STREQ(string1, "HOSTMINREQS"))
      commandtype = HOSTMINREQS_;
    if (STREQ(string1, "DOMMINREQS"))
      commandtype = DOMMINREQS_;
    else if (STREQ(string1, "SUBDOMMINREQS"))
      commandtype = SUBDOMMINREQS_;
    else if (STREQ(string1, "DIRMINREQS"))
      commandtype = DIRMINREQS_;
    else if (STREQ(string1, "TYPEMINREQS"))
      commandtype = TYPEMINREQS_;
    else if (STREQ(string1, "REQMINREQS"))
      commandtype = REQMINREQS_;
    else if (STREQ(string1, "REFMINREQS"))
      commandtype = REFMINREQS_;
    else if (STREQ(string1, "BROWMINREQS"))
      commandtype = BROWMINREQS_;
    else if (STREQ(string1, "FULLBROWMINREQS"))
      commandtype = FULLBROWMINREQS_;
    else if (STREQ(string1, "HOSTMINPAGES"))
      commandtype = HOSTMINPAGES_;
    else if (STREQ(string1, "DOMMINPAGES"))
      commandtype = DOMMINPAGES_;
    else if (STREQ(string1, "SUBDOMMINPAGES"))
      commandtype = SUBDOMMINPAGES_;
    else if (STREQ(string1, "DIRMINPAGES"))
      commandtype = DIRMINPAGES_;
    else if (STREQ(string1, "TYPEMINPAGES"))
      commandtype = TYPEMINPAGES_;
    else if (STREQ(string1, "REQMINPAGES"))
      commandtype = REQMINPAGES_;
    else if (STREQ(string1, "REFMINPAGES"))
      commandtype = REFMINPAGES_;
    else if (STREQ(string1, "BROWMINPAGES"))
      commandtype = BROWMINPAGES_;
    else if (STREQ(string1, "FULLBROWMINPAGES"))
      commandtype = FULLBROWMINPAGES_;
    else if (STREQ(string1, "HOSTMINBYTES"))
      commandtype = HOSTMINBYTES_;
    else if (STREQ(string1, "DOMMINBYTES"))
      commandtype = DOMMINBYTES_;
    else if (STREQ(string1, "SUBDOMMINBYTES"))
      commandtype = SUBDOMMINBYTES_;
    else if (STREQ(string1, "DIRMINBYTES"))
      commandtype = DIRMINBYTES_;
    else if (STREQ(string1, "TYPEMINBYTES"))
      commandtype = TYPEMINBYTES_;
    else if (STREQ(string1, "REQMINBYTES"))
      commandtype = REQMINBYTES_;
    else if (STREQ(string1, "REFMINBYTES"))
      commandtype = REFMINBYTES_;
    else if (STREQ(string1, "BROWMINBYTES"))
      commandtype = BROWMINBYTES_;
    if (STREQ(string1, "FULLBROWMINBYTES"))
      commandtype = FULLBROWMINBYTES_;
    else if (STREQ(string1, "ERRMINOCCS"))
      commandtype = ERRMINOCCS_;
    else if (STREQ(string1, "REQSORTBY"))
      commandtype = REQSORTBY_;
    else if (STREQ(string1, "DOMSORTBY"))
      commandtype = DOMSORTBY_;
    else if (STREQ(string1, "DIRSORTBY"))
      commandtype = DIRSORTBY_;
    else if (STREQ(string1, "TYPESORTBY"))
      commandtype = TYPESORTBY_;
    else if (STREQ(string1, "HOSTSORTBY"))
      commandtype = HOSTSORTBY_;
    else if (STREQ(string1, "REFSORTBY"))
      commandtype = REFSORTBY_;
    else if (STREQ(string1, "BROWSORTBY"))
      commandtype = BROWSORTBY_;
    else if (STREQ(string1, "FULLBROWSORTBY"))
      commandtype = FULLBROWSORTBY_;
    else if (STREQ(string1, "MARKCHAR"))
      commandtype = MARKCHAR_;
    else if (STREQ(string1, "PAGEWIDTH"))
      commandtype = PAGEWIDTH_;
    else if (STREQ(string1, "ALLBACK"))
      commandtype = ALLBACK_;
    else if (STREQ(string1, "MONTHLYBACK"))
      commandtype = MONTHLYBACK_;
    else if (STREQ(string1, "FULLHOURLYBACK"))
      commandtype = FULLHOURLYBACK_;
    else if (STREQ(string1, "FULLDAILYBACK"))
      commandtype = FULLDAILYBACK_;
    else if (STREQ(string1, "WEEKLYBACK"))
      commandtype = WEEKLYBACK_;
    else if (STREQ(string1, "MONTHROWS"))
      commandtype = MONTHROWS_;
    else if (STREQ(string1, "FULLHOURROWS"))
      commandtype = FULLHOURROWS_;
    else if (STREQ(string1, "WEEKROWS"))
      commandtype = WEEKROWS_;
    else if (STREQ(string1, "FULLDAYROWS"))
      commandtype = FULLDAYROWS_;
    else if (STREQ(string1, "MONTHLY"))
      commandtype = MONTHLY_;
    else if (STREQ(string1, "DAILY"))
      commandtype = DAILY_;
    else if (STREQ(string1, "FULLDAILY"))
      commandtype = FULLDAILY_;
    else if (STREQ(string1, "WEEKLY"))
      commandtype = WEEKLY_;
    if (STREQ(string1, "HOURLY"))
      commandtype = HOURLY_;
    else if (STREQ(string1, "FULLHOURLY"))
      commandtype = FULLHOURLY_;
    else if (STREQ(string1, "DOMAIN"))
      commandtype = DOMAIN_;
    else if (STREQ(string1, "DIRECTORY"))
      commandtype = DIRECTORY_;
    else if (STREQ(string1, "FILETYPE"))
      commandtype = FILETYPE_;
    else if (STREQ(string1, "REQUEST"))
      commandtype = REQUEST_;
    else if (STREQ(string1, "FULLHOSTS"))
      commandtype = FULLHOSTS_;
    else if (STREQ(string1, "REFERRER") || STREQ(string1, "REFERER"))
      commandtype = REFERRER_;
    else if (STREQ(string1, "BROWSER"))
      commandtype = BROWSER_;
    else if (STREQ(string1, "FULLBROWSER"))
      commandtype = FULLBROWSER_;
    else if (STREQ(string1, "STATUS"))
      commandtype = STATUS_;
    else if (STREQ(string1, "ERROR"))
      commandtype = ERROR_;
    else if (STREQ(string1, "DIRLEVEL"))
      commandtype = DIRLEVEL_;
    else if (STREQ(string1, "COUNTHOSTS"))
      commandtype = COUNTHOSTS_;
    else if (STREQ(string1, "LASTSEVEN"))
      commandtype = LASTSEVEN_;
    else if (STREQ(string1, "WARNINGS"))
      commandtype = WARNINGS_;
    else if (STREQ(string1, "CASE"))
      commandtype = CASE_;
    else if (STREQ(string1, "IMAGEDIR"))
      commandtype = IMAGEDIR_;
    else if (STREQ(string1, "DIRSUFFIX"))
      commandtype = DIRSUFFIX_;
    else if (STREQ(string1, "MONTHLYUNIT"))
      commandtype = MONTHLYUNIT_;
    else if (STREQ(string1, "HOURLYUNIT"))
      commandtype = HOURLYUNIT_;
    else if (STREQ(string1, "FULLHOURLYUNIT"))
      commandtype = FULLHOURLYUNIT_;
    else if (STREQ(string1, "DAILYUNIT"))
      commandtype = DAILYUNIT_;
    else if (STREQ(string1, "FULLDAILYUNIT"))
      commandtype = FULLDAILYUNIT_;
    else if (STREQ(string1, "WEEKLYUNIT"))
      commandtype = WEEKLYUNIT_;
    if (STREQ(string1, "LOGOURL"))
      commandtype = LOGOURL_;
    else if (STREQ(string1, "HEADERFILE"))
      commandtype = HEADERFILE_;
    else if (STREQ(string1, "FOOTERFILE"))
      commandtype = FOOTERFILE_;
    else if (STREQ(string1, "ALL"))
      commandtype = ALL_;
    else if (STREQ(string1, "GENERAL"))
      commandtype = GENERAL_;
    else if (STREQ(string1, "OUTPUT"))
      commandtype = OUTPUT_;
    else if (STREQ(string1, "LANGUAGE"))
      commandtype = LANGUAGE_;
    else if (STREQ(string1, "DEBUG"))
      commandtype = DEBUG_;
    else if (STREQ(string1, "PROGRESSFREQ"))
      commandtype = PROGRESSFREQ_;
    else if (STREQ(string1, "RAWBYTES"))
      commandtype = RAWBYTES_;
    else if (STREQ(string1, "UNCOMPRESS"))
      commandtype = UNCOMPRESS_;
    else if (STREQ(string1, "REQHASHSIZE"))
      commandtype = REQHASHSIZE_;
    else if (STREQ(string1, "DIRHASHSIZE"))
      commandtype = DIRHASHSIZE_;
    else if (STREQ(string1, "TYPEHASHSIZE"))
      commandtype = TYPEHASHSIZE_;
    else if (STREQ(string1, "HOSTHASHSIZE"))
      commandtype = HOSTHASHSIZE_;
    else if (STREQ(string1, "REFHASHSIZE"))
      commandtype = REFHASHSIZE_;
    else if (STREQ(string1, "BROWHASHSIZE"))
      commandtype = BROWHASHSIZE_;
    else if (STREQ(string1, "FULLBROWHASHSIZE"))
      commandtype = FULLBROWHASHSIZE_;
    else if (STREQ(string1, "SUBDOMHASHSIZE"))
      commandtype = SUBDOMHASHSIZE_;
#ifndef NODNS
    else if (STREQ(string1, "DNSHASHSIZE"))
      commandtype = DNSHASHSIZE_;
    else if (STREQ(string1, "NUMLOOKUP"))
      commandtype = NUMLOOKUP_;
    else if (STREQ(string1, "DNSFILE"))
      commandtype = DNSFILE_;
    else if (STREQ(string1, "DNSFRESHHOURS"))
      commandtype = DNSFRESHHOURS_;
#endif
    else if (STREQ(string1, "CONFIGFILE"))
      commandtype = CONFIGFILE_;
    else if (STREQ(string1, "OUTFILE"))
      commandtype = OUTFILE_;
    
    switch(commandtype) {
    case (BADCOMMAND_):
      configwarning2(inputline);
      break;
    case (FILEALIAS_):
      configalias(string2, string3, &filealiasp, string1, inputline, rc);
      break;
    case (HOSTALIAS_):
      configalias(strtolower(string2), strtolower(string3), &hostaliasp,
		  string1, inputline, rc);
      break;
    case (REFALIAS_):
      configalias(string2, string3, &refaliasp, string1, inputline, rc);
      break;
    case (BROWALIAS_):
      configalias(string2, string3, &browaliasp, string1, inputline, rc);
      break;
    case (REQOUTPUTALIAS_):
      configalias(string2, string3, &routaliasp, string1, inputline, rc);
      break;
    case (DIROUTPUTALIAS_):
      configalias(string2, string3, &ioutaliasp, string1, inputline, rc);
      break;
    case (HOSTOUTPUTALIAS_):
      configalias(string2, string3, &Soutaliasp, string1, inputline, rc);
      break;
    case (REFOUTPUTALIAS_):
      configalias(string2, string3, &foutaliasp, string1, inputline, rc);
      break;
    case (BROWOUTPUTALIAS_):
      configalias(string2, string3, &boutaliasp, string1, inputline, rc);
      break;
    case (TYPEOUTPUTALIAS_):
      configalias(string2, string3, &toutaliasp, string1, inputline, rc);
      break;
    case (FILEINCLUDE_):
      include(string2, &wantfilep, wantfilehead, TRUE, string1, inputline, rc,
	      &filemaskq);
      break;
    case (FILEEXCLUDE_):
      include(string2, &wantfilep, wantfilehead, FALSE, string1, inputline,
	      rc, &filemaskq);
      break;
    case (FILEALLOW_):
      include(string2, &wantfilep, wantfilehead, UNSET, string1, inputline, rc,
	      &tempflag);
      break;
    case (HOSTINCLUDE_):
      include(strtolower(string2), &wanthostp, wanthosthead, TRUE, string1,
	      inputline, rc, &hostmaskq);
      break;
    case (HOSTEXCLUDE_):
      include(strtolower(string2), &wanthostp, wanthosthead, FALSE, string1,
	      inputline, rc, &hostmaskq);
      break;
    case (HOSTALLOW_):
      include(strtolower(string2), &wanthostp, wanthosthead, UNSET, string1,
	      inputline, rc, &tempflag);
      break;
    case (REFINCLUDE_):
      include(string2, &wantrefp, wantrefhead, TRUE, string1, inputline, rc,
	      &refmaskq);
      break;
    case (REFEXCLUDE_):
      include(string2, &wantrefp, wantrefhead, FALSE, string1, inputline, rc,
	      &refmaskq);
      break;
    case (REFALLOW_):
      include(string2, &wantrefp, wantrefhead, UNSET, string1, inputline, rc,
	      &tempflag);
      break;
    case (REQINCLUDE_):
      include(string2, &wantreqp, wantreqhead, TRUE, string1, inputline, rc,
	      &tempflag);
      break;
    case (REQEXCLUDE_):
      include(string2, &wantreqp, wantreqhead, FALSE, string1, inputline, rc,
	      &tempflag);
      break;
    case (REQALLOW_):
      include(string2, &wantreqp, wantreqhead, UNSET, string1, inputline, rc,
	      &tempflag);
      break;
    case (LINKINCLUDE_):
      include(string2, &linkp, linkhead, TRUE, string1, inputline, rc,
	      &tempflag);
      break;
    case (LINKEXCLUDE_):
      include(string2, &linkp, linkhead, FALSE, string1, inputline, rc,
	      &tempflag);
      break;
    case (LINKALLOW_):
      include(string2, &linkp, linkhead, UNSET, string1, inputline, rc,
	      &tempflag);
      break;
    case (REFLINKINCLUDE_):
      include(string2, &reflinkp, reflinkhead, TRUE, string1, inputline, rc,
	      &tempflag);
      break;
    case (REFLINKEXCLUDE_):
      include(string2, &reflinkp, reflinkhead, FALSE, string1, inputline, rc,
	      &tempflag);
      break;
    case (REFLINKALLOW_):
      include(string2, &reflinkp, reflinkhead, UNSET, string1, inputline, rc,
	      &tempflag);
      break;
    case (FROM_):
      fromtodate(string2, &fromtime, TRUE, string1, inputline, rc);
      break;
    case (TO_):
      fromtodate(string2, &totime, FALSE, string1, inputline, rc);
      break;
    case (SUBDOMAIN_):
      if (string2[0] == '\0')
	configwarning2(inputline);
      else if (rc < 2)
	configwarning(string1, inputline);
      else {
	strtolower(string2);
	if (rc > 3 ||
	    (rc == 3 && (string2[0] == '*' || 
			 string2[(int)strlen(string2) - 1] == '*' ||
			 string2[0] == '%')))
	  configwarning3(string1, inputline);
	strcpy(subdomp -> from, string2);
	if (rc == 2 || string2[0] == '*' ||
	    string2[(int)strlen(string2) - 1] == '*' || string2[0] == '%')
	  strcpy(subdomp -> to, "?");
	else
	  strcpy(subdomp -> to, string3);
	subdomp -> next =
	  (struct alias *)xmalloc(sizeof(struct alias));
	subdomp = subdomp -> next;
	subdomp -> from[0] = '\0';
      }
      break;
    case (WEEKBEGINSON_):
      if (rc < 2)
	configwarning(string1, inputline);
      else {
	if (rc > 2)
	  configwarning3(string1, inputline);
	strtoupper(string2);
	if (STREQ(string2, "SUNDAY"))
	  weekbeginson = SUNDAY;
	else if (STREQ(string2, "MONDAY"))
	  weekbeginson = MONDAY;
	else if (STREQ(string2, "TUESDAY"))
	  weekbeginson = TUESDAY;
	else if (STREQ(string2, "WEDNESDAY"))
	  weekbeginson = WEDNESDAY;
	else if (STREQ(string2, "THURSDAY"))
	  weekbeginson = THURSDAY;
	else if (STREQ(string2, "FRIDAY"))
	  weekbeginson = FRIDAY;
	else if (STREQ(string2, "SATURDAY"))
	  weekbeginson = SATURDAY;
	else
	  configwarning2(inputline);
      }
      break;
    case (APPROXHOSTSIZE_):
      if (rc < 2)
	configwarning(string1, inputline);
      else {
	if (rc > 2)
	  configwarning3(string1, inputline);
	approxhostsize = atoi(string2);
	if (approxhostsize <= 0)
	  configwarning2(inputline);
      }
      break;
    case (ISPAGE_):
      include(string2, &ispagep, ispagehead, TRUE, string1, inputline, rc,
	      &tempflag);
      break;
    case (ISNOTPAGE_):
      include(string2, &ispagep, ispagehead, FALSE, string1, inputline, rc,
	      &tempflag);
      break;
    case (SEPCHAR_):
      if (rc < 2)
	configwarning(string1, inputline);
      else {
	if (rc > 2 || (string2[0] != '\0' && string2[1] != '\0'))
	  configwarning3(string1, inputline);
	sepchar = string2[0];
      }
      break;
    case (REPSEPCHAR_):
      if (rc < 2)
	configwarning(string1, inputline);
      else {
	if (rc > 2 || (string2[0] != '\0' && string2[1] != '\0'))
	  configwarning3(string1, inputline);
	repsepchar = string2[0];
      }
      break;
    case (DECPOINT_):
      if (rc < 2 || string2[0] == '\0')
	configwarning(string1, inputline);
      else {
	if (rc > 2 || string2[1] != '\0')
	  configwarning3(string1, inputline);
	decpoint = string2[0];
      }
      break;
    case (PRESEP_):
      configstr(string2, presep, string1, inputline, rc);
      break;
    case (REPORTORDER_):
      if (rc < 2)
	configwarning(string1, inputline);
      else {
	if (rc > 2 || (int)strlen(string2) > 19)
	  configwarning3(string1, inputline);
	strncpy(reportorder, string2, 19);
      }
      break;
    case (WITHARGS_):
      include(string2, &noexpandp, noexpandhead, FALSE, string1, inputline,
	      rc, &tempflag);
      break;
    case (WITHOUTARGS_):
      include(string2, &noexpandp, noexpandhead, TRUE, string1, inputline, rc,
	      &tempflag);
      break;
    case (REFWITHARGS_):
      include(string2, &refexpandp, refexpandhead, TRUE, string1, inputline,
	      rc, &tempflag);
      break;
    case (REFWITHOUTARGS_):
      include(string2, &refexpandp, refexpandhead, FALSE, string1, inputline,
	      rc, &tempflag);
      break;
    case (NOTSUBDOMAIN_):
      if (rc < 2)
	configwarning(string1, inputline);
      else {
	strtolower(string2);
	if (rc > 2)
	  configwarning3(string1, inputline);
	tempflag = OFF;
	for (subdomtempp = subdomshead; subdomtempp -> from[0] != '\0';
	     subdomtempp = subdomtempp -> next) {
	  if (STREQ(subdomtempp -> from, string2)) {
	    subdomtempp -> from[0] = '?'; /* mark that we don't want it */
	    tempflag = ON;
	  }
	}
	if (!tempflag && warnq) {
	  fprintf(stderr, "%s: Warning: NOTSUBDOMAIN command before corresponding SUBDOMAIN at\n", commandname);
	  fprintf(stderr, "  %s", inputline);
	  if (inputline[MAX(strlen(inputline) - 1, 0)] != '\n')
	    fprintf(stderr, "\n");
	  anywarns = ON;
	}
      }
      break;
    case (BASEURL_):
      configstr(string2, baseurl, string1, inputline, rc);
      break;
    case (DOMCOLS_):
      configcols(string2, ocols, string1, inputline, rc);
      break;
    case (HOSTCOLS_):
      configcols(string2, Scols, string1, inputline, rc);
      break;
    case (DIRCOLS_):
      configcols(string2, icols, string1, inputline, rc);
      break;
    case (TYPECOLS_):
      configcols(string2, tcols, string1, inputline, rc);
      break;
    case (REQCOLS_):
      configcols(string2, rcols, string1, inputline, rc);
      break;
    case (REFCOLS_):
      configcols(string2, fcols, string1, inputline, rc);
      break;
    case (BROWCOLS_):
      configcols(string2, bcols, string1, inputline, rc);
      break;
    case (FULLBROWCOLS_):
      configcols(string2, Bcols, string1, inputline, rc);
      break;
    case (MONTHCOLS_):
      configcols(string2, mcols, string1, inputline, rc);
      break;
    case (DAYCOLS_):
      configcols(string2, dcols, string1, inputline, rc);
      break;
    case (FULLDAYCOLS_):
      configcols(string2, Dcols, string1, inputline, rc);
      break;
    case (WEEKCOLS_):
      configcols(string2, Wcols, string1, inputline, rc);
      break;
    case (HOURCOLS_):
      configcols(string2, hcols, string1, inputline, rc);
      break;
    case (FULLHOURCOLS_):
      configcols(string2, Hcols, string1, inputline, rc);
      break;
    case (MONTHGRAPH_):
      configchar(string2, &mgraph, string1, inputline, rc);
      break;
    case (DAYGRAPH_):
      configchar(string2, &dgraph, string1, inputline, rc);
      break;
    case (FULLDAYGRAPH_):
      configchar(string2, &Dgraph, string1, inputline, rc);
      break;
    case (HOURGRAPH_):
      configchar(string2, &hgraph, string1, inputline, rc);
      break;
    case (FULLHOURGRAPH_):
      configchar(string2, &Hgraph, string1, inputline, rc);
      break;
    case (WEEKGRAPH_):
      configchar(string2, &Wgraph, string1, inputline, rc);
      break;
    case (GRAPHICAL_):
      onoff(string2, &graphical, string1, inputline, rc);
      break;
    case (LOGFILE_):
      if (rc < 2)
	configwarning(string1, inputline);
      else if (STREQ(string2, "none")) {
	logfilep = logfilehead;
	logfilehead -> name[0] = '\0';
      }
      else if (rc == 2)
	addlogfile(&logfilep, string2, "", ON);
      else {
	addlogfile(&logfilep, string2, string3, ON);
	if (rc > 3)
	  configwarning3(string1, inputline);
      }
      break;
    case (CACHEFILE_):
      if (STREQ(string2, "none")) {
	cachefilep = cachefilehead;
	cachefilehead -> name[0] = '\0';
      }
      else
	configstrlist(string2, &cachefilep, string1, inputline, rc, ON);
      break;
    case (REFLOG_):
      if (STREQ(string2, "none")) {
	reflogp = refloghead;
	refloghead -> name[0] = '\0';
      }
      else
	configstrlist(string2, &reflogp, string1, inputline, rc, ON);
      break;
    case (BROWLOG_):
      if (STREQ(string2, "none")) {
	browlogp = browloghead;
	browloghead -> name[0] = '\0';
      }
      else
	configstrlist(string2, &browlogp, string1, inputline, rc, ON);
      break;
    case (ERRLOG_):
      if (STREQ(string2, "none")) {
	errlogp = errloghead;
	errloghead -> name[0] = '\0';
      }
      else
	configstrlist(string2, &errlogp, string1, inputline, rc, ON);
      break;
    case (DOMAINSFILE_):
      configstr(string2, domainsfile, string1, inputline, rc);
      break;
    case (HOSTNAME_):
      configstr(string2, hostname, string1, inputline, rc);
      break;
    case (HOSTURL_):
      configstr(string2, hosturl, string1, inputline, rc);
      break;
    case (HOSTMINREQS_):
      configstr(string2, Sminreqstr, string1, inputline, rc);
      break;
    case (DOMMINREQS_):
      configstr(string2, ominreqstr, string1, inputline, rc);
      break;
    case (SUBDOMMINREQS_):
      configstr(string2, Ominreqstr, string1, inputline, rc);
      break;
    case (DIRMINREQS_):
      configstr(string2, iminreqstr, string1, inputline, rc);
      break;
    case (TYPEMINREQS_):
      configstr(string2, tminreqstr, string1, inputline, rc);
      break;
    case (REQMINREQS_):
      configstr(string2, rminreqstr, string1, inputline, rc);
      break;
    case (REFMINREQS_):
      configstr(string2, fminreqstr, string1, inputline, rc);
      break;
    case (BROWMINREQS_):
      configstr(string2, bminreqstr, string1, inputline, rc);
      break;
    case (FULLBROWMINREQS_):
      configstr(string2, Bminreqstr, string1, inputline, rc);
      break;
    case (HOSTMINPAGES_):
      configstr(string2, Sminpagestr, string1, inputline, rc);
      break;
    case (DOMMINPAGES_):
      configstr(string2, ominpagestr, string1, inputline, rc);
      break;
    case (SUBDOMMINPAGES_):
      configstr(string2, Ominpagestr, string1, inputline, rc);
      break;
    case (DIRMINPAGES_):
      configstr(string2, iminpagestr, string1, inputline, rc);
      break;
    case (TYPEMINPAGES_):
      configstr(string2, tminpagestr, string1, inputline, rc);
      break;
    case (REQMINPAGES_):
      configstr(string2, rminpagestr, string1, inputline, rc);
      break;
    case (REFMINPAGES_):
      configstr(string2, fminpagestr, string1, inputline, rc);
      break;
    case (BROWMINPAGES_):
      configstr(string2, bminpagestr, string1, inputline, rc);
      break;
    case (FULLBROWMINPAGES_):
      configstr(string2, Bminpagestr, string1, inputline, rc);
      break;
    case (HOSTMINBYTES_):
      configstr(string2, Sminbytestr, string1, inputline, rc);
      break;
    case (DOMMINBYTES_):
      configstr(string2, ominbytestr, string1, inputline, rc);
      break;
    case (SUBDOMMINBYTES_):
      configstr(string2, Ominbytestr, string1, inputline, rc);
      break;
    case (DIRMINBYTES_):
      configstr(string2, iminbytestr, string1, inputline, rc);
      break;
    case (TYPEMINBYTES_):
      configstr(string2, tminbytestr, string1, inputline, rc);
      break;
    case (REQMINBYTES_):
      configstr(string2, rminbytestr, string1, inputline, rc);
      break;
    case (REFMINBYTES_):
      configstr(string2, fminbytestr, string1, inputline, rc);
      break;
    case (BROWMINBYTES_):
      configstr(string2, bminbytestr, string1, inputline, rc);
      break;
    case (FULLBROWMINBYTES_):
      configstr(string2, Bminbytestr, string1, inputline, rc);
      break;
    case (ERRMINOCCS_):
      configint(string2, &eminreqs, string1, inputline, rc);
      break;
    case (REQSORTBY_):
      configsortby(string2, &rsortby, string1, inputline, rc);
      break;
    case (DOMSORTBY_):
      configsortby(string2, &osortby, string1, inputline, rc);
      break;
    case (DIRSORTBY_):
      configsortby(string2, &isortby, string1, inputline, rc);
      break;
    case (TYPESORTBY_):
      configsortby(string2, &tsortby, string1, inputline, rc);
      break;
    case (HOSTSORTBY_):
      configsortby(string2, &Ssortby, string1, inputline, rc);
      break;
    case (REFSORTBY_):
      configsortby(string2, &fsortby, string1, inputline, rc);
      break;
    case (BROWSORTBY_):
      configsortby(string2, &bsortby, string1, inputline, rc);
      break;
    case (FULLBROWSORTBY_):
      configsortby(string2, &Bsortby, string1, inputline, rc);
      break;
    case (MARKCHAR_):
      if (rc < 2)
	configwarning(string1, inputline);
      else {
	if (rc > 2 || string2[1] != '\0')
	  configwarning3(string1, inputline);
	markchar = string2[0];
      }
      break;
    case (PAGEWIDTH_):
      if (rc < 2)
	configwarning(string1, inputline);
      else {
	if (rc > 2)
	  configwarning3(string1, inputline);
	pagewidth = atoi(string2);
	if (pagewidth < MINPAGEWIDTH || pagewidth > MAXPAGEWIDTH) {
	  fprintf(stderr, "%s: Page width should be between %d and %d\n",
		  commandname, MINPAGEWIDTH, MAXPAGEWIDTH);
	  configwarning2(inputline);
	  pagewidth = PAGEWIDTH;
	}
      }
      break;
    case (ALLBACK_):  /* onoff() extended */
      if (rc < 2)
	configwarning(string1, inputline);
      else {
	strtoupper(string2);
	if (STREQ(string2, "ON")) {
	  mback = ON;
	  Hback = ON;
	  Wback = ON;
	  Dback = ON;
	}
	else if (STREQ(string2, "OFF")) {
	  mback = OFF;
	  Hback = OFF;
	  Wback = OFF;
	  Dback = OFF;
	}
	else
	  configwarning2(inputline);
      }
      break;
    case (MONTHLYBACK_):
      onoff(string2, &mback, string1, inputline, rc);
      break;
    case (FULLHOURLYBACK_):
      onoff(string2, &Hback, string1, inputline, rc);
      break;
    case (FULLDAILYBACK_):
      onoff(string2, &Dback, string1, inputline, rc);
      break;
    case (WEEKLYBACK_):
      onoff(string2, &Wback, string1, inputline, rc);
      break;
    case (MONTHROWS_):
      configint(string2, &mrows, string1, inputline, rc);
      break;
    case (FULLHOURROWS_):
      configint(string2, &Hrows, string1, inputline, rc);
      break;
    case (WEEKROWS_):
      configint(string2, &Wrows, string1, inputline, rc);
      break;
    case (FULLDAYROWS_):
      configint(string2, &Drows, string1, inputline, rc);
      break;
    case (MONTHLY_):
      onoff(string2, &mq, string1, inputline, rc);
      break;
    case (DAILY_):
      onoff(string2, &dq, string1, inputline, rc);
      break;
    case (FULLDAILY_):
      onoff(string2, &Dq, string1, inputline, rc);
      break;
    case (HOURLY_):
      onoff(string2, &hq, string1, inputline, rc);
      break;
    case (FULLHOURLY_):
      onoff(string2, &Hq, string1, inputline, rc);
      break;
    case (WEEKLY_):
      onoff(string2, &Wq, string1, inputline, rc);
      break;
    case (DOMAIN_):
      onoff(string2, &oq, string1, inputline, rc);
      break;
    case (FULLHOSTS_):
      onoff(string2, &Sq, string1, inputline, rc);
      break;
    case (DIRECTORY_):
      onoff(string2, &iq, string1, inputline, rc);
      break;
    case (FILETYPE_):
      onoff(string2, &tq, string1, inputline, rc);
      break;
    case (REQUEST_):
      onoff(string2, &rq, string1, inputline, rc);
      break;
    case (REFERRER_):
      onoff(string2, &fq, string1, inputline, rc);
      break;
    case (BROWSER_):
      onoff(string2, &bq, string1, inputline, rc);
      break;
    case (FULLBROWSER_):
      onoff(string2, &Bq, string1, inputline, rc);
      break;
    case (STATUS_):
      onoff(string2, &cq, string1, inputline, rc);
      break;
    case (ERROR_):
      onoff(string2, &eq, string1, inputline, rc);
      break;
    case (ALL_):
      if (rc < 2)
	configwarning(string1, inputline);
      else {
	strtoupper(string2);
	if (STREQ(string2, "ON")) {
	  mq = ON;
	  Wq = ON;
	  dq = ON;
	  Dq = ON;
	  hq = ON;
	  Hq = ON;
	  oq = ON;
	  Sq = ON;
	  iq = ON;
	  tq = ON;
	  rq = ON;
	  fq = ON;
	  bq = ON;
	  Bq = ON;
	  cq = ON;
	  eq = ON;
	}
	else if (STREQ(string2, "OFF"))  {
	  mq = OFF;
	  Wq = OFF;
	  dq = OFF;
	  Dq = OFF;
	  hq = OFF;
	  Hq = OFF;
	  oq = OFF;
	  Sq = OFF;
	  iq = OFF;
	  tq = OFF;
	  rq = OFF;
	  fq = OFF;
	  bq = OFF;
	  Bq = OFF;
	  cq = OFF;
	  eq = OFF;
	}
	else
	  configwarning2(inputline);
      }
      break;
    case (GENERAL_):
      onoff(string2, &xq, string1, inputline, rc);
      break;
    case (DIRLEVEL_):
      configint(string2, &dirlevel, string1, inputline, rc);
      break;
    case (COUNTHOSTS_):
      if (rc < 2)
	configwarning(string1, inputline);
      else {
	strtoupper(string2);
	if (STREQ(string2, "ON"))
	  sq = ON;
	else if (STREQ(string2, "OFF"))
	  sq = OFF;
	else if (STREQ(string2, "APPROX"))
	  sq = APPROX;
	else
	  configwarning2(inputline);
      }
      break;
    case (LASTSEVEN_):
      onoff(string2, &q7, string1, inputline, rc);
      break;
    case (WARNINGS_):
      onoff(string2, &warnq, string1, inputline, rc);
      break;
    case (CASE_):
      if (rc < 2)
	configwarning(string1, inputline);
      else {
	strtoupper(string2);
	if (STREQ(string2, "SENSITIVE"))
	  case_insensitive = OFF;
	else if (STREQ(string2, "INSENSITIVE"))
	  case_insensitive = ON;
	else
	  configwarning2(inputline);
      }
      break;
    case (IMAGEDIR_):
      configstr(string2, imagedir, string1, inputline, rc);
      break;
    case (DIRSUFFIX_):
      configstr(string2, dirsuffix, string1, inputline, rc);
      break;
    case (MONTHLYUNIT_):
      configint(string2, &munit, string1, inputline, rc);	  
      break;
    case (HOURLYUNIT_):
      configint(string2, &hunit, string1, inputline, rc);	  
      break;
    case (FULLHOURLYUNIT_):
      configint(string2, &Hunit, string1, inputline, rc);	  
      break;
    case (DAILYUNIT_):
      configint(string2, &dunit, string1, inputline, rc);	  
      break;
    case (FULLDAILYUNIT_):
      configint(string2, &Dunit, string1, inputline, rc);	  
      break;
    case (WEEKLYUNIT_):
      configint(string2, &Wunit, string1, inputline, rc);	  
      break;
    case (LOGOURL_):
      configstr(string2, logourl, string1, inputline, rc);
      break;
    case (HEADERFILE_):
      configstr(string2, headerfile, string1, inputline, rc);
      break;
    case (FOOTERFILE_):
      configstr(string2, footerfile, string1, inputline, rc);
      break;
    case (OUTPUT_):
      if (rc < 2)
	configwarning(string1, inputline);
      else {
	if (rc > 2)
	  configwarning3(string1, inputline);
	strtoupper(string2);
	if (STREQ(string2, "ASCII"))
	  aq = ASCII;
	else if (STREQ(string2, "HTML"))
	  aq = HTML;
	else if (STREQ(string2, "CACHE"))
	  aq = CACHE;
	else if (STREQ(string2, "PREFORMATTED"))
	  aq = PREFORMATTED;
	else
	  configwarning2(inputline);
      }
      break;
    case (LANGUAGE_):
      if (rc < 2)
	configwarning(string1, inputline);
      else {
	if (rc > 2)
	  configwarning3(string1, inputline);
	strtoupper(string2);
	if (STREQ(string2, "ENGLISH"))
	  lang = ENGLISH;
	else if (STREQ(string2, "US-ENGLISH"))
	  lang = US_ENGLISH;
	else if (STREQ(string2, "FRENCH"))
	  lang = FRENCH;
	else if (STREQ(string2, "GERMAN"))
	  lang = GERMAN;
	else if (STREQ(string2, "ITALIAN"))
	  lang = ITALIAN;
	else if (STREQ(string2, "SPANISH"))
	  lang = SPANISH;
	else if (STREQ(string2, "DANISH"))
	  lang = DANISH;
	else
	  configwarning2(inputline);
      }
      break;
    case (DEBUG_):
      configint(string2, &debug, string1, inputline, rc);	  
      break;
    case (PROGRESSFREQ_):
      configint(string2, &progressfreq, string1, inputline, rc);	  
      break;
    case (RAWBYTES_):
      onoff(string2, &rawbytes, string1, inputline, rc);
      break;
    case (UNCOMPRESS_):
      if (rc < 3)
	configwarning(string1, inputline);
      else {
	addlogfile(&uncompressp, string2, string3, OFF);
	if (rc > 3)
	  configwarning3(string1, inputline);
      }
      break;
    case (REQHASHSIZE_):
      configsizet(string2, &rhashsize, string1, inputline, rc);	  
      break;
    case (DIRHASHSIZE_):
      configsizet(string2, &ihashsize, string1, inputline, rc);	  
      break;
    case (TYPEHASHSIZE_):
      configsizet(string2, &thashsize, string1, inputline, rc);	  
      break;
    case (HOSTHASHSIZE_):
      configsizet(string2, &Shashsize, string1, inputline, rc);	  
      break;
    case (REFHASHSIZE_):
      configsizet(string2, &fhashsize, string1, inputline, rc);	  
      break;
    case (BROWHASHSIZE_):
      configsizet(string2, &bhashsize, string1, inputline, rc);	  
      break;
    case (FULLBROWHASHSIZE_):
      configsizet(string2, &Bhashsize, string1, inputline, rc);	  
      break;
    case (SUBDOMHASHSIZE_):
      configsizet(string2, &Ohashsize, string1, inputline, rc);	  
      break;
#ifndef NODNS
    case (DNSHASHSIZE_):
      configsizet(string2, &dnshashsize, string1, inputline, rc);	  
      break;
    case (NUMLOOKUP_):
      onoff(string2, &dnsq, string1, inputline, rc);
      break;
    case (DNSFILE_):
      configstr(string2, dnsfile, string1, inputline, rc);
      break;
    case (DNSFRESHHOURS_):
      configint(string2, &dnsfreshhours, string1, inputline, rc);
      break;
#endif
    case (CONFIGFILE_):
      config(string2);
      break;
    case (OUTFILE_):
      configstr(string2, outfile, string1, inputline, rc);
      break;
    }
  }
}

flag config(char *filename)
{
  FILE *cf;
  flag ispipe;
  char inputline[MAXLINELENGTH];

  if (STREQ(filename, "none"))
    return(0);
  else {
    no_configs++;
    if (no_configs > MAX_CONFIGS) {
      fprintf(stderr, "%s: Error: More than %d configuration files:\n",
	      commandname, MAX_CONFIGS);
      fprintf(stderr, "  probably being called in circles: exiting\n");
      exit(ERR);
    }
    cf = fopenlog(filename, "configuration file", &ispipe);
    if (cf == NULL)
      return(1);
    else {  /* we can read the config. file */
      while (fgets(inputline, MAXLINELENGTH, cf) != NULL)
	configline(inputline);
      fcloselog(cf, filename, "configuration file", ispipe);
      return(0);
    }
  }
}

/*** Now the main commandline command ***/

void commandline(int argc, char **argv)
{
  int i;

  flag Gfound = FALSE;
  char tempstr1[MAXSTRINGLENGTH], tempstr2[MAXSTRINGLENGTH];

  /* First see whether to include the default config. file, by scanning
     backwards through the arguments looking for the (last) occurrence of
     +G or -G. We then run the config. file, then look at the other args. */

  for (i = argc - 1; i >= 1 && !Gfound; i--) {
    if (argv[i][1] == 'G') {
      if (argv[i][2] != '\0' && (argv[i][0] == '+' || argv[i][0] == '-')) {
	if (warnq) {
	  fprintf(stderr,
		  "%s: Warning: ignoring extra text after %cG option\n",
		  commandname, argv[i][0]);
	  anywarns = ON;
	}
      }
      if (argv[i][0] == '+') {
	Gfound = TRUE;
	config(DEFAULTCONFIGFILE);
      }
      else if (argv[i][0] == '-') {
	Gfound = TRUE;
      }
    }
  }
  if (!Gfound) {
    logfilep = logfilehead;
    cachefilep = cachefilehead;
    reflogp = refloghead;
    browlogp = browloghead;
    errlogp = errloghead;
    config(DEFAULTCONFIGFILE);
  }

  logfilep = logfilehead;  /* reset logfile pointers for over-write */
  cachefilep = cachefilehead;
  reflogp = refloghead;
  browlogp = browloghead;
  errlogp = errloghead;

  /* Now read the other arguments */

  for (i = 1; i < argc; i++) {

    if (argv[i][0] != '+' && argv[i][0] != '-') {
      if (STREQ(argv[i], "none")) {
	logfilep = logfilehead;
	logfilehead -> name[0] = '\0';
      }
      else
	addlogfile(&logfilep, argv[i], "", ON);
    }
    else switch (argv[i][1]) {
    case '\0':    /* read stdin */
      addlogfile(&logfilep, "stdin", "", ON);
      break;
#ifndef NODNS
    case '1':
      clflag(&dnsq, argv[i]);
      break;
#endif
    case '7':     /* stats for last 7 days */
      clflag(&q7, argv[i]);
      break;
    case 'a':     /* ASCII output */
      clflag(&aq, argv[i]);  /* This works because ON = ASCII, OFF = HTML */
      break;      
    case 'A':     /* all reports */
      if (argv[i][0] == '-')
	configline("ALL OFF");
      else
	configline("ALL ON");
      if (argv[i][2] != '\0' && warnq) {
	fprintf(stderr, "%s: Warning: ignoring extra text after %cA option\n",
		commandname, argv[i][0]);
	anywarns = ON;
      }
      break;
    case 'b':     /* browser summary */
      clgenrep(&bq, &bsortby, bminreqstr, bminpagestr, bminbytestr, argv[i]);
      break;
    case 'B':     /* browser report */
      clgenrep(&Bq, &Bsortby, Bminreqstr, Bminpagestr, Bminbytestr, argv[i]);
      break;
    case 'c':     /* status code report */
      clflag(&cq, argv[i]);
      break;
    case 'C':     /* configuration command */
      if (argv[i][2] == '\0') {
	if (warnq) {
	  fprintf(stderr, "%s: Warning: no command supplied after +C option\n",
		  commandname);
	  fprintf(stderr, "  (or space left before command)\n");
	  anywarns = ON;
	}
      }
      else
	configline(argv[i] + 2);
      break;
    case 'd':     /* daily summary */
      cldaterep(&dq, &dgraph, argv[i]);
      break;
    case 'D':     /* full daily report */
      cldaterep(&Dq, &Dgraph, argv[i]);
      break;
    case 'e':     /* error report */
      clflag(&eq, argv[i]);
      break;
    case 'f':     /* form */
      if (STREQ(argv[i] + 2, "orm"))
	formq = ON;
      else        /* referrer report */
	clgenrep(&fq, &fsortby, fminreqstr, fminpagestr, fminbytestr, argv[i]);
      break;
    case 'F':     /* FROM */
      if (argv[i][0] == '-') {
	configline("FROM OFF");
	if (argv[i][2] != '\0' && warnq) {
	  fprintf(stderr, "%s: Warning: ignoring extra text after -F option\n",
		  commandname);
	  anywarns = ON;
	}
      }
      else if (argv[i][2] == '\0' && warnq) {
	fprintf(stderr, "%s: Warning: no date supplied after +F option\n",
		commandname);
	fprintf(stderr, "  (or space left before date)\n");
	anywarns = ON;
      }
      else {
	strcpy(tempstr2, "FROM ");
	strcat(tempstr2, argv[i] + 2);
	configline(tempstr2);
      }
      break;
    case 'g':     /* configuration file */
      if (argv[i][0] == '+') {
	if (argv[i][2] == '\0') {
	  if (warnq) {
	    fprintf(stderr,
		    "%s: Warning: no filename supplied after +g option\n",
		    commandname);
	    fprintf(stderr, "  (or space left before filename)\n");
	    anywarns = ON;
	  }
	}
	else
	  config(argv[i] + 2);
      }
      else {
	fprintf(stderr, "%s: Warning: Ignoring unknown option -g:\n",
		commandname);
	fprintf(stderr, "  see Readme.html for correct usage\n");
	fprintf(stderr,
		"  or go to http://www.statslab.cam.ac.uk/~sret1/analog/\n");
      }
      break;
    case 'G':     /* default configuration file: done already */
      break;
    case 'h':     /* help */
      if (STREQ(argv[i] + 2, "elp")) {
	fprintf(stderr, "For help see Readme.html, or ");
	fprintf(stderr, "http://www.statslab.cam.ac.uk/~sret1/analog/\n");
	exit(OK);
      }
      else        /* hourly summary */
	cldaterep(&hq, &hgraph, argv[i]);
      break;
    case 'H':     /* hourly report */
      cldaterep(&Hq, &Hgraph, argv[i]);
      break;
    case 'i':     /* directory report */
      clgenrep(&iq, &isortby, iminreqstr, iminpagestr, iminbytestr, argv[i]);
      break;
    case 'l':     /* 'level' of dir report */
      dirlevel = atoi(argv[i] + 2);
      break;
    case 'm':     /* monthly report */
      cldaterep(&mq, &mgraph, argv[i]);
      break;
    case 'n':     /* our host or organisation name */
      if (argv[i][2] == '\0') {
	if (warnq) {
	  fprintf(stderr, "%s: Warning: no text supplied after %cn option\n",
		  commandname, argv[i][0]);
	  fprintf(stderr, "  (or space left before text)\n");
	  anywarns = ON;
	}
      }
      else
	strncpy(hostname, argv[i] + 2, MAXSTRINGLENGTH - 1);
      break;
    case 'o':                 /* domain report */
      clgenrep(&oq, &osortby, ominreqstr, ominpagestr, ominbytestr, argv[i]);
      break;
    case 'O':     /* outfile */
      clfile(outfile, argv[i]);
      break;
    case 'p':    /* logo? */
      clfile(logourl, argv[i]);
      break;
    case 'q':    /* warnings? */
      clflag(&warnq, argv[i]);
      break;
    case 'r':    /* request report */
      clgenrep(&rq, &rsortby, rminreqstr, rminpagestr, rminbytestr, argv[i]);
      break;
    case 's':      /* count hosts? */
      if (argv[i][0] == '-')
	sq = OFF;
      else if (argv[i][2] == 's')
	sq = APPROX;
      else
	sq = ON;
      if (argv[i][2] == 's') {
	if (argv[i][3] != '\0' && warnq) {
	  fprintf(stderr,
		  "%s: Warning: ignoring extra text after %css option\n",
		  commandname, argv[i][0]);
	  anywarns = ON;
	}
      }
      else {  /* argv[i][2] != 's' */
	if (argv[i][2] != '\0' && warnq) {
	  fprintf(stderr,
		  "%s: Warning: ignoring extra text after %cs option\n",
		  commandname, argv[i][0]);
	  anywarns = ON;
	}
      }
      break;
    case 'S':      /* full hostname report */
      clgenrep(&Sq, &Ssortby, Sminreqstr, Sminpagestr, Sminbytestr, argv[i]);
      break;
    case 't':     /* file type report */
      clgenrep(&tq, &tsortby, tminreqstr, tminpagestr, tminbytestr, argv[i]);
      break;
    case 'T':     /* TO */
      if (argv[i][0] == '-') {
	configline("TO OFF");
	if (argv[i][2] != '\0' && warnq) {
	  fprintf(stderr, "%s: Warning: ignoring extra text after -T option\n",
		  commandname);
	  anywarns = ON;
	}
      }
      else if (argv[i][2] == '\0' && warnq) {
	fprintf(stderr, "%s: Warning: no date supplied after +T option\n",
		commandname);
	fprintf(stderr, "  (or space left before date)\n");
	anywarns = ON;
      }
      else {
	strcpy(tempstr2, "TO ");
	strcat(tempstr2, argv[i] + 2);
	configline(tempstr2);
      }
      break;
    case 'u':     /* host URL */
      if (argv[i][2] == '\0') {
	if (warnq) {
	  fprintf(stderr, "%s: Warning: no URL supplied after %cu option\n",
		  commandname, argv[i][0]);
	  fprintf(stderr, "  (or space left before URL)\n");
	  anywarns = ON;
	}
      }
      else
	strncpy(hosturl, argv[i] + 2, MAXSTRINGLENGTH - 1);
      break;
    case 'U':      /* cache file */
      if(clfile(tempstr1, argv[i]) == OK) {
	strcpy(tempstr2, "CACHEFILE ");
	strncat(tempstr2, tempstr1, MAXSTRINGLENGTH - 11);
	configline(tempstr2);
      }
      break;
    case 'v':          /* print variables and exit */
      if (argv[i][2] != '\0' && warnq) {
	fprintf(stderr, "%s: Warning: ignoring extra text after %cv option\n",
		commandname, argv[i][0]);
	anywarns = ON;
      }
      vblesonly = ON;
      break;
    case 'V':          /* debugging info */
      if (argv[i][0] == '-') {
	debug = OFF;
	if (argv[i][2] != '\0' && warnq) {
	  fprintf(stderr, "%s: Warning: ignoring extra text after -V option\n",
		  commandname);
	  anywarns = ON;
	}
      }
      else {
	if (argv[i][2] == '\0')
	  debug = 1;
	else
	  debug = atoi(argv[i] + 2);
      }
      break;
    case 'w':          /* pagewidth */
      pagewidth = atoi(argv[i] + 2);
      if (pagewidth < MINPAGEWIDTH || pagewidth > MAXPAGEWIDTH) {
	if (warnq) {
	  fprintf(stderr,"%s: Warning: at option %s, page width should be between %d and %d\n", commandname, argv[i], MINPAGEWIDTH, MAXPAGEWIDTH);
	  fprintf(stderr, "  Resetting to default value of %d\n", PAGEWIDTH);
	  anywarns = ON;
	}
	pagewidth = PAGEWIDTH;
      }
      break;
    case 'W':           /* weekly report */
      cldaterep(&Wq, &Wgraph, argv[i]);
      break;
    case 'x':           /* general summary and gotos */
      clflag(&xq, argv[i]);
      break;
    default:
      fprintf(stderr, "%s: Warning: Ignoring unknown option %s:\n",
	      commandname, argv[i]);
      fprintf(stderr, "  see Readme.html for correct usage\n");
      fprintf(stderr,
      "  or go to http://www.statslab.cam.ac.uk/~sret1/analog/\n");
    }
  }

  /* Finally, the mandatory config file */
  logfilep = logfilehead;  /* reset logfile pointers for over-write */
  cachefilep = cachefilehead;
  reflogp = refloghead;
  browlogp = browloghead;
  errlogp = errloghead;

  if (config(MANDATORYCONFIGFILE)) {
    fprintf(stderr,
    "%s: Error: Cannot ignore mandatory configuration file: exiting\n",
	    commandname);
    exit(ERR);
  }

}

/*** The actual initialise() function ***/

void initialise(int argc, char **argv)
{
  FILE *outf;

  time(&starttime);
  starttimetm = localtime(&starttime);
  starttimec.year = 1900 + starttimetm -> tm_year;
  starttimec.date = starttimetm -> tm_mday;
  starttimec.monthno = starttimetm -> tm_mon;
  starttimec.hr = starttimetm -> tm_hour;
  starttimec.min = starttimetm -> tm_min;
  starttimec.code = timecode(starttimec.date, starttimec.monthno,
			     starttimec.year, starttimec.hr, starttimec.min);

  defaults();   /* enter the defaults for all the variables
		   (before possibly changing them). */

#ifdef MAC_EVENTS
  commandname = (char *)xmalloc(7);
  strcpy(commandname, "analog");
#else
  commandname = (char *)xmalloc(strlen(argv[0]) + 1);
  strcpy(commandname, argv[0]);
#endif

  init_structs();   /* initialise all the structures (and pointers to them) */

  commandline(argc, argv);  /* parse commandline. This also parses all the
			       configuration files. */

  /* correct any variables for which wrong value given */

  if (fromtime.code > totime.code) {
    fprintf(stderr, "%s: Error: FROM and TO exclude all dates.\n",
	    commandname);
    exit(ERR);
  }

  if (dirlevel == 0)
    dirlevel = 1;

  if (Sq)
    sq = ON;      /* +S implies +s */

  if (STREQ(baseurl, "none"))
    baseurl[0] = '\0';
  else if (baseurl[MAX(strlen(baseurl) - 1, 0)] == '/')
    baseurl[strlen(baseurl) - 1] = '\0';

  if (aq == CACHE) {
    configline("ALL OFF");
    xq = OFF;
    Hq = ON;
    Hback = OFF;
    Hrows = 0;
  }

  else if (aq == PREFORMATTED) {
    rawbytes = ON;
    lang = ENGLISH;  /* only affects days of the week */
    sepchar = '\0';
    repsepchar = '\0';
    decpoint = '.';  /* don't need this last one at the moment, but... */
  }

  if (rsortby == BYPAGES) {
    fprintf(stderr,
	    "%s: Warning: Cannot sort request report by page requests:\n",
	    commandname);
    fprintf(stderr, "  Sorting by requests instead.\n");
    rsortby = BYREQUESTS;
  }

  if (case_insensitive) {
    alias_to_lower(filealiashead);
    include_to_lower(wantfilehead);
    include_to_lower(wantreqhead);
    include_to_lower(linkhead);
    include_to_lower(ispagehead);
    include_to_lower(noexpandhead);
    strtolower(dirsuffix);
  }

  if (vblesonly)
    printvbles();    /* which also exits */

  if (lang == US_ENGLISH) {
    lang = ENGLISH;
    dialect = US_ENGLISH;
  }

  if (!STREQ(outfile, "stdout")) {
    if ((outf = fopen(outfile, "w")) == NULL) {
      fprintf(stderr,
	      "%s: Error: failed to open output file %s for writing.\n",
	      commandname, outfile);
      exit(ERR);   /* test now so we don't do the processing THEN find out */
    }
    else
      fclose(outf);  /* no need to hold it open */
  }

  /* if we just want a form, generate that and exit */

  if (formq) {
    formgen();
    exit(OK);
  }

  othervars();

}   /* end initialise() */


/*** Finally, a boring function just to print variables and exit ***/

void printvbles(void)
{
  FILE *filep;
  char *c;

  stdin_used = FALSE;

  printf("This is analog version %s\n", VERSION);
  printf("For more information on analog see Readme.html or\n");
  printf("http://www.statslab.cam.ac.uk/~sret1/analog/\n\n");

  if (formq) {
    printf("These options would construct form in %s; see that file for options set\n",
	   outfile);
  }
  else {
    printf("Logfiles to analyse:\n");   /* as pvfilelist(), but for logfiles */
    if (logfilehead -> name[0] == '\0')
      printf("  none\n");
    for (logfilep = logfilehead; logfilep -> name[0] != '\0';
	 logfilep = logfilep -> next) {
      printf("  %s", logfilep -> name);
      if ((filep = fopen(logfilep -> name, "r")) == NULL &&
	  !STREQ(logfilep -> name, "stdin") && !STREQ(logfilep -> name, "-"))
	printf(":   Warning: cannot open that file");
      else
	fclose(filep);  /* NB So condl 3 lines back must be in that order */
      if (STREQ(logfilep -> name, "stdin") || STREQ(logfilep -> name, "-")) {
	if (stdin_used)
	  printf("\n  Warning: attempt to use stdin twice will fail");
	stdin_used = TRUE;
      }
      printf("\n");
    }

    pvfilelist(cachefilehead, "Cache files");

    if (aq != CACHE) {
      pvfilelist(refloghead, "Referrer logs");
      pvfilelist(browloghead, "Browser logs");
      pvfilelist(errloghead, "Error logs");
    }

    if (uncompresshead -> name[0] != '\0') {
      printf("Files uncompressed by the following methods:\n");
      for (uncompressp = uncompresshead; uncompressp -> name[0] != '\0';
	   uncompressp = uncompressp -> next)
	printf("  %s by %s\n", uncompressp -> name, uncompressp -> prefix);
    }
    printf("Filenames are case %s\n",
	   (case_insensitive)?"insensitive":"sensitive");
    
    if (aq == CACHE)
      printf("\nOutputting cache file only.\n");
    else {
      printf("\nThe output will be in ");
      if (aq == HTML)
	printf("HTML\n");
      else if (aq == ASCII)
	printf("plain text\n");
      else /* aq == PREFORMATTED */
	printf("preformatted format\n");
      if (aq != PREFORMATTED) {
	printf("The output language will be ");
	if (lang == ENGLISH)
	  printf("English\n");
	else if (lang == US_ENGLISH)
	  printf("US English\n");
	else if (lang == FRENCH)
	  printf("French\n");
	else if (lang == GERMAN)
	  printf("German\n");
	else if (lang == SPANISH)
	  printf("Spanish\n");
   	else if (lang == DANISH)
	  printf("Danish\n");
        else /* lang == ITALIAN */
          printf("Italian\n");
         }
      lang = ENGLISH;   /* So that whatincluded() goes in English */
      printf("The domains file is %s\n", domainsfile);
      if (((filep = fopen(domainsfile, "r")) == NULL) &&
	  !STREQ(domainsfile, "stdin") && !STREQ(domainsfile, "-"))
	printf("  Warning: cannot open that file: cannot construct domain report\n");
      else
	fclose(filep);
      if (STREQ(domainsfile, "stdin") || STREQ(domainsfile, "-")) {
	if (stdin_used)
	  printf("\n  Warning: attempt to use stdin twice will fail");
	stdin_used = TRUE;
      }

#ifndef NODNS
      if (dnsq) {
	printf("DNS lookups performed with DNS cache file %s\n", dnsfile);
	if (((filep = fopen(dnsfile, "r")) == NULL) &&
	    !STREQ(dnsfile, "stdin") && !STREQ(dnsfile, "-"))
	  printf("  Warning: cannot open that file:\n");
	else
	  fclose(filep);
	if (STREQ(dnsfile, "stdin") || STREQ(dnsfile, "-")) {
	  if (stdin_used)
	    printf("\n  Warning: attempt to use stdin twice will fail");
	  stdin_used = TRUE;
	}
	printf("Old DNS lookups will be rechecked if they are more than %d hours old\n", dnsfreshhours);
      }
#endif

      printf("The output file is %s\n", outfile);
      /* Don't check for being able to write as it will destroy the file */

      printf("\nReport order:\n");
      printf("General summary    %s\n", xq?"ON":"OFF");
      for (c = reportorder; *c != '\0'; c++) {
	switch(*c) {
	case 'b':
	  pvgen("Browser summary", bq, bsortby, bminreqstr, bminpagestr,
		bminbytestr, bcols, "browser", "browsers");
	  if (bq)
	    pvalias("Browser summary", boutaliashead);
	  break;
	case 'B':
	  pvgen("Browser report", Bq, Bsortby, Bminreqstr, Bminpagestr,
		Bminbytestr, Bcols, "browser", "browsers");
	  break;
	case 'c':
	  printf("Status code report %s\n", cq?"ON":"OFF");
	  break;
	case 'd':
	  pvtime("Daily summary", dq, dgraph, dunit, dcols, 0);
	  break;
	case 'D':
	  pvtime("Daily report", Dq, Dgraph, Dunit, Dcols, Drows);
	  break;
	case 'e':
	  printf("Error report       %s\n", eq?"ON":"OFF");
	  if (eminreqs == 0)
	    printf("  Printing all possible errors, ");
	  else
	    printf("  Printing all errors with at least %d occurence%s,\n",
		   eminreqs, (eminreqs == 1)?"":"s");
	  printf("  sorted by number of occurrences.");
	  break;
	case 'f':
	  pvgen("Referrer report", fq, fsortby, fminreqstr, fminpagestr,
		fminbytestr, fcols, "referrer", "referrers");
	  if (fq) {
	    pvalias("Referrer report", foutaliashead);
	    pvinout("as linked items", reflinkhead);
	  }
	  break;
	case 'h':
	  pvtime("Hourly summary", hq, hgraph, hunit, hcols, 0);
	  break;
	case 'H':
	  pvtime("Hourly report", Hq, Hgraph, Hunit, Hcols, Hrows);
	  break;
	case 'i':
	  pvgen("Directory report", iq, isortby, iminreqstr, iminpagestr,
		iminbytestr, icols, "directory", "directories");
	  if (iq) {
	    printf("  Printing directories to depth %d.\n", dirlevel);
	    pvalias("Directory report", ioutaliashead);
	  }
	  break;
	case 'm':
	  pvtime("Monthly report", mq, mgraph, munit, mcols, mrows);
	  break;
	case 'o':
	  pvgen("Domain report", oq, osortby, ominreqstr, ominpagestr,
		ominbytestr, ocols, "domain", "domains");
	  if (oq) {
	    printf("  ");
	    whatincluded(stdout, osortby, Ominreqstr, Ominpagestr, Ominbytestr,
			 "requested subdomain", "requested subdomains", ON,
			 'm');
	  }
	  break;
	case 'r':
	  pvgen("Request report", rq, rsortby, rminreqstr, rminpagestr,
		rminbytestr, rcols, "requested file", "requested files");
	  if (rq) {
	    pvinout("in the report", wantreqhead);
	    pvalias("Request report", routaliashead);
	    pvinout("as linked items", linkhead);
	    if (baseurl[0] != '\0')
	      printf("  (links prepended by %s)\n", baseurl);
	  }
	  break;
	case 'S':
	  pvgen("Host report", Sq, Ssortby, Sminreqstr, Sminpagestr,
		Sminbytestr, Scols, "host", "hosts");
	  if (Sq)
	    pvalias("Host report", Soutaliashead);
	  break;
	case 't':
	  pvgen("File type report", tq, tsortby, tminreqstr, tminpagestr,
		tminbytestr, tcols, "extension", "extensions");
	  if (tq)
	    pvalias("File type report", toutaliashead);
	  break;
	case 'W':
	  pvtime("Weekly report", Wq, Wgraph, Wunit, Wcols, Wrows);
	  break;
	}  /* end switch c */
      }    /* end for c */
      

      if (sq == APPROX) {
	printf("\nApproximate hostname count ON\n");
	printf("  Space used for hostname count: ");
	int3printf(stdout, approxhostsize, sepchar, 0);
	printf(" bytes\n");
      }
      else
	printf("\nHostname count     %s\n", (sq == ON)?"ON":"OFF");

      printf("Statistics for last 7 days %s\n", q7?"ON":"OFF");

      printf("Hash sizes are:\n");
      printf("  Requests        %6ld\n", rhashsize);
      printf("  Directories     %6ld\n", ihashsize);
      printf("  File types      %6ld\n", thashsize);
      printf("  Hosts           %6ld\n", Shashsize);
      printf("  Referrers       %6ld\n", fhashsize);
      printf("  Browser summary %6ld\n", bhashsize);
      printf("  Browser report  %6ld\n", Bhashsize);
      printf("  Subdomains      %6ld\n", Ohashsize);
#ifndef NODNS
      if (dnsq)
	printf("  DNS cache       %6ld\n", dnshashsize);
#endif
      
      if (oq) {
	printf("\nRequested subdomains:\n");
	if (subdomshead -> from[0] == '\0')
	  printf("  None\n");
	else for (subdomp = subdomshead; subdomp -> from[0] != '\0';
		  subdomp = subdomp -> next) {
	  if (subdomp -> from[0] == '?')  /* don't want it */
	    ;
	  else if (subdomp -> from[0] == '%')
	    printf("  Numerical subdomains\n");
	  else {
	    printf("  %s", subdomp -> from);
	    if (subdomp -> to[0] != '?')
	      printf(" (%s)", subdomp -> to);
	    printf("\n");
	  }
	}
      }
    
      if (mq || dq || hq || Hq || Dq || Wq) {
	printf("\nThe character used in the graphs will be '%c'\n", markchar);
	printf("The page width is %d\n", pagewidth);
      }

      if (sepchar != '\0')
	printf("The character used as a separator in big numbers will be '%c'\n",
	       sepchar);
      if (repsepchar != '\0')
	printf("The character used as a separator in big numbers within reports will be '%c'\n", repsepchar);
      printf("The character used as a decimal point will be '%c'\n", decpoint);

      if (Wq || Dq || dq) {
	printf("Weeks are taken to begin on ");
	switch(weekbeginson) {
	case (SUNDAY):
	  printf("Sunday.\n");
	  break;
	case (MONDAY):
	  printf("Monday.\n");
	  break;
	case (TUESDAY):
	  printf("Tuesday.\n");
	  break;
	case (WEDNESDAY):
	  printf("Wednesday.\n");
	  break;
	case (THURSDAY):
	  printf("Thursday.\n");
	  break;
	case (FRIDAY):
	  printf("Friday.\n");
	  break;
	case (SATURDAY):
	  printf("Saturday.\n");
	  break;
	}
      }

      printf("The following will be included in the output:\n");

      if (!aq)
	printf("Logo               %s\n",
	       STREQ(logourl, "none")?logourl:"OFF");
      printf("Header file        %s\n",
	     STREQ(headerfile, "none")?"OFF":headerfile);
      if (!STREQ(headerfile, "none")) {
	if (((filep = fopen(headerfile, "r")) == NULL) &&
	    !STREQ(headerfile, "stdin") && !STREQ(headerfile, "-"))
	  printf("  Warning: cannot open that file: will ignore it\n");
	else
	  fclose(filep);
      }
      printf("Footer file        %s\n",
	     STREQ(footerfile, "none")?"OFF":footerfile);
      if (!STREQ(footerfile, "none")) {
	if ((filep = fopen(footerfile, "r")) == NULL &&
	    !STREQ(footerfile, "stdin") && !STREQ(footerfile, "-"))
	  printf("  Warning: cannot open that file: will ignore it\n");
	else
	  fclose(filep);
      }
      printf("Organisation name  \"%s\"\n", hostname);
      if (!aq)
	printf("Name linked to URL %s\n\n", (hosturl[0]=='-')?"OFF":hosturl);
      
      pvinout("as pages", ispagehead);
      pvalias("File", filealiashead);
      pvalias("Host", hostaliashead);
      pvalias("Referrer", refaliashead);
      pvalias("Brower", browaliashead);
      
    }   /* end if aq != CACHE */

    if (filemaskq)
      pvinout("files", wantfilehead);
    if (hostmaskq)
      pvinout("hosts", wanthosthead);
    if (refmaskq && aq != CACHE)
      pvinout("referrers", wantrefhead);
    
    if (fromtime.code > -INFINITY || totime.code < INFINITY) {
      printf("\nExamining only times");
      if (fromtime.code > -INFINITY)
	printf(" from %02d/%s/%d", fromtime.date,
	       enmonthname[fromtime.monthno], fromtime.year);
      if (totime.code < INFINITY)
	printf(" to %02d/%s/%d", totime.date,
	       enmonthname[totime.monthno], totime.year);
      printf("\n");
    }

    printf("\nDebug level is %d\n", debug);
    printf("Warnings are %s\n", warnq?"ON":"OFF");
    if (progressfreq > 0)
      printf("Progress report every %d logfile lines\n", progressfreq);
    printf("\n");

  }  /* end not form */

  exit(OK);

}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.