1 /***             analog 6.0             http://www.analog.cx/             ***/
2 /*** This program is copyright (c) Stephen R. E. Turner 1995 - 2004 except as
3  *** stated otherwise.
4  ***
5  *** This program is free software. You can redistribute it and/or modify it
6  *** under the terms of version 2 of the GNU General Public License, which you
7  *** should have received with it.
8  ***
9  *** This program is distributed in the hope that it will be useful, but
10  *** without any warranty, expressed or implied.   ***/
11 
12 /*** anlghea3.h: third header file ***/
13 
14 /*** The things in this file are not user-definable; user-definable options
15  *** can be found in anlghead.h ***/
16 
17 #ifndef ANLGHEA3_H
18 #define ANLGHEA3_H
19 
20 /*** OS specific things ***/
21 
22 #define VNUMBER "6.0"    /* the version number of this program */
23 
24 #undef VERSION /* If no OS set, compilation will fail by not knowing VERSION */
25 
26 #ifdef __MWERKS__
27 #undef MAC
28 #define MAC        /* So MWERKS compiler automatically switches to Mac */
29 #endif
30 
31 #ifdef __BEOS__
32 #undef MAC
33 #undef BEOS
34 #define BEOS
35 #endif
36 
37 #ifdef _WIN32
38 #ifndef UNIX  /* So as to signal CYGWIN */
39 #undef WIN32
40 #define WIN32
41 #endif
42 #endif
43 
44 #ifdef MAC
45 #define MAC_EVENTS
46 #define NOPIPES
47 /* #define MACDIRENT */   /* No longer needed and POSIX dirent is better */
48 #define NOGLOB
49 #define NOFOLLOW
50 #define NOOPEN
51 #define NOALARM
52 #define LINE_PARSER
53 #define USE_ZLIB
54 #if !TARGET_API_MAC_CARBON
55 #include <MacHeaders.h>
56 #endif
57 #include <sioux.h>
58 #include <siouxglobals.h>
59 #define PATHSEPS ":"
60 #define DIRSEP ':'
61 #define EXTSEP '.'
62 #define VERSION VNUMBER"/Mac"
63 #endif
64 
65 #ifdef DOS
66 #define NODNS
67 #define NOALARM
68 #define NODIRENT
69 #define NOFOLLOW
70 #define PATHSEPS ":\\/"
71 #define DIRSEP '\\'
72 #define EXTSEP '.'
73 #define VERSION VNUMBER"/DOS"
74 #endif
75 
76 #ifdef VMS
77 #define NOPIPES
78 #define NOALARM
79 #define VMSDIRENT
80 #define NOFOLLOW
81 #ifdef __VMS_VER
82 #if (__VMS_VER < 70000000)
83 #define NOGMTIME
84 #endif
85 #endif
86 #define PATHSEPS ":>#]/" /* first four are real VMS, last for Unix emulation */
87 #define DIRSEP '/'
88 #define EXTSEP '.'
89 #include <unixio.h>
90 /* old DEC C (v4.x?) <stat.h> was missing these two defines */
91 #ifndef S_IWUSR
92 #define S_IWUSR 0000200 /* write permission, owner */
93 #endif
94 #ifndef S_IRUSR
95 #define S_IRUSR 0000400 /* read permission, owner */
96 #endif
97 #define cma$tis_errno_get_addr CMA$TIS_ERRNO_GET_ADDR
98 #define FOPENR(s) fopen(s, "r", "shr=upd")
99 #define VERSION VNUMBER"/OpenVMS"
100 #endif
101 
102 #ifdef BEOS
103 #define NOALARM
104 #define NOFOLLOW
105 #define PATHSEPS "/"
106 #define DIRSEP '/'
107 #define EXTSEP '.'
108 #define VERSION VNUMBER"/BeOS"
109 #endif
110 
111 #ifdef OSX
112 #define PATHSEPS "/"
113 #define DIRSEP '/'
114 #define EXTSEP '.'
115 #define VERSION VNUMBER"/OS X"
116 #endif
117 
118 #ifdef UNIX
119 #ifndef OSX
120 #ifndef BEOS
121 #define PATHSEPS "/"
122 #define DIRSEP '/'
123 #define EXTSEP '.'
124 #define VERSION VNUMBER"/Unix"
125 #endif
126 #endif
127 #endif
128 
129 #ifdef WIN32
130 #define popen _popen
131 #define pclose _pclose
132 extern void Win32Init(void);
133 extern void Win32Cleanup(void);
134 #define WIN32DIRENT  /* can comment out if POSIX dirent present, eg Borland */
135 #define NOFOLLOW
136 #define NOALARM
137 #define FOPENR_BINARY
138 #define POPENR_BINARY
139 #define PATHSEPS ":\\/"
140 #define DIRSEP '\\'
141 #define EXTSEP '.'
142 #define VERSION VNUMBER"/Win32"
143 #endif
144 
145 #ifdef OS2
146 #define NOFOLLOW
147 #define NOALARM
148 #define PATHSEPS "\\/"
149 #define DIRSEP '\\'
150 #define EXTSEP '.'
151 #define VERSION VNUMBER"/OS2"
152 #endif
153 
154 #ifdef RISCOS
155 #define NOOPEN
156 #define NOPIPES
157 #define RISCOSDIRENT
158 #define NOFOLLOW
159 #define NOALARM
160 #define PATHSEPS "."
161 #define DIRSEP '.'
162 #define EXTSEP '/'
163 #define VERSION VNUMBER MINORVERSION"/RISCOS"
164 #include <swis.h>
165 #endif
166 
167 #ifdef NEXTSTEP
168 #define NOFOLLOW
169 #define NOALARM
170 #define PATHSEPS "/"
171 #define DIRSEP '/'
172 #define EXTSEP '.'
173 #ifndef S_IWUSR
174 #define S_IWUSR 0000200 /* write permission, owner */
175 #endif
176 #ifndef S_IRUSR
177 #define S_IRUSR 0000400 /* read permission, owner */
178 #endif
179 #define VERSION VNUMBER"/NeXTSTEP"
180 #endif
181 
182 #ifdef MPEIX
183 #define NOFOLLOW
184 #define PATHSEPS "/"
185 #define DIRSEP '/'
186 #define EXTSEP '.'
187 #define VERSION VNUMBER"/iX"
188 #endif
189 
190 #ifdef BS2000
191 #define EBCDIC
192 #define NOALARM
193 #define NOFOLLOW
194 #define PATHSEPS "/"
195 #define DIRSEP '/'
196 #define EXTSEP '.'
197 #define VERSION VNUMBER"/BS2000/OSD"
198 #endif
199 
200 #ifdef OS390
201 #define EBCDIC
202 #define NOALARM
203 #define NOFOLLOW
204 #define PATHSEPS "/"
205 #define DIRSEP '/'
206 #define EXTSEP '.'
207 #define VERSION VNUMBER"/OS390"
208 #endif
209 
210 #ifdef AS400
211 #define EBCDIC
212 #define PATHSEPS "/"
213 #define DIRSEP '/'
214 #define EXTSEP '.'
215 #define ALIGNSIZE (16)
216 #define NOPIPES
217 #define NOALARM
218 #define NOFOLLOW
219 #define FOPENR(s) fopen(s, "r,ccsid=37")
220 #define FOPENW(s) fopen(s, "w,ccsid=37")
221 #define FOPENWB(s) fopen(s, "wb,ccsid=37")
222 #define FOPENA(s) fopen(s, "a,ccsid=37")
223 #define VERSION VNUMBER"/AS400"
224 #endif
225 
226 #if defined(EBCDIC) && !defined(OS390) && !defined(AS400) && !defined(BS2000)
227 /* Seems to be a not-yet-supported platform. */
228 #error Unsupported EBCDIC platform. Please port Analog and contribute your changes back to <analog-author@lists.meer.net>!
229 /* You might also want to have a look at:
230  *   - globals.c  (system dependent EBCDIC translation tables)
231  *   - settings.c (identification string for your OS)
232  *   - Makefile   (extra Define)
233  */
234 #endif
235 
236 /*** ANSI header files ***/
237 
238 #include <stdio.h>
239 #include <stdarg.h>
240 #include <stddef.h>
241 #include <stdlib.h>
242 #include <string.h>
243 #include <ctype.h>
244 #include <limits.h>
245 #include <float.h>
246 #include <time.h>
247 #include <signal.h>
248 #include <errno.h>
249 #ifndef NOGRAPHICS
250 #include <math.h>
251 #endif
252 #ifndef NOALARM
253 #include <setjmp.h>
254 #endif
255 
256 /*** system dependent header files ***/
257 
258 #ifndef LINE_PARSER
259 #include "zlib/zlib.h"
260 #include "unzip/unzip.h"
261 #include "bzip2/bzlib.h"
262 #endif
263 
264 #include "pcre/pcre.h"
265 
266 #include "libgd/gd.h"
267 #include "libgd/gdfontf.h"
268 #include "libgd/gdfonts.h"
269 
270 #ifndef NOFOLLOW
271 #include <unistd.h>
272 #ifndef PATH_MAX
273 #include <sys/param.h>
274 #define PATH_MAX MAXPATHLEN
275 #endif
276 #endif
277 
278 #ifdef WIN32
279 #include <windows.h>
280 #endif
281 
282 #ifdef MAC
283 #ifdef LINE_PARSER
284 #ifndef REAL_STDIO
285 #define fopen(name,mode) mac_fopen((name),(mode))
286 #define fread(ptr,siz,num,file) mac_fread(ptr,siz,num,file)
287 #undef getc
288 #define getc(file) mac_getc(file)
289 #define fclose(file) mac_fclose((file))
290 #undef feof
291 #define feof(file) mac_feof(file)
292 #endif
293 extern FILE *mac_fopen(const char *name,const char *mode);
294 extern size_t mac_fread(void *ptr, size_t size, size_t num, FILE *file);
295 extern int mac_getc(FILE *file);
296 extern int mac_fclose(FILE *file);
297 extern int mac_feof(FILE *file);
298 #endif
299 #ifndef REAL_ALLOC
300 #define malloc(size) mac_malloc((size))
301 #define calloc(num,size) mac_calloc((num),(size))
302 #define realloc(ptr,size) mac_realloc((ptr),(size))
303 #define free(ptr) mac_free((ptr))
304 #endif
305 extern void *mac_malloc(size_t size);
306 extern void *mac_calloc(size_t num, size_t size);
307 extern void *mac_realloc(void *ptr, size_t size);
308 extern void mac_free(void *ptr);
309 #endif
310 
311 #ifdef NEED_FLOATINGPOINT_H
312 #include <floatingpoint.h>
313 #endif
314 
315 #ifndef NOOPEN
316 #include <sys/types.h>
317 #include <sys/stat.h>
318 #include <fcntl.h>
319 #ifdef WIN32
320 #include <io.h>
321 #define OPEN_MODE (S_IREAD | S_IWRITE)
322 #else
323 #define OPEN_MODE (S_IRUSR | S_IWUSR)
324 /* Most systems will accept the above too, but this is POSIXly correct. */
325 #endif
326 #endif
327 
328 /* I assume the header files are well enough behaved that we can include them
329    twice without harm, so that we can just do !NOSTAT and !NODIRENT indep. */
330 /* See init2.c for an explanation of the DIRENT #define logic */
331 #ifndef NODIRENT
332 #ifndef VMSDIRENT
333 #ifndef MACDIRENT
334 #ifndef WIN32DIRENT
335 #ifndef RISCOSDIRENT
336 #ifndef NOGLOB
337 #include <glob.h>            /* POSIX.2 glob */
338 #else
339 #ifdef MAC
340 #include <stat.h>            /* Mac POSIX dirent */
341 #include <dirent.h>
342 #else
343 #include <sys/types.h>       /* Normal POSIX dirent */
344 #include <dirent.h>
345 #include <sys/stat.h>
346 #endif  /* MAC */
347 #endif  /* NOGLOB */
348 #endif  /* RISCOSDIRENT */
349 #else
350 #include <io.h>              /* Win32 dirent */
351 #include <sys/types.h>
352 #include <sys/stat.h>
353 #endif  /* WIN3DIRENT */
354 #else
355 #include "macdir.h"          /* Old Mac dirent (no longer used) */
356 #define NOGLOB
357 #endif  /* MACDIRENT */
358 #else
359 #define VMS_FSPEC_MAX 256    /* VMS dirent */
360 #include <descrip.h>
361 #endif  /* VMSDIRENT */
362 #endif  /* NODIRENT */
363 
364 #ifndef NODNS
365 #ifdef MAC
366 #if !TARGET_API_MAC_CARBON
367 #include <Gestalt.h>         /* Mac DNS */
368 #include <MacTCP.h>
369 #include <OpenTransport.h>
370 #include <OpenTptInternet.h>
371 #include <AddressXlation.h>
372 #endif
373 #else                        /* Win32 and normal DNS */
374 #ifdef HAVE_ADDR_T   /* define in Makefile if in_addr_t != unsigned long */
375 #define IN_ADDR_T in_addr_t
376 #else
377 typedef unsigned long IN_ADDR_T;
378 #endif
379 #ifdef WIN32    /* Win32 DNS: NB windows.h above includes winsock.h */
380 #define INET_ADDR_ERR ((IN_ADDR_T)(INADDR_NONE))
381 #else
382 #ifdef RISCOS
383 #include <sys/types.h>
384 #endif
385 #include <sys/socket.h>      /* Normal DNS */
386 #include <netinet/in.h>
387 #include <netdb.h>
388 #ifndef BEOS
389 #include <arpa/inet.h>
390 #else
391 #ifdef BONE_VERSION
392 #include <arpa/inet.h>
393 #endif
394 #endif  /* BEOS */
395 #define INET_ADDR_ERR ((IN_ADDR_T)(-1))
396 #endif  /* !WIN32 */
397 #endif  /* !MAC */
398 #ifndef NOALARM              /* All DNS */
399 #include <unistd.h>
400 #endif
401 #ifndef SIGALRM
402 #define NOALARM
403 #endif
404 #endif  /* !NODNS */
405 
406 #ifdef NODNS
407 #define NOALARM
408 #endif
409 #ifndef SIGALRM
410 #define NOALARM
411 #endif
412 #ifndef NOALARM
413 #ifdef USE_PLAIN_SETJMP
414 #define SETJMP setjmp
415 #define LONGJMP longjmp
416 #define JMP_BUF jmp_buf
417 #else
418 #define SETJMP(b) sigsetjmp((b), 1)
419 #define LONGJMP siglongjmp
420 #define JMP_BUF sigjmp_buf
421 #endif
422 #endif
423 
424 /*** User-definable header file ***/
425 
426 #include "anlghead.h"
427 
428 /*** definitions ***/
429 
430 #undef TRUE
431 #define TRUE (1)
432 #undef FALSE
433 #define FALSE (0)
434 #undef OK
435 #define OK (0)
436 #undef ERR
437 #define ERR (-1)
438 #undef UNSET
439 #define UNSET (-1)
440 #ifndef EXIT_SUCCESS
441 #define EXIT_SUCCESS (0)   /* ANSI, but some broken implementations lack it. */
442 #endif
443 #ifndef EXIT_FAILURE
444 #define EXIT_FAILURE (1)
445 #endif
446 #define EXIT_SIGNAL ((EXIT_FAILURE) + 1)
447 #ifdef WIN32
448 #define ERRBUFMODE (_IONBF)  /* on Windows, _IOLBF causes full buffering */
449 #else
450 #define ERRBUFMODE (_IOLBF)
451 #endif
452 #define FEW (2)  /* used for GOTOS and REPORTSPAN */
453 #define EXCLUDED (2)  /* in my_sort() */
454 #define NEWLOGFMT (2)
455 #define BADLOGFMT (3)
456 #define CONTINUATION (-1)  /* used in warn() in utils.c */
457 #define IPADDR_INC (3)   /* next six used in (struct include).type */
458 #define REGEX_INC (2) /* see also IS_REGEXT(), IS_IPADDRT(), IS_INC() below */
459 #define NORMAL_INC (1)
460 #define NORMAL_EXC (-1)
461 #define REGEX_EXC (-2)
462 #define IPADDR_EXC (-3)
463 #define BLOCK_EPSILON (30)
464 #define MIN_SC (100)   /* see parsescode() in input.c */
465 #define SC_NUMBER (600)
466 #define IGNORE_CODE (1000)
467 #define EPSILON (1e-8)
468 #define MINS_IN_WEEK (10080)
469 #define HASHSIZE (8)      /* initial size of hash table; a power of 2 */
470 #define TREEHASHSIZE (3)  /* a power of 2 plus 1 */
471 #define SIZEBINS (11)     /* in sizescore() */
472 #define ENGMONTHLEN (3)   /* length of longest of engmonths in globals.c */
473 #define ENGSHORTDAYLEN (3)/* length of longest of engshortdays in globals.c */
474 #define ITEMFNS_NUMBER ((ITEM_NUMBER) + 2) /* in inpfns[] in globals.c */
475 #define ANALOGURL "http://www.analog.cx/"
476 #define FIRST_TIME (0)
477 #define LAST_TIME (ULONG_MAX)
478 #define LAST_DATE ((ULONG_MAX) / 1440)
479 #define WHITESPACE ((char)(-1))
480 #define DOMLEVEL_NUMBER (677)  /* 26^2 + 1 */
481 #define PMATCH_SIZE (30)  /* This allows PCRE to capture 9 subexpressions */
482 /* Amount of stuff recorded by cache files: see cache_records in globals.c */
483 #define V34_DATA_NUMBER (7)
484 #define V5_DATA_NUMBER (10)
485 #ifdef MAC_EVENTS
486 #define MAC_IDLE_FREQ (200)
487 #endif
488 
489 /* Special codes for certain reports. We collect them here just to avoid
490    changing several instances if they change (although see Pnenxtname() too).
491    *
492    It would be nice to let the user use localised versions of these in e.g.
493    *EXCLUDE commands, but that doesn't scale to the case of reports in two
494    languages in one pass, because not all trees are built as late as output
495    time. */
496 #define LNGSTR_UNRESOLVED "[unresolved numerical addresses]"
497 #define LNGSTR_NODOMAIN "[domain not given]"
498 #define LNGSTR_UNKDOMAIN "[unknown domain]"
499 #define LNGSTR_ROOTDIR "[root directory]"
500 #define LNGSTR_NODIR "[no directory]"
501 #define LNGSTR_NOEXT "[no extension]"
502 #define LNGSTR_BRKDIRS "[directories]"
503 #define LNGSTR_UNKWIN "Unknown Windows"
504 #define LNGSTR_UNKUX "Other Unix"
505 #define LNGSTR_ROBOTS "Robots"
506 #define LNGSTR_UNKOS "OS unknown"
507 
508 /*** logfile line types ***/
509 
510 #define LOG_COMMON1 "%S %j %u [%d/%M/%Y:%h:%n:%j] \"%j%w%r%wHTTP%j\" %c %b"
511 #define LOG_COMMON2 "%S %j %u [%d/%M/%Y:%h:%n:%j] \"%j%w%r\" %c %b"
512 #define LOG_COMMON3 "%S %j %u [%d/%M/%Y:%h:%n:%j] \"%r\" %c %b"
513 #define LOG_MS_COMMON1 "%S %j %u [%d/%M/%Y:%h:%n:%j] \"%j%w%r%w\"HTTP%j\" %c %b"
514 #define LOG_COMBINED1 \
515   "%S %j %u [%d/%M/%Y:%h:%n:%j] \"%j%w%r%wHTTP%j\" %c %b \"%f\" \"%B\""
516 #define LOG_COMBINED2 \
517   "%S %j %u [%d/%M/%Y:%h:%n:%j] \"%j%w%r\" %c %b \"%f\" \"%B\""
518 #define LOG_COMBINED3 \
519   "%S %j %u [%d/%M/%Y:%h:%n:%j] \"%r\" %c %b \"%f\" \"%B\""
520 #define LOG_MS_INT1 "%S, %u, %d/%m/%Z, %h:%n:%j, W3SVC%j, %j, %v, %T, %j, %b, %c, %j, %j, %r, %q,"
521 #define LOG_MS_INT2 "%*S, %*u, %d/%m/%Z, %h:%n:%j, %j"
522 #define LOG_MS_NA1 "%S, %u, %m/%d/%Z, %h:%n:%j, W3SVC%j, %j, %v, %T, %j, %b, %c, %j, %j, %r, %q,"
523 #define LOG_MS_NA2 "%*S, %*u, %m/%d/%Z, %h:%n:%j, %j"
524 #define LOG_WEBSTAR1 "!!LOG_FORMAT%x2"
525 #define LOG_WEBSTAR2 "!!%j"
526 #define LOG_EXTENDED1 "#Fields:%x3"
527 #define LOG_EXTENDED2 "#%j"
528 #define LOG_MS_EXTENDED1 "#Fields:%x5"
529 #define LOG_WEBSTAR_EXTENDED1 "#Fields:%x6"
530 #define LOG_WEBSITE_NA \
531   "%m/%d/%y %h:%n:%j\t%S\t%v\t%j\t%u\t%j\t%r\t%f\t%j\t%B\t%c\t%b\t%T"
532 #define LOG_WEBSITE_INT \
533   "%d/%m/%y %h:%n:%j\t%S\t%v\t%j\t%u\t%j\t%r\t%f\t%j\t%B\t%c\t%b\t%T"
534 #define LOG_MACHTTP "%m/%d/%y\t%h:%n:%j \t%C%w%S\t%r\t%b"
535 #define LOG_NETSCAPE "format=%x4"
536 #define LOG_REFERRER1 "[%d/%M/%Y:%h:%n:%j] %F -> %*r"
537 #define LOG_REFERRER2 "%F -> %*r"
538 #define LOG_BROWSER "[%d/%M/%Y:%h:%n:%j] %B"
539 
540 /*** enums ***/
541 
542 /* Types of item and other inputs: must have ITEMs in process_data() order:
543    code, bytes, proctime, unixtime, am, date in some order (these are
544    INPUT_NUMBER, not to be confused with INP_NUMBER): then rest in some order.
545    NB I don't know if changing process_data() order would have side-effects. */
546 /* See also item_type in globals.c */
547 enum {ITEM_VHOST, ITEM_FILE, ITEM_USER, ITEM_REFERRER, ITEM_BROWSER, ITEM_HOST,
548       INP_CODE, INP_BYTES, INP_PROCTIME, INP_UNIXTIME, INP_AM, INP_DATE,
549       INP_YEAR, INP_MONTH, INP_HOUR, INP_MIN, INP_QUERY, INP_IP, INP_NUMBER};
550 #define ITEM_NUMBER (INP_CODE)
551 #define INPUT_NUMBER (INP_YEAR)  /* NB There is INP_NUMBER and INPUT_NUMBER */
552 
553 /* Types of report. They must be in the following order: date Reports;
554    date Summaries; GENSUM; general reports; dervreps; arrayreps.
555    (The order is insignificant within each section.) */
556 /* See also repcodes, anchorname and repname in globals.c */
557 /* Also report descriptions files have these entries in this order */
558 enum {REP_YEAR, REP_QUARTERLY, REP_MONTH, REP_WEEK, REP_DAYREP, REP_HOURREP,
559       REP_QUARTERREP, REP_FIVEREP, REP_DAYSUM, REP_HOURSUM, REP_WEEKHOUR,
560       REP_QUARTERSUM, REP_FIVESUM, REP_GENSUM, REP_REQ, REP_REDIR, REP_FAIL,
561       REP_TYPE, REP_DIR, REP_HOST, REP_REDIRHOST, REP_FAILHOST, REP_DOM,
562       REP_REF, REP_REFSITE, REP_REDIRREF, REP_FAILREF, REP_BROWREP, REP_VHOST,
563       REP_REDIRVHOST, REP_FAILVHOST, REP_USER, REP_REDIRUSER, REP_FAILUSER,
564       REP_ORG, REP_SEARCHREP, REP_SEARCHSUM, REP_INTSEARCHREP,
565       REP_INTSEARCHSUM, REP_BROWSUM, REP_OS, REP_SIZE, REP_CODE, REP_PROCTIME,
566       REP_NUMBER};
567 #define DATEREPORTS_NUMBER (REP_DAYSUM)   /* just the eight "Reports" */
568 #define DATEREP_NUMBER (REP_GENSUM)   /* including the five "Summaries" too */
569 #define FIRST_GENREP (REP_GENSUM + 1)
570 #define GENREP_NUMBER (REP_NUMBER - FIRST_GENREP)
571 #define FIRST_DERVREP (REP_SEARCHREP)
572 #define DERVREP_NUMBER (6)
573 #define FIRST_ARRAYREP (REP_SIZE)
574 #define ARRAYREP_NUMBER (3)
575 #define LAST_NORMALREP (REP_OS)
576 
577 /* Types of logfile line. Order insignificant. */
578 enum {SUCCESS, FAILURE, REDIRECT, INFO, UNWANTED};
579 #define OUTCOME_NUMBER (INFO)  /* only first 3 needed for datacols[] */
580 
581 /* Counts then dates collected about each item, and then other floor/sort
582    criteria: order otherwise insignificant. See also methodname in globals.c
583    and cache_records in cache.c. */
584 enum {REQUESTS, REQUESTS7, PAGES, PAGES7, REDIR, REDIR7, FAIL, FAIL7, SUCCDATE,
585       REDIRDATE, FAILDATE, SUCCFIRSTD, REDIRFIRSTD, FAILFIRSTD, BYTES, BYTES7,
586       ALPHABETICAL, RANDOM, METHOD_NUMBER};
587 #define COUNT_NUMBER (SUCCDATE)
588 #define DATESORT (SUCCDATE)
589 #define FIRSTDATE (SUCCFIRSTD)
590 #define DATA_NUMBER (BYTES)
591 #define CHART_NONE (SUCCDATE)
592 #define CHART_SORTBY (CHART_NONE + 1)
593 
594 /* abbreviated version ignoring HTTP status code */
595 enum {REQUESTS2, REQUESTS72, PAGES2, PAGES72, DATE2, FIRSTD2, DATA2_NUMBER,
596       DATACOLS_NUMBER};
597 
598 /* Type of logfile by compression */
599 enum {LF_NOTOPENED, LF_NORMAL, LF_PIPE, LF_GZIP, LF_ZIP, LF_ZIPMEMBER, LF_BZ2};
600 
601 /* Data collected about total requests etc. in each logfile */
602 enum {LOGDATA_UNWANTED, LOGDATA_UNKNOWN, LOGDATA_UNKNOWN7, LOGDATA_INFO,
603       LOGDATA_INFO7, LOGDATA_SUCC, LOGDATA_SUCC7, LOGDATA_PAGES,
604       LOGDATA_PAGES7, LOGDATA_REDIR, LOGDATA_REDIR7, LOGDATA_FAIL,
605       LOGDATA_FAIL7, LOGDATA_CORRUPT, LOGDATA_NUMBER};
606 
607 /* Poss. columns: COL_TITLE must be first; see also colcodes[] in globals.c */
608 enum {COL_TITLE, COL_REQS, COL_REQS7, COL_PAGES, COL_PAGES7, COL_BYTES,
609       COL_BYTES7, COL_PREQS, COL_PREQS7, COL_PPAGES, COL_PPAGES7, COL_PBYTES,
610       COL_PBYTES7, COL_DATE, COL_TIME, COL_FIRSTD, COL_FIRSTT, COL_INDEX,
611       COL_NUMBER};
612 
613 /* Levels of DNS lookup. Keep in order. */
614 enum {DNS_NONE, DNS_READ, DNS_LOOKUP, DNS_WRITE};
615 
616 /* Output types: start with XHTML then PLAIN */
617 enum {XHTML, PLAIN, ASCII, HTML, LATEX, COMPUTER, XML, OUT_NONE};
618 
619 /* days of the week */
620 enum {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY};
621 
622 /* languages; see also country in globals.c */
623 enum {ARMENIAN, BASQUE, /*BOSNIAN,*/ BULGARIAN, BULGARIAN_MIK, CATALAN,
624       SIMP_CHINESE, TRAD_CHINESE, /*CROATIAN,*/ CZECH, CZECH_1250, DANISH,
625       DUTCH, ENGLISH, US_ENGLISH, FINNISH, FRENCH, GERMAN, /*GREEK,*/
626       HUNGARIAN, /*ICELANDIC,*/ INDONESIAN, ITALIAN, JAPANESE_EUC,
627       JAPANESE_JIS,
628       JAPANESE_SJIS, JAPANESE_UTF, KOREAN, LATVIAN, /*LITHUANIAN,*/
629       NORWEGIAN, NYNORSK, POLISH, PORTUGUESE, BR_PORTUGUESE, /*ROMANIAN,*/
630       RUSSIAN, RUSSIAN_1251, SERBIAN, SLOVAK, SLOVAK_1250, SLOVENE,
631       SLOVENE_1250, SPANISH, SWEDISH, SWEDISH_ALT, TURKISH, UKRAINIAN};
632 #define OLDLANG (-2)
633 
634 /* source of data passed to htmlputs(): see comments there. These represent
635    roughly increasing levels of security. */
636 enum {AS_IS, TRUSTED, FROM_CFG, UNTRUSTED, IN_HREF};
637 
638 /* lngstrs; charset_ must be first */
639 enum {charset_, weekbeg_, year_, quarteryr_, month_, day_, days_, hr_, minute_,
640       minutes_, second_, seconds_, byte_, bytes_, xbytes_, request_, requests_,
641       date_, datetime_, time_, firstdate_, firsttime_, lastdate_, lasttime_,
642       file_, files_, host_, hosts_, vhost_, vhosts_, dir_, dirs_, dom_, doms_,
643       org_, orgs_, ext_, exts_, url_, urls_, browser_, browsers_, os_, oss_,
644       size_, search_, searches_, site_, sites_, user_, users_, code_, codes_,
645       webstatsfor_, kilo_, mega_, giga_, tera_, peta_, exa_, zeta_, yotta_,
646       kiloabbr_, megaabbr_, gigaabbr_, teraabbr_, petaabbr_, exaabbr_,
647       zetaabbr_, yottaabbr_, filesize0_, filesize1_, filesize2_, filesize3_,
648       filesize4_, filesize5_, filesize6_, filesize7_, filesize8_, filesize9_,
649       filesize10_, gensum_, yearrep_, busyyear_, quarterlyrep_,
650       busyquarteryr_, monthrep_, busymonth_, weekrep_, busyweek_, daysum_,
651       dayrep_, busyday_, hourrep_, hoursum_, weekhoursum_, busyhour_,
652       quarterrep_, quartersum_, busyquarterhr_, fiverep_, fivesum_, busyfive_,
653       hostrep_, hostgs_, hostgp_, hostgen_, redirhostrep_, redirhostgs_,
654       redirhostgp_, redirhostgen_, failhostrep_, failhostgs_, failhostgp_,
655       failhostgen_, dirrep_, dirgs_, dirgp_, dirgen_, typerep_, extgs_, extgp_,
656       extgen_, reqrep_, filegs_, filegp_, filegen_, redirrep_, redirgs_,
657       redirgp_, redirgen_, failrep_, failgs_, failgp_, failgen_, refrep_,
658       refgs_, refgp_, refgen_, refsiterep_, refsitegs_, refsitegp_,
659       refsitegen_, redirrefrep_, redirrefgs_, redirrefgp_, redirrefgen_,
660       failrefrep_, failrefgs_, failrefgp_, failrefgen_, searchrep_,
661       searchrepgs_, searchrepgp_, searchrepgen_, searchsum_, searchsumgs_,
662       searchsumgp_, searchsumgen_, intsearchrep_, intsearchrepgs_,
663       intsearchrepgp_, intsearchrepgen_, intsearchsum_, intsearchsumgs_,
664       intsearchsumgp_, intsearchsumgen_, vhostrep_, vhostgs_, vhostgp_,
665       vhostgen_, redirvhostrep_, redirvhostgs_, redirvhostgp_, redirvhostgen_,
666       failvhostrep_, failvhostgs_, failvhostgp_, failvhostgen_, userrep_,
667       usergs_, usergp_, usergen_, rediruserrep_, redirusergs_, redirusergp_,
668       redirusergen_, failuserrep_, failusergs_, failusergp_, failusergen_,
669       browsum_, browgs_, browgp_, browgen_, browrep_, browrepgs_, browrepgp_,
670       browrepgen_, osrep_, osgs_, osgp_, osgen_, domrep_, domgs_, domgp_,
671       domgen_, orgrep_, orggs_, orggp_, orggen_, statrep_, codegs_, codegp_,
672       codegen_, proctimerep_, sizerep_, credit_, runtime_, lessone_, eachunit_,
673       represents_, partof_, pagereq_, pagereqs_, notlistedm_, notlistedf_,
674       notlistedn_, otherm_, otherf_, othern_, progstart_, reqstart_, to_,
675       succreqs_, avereqs_, totpages_, avepages_, totunknown_, totfails_,
676       totredirs_, inforeqs_, distfiles_, disthosts_, corrupt_, unwanted_,
677       totdata_, avedata_, brackets_, sevendaysto_, lastsevendays_, goto_, top_,
678       unresolved_, nodomain_, unkdomain_, rootdir_, nodir_, noext_, brkdirs_,
679       unkwin_, unkux_, robots_, unkos_, nreqs_, nreqs7_, preqs_,
680       preqs7_, npgs_, npgs7_, ppgs_, ppgs7_, nbytes_, nxbytes_, nbytes7_,
681       nxbytes7_, pbytes_, pbytes7_, index_, firstsm_, firstsf_, firstsn_,
682       firstdsm_, firstdsf_, firstdsn_, allsm_, allsf_, allsn_, floorby_,
683       atleast_, request7_, requests7_, pagereq7_, pagereqs7_, redirreq_,
684       redirreqs_, redirreq7_, redirreqs7_, failreq_, failreqs_, failreq7_,
685       failreqs7_, ptraffic_, ptraffic7_, pmtraffic_, pmtraffic7_, bytetraffic_,
686       bytestraffic_, xbytestraffic_, bytetraffic7_, bytestraffic7_,
687       xbytestraffic7_, sincedate_, sinceredirdate_, sincefaildate_,
688       sincefirstd_, sinceredirfirstd_, sincefailfirstd_, sortedm_, sortedf_,
689       sortedn_, repspan_, chartby_, traffic_, traffic7_,
690       prequests_, prequests7_, pmrequests_, pmrequests7_, nrequests_,
691       nrequests7_, ppages_, ppages7_, pmpages_, pmpages7_, npages_, npages7_,
692       predirs_, predirs7_, pmredirs_, pmredirs7_, nredirs_, nredirs7_, pfails_,
693       pfails7_, pmfails_, pmfails7_, nfails_, nfails7_, succdate_, redirdate_,
694       faildate_, succfirstd_, redirfirstd_, failfirstd_, alphasortm_,
695       alphasortf_, alphasortn_, numsortm_, numsortf_, numsortn_, unsortedm_,
696       unsortedf_, unsortedn_, sepchar_, decpoint_, colon_, am_, pm_, datefmt1_,
697       datefmt2_, dayrepfmt_, daysumfmt_, hourrepfmt_, hoursumfmt_,
698       weekhoursumfmt_, quarterrepfmt_, quartersumfmt_, weekfmt_, monthfmt_,
699       quarterlyfmt_, yearfmt_, genrepdate_, genreptime_,
700       whatincfmt_, code100_, code101_, code199_, code200_, code201_, code202_,
701       code203_, code204_, code205_, code206_, code299_, code300_, code301_,
702       code302_, code303_, code304_, code_305, code306_, code307_, code399_,
703       code400_, code401_, code402_, code403_, code404_, code405_, code406_,
704       code407_, code408_, code409_, code410_, code411_, code412_, code413_,
705       code414_, code415_, code416_, code417_, code499_, code500_, code501_,
706       code502_, code503_, code504_, code505_, code506_, code599_, code999_,
707       LNGSTR_NUMBER};
708 #define byteprefix_ (kilo_ - 1)
709 #define byteprefixabbr_ (kiloabbr_ - 1)
710 
711 /* return codes from strtoinfmt() */
712 /* see also configlogfmt() in init2.c */
713 enum {FMT_OK, FMT_NOPC, FMT_DUP, FMT_BADCHAR, FMT_NOTERM, FMT_BADBUILTIN,
714       FMT_BADPC, FMT_PARTTIME, FMT_QBUTNOR};
715 
716 /*** typedefs ***/
717 
718 typedef unsigned char logical;
719 typedef signed char choice;
720 typedef unsigned int datecode_t;
721 typedef unsigned long timecode_t;
722 
723 /*** typedef function pointers ***/
724 
725 struct hashindex;
726 struct logfile;
727 
728 typedef void (*cutfnp)(char **, char **, char *, logical);
729 typedef void (*dcutfnp)(char **, char **, char *, void *);
730 typedef struct hashindex *(*mergefnp)(struct hashindex *, struct hashindex *,
731 				      unsigned long, unsigned long, choice);
732 typedef void (*conffnp)(void *, char *, char *, char *, int);
733 typedef choice (*inputfnp)(struct logfile *lf, void *, char);
734 
735 /*** structs */
736 
737 typedef struct {
738   double bytes, bytes7;
739   unsigned long *data;  /* some are really timecode_t */
740   logical reused;  /* for reused, see newtreedata() in tree.c */
741   choice ispage;
742 } Hashentry;
743 
744 typedef struct hashindex {
745   char *name;
746   Hashentry *own;
747   void *other;
748   struct hashindex *next;
749 } Hashindex;
750 
751 typedef struct aliasto {
752   char *string;
753   choice after;
754   struct aliasto *next;
755 } AliasTo;
756 /* The target of an alias alternates a "string" and possibly a part of the
757    original name indexed by "after" (else after == -1) (see printalias()). */
758 
759 typedef struct alias {
760   char *from;
761   pcre *pattern;
762   AliasTo *to;
763   logical isregex;
764   struct alias *next;
765 } Alias;
766 /* For a normal pattern, nmatch is no. of *'s. For a regular expression, it's
767    -3 * (no. of capturing subexpressions): this is what pcre_exec needs. */
768 
769 typedef struct strpairlist {
770   char *name, *data;
771   struct strpairlist *next;
772 } Strpairlist;
773 
774 typedef struct {
775   char *name;
776   conffnp fn;
777   void *opt;
778 } Configfns;
779 
780 typedef struct {
781   char *name;
782   choice arg;
783 } Choices;
784 
785 typedef struct {
786   char code;
787   choice type;
788   inputfnp fn;
789   void *opt;
790 } Inputfns;
791 
792 typedef struct inputformat {
793   Inputfns *inpfns;
794   char sep;
795   struct inputformat *next;
796 } Inputformat;
797 
798 typedef struct inputformatlist {
799   Inputformat *form;
800   choice count[INPUT_NUMBER]; /* 0 = not present, 1 = starred, 2 = unstarred */
801   logical used;
802   struct inputformatlist *next;
803 } Inputformatlist;
804 
805 typedef struct logfile {
806   char *name;
807   void *file;
808   void *file2;  /* bzip2 needs the (FILE *) and the (BZFILE *) */
809   choice type;
810   Inputformatlist *format;
811   timecode_t from, to;
812   unsigned long data[LOGDATA_NUMBER];
813   double bytes, bytes7;
814   char *prefix;
815   size_t prefixlen;
816   int pvpos, tz;
817   struct logfile *next;
818 } Logfile;
819 
820 typedef struct mmlist {
821   void *pos;
822   struct mmlist *next;
823 } Mmlist;
824 
825 typedef struct {
826   void *block_end, *curr_pos, *next_pos;
827   Mmlist *first, *last;
828   unsigned short alignment;
829 } Memman;
830 
831 typedef struct daysdata {
832   unsigned long *reqs, *pages;
833   double *bytes;
834   struct daysdata *prev, *next;
835 } Daysdata;
836 
837 typedef struct {
838   char *fromstr, *tostr;
839   timecode_t from, to, last7from, last7to, firsttime, lasttime;
840   datecode_t firstdate, lastdate, currdate;
841   /* perhaps bad name: currdate is date of current logfile entry */
842   Daysdata *firstdp, *lastdp, *currdp;
843 } Dateman;
844 
845 typedef struct timerep {
846   unsigned long reqs, pages;
847   double bytes;
848   datecode_t date;
849   unsigned int time;
850   struct timerep *prev, *next;
851 } Timerep;
852 
853 typedef struct {
854   double threshold;
855   unsigned long reqs, reqs7, pages, pages7;
856   double bytes, bytes7;
857   timecode_t firstdate, lastdate;
858 } Arraydata;
859 
860 typedef struct {
861   Hashindex **head;
862   unsigned long size;
863   unsigned long n;
864 } Hashtable;
865 
866 typedef struct {
867   Hashtable *tree;
868   cutfnp cutfn;
869   Memman *space;
870 } Tree;
871 
872 typedef struct {
873   Hashtable *table;
874   dcutfnp cutfn;
875   Memman *space;
876   void *arg;
877 } Derv;
878 
879 typedef struct strlist {
880   char *name;
881   struct strlist *next;
882 } Strlist;
883 
884 typedef struct {
885   char *name;
886   double angle;
887 } Wedge;
888 
889 typedef struct include {
890   char *name;
891   pcre *pattern;
892   unsigned long minaddr, maxaddr;
893   choice type;
894   struct include *next;
895 } Include;
896 
897 typedef struct {
898   double min;
899   char qual;
900   choice floorby;
901 } Floor;
902 
903 typedef struct {
904   choice code;
905   char *file;
906 } Lang;
907 
908 struct outchoices;
909 
910 /* The actual outputters are defined in globals.c */
911 typedef struct {
912   unsigned int (*pagewidth)(struct outchoices *);
913   void (*cgihead)(FILE *, struct outchoices *);
914   void (*stylehead)(FILE *, struct outchoices *);
915   void (*pagetitle)(FILE *, struct outchoices *);
916   void (*timings)(FILE *, struct outchoices *, Dateman *);
917   void (*closehead)(FILE *, struct outchoices *);
918   void (*pagebotstart)(FILE *, struct outchoices *);
919   void (*credit)(FILE *, struct outchoices *);
920   void (*runtime)(FILE *, struct outchoices *, long);
921   void (*pagefoot)(FILE *, struct outchoices *);
922   void (*stylefoot)(FILE *, struct outchoices *);
923   void (*reporttitle)(FILE *, struct outchoices *, choice);
924   void (*reportfooter)(FILE *, struct outchoices *, choice);
925   void (*reportdesc)(FILE *, struct outchoices *, choice);
926   void (*reportspan)(FILE *, struct outchoices *, choice, timecode_t,
927 		     timecode_t);
928   void (*gensumhead)(FILE *, struct outchoices *);
929   void (*gensumfoot)(FILE *, struct outchoices *);
930   void (*gensumline)(FILE *, struct outchoices *, int, unsigned long,
931 		     unsigned long, logical);
932   void (*gensumlineb)(FILE *, struct outchoices *, int, double, double,
933 		      logical);
934   void (*lastseven)(FILE *, struct outchoices *, timecode_t);
935   void (*prestart)(FILE *, struct outchoices *);
936   void (*preend)(FILE *, struct outchoices *);
937   void (*hrule)(FILE *, struct outchoices *);
938   char *(*endash)(void);
939   void (*putch)(FILE *, char);
940   size_t (*strlength)(const char *);
941   logical (*allowmonth)(void);
942   void (*calcwidths)(struct outchoices *, choice, unsigned int [],
943 		     unsigned int *, unsigned int *, double *, unsigned long,
944 		     unsigned long, unsigned long, unsigned long, double,
945 		     double, unsigned long);
946   void (*declareunit)(FILE *, struct outchoices *, char, double, unsigned int);
947   void (*colheadstart)(FILE *, struct outchoices *, choice);
948   void (*colheadcol)(FILE *, struct outchoices *, choice, choice, unsigned int,
949 		     char *, logical);
950   void (*colheadend)(FILE *, struct outchoices *, choice);
951   void (*colheadustart)(FILE *, struct outchoices *, choice);
952   void (*colheadunderline)(FILE *, struct outchoices *, choice,
953 			   choice, unsigned int, char *);
954   void (*colheaduend)(FILE *, struct outchoices *, choice);
955   void (*rowstart)(FILE *, struct outchoices *, choice, choice *, int, char *,
956 		   char *, char *);
957   void (*levelcell)(FILE *, struct outchoices *, choice, int);
958   void (*namecell)(FILE *, struct outchoices *, choice, char *, choice,
959 		   unsigned int, logical, logical, logical, Alias *, Include *,
960 		   logical, unsigned int, char *);
961   void (*ulcell)(FILE *, struct outchoices *, choice, choice, unsigned long,
962 		 unsigned int);
963   void (*strcell)(FILE *, struct outchoices *, choice, choice, char *,
964 		  unsigned int);
965   void (*bytescell)(FILE *, struct outchoices *, choice, choice, double,
966 		    double, unsigned int);
967   void (*pccell)(FILE *, struct outchoices *, choice, choice, double, double,
968 		 unsigned int);
969   void (*indexcell)(FILE *, struct outchoices *, choice, choice, long,
970 		    unsigned int);
971   void (*rowend)(FILE *, struct outchoices *, choice);
972   void (*blankline)(FILE *, struct outchoices *, choice *);
973   void (*barchart)(FILE *, struct outchoices *, int, char);
974   void (*busyprintf)(FILE *, struct outchoices *, choice, char *,
975 		     unsigned long, unsigned long, double, datecode_t,
976 		     unsigned int, unsigned int, datecode_t, unsigned int,
977 		     unsigned int, char);
978   void (*notlistedstr)(FILE *, struct outchoices *, choice, unsigned long);
979   void (*whatincluded)(FILE *, struct outchoices *, choice, unsigned long,
980 		       Dateman *);
981   void (*whatinchead)(FILE *, struct outchoices *);
982   void (*whatincfoot)(FILE *, struct outchoices *);
983   void (*whatincprintstr)(FILE *, struct outchoices *, char *);
984   void (*printdouble)(FILE *, struct outchoices *, double);
985   void (*includefile)(FILE *, struct outchoices *, char *, char);
986   unsigned int (*riscosfiletype)(void);
987 } Outputter;
988 
989 typedef struct outchoices {
990   Outputter *outputter;
991   char *outfile, *cacheoutfile;
992   char *domainsfile, *descfile, *headerfile, *footerfile;
993   choice outstyle, gotos;
994   logical descriptions, multibyte, html, repspan, pdflatex;
995   unsigned int rsthresh;
996   choice reporder[REP_NUMBER + 1];
997   logical repq[REP_NUMBER], last7, runtime;
998   choice cols[REP_NUMBER][COL_NUMBER];
999   unsigned int rows[DATEREPORTS_NUMBER];
1000   char graph[DATEREP_NUMBER];
1001   logical back[DATEREPORTS_NUMBER];
1002   choice chartby[GENREP_NUMBER];
1003   logical jpegcharts, pngimages;
1004   choice sortby[GENREP_NUMBER], subsortby[GENREP_NUMBER];
1005   Floor floor[GENREP_NUMBER], subfloor[GENREP_NUMBER];
1006   Lang lang;
1007   char *dayname[7], *monthname[12], **lngstr, *descstr[REP_NUMBER];
1008   size_t daylen, plaindaylen, monthlen, plainmonthlen, ampmlen, plainampmlen;
1009   char *hostname, *hosturl, *logo, *logourl, *imagedir;
1010   char *stylesheet,*cssprefix, *chartdir, *localchartdir;
1011   char markchar;
1012   logical norobots;
1013   logical rawbytes;
1014   unsigned int bytesdp;
1015   choice weekbeginson;
1016   unsigned int plainpagewidth, htmlpagewidth, latexpagewidth;
1017   unsigned int mingraphwidth;
1018   char sepchar, repsepchar, decpt, barstyle;
1019   char *compsep, *gensumlines;
1020   Tree *tree[GENREP_NUMBER];
1021   Strlist *suborgs;
1022   Derv *derv[DERVREP_NUMBER];
1023   choice *alltrees, *alldervs;
1024   Include *wanthead[GENREP_NUMBER];
1025   Alias *aliashead[GENREP_NUMBER];
1026   Include *link[GENREP_NUMBER];
1027   Strlist *expandhead[GENREP_NUMBER];
1028   char *baseurl;
1029   choice searchconv;
1030   unsigned char convfloor;
1031 } Outchoices;
1032 
1033 typedef struct {
1034   Logfile *logfile[2];  /* [0] are logfiles, [1] are cache files */
1035   unsigned long data[LOGDATA_NUMBER];
1036   double bytes, bytes7;
1037   char *dirsuffix;
1038   unsigned int dirsufflength;
1039   choice lowmem[ITEM_NUMBER];
1040   logical case_insensitive, usercase_insensitive;
1041   unsigned int granularity;
1042 } Miscoptions;
1043 
1044 typedef struct {
1045   Hashtable *hash[ITEM_NUMBER];
1046   Arraydata *arraydata[ARRAYREP_NUMBER];
1047   choice datacols[ITEM_NUMBER][OUTCOME_NUMBER][DATACOLS_NUMBER][2];
1048   /* given item type i, outcome j, the kth thing to do is to store data of
1049      data2-type dc[i][j][k][1] in structure's column index dc[i][j][k][0]. */
1050   choice data2cols[ITEM_NUMBER][DATA_NUMBER];
1051   /* item type i, data type j, is stored in this column (or -1 if unwanted) */
1052   unsigned int no_cols[ITEM_NUMBER];
1053   Hashindex **gooditems, **baditems;
1054   Include *wanthead[ITEM_NUMBER], *ispagehead, *argshead, *refargshead;
1055   choice code2type[SC_NUMBER];
1056   logical succ304;
1057   Alias *aliashead[ITEM_NUMBER];
1058   Strpairlist *searchengines, *intsearchengines;
1059   Include *robots;
1060   Dateman dman;
1061   Outchoices outopts;
1062   Miscoptions miscopts;
1063   Strlist *conffilelist;
1064 } Options;
1065 
1066 /*** macros ***/
1067 
1068 #undef MAX
1069 #define MAX(a, b) (((a) > (b))?(a):(b))
1070 #undef MIN
1071 #define MIN(a, b) (((a) < (b))?(a):(b))
1072 /* a whole set of macros to cope with to...() and is...() commands if
1073    char is unsigned. */
1074 #define ISALNUM(c) isalnum((unsigned char)(c))
1075 #define ISALPHA(c) isalpha((unsigned char)(c))
1076 #define ISDIGIT(c) isdigit((unsigned char)(c))
1077 #define ISLOWER(c) islower((unsigned char)(c))
1078 #define ISSPACE(c) isspace((unsigned char)(c))
1079 #define ISUPPER(c) isupper((unsigned char)(c))
1080 #define TOLOWER(c) ((char)tolower((unsigned char)(c)))
1081 #define TOUPPER(c) ((char)toupper((unsigned char)(c)))
1082 #ifdef NEED_STRCMP
1083 #define strcmp my_strcmp
1084 #endif
1085 #ifdef NEED_DIFFTIME
1086 #define difftime(t, s) ((double)((t) - (s)))
1087 #endif
1088 #ifdef NEED_STRTOUL
1089 #define strtoul(a, b, c) ((unsigned long)(strtol(a, b, c)))
1090 /* This is not quite right because of the different ranges of long and
1091    unsigned long, but it's probably OK for our purposes */
1092 #endif
1093 #define STREQ(s, t) (strcmp(s, t) == 0)
1094 #define MATCHES(s, p) (matchq(s, (void *)p, FALSE, NULL))
1095 /* Date conversion functions. See dates.c on the representation of dates. */
1096 #define FEB (1)
1097 #define DEC (11)
1098 #define IS_LEAPYEAR(y) ((y) % 4 == 0) /* This is not Year 2100 compatible but
1099 					 is Year 2000 compatible! */
1100 #define DATE2CODE(y, m, d) (((y) - 1970) * 365 + ((y) - 1968) / 4 + \
1101 		 daysbefore[m] + (d) - (IS_LEAPYEAR(y) && (m) <= FEB))
1102 #define TIMECODE(datecode, hr, min) ((timecode_t)((datecode) * 1440 + (datecode_t)((hr) * 60 + (min))))
1103 #define UXTIME2CODE(t) ((timecode_t)(((t) / 60) + 1440))
1104 #define DAYOFWEEK(d) ((choice)(((d) + 10) % 7))
1105 #define IS_EMPTY_STRING(s) ((s)[0] == '\0')
1106 #define IS_STDIN(s) (STREQ((s), "-") || strcaseeq((s), "stdin"))
1107 #define IS_STDOUT(s) (STREQ((s), "-") || strcaseeq((s), "stdout"))
1108 #define TO_NEXT(x) (x) = (x)->next
1109 #ifndef FOPENR
1110 #ifdef FOPENR_BINARY
1111 #define FOPENR(s) fopen(s, "rb")
1112 #else
1113 #define FOPENR(s) fopen(s, "r")
1114 #endif
1115 #endif
1116 #ifndef FOPENW
1117 #define FOPENW(s) fopen(s, "w")
1118 #endif
1119 #ifndef FOPENWB
1120 #define FOPENWB(s) fopen(s, "wb")
1121 #endif
1122 #ifndef FOPENA
1123 #define FOPENA(s) fopen(s, "a")
1124 #endif
1125 #ifndef POPENR
1126 #ifdef POPENR_BINARY
1127 #define POPENR(s) popen(s, "rb")
1128 #else
1129 #define POPENR(s) popen(s, "r")
1130 #endif
1131 #endif
1132 #define ENTRY_WANTED(e) ((e) != unwanted_entry)
1133 #define ENTRY_BLANK(e) ((e) == blank_entry)
1134 #define LEN3(n, c) ((unsigned int)((c == '\0')?(n):((n) + (((n) - 1) / 3))))
1135 /* The length of an n digit number with seps; e.g. 56789 [5] -> 56,789 [6] */
1136 #define COPYSTR(s, n) {char *z = n; s = (char *)xmalloc(strlen(z) + 1); \
1137                        strcpy(s, z);}  /* z needed so n only evaluated once */
1138 /* Note memory leak in COPYSTR, so only used in initialisation */
1139 #define TOO_FULL(n, z) ((n) > (z))   /* defn for hash table too full */
1140 #define TOO_FULL_TREE TOO_FULL
1141 #define NEW_SIZE(z) (2 * (z))        /* new size of the hash table */
1142 #define NEW_SIZE_TREE(z) (2 * (z) - 1)
1143 /* Next three: see IPADDR_INC etc. above */
1144 #define IS_IPADDRT(type) ((type) == 3 || (type) == -3)  /* for includes */
1145 #define IS_REGEXT(type) ((type) == 2 || (type) == -2)  /* for includes */
1146 #define IS_INC(type) ((type) > 0)     /* for includes */
1147 /* static char *s = NULL; static size_t len = 0; ENSURE_LEN(s, len, req_len) */
1148 #define ENSURE_LEN(s, l, n) if ((n) > (l)) { \
1149                               s = (char *)xrealloc((void *)s, n); \
1150 			      l = n;}
1151 /* These PUT's are used in datesprintf() etc.: quicker than using sprintf() */
1152 #define PUT02d(s, d) {*((s)++) = ((d) / 10) + '0'; \
1153 			*((s)++) = ((d) % 10) + '0'; }
1154 #define PUT04d(s, d) {*((s)++) = ((d) / 1000) + '0'; \
1155 			*((s)++) = ((d) / 100) % 10 + '0'; \
1156 			*((s)++) = ((d) / 10) % 10 + '0'; \
1157 			*((s)++) = ((d) % 10) + '0'; }
1158 #define PUT2d(s, d) {*((s)++) = ((d) < 10)?' ':(((d) / 10) + '0'); \
1159 		       *((s)++) = ((d) % 10) + '0'; }
1160 #define PUT1d(s, d) {*((s)++) = (d) + '0'; }
1161 #define PUTc(s, c) {*((s)++) = (c); }
1162 #define PUTs(s, t, n) {int z; size_t l = strlen(t); \
1163 			  memcpy((void *)s, (void *)t, l); s += l; \
1164                           for (z = n; z > 0; z--) *((s)++) = ' '; }
1165 /* Some simple command line processing parts implemented as macros */
1166 #define CLSHORTWARN(arg) warn('C', TRUE, "No argument specified after %s command line option (or space wrongly left before argument)", arg)
1167 #define CLLONGWARN(arg) warn('C', TRUE, "Command line argument %s too long: ignoring end of it", arg)
1168 #define CLSHORTCHECK(command) if (argv[i][2] == '\0') CLSHORTWARN(argv[i]); \
1169                               else command
1170 #define CLLONGCHECK(command) if (argv[i][2] != '\0') CLLONGWARN(argv[i]); \
1171                             command
1172 #define CLTOGGLE(f) CLLONGCHECK(f = (argv[i][0] == '+')?TRUE:FALSE)
1173 #define CLREPTOGGLE(n) CLTOGGLE(op->outopts.repq[n])
1174 #define CLOUTSTYLE CLTOGGLE
1175 #define CLGOTOS CLTOGGLE
1176 /* these work because PLAIN == TRUE == ON and XHTML == FALSE == OFF */
1177 /* an abbreviation for arrays with size GENREP_NUMBER */
1178 #define G(r) ((r) - FIRST_GENREP)
1179 /* magicno as macro not fn. for speed: x is unsigned long to contain answer,
1180    s is (char *) to be magicked,
1181    b is unsigned long base (no. of hash bins); power of 2 in practice.
1182    Formula is (\sum_i 9^i c_i) [mod (ULONG_MAX + 1)] mod b */
1183 #define MAGICNO(x, s, b) {register unsigned char *r; \
1184 		    for(x = 0, r = (unsigned char *)(s); *r != '\0'; r++) { \
1185 		    x = (x << 3) + x + (long)(*r); } \
1186 		    x %= b; }
1187 /* for tree magic number, t is end of string, bins are power of 2 plus 1,
1188    and formula has 33 in place of 9 */
1189 #define MAGICNOTREE(x, s, t, b) {register unsigned char *r; \
1190 		    for(x = 0, r = (unsigned char *)(s); \
1191 			r < (unsigned char *)(t); r++) { \
1192 		    x = (x << 5) + x + (long)(*r); } \
1193 		    x %= (b - 1); x++; }
1194 
1195 #include "anlghea4.h"  /* import function declarations */
1196 
1197 #endif  /* ANLGHEA3_H */
1198