1/* A Bison parser, made by GNU Bison 3.0.4.  */
2
3/* Bison implementation for Yacc-like parsers in C
4
5   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
6
7   This program is free software: you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation, either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20/* As a special exception, you may create a larger work that contains
21   part or all of the Bison parser skeleton and distribute that work
22   under terms of your choice, so long as that work isn't itself a
23   parser generator using the skeleton or a modified version thereof
24   as a parser skeleton.  Alternatively, if you modify or redistribute
25   the parser skeleton itself, you may (at your option) remove this
26   special exception, which will cause the skeleton and the resulting
27   Bison output files to be licensed under the GNU General Public
28   License without this special exception.
29
30   This special exception was added by the Free Software Foundation in
31   version 2.2 of Bison.  */
32
33/* C LALR(1) parser skeleton written by Richard Stallman, by
34   simplifying the original so-called "semantic" parser.  */
35
36/* All symbols defined below should begin with yy or YY, to avoid
37   infringing on user name space.  This should be done even for local
38   variables, as they might otherwise be expanded by user macros.
39   There are some unavoidable exceptions within include files to
40   define necessary library symbols; they are noted "INFRINGES ON
41   USER NAME SPACE" below.  */
42
43/* Identify Bison output.  */
44#define YYBISON 1
45
46/* Bison version.  */
47#define YYBISON_VERSION "3.0.4"
48
49/* Skeleton name.  */
50#define YYSKELETON_NAME "yacc.c"
51
52/* Pure parsers.  */
53#define YYPURE 0
54
55/* Push parsers.  */
56#define YYPUSH 0
57
58/* Pull parsers.  */
59#define YYPULL 1
60
61
62
63
64/* Copy the first part of user declarations.  */
65#line 1 "grammar.y" /* yacc.c:339  */
66
67
68/*
69 * ufdbGuard is copyrighted (C) 2005-2020 by URLfilterDB B.V. with all rights reserved.
70 *
71 * Parts of the ufdbGuard daemon are based on squidGuard.
72 * squidGuard is copyrighted (C) 1998 by
73 * ElTele �st AS, Oslo, Norway, with all rights reserved.
74 *
75 * This program is free software; you can redistribute it and/or modify it
76 * under the terms of the GNU General Public License (version 2) as
77 * published by the Free Software Foundation.  It is distributed in the
78 * hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
79 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
80 * PURPOSE.  See the GNU General Public License (GPL) for more details.
81 *
82 * You should have received a copy of the GNU General Public License
83 * (GPL2) along with this program.
84 */
85
86#define YYMALLOC  ufdbMalloc
87#define YYFREE    ufdbFree
88
89#define UFDB_LOG_USER_QUOTA   0   /* TODO remove */
90
91#undef UFDB_DEBUG_ACL_ACCESS
92#define UFDB_DEBUG_ACL_ACCESS 1
93
94#include "ufdb.h"
95#include "sg.h"
96#include "ufdb_globals.h"
97#include "ufdblib.h"
98#include "ufdbdb.h"
99#include "ufdbchkport.h"
100
101#define UFDB_DEBUG 1
102
103#if UFDB_DEBUG
104#undef YYDEBUG
105#define YYDEBUG 1
106#endif
107
108#define UFDB_TIME_DEBUG 0
109
110#if __linux__
111#include <sys/mman.h>
112#endif
113#include <pthread.h>
114#include <sys/types.h>
115#include <stdlib.h>
116#include <string.h>
117#include <errno.h>
118#include <netdb.h>
119#include <grp.h>
120#include <syslog.h>
121#include <signal.h>
122#include <sched.h>
123#include <fcntl.h>
124#include <sys/stat.h>
125#include <unistd.h>
126#include <sys/socket.h>
127
128
129extern FILE * yyin;
130extern FILE * yyout;
131
132int    lineno;
133
134static int   numTimeElements = 0;
135static int * TimeElementsEvents = NULL;
136
137static int   time_switch = 0;
138static int   date_switch = 0;
139
140static void setDBhome( char * dbhome );
141static void setAdministrator( char * value );
142static void setLogdir( char * value );
143static void setPidfile( char * value );
144static void setRefreshUserlist( int nmin );
145static void setRefreshDomainlist( int nmin );
146static void setRefreshIPlist( int nmin );
147static void ufdbSourceExecIPList( char * command );
148
149static void ufdbSourceGroup( int groupType, char * groupName );
150static void ufdbSourceUserQuota( const char * seconds, const char * sporadic, const char * renew );
151static void ufdbSourceUser( char * user );
152static void ufdbSourceUserList( char * file );
153static void ufdbSourceExecUserList( char * command );
154
155static void defSource( char * source );
156static void defSourceEnd( void );
157static struct Source * defSourceFindName( struct Source * slist, const char * name );
158static void defSourceDomain( char * );
159static void ufdbSourceEval( int method  );
160static void defSourceIPV4List( char * file );
161static void defSourceIPV6List( char * file );
162
163static void ufdbCategoryCACertsFile( char * cacertsFile );
164static void ufdbCategoryCACertsDir( char * cacertsDir );
165
166static void sgIpv4( const char * name, int type, const char * file, int lineno );
167static void sgIpv6( const char * addr, int type, const char * file, int line );
168
169void ufdbFreeDomainDb( struct sgDb * dbp );
170
171static void   ufdbAcl( const char * name, const char * value, int within );
172static void   ufdbAclSetValue( const char * what, const char * value, int allowed );
173
174static void   sgTime( char * );
175static struct ufdbTime * sgTimeFindName( const char * name );
176static void   sgTimeElementInit( void );
177static void   sgTimeElementAdd( char *, char );
178static void   sgTimeElementEnd( void );
179static void   sgTimeElementClone( void );
180static void   defSourceTime( char * name, int within );
181
182static void   ufdbCategoryTime( char * name, int within );
183static void   ufdbCategoryActiveBumping( int flag );
184static void   ufdbCategoryBlockConnect( int flag );
185static void   ufdbCategoryRewrite( char * value );
186static void   ufdbCategoryRedirect( char * value );
187static void   ufdbCategoryExecDomainList( char * command );
188
189static void   ufdbCategoryUrlList( char * urllist );
190static void   ufdbCategoryOption( int value, int option );
191
192static void   sgRewrite( char * rewrite );
193static void   sgRewriteTime( char * name, int within );
194static void   sgRewriteSubstitute( char * string );
195static struct sgRewrite * sgRewriteFindName( const char * name );
196
197static void   logConfig( void );
198
199
200#line 201 "grammar.tab.c" /* yacc.c:339  */
201
202# ifndef YY_NULLPTR
203#  if defined __cplusplus && 201103L <= __cplusplus
204#   define YY_NULLPTR nullptr
205#  else
206#   define YY_NULLPTR 0
207#  endif
208# endif
209
210/* Enabling verbose error messages.  */
211#ifdef YYERROR_VERBOSE
212# undef YYERROR_VERBOSE
213# define YYERROR_VERBOSE 1
214#else
215# define YYERROR_VERBOSE 0
216#endif
217
218/* In a future release of Bison, this section will be replaced
219   by #include "grammar.tab.h".  */
220#ifndef YY_YY_GRAMMAR_TAB_H_INCLUDED
221# define YY_YY_GRAMMAR_TAB_H_INCLUDED
222/* Debug traces.  */
223#ifndef YYDEBUG
224# define YYDEBUG 0
225#endif
226#if YYDEBUG
227extern int yydebug;
228#endif
229
230/* Token type.  */
231#ifndef YYTOKENTYPE
232# define YYTOKENTYPE
233  enum yytokentype
234  {
235    ADMINISTRATOR = 258,
236    QSTRING = 259,
237    CHECK_PROXY_TUNNELS = 260,
238    QUEUE_CHECKS = 261,
239    AGGRESSIVE = 262,
240    LOG_ONLY = 263,
241    ON = 264,
242    OFF = 265,
243    CHAR_MINUS = 266,
244    CHAR_I = 267,
245    CHAR_EXCLAMATION = 268,
246    IGNORECASE = 269,
247    COMMA = 270,
248    EQUAL = 271,
249    PORT = 272,
250    HTTP_SERVER = 273,
251    INTERFACE = 274,
252    IMAGES = 275,
253    HTTPS_PROHIBIT_INSECURE_SSLV2 = 276,
254    HTTPS_PROHIBIT_INSECURE_SSLV3 = 277,
255    HTTPS_CONNECTION_CACHE_SIZE = 278,
256    IDENTIFIER = 279,
257    WORD = 280,
258    END = 281,
259    START_BRACKET = 282,
260    STOP_BRACKET = 283,
261    WEEKDAY = 284,
262    CATEGORY = 285,
263    REWRITE = 286,
264    ACL = 287,
265    CPUS = 288,
266    TIME = 289,
267    TVAL = 290,
268    DVAL = 291,
269    DVALCRON = 292,
270    BLOCK_BUMPED_CONNECT = 293,
271    EVALUATE_AND = 294,
272    EVALUATE_OR = 295,
273    SOURCE = 296,
274    CONTINUE = 297,
275    IPV4ADDR = 298,
276    IPV4NET = 299,
277    IPV4CLASS = 300,
278    IPV4RANGE = 301,
279    IPV6ADDR = 302,
280    IPV6NET = 303,
281    DBHOME = 304,
282    DOMAINLIST = 305,
283    EXECDOMAINLIST = 306,
284    REFRESHDOMAINLIST = 307,
285    URLLIST = 308,
286    EXPRESSIONLIST = 309,
287    CACERTS = 310,
288    CACERTSDIR = 311,
289    IPV4 = 312,
290    IPV4LIST = 313,
291    IPV6 = 314,
292    IPV6LIST = 315,
293    DOMAIN = 316,
294    UNIX = 317,
295    LDAP = 318,
296    USER = 319,
297    USERLIST = 320,
298    EXECUSERLIST = 321,
299    REFRESHUSERLIST = 322,
300    EXECIPLIST = 323,
301    REFRESHIPLIST = 324,
302    USERQUOTA = 325,
303    GROUP = 326,
304    NL = 327,
305    NUMBER = 328,
306    NUMBERS = 329,
307    PASS = 330,
308    REDIRECT = 331,
309    SUBST = 332,
310    CHAR = 333,
311    MINUTELY = 334,
312    HOURLY = 335,
313    DAILY = 336,
314    WEEKLY = 337,
315    DATE = 338,
316    REDIRECT_FATAL_ERROR = 339,
317    REDIRECT_LOADING_DATABASE = 340,
318    REDIRECT_HTTPS = 341,
319    REDIRECT_BUMPED_HTTPS = 342,
320    WITHIN = 343,
321    OUTSIDE = 344,
322    ELSE = 345,
323    ANONYMOUS = 346,
324    SPORADIC = 347,
325    PIDFILE = 348,
326    LOGFILE = 349,
327    LOGDIR = 350,
328    LOGPASS = 351,
329    LOGBLOCK = 352,
330    LOGALL = 353,
331    LOGALL_HTTPD = 354,
332    MAIL_SERVER = 355,
333    MY_HOSTNAME = 356,
334    ADMIN_EMAIL = 357,
335    SENDER_EMAIL = 358,
336    EXTERNAL_STATUS_COMMAND = 359,
337    TOKEN_ALLOW = 360,
338    TOKEN_DENY = 361,
339    YOUTUBE_EDUFILTER = 362,
340    YOUTUBE_EDUFILTER_ID = 363,
341    ALLOW_GOOGLE_HTTPS_USING_IP = 364,
342    URL_LOOKUP_RESULT_DB_RELOAD = 365,
343    URL_LOOKUP_RESULT_FATAL_ERROR = 366,
344    URL_LOOKUP_DELAY_DB_RELOAD = 367,
345    OPTION = 368,
346    UFDB_SHOW_URL_DETAILS = 369,
347    UFDB_LOG_URL_DETAILS = 370,
348    SQUID_VERSION = 371,
349    SQUID_USES_ACTIVE_BUMPING = 372,
350    UPLOAD_CRASH_REPORTS = 373,
351    LOOKUP_REVERSE_IP = 374,
352    USE_IPV6_ON_WAN = 375,
353    PARSE_URL_PARAMETERS = 376,
354    STRIP_DOMAIN_FROM_USERNAME = 377,
355    UFDB_DEBUG_FILTER = 378,
356    UFDB_DEBUG_COREDUMP = 379,
357    MADVISE_HUGEPAGES = 380,
358    FAST_REFRESH = 381,
359    UFDB_DEBUG_SKYPE_PROBES = 382,
360    UFDB_DEBUG_GTALK_PROBES = 383,
361    UFDB_DEBUG_YAHOOMSG_PROBES = 384,
362    UFDB_DEBUG_AIM_PROBES = 385,
363    UFDB_DEBUG_FBCHAT_PROBES = 386,
364    UFDB_DEBUG_CITRIXONLINE_PROBES = 387,
365    UFDB_EXPRESSION_OPTIMISATION = 388,
366    UFDB_EXPRESSION_DEBUG = 389,
367    UFDB_DEBUG_EXTERNAL_SCRIPTS = 390,
368    UFDB_NUM_WORKER_THREADS = 391,
369    ENFORCE_HTTPS_WITH_HOSTNAME = 392,
370    ENFORCE_HTTPS_OFFICAL_CERTIFICATE = 393,
371    ALLOW_SKYPE_OVER_HTTPS = 394,
372    ALLOW_UNKNOWN_PROTOCOL_OVER_HTTPS = 395,
373    ALLOW_GTALK_OVER_HTTPS = 396,
374    ALLOW_YAHOOMSG_OVER_HTTPS = 397,
375    ALLOW_AIM_OVER_HTTPS = 398,
376    ALLOW_FBCHAT_OVER_HTTPS = 399,
377    ALLOW_CITRIXONLINE_OVER_HTTPS = 400,
378    ALLOW_ANYDESK_OVER_HTTPS = 401,
379    ALLOW_TEAMVIEWER_OVER_HTTPS = 402,
380    ANALYSE_UNCATEGORISED = 403,
381    LOG_UNCATEGORISED_URLS = 404,
382    UPLOAD_STATS = 405,
383    SAFE_SEARCH = 406,
384    MAX_LOGFILE_SIZE = 407
385  };
386#endif
387
388/* Value type.  */
389#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
390
391union YYSTYPE
392{
393#line 136 "grammar.y" /* yacc.c:355  */
394
395  char * string;
396  char * tval;
397  char * dval;
398  char * dvalcron;
399  int    integer;
400
401#line 402 "grammar.tab.c" /* yacc.c:355  */
402};
403
404typedef union YYSTYPE YYSTYPE;
405# define YYSTYPE_IS_TRIVIAL 1
406# define YYSTYPE_IS_DECLARED 1
407#endif
408
409
410extern YYSTYPE yylval;
411
412int yyparse (void);
413
414#endif /* !YY_YY_GRAMMAR_TAB_H_INCLUDED  */
415
416/* Copy the second part of user declarations.  */
417
418#line 419 "grammar.tab.c" /* yacc.c:358  */
419
420#ifdef short
421# undef short
422#endif
423
424#ifdef YYTYPE_UINT8
425typedef YYTYPE_UINT8 yytype_uint8;
426#else
427typedef unsigned char yytype_uint8;
428#endif
429
430#ifdef YYTYPE_INT8
431typedef YYTYPE_INT8 yytype_int8;
432#else
433typedef signed char yytype_int8;
434#endif
435
436#ifdef YYTYPE_UINT16
437typedef YYTYPE_UINT16 yytype_uint16;
438#else
439typedef unsigned short int yytype_uint16;
440#endif
441
442#ifdef YYTYPE_INT16
443typedef YYTYPE_INT16 yytype_int16;
444#else
445typedef short int yytype_int16;
446#endif
447
448#ifndef YYSIZE_T
449# ifdef __SIZE_TYPE__
450#  define YYSIZE_T __SIZE_TYPE__
451# elif defined size_t
452#  define YYSIZE_T size_t
453# elif ! defined YYSIZE_T
454#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
455#  define YYSIZE_T size_t
456# else
457#  define YYSIZE_T unsigned int
458# endif
459#endif
460
461#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
462
463#ifndef YY_
464# if defined YYENABLE_NLS && YYENABLE_NLS
465#  if ENABLE_NLS
466#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
467#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
468#  endif
469# endif
470# ifndef YY_
471#  define YY_(Msgid) Msgid
472# endif
473#endif
474
475#ifndef YY_ATTRIBUTE
476# if (defined __GNUC__                                               \
477      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \
478     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
479#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)
480# else
481#  define YY_ATTRIBUTE(Spec) /* empty */
482# endif
483#endif
484
485#ifndef YY_ATTRIBUTE_PURE
486# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))
487#endif
488
489#ifndef YY_ATTRIBUTE_UNUSED
490# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
491#endif
492
493#if !defined _Noreturn \
494     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
495# if defined _MSC_VER && 1200 <= _MSC_VER
496#  define _Noreturn __declspec (noreturn)
497# else
498#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
499# endif
500#endif
501
502/* Suppress unused-variable warnings by "using" E.  */
503#if ! defined lint || defined __GNUC__
504# define YYUSE(E) ((void) (E))
505#else
506# define YYUSE(E) /* empty */
507#endif
508
509#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
510/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
511# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
512    _Pragma ("GCC diagnostic push") \
513    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
514    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
515# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
516    _Pragma ("GCC diagnostic pop")
517#else
518# define YY_INITIAL_VALUE(Value) Value
519#endif
520#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
521# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
522# define YY_IGNORE_MAYBE_UNINITIALIZED_END
523#endif
524#ifndef YY_INITIAL_VALUE
525# define YY_INITIAL_VALUE(Value) /* Nothing. */
526#endif
527
528
529#if ! defined yyoverflow || YYERROR_VERBOSE
530
531/* The parser invokes alloca or malloc; define the necessary symbols.  */
532
533# ifdef YYSTACK_USE_ALLOCA
534#  if YYSTACK_USE_ALLOCA
535#   ifdef __GNUC__
536#    define YYSTACK_ALLOC __builtin_alloca
537#   elif defined __BUILTIN_VA_ARG_INCR
538#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
539#   elif defined _AIX
540#    define YYSTACK_ALLOC __alloca
541#   elif defined _MSC_VER
542#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
543#    define alloca _alloca
544#   else
545#    define YYSTACK_ALLOC alloca
546#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
547#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
548      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
549#     ifndef EXIT_SUCCESS
550#      define EXIT_SUCCESS 0
551#     endif
552#    endif
553#   endif
554#  endif
555# endif
556
557# ifdef YYSTACK_ALLOC
558   /* Pacify GCC's 'empty if-body' warning.  */
559#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
560#  ifndef YYSTACK_ALLOC_MAXIMUM
561    /* The OS might guarantee only one guard page at the bottom of the stack,
562       and a page size can be as small as 4096 bytes.  So we cannot safely
563       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
564       to allow for a few compiler-allocated temporary stack slots.  */
565#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
566#  endif
567# else
568#  define YYSTACK_ALLOC YYMALLOC
569#  define YYSTACK_FREE YYFREE
570#  ifndef YYSTACK_ALLOC_MAXIMUM
571#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
572#  endif
573#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
574       && ! ((defined YYMALLOC || defined malloc) \
575             && (defined YYFREE || defined free)))
576#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
577#   ifndef EXIT_SUCCESS
578#    define EXIT_SUCCESS 0
579#   endif
580#  endif
581#  ifndef YYMALLOC
582#   define YYMALLOC malloc
583#   if ! defined malloc && ! defined EXIT_SUCCESS
584void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
585#   endif
586#  endif
587#  ifndef YYFREE
588#   define YYFREE free
589#   if ! defined free && ! defined EXIT_SUCCESS
590void free (void *); /* INFRINGES ON USER NAME SPACE */
591#   endif
592#  endif
593# endif
594#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
595
596
597#if (! defined yyoverflow \
598     && (! defined __cplusplus \
599         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
600
601/* A type that is properly aligned for any stack member.  */
602union yyalloc
603{
604  yytype_int16 yyss_alloc;
605  YYSTYPE yyvs_alloc;
606};
607
608/* The size of the maximum gap between one aligned stack and the next.  */
609# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
610
611/* The size of an array large to enough to hold all stacks, each with
612   N elements.  */
613# define YYSTACK_BYTES(N) \
614     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
615      + YYSTACK_GAP_MAXIMUM)
616
617# define YYCOPY_NEEDED 1
618
619/* Relocate STACK from its old location to the new one.  The
620   local variables YYSIZE and YYSTACKSIZE give the old and new number of
621   elements in the stack, and YYPTR gives the new location of the
622   stack.  Advance YYPTR to a properly aligned location for the next
623   stack.  */
624# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
625    do                                                                  \
626      {                                                                 \
627        YYSIZE_T yynewbytes;                                            \
628        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
629        Stack = &yyptr->Stack_alloc;                                    \
630        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
631        yyptr += yynewbytes / sizeof (*yyptr);                          \
632      }                                                                 \
633    while (0)
634
635#endif
636
637#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
638/* Copy COUNT objects from SRC to DST.  The source and destination do
639   not overlap.  */
640# ifndef YYCOPY
641#  if defined __GNUC__ && 1 < __GNUC__
642#   define YYCOPY(Dst, Src, Count) \
643      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
644#  else
645#   define YYCOPY(Dst, Src, Count)              \
646      do                                        \
647        {                                       \
648          YYSIZE_T yyi;                         \
649          for (yyi = 0; yyi < (Count); yyi++)   \
650            (Dst)[yyi] = (Src)[yyi];            \
651        }                                       \
652      while (0)
653#  endif
654# endif
655#endif /* !YYCOPY_NEEDED */
656
657/* YYFINAL -- State number of the termination state.  */
658#define YYFINAL  3
659/* YYLAST -- Last index in YYTABLE.  */
660#define YYLAST   558
661
662/* YYNTOKENS -- Number of terminals.  */
663#define YYNTOKENS  153
664/* YYNNTS -- Number of nonterminals.  */
665#define YYNNTS  118
666/* YYNRULES -- Number of rules.  */
667#define YYNRULES  344
668/* YYNSTATES -- Number of states.  */
669#define YYNSTATES  508
670
671/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
672   by yylex, with out-of-bounds checking.  */
673#define YYUNDEFTOK  2
674#define YYMAXUTOK   407
675
676#define YYTRANSLATE(YYX)                                                \
677  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
678
679/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
680   as returned by yylex, without out-of-bounds checking.  */
681static const yytype_uint8 yytranslate[] =
682{
683       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
684       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
685       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
686       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
687       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
688       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
689       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
690       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
691       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
692       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
693       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
694       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
695       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
696       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
697       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
698       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
699       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
700       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
701       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
702       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
703       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
704       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
705       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
706       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
707       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
708       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
709       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
710      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
711      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
712      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
713      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
714      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
715      65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
716      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
717      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
718      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
719     105,   106,   107,   108,   109,   110,   111,   112,   113,   114,
720     115,   116,   117,   118,   119,   120,   121,   122,   123,   124,
721     125,   126,   127,   128,   129,   130,   131,   132,   133,   134,
722     135,   136,   137,   138,   139,   140,   141,   142,   143,   144,
723     145,   146,   147,   148,   149,   150,   151,   152
724};
725
726#if YYDEBUG
727  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
728static const yytype_uint16 yyrline[] =
729{
730       0,   226,   226,   230,   231,   235,   240,   241,   245,   246,
731     247,   251,   255,   259,   263,   267,   271,   275,   279,   283,
732     287,   288,   293,   297,   303,   309,   315,   322,   323,   324,
733     325,   329,   333,   337,   338,   342,   347,   352,   357,   361,
734     365,   369,   374,   397,   402,   407,   412,   417,   422,   426,
735     430,   434,   438,   442,   446,   450,   454,   458,   462,   466,
736     470,   474,   478,   482,   487,   488,   492,   493,   497,   508,
737     520,   524,   525,   529,   534,   539,   544,   549,   554,   561,
738     566,   574,   581,   586,   598,   599,   605,   611,   612,   613,
739     617,   618,   622,   626,   627,   629,   631,   633,   638,   642,
740     643,   647,   648,   649,   650,   651,   652,   653,   654,   655,
741     656,   657,   658,   659,   660,   661,   662,   663,   664,   665,
742     666,   667,   668,   669,   670,   671,   672,   673,   674,   675,
743     676,   677,   678,   679,   680,   681,   682,   683,   684,   685,
744     686,   687,   688,   689,   690,   692,   694,   696,   701,   705,
745     709,   710,   714,   715,   716,   717,   718,   719,   720,   721,
746     722,   723,   724,   725,   726,   727,   729,   731,   733,   735,
747     736,   737,   738,   739,   740,   741,   742,   743,   744,   745,
748     748,   751,   754,   757,   762,   763,   764,   765,   769,   770,
749     771,   772,   776,   779,   780,   784,   785,   786,   790,   792,
750     791,   797,   798,   802,   810,   811,   812,   813,   814,   817,
751     820,   823,   829,   830,   831,   832,   833,   834,   838,   839,
752     840,   844,   846,   848,   850,   855,   856,   857,   861,   863,
753     868,   869,   873,   877,   878,   883,   884,   885,   886,   889,
754     892,   895,   902,   906,   910,   911,   916,   916,   916,   917,
755     917,   917,   918,   918,   918,   919,   919,   920,   924,   924,
756     925,   929,   930,   931,   932,   933,   934,   937,   940,   943,
757     947,   953,   954,   958,   959,   960,   961,   962,   963,   964,
758     965,   966,   967,   968,   969,   970,   971,   972,   973,   974,
759     975,   976,   977,   978,   979,   980,   981,   982,   983,   984,
760     985,   986,   987,   988,   989,   990,   991,   992,   993,   994,
761     995,   996,   997,   998,   999,  1000,  1001,  1002,  1003,  1004,
762    1005,  1006,  1007,  1008,  1009,  1010,  1011,  1012,  1013,  1014,
763    1015,  1016,  1017,  1018,  1019,  1020,  1021,  1022,  1023,  1024,
764    1025,  1026,  1027,  1028,  1029
765};
766#endif
767
768#if YYDEBUG || YYERROR_VERBOSE || 0
769/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
770   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
771static const char *const yytname[] =
772{
773  "$end", "error", "$undefined", "ADMINISTRATOR", "QSTRING",
774  "CHECK_PROXY_TUNNELS", "QUEUE_CHECKS", "AGGRESSIVE", "LOG_ONLY", "ON",
775  "OFF", "CHAR_MINUS", "CHAR_I", "CHAR_EXCLAMATION", "IGNORECASE", "COMMA",
776  "EQUAL", "PORT", "HTTP_SERVER", "INTERFACE", "IMAGES",
777  "HTTPS_PROHIBIT_INSECURE_SSLV2", "HTTPS_PROHIBIT_INSECURE_SSLV3",
778  "HTTPS_CONNECTION_CACHE_SIZE", "IDENTIFIER", "WORD", "END",
779  "START_BRACKET", "STOP_BRACKET", "WEEKDAY", "CATEGORY", "REWRITE", "ACL",
780  "CPUS", "TIME", "TVAL", "DVAL", "DVALCRON", "BLOCK_BUMPED_CONNECT",
781  "EVALUATE_AND", "EVALUATE_OR", "SOURCE", "CONTINUE", "IPV4ADDR",
782  "IPV4NET", "IPV4CLASS", "IPV4RANGE", "IPV6ADDR", "IPV6NET", "DBHOME",
783  "DOMAINLIST", "EXECDOMAINLIST", "REFRESHDOMAINLIST", "URLLIST",
784  "EXPRESSIONLIST", "CACERTS", "CACERTSDIR", "IPV4", "IPV4LIST", "IPV6",
785  "IPV6LIST", "DOMAIN", "UNIX", "LDAP", "USER", "USERLIST", "EXECUSERLIST",
786  "REFRESHUSERLIST", "EXECIPLIST", "REFRESHIPLIST", "USERQUOTA", "GROUP",
787  "NL", "NUMBER", "NUMBERS", "PASS", "REDIRECT", "SUBST", "CHAR",
788  "MINUTELY", "HOURLY", "DAILY", "WEEKLY", "DATE", "REDIRECT_FATAL_ERROR",
789  "REDIRECT_LOADING_DATABASE", "REDIRECT_HTTPS", "REDIRECT_BUMPED_HTTPS",
790  "WITHIN", "OUTSIDE", "ELSE", "ANONYMOUS", "SPORADIC", "PIDFILE",
791  "LOGFILE", "LOGDIR", "LOGPASS", "LOGBLOCK", "LOGALL", "LOGALL_HTTPD",
792  "MAIL_SERVER", "MY_HOSTNAME", "ADMIN_EMAIL", "SENDER_EMAIL",
793  "EXTERNAL_STATUS_COMMAND", "TOKEN_ALLOW", "TOKEN_DENY",
794  "YOUTUBE_EDUFILTER", "YOUTUBE_EDUFILTER_ID",
795  "ALLOW_GOOGLE_HTTPS_USING_IP", "URL_LOOKUP_RESULT_DB_RELOAD",
796  "URL_LOOKUP_RESULT_FATAL_ERROR", "URL_LOOKUP_DELAY_DB_RELOAD", "OPTION",
797  "UFDB_SHOW_URL_DETAILS", "UFDB_LOG_URL_DETAILS", "SQUID_VERSION",
798  "SQUID_USES_ACTIVE_BUMPING", "UPLOAD_CRASH_REPORTS", "LOOKUP_REVERSE_IP",
799  "USE_IPV6_ON_WAN", "PARSE_URL_PARAMETERS", "STRIP_DOMAIN_FROM_USERNAME",
800  "UFDB_DEBUG_FILTER", "UFDB_DEBUG_COREDUMP", "MADVISE_HUGEPAGES",
801  "FAST_REFRESH", "UFDB_DEBUG_SKYPE_PROBES", "UFDB_DEBUG_GTALK_PROBES",
802  "UFDB_DEBUG_YAHOOMSG_PROBES", "UFDB_DEBUG_AIM_PROBES",
803  "UFDB_DEBUG_FBCHAT_PROBES", "UFDB_DEBUG_CITRIXONLINE_PROBES",
804  "UFDB_EXPRESSION_OPTIMISATION", "UFDB_EXPRESSION_DEBUG",
805  "UFDB_DEBUG_EXTERNAL_SCRIPTS", "UFDB_NUM_WORKER_THREADS",
806  "ENFORCE_HTTPS_WITH_HOSTNAME", "ENFORCE_HTTPS_OFFICAL_CERTIFICATE",
807  "ALLOW_SKYPE_OVER_HTTPS", "ALLOW_UNKNOWN_PROTOCOL_OVER_HTTPS",
808  "ALLOW_GTALK_OVER_HTTPS", "ALLOW_YAHOOMSG_OVER_HTTPS",
809  "ALLOW_AIM_OVER_HTTPS", "ALLOW_FBCHAT_OVER_HTTPS",
810  "ALLOW_CITRIXONLINE_OVER_HTTPS", "ALLOW_ANYDESK_OVER_HTTPS",
811  "ALLOW_TEAMVIEWER_OVER_HTTPS", "ANALYSE_UNCATEGORISED",
812  "LOG_UNCATEGORISED_URLS", "UPLOAD_STATS", "SAFE_SEARCH",
813  "MAX_LOGFILE_SIZE", "$accept", "start", "qidentifier",
814  "https_cache_size", "allow_or_deny", "on_or_off", "log_pass",
815  "log_block", "log_all", "logall_httpd", "youtube_edufilter",
816  "youtube_edufilter_id", "allow_google_https_using_ip",
817  "madvise_hugepages", "fast_refresh", "debug_filter", "debug_coredump",
818  "enforce_https_with_hostname", "enforce_https_offical_certificate",
819  "https_prohibit_insecure_sslv2", "https_prohibit_insecure_sslv3",
820  "check_proxy_tunnel_option", "check_proxy_tunnels", "admin_spec",
821  "dbhome", "refreshuserlist", "refreshiplist", "refreshdomainlist",
822  "url_lookup_result_db_reload", "url_lookup_result_fatal_error",
823  "url_lookup_delay_db_reload", "squid_version", "num_worker_threads",
824  "upload_crash_reports", "lookup_reverse_ip", "use_ipv6_on_wan",
825  "parse_url_parameters", "squid_uses_active_bumping",
826  "ufdb_log_url_details", "ufdb_show_url_details",
827  "ufdb_debug_skype_probes", "ufdb_debug_gtalk_probes",
828  "ufdb_debug_yahoomsg_probes", "ufdb_debug_aim_probes",
829  "ufdb_debug_fbchat_probes", "ufdb_debug_citrixonline_probes",
830  "ufdb_expression_optimisation", "ufdb_expression_debug",
831  "ufdb_debug_external_scripts", "mail_server", "my_hostname",
832  "admin_email", "sender_email", "external_status_command", "logdir",
833  "pidfile", "port", "interface", "cpus", "upload_stats", "redirect_https",
834  "redirect_bumped_https", "redirect_loading_database",
835  "redirect_fatal_error", "log_uncategorised_urls",
836  "analyse_uncategorised", "strip_domain_from_username", "safe_search",
837  "max_logfile_size", "httpd_option", "httpd_options", "http_server_def",
838  "category", "category_block", "category_contents", "category_content",
839  "source", "source_block", "source_contents", "source_content", "domain",
840  "user", "acl_block", "acl_contents", "acl_header", "acl_content", "$@1",
841  "access_contents", "access_content", "access_pass", "ipv4s", "ipv4",
842  "ipv6s", "ipv6", "rew", "rew_block", "rew_contents", "rew_content",
843  "time", "time_block", "time_contents", "time_content", "$@2", "$@3",
844  "$@4", "$@5", "$@6", "$@7", "$@8", "ttime", "$@9", "date", "dval",
845  "tval", "dvalcron", "an_error", "statements", "statement", YY_NULLPTR
846};
847#endif
848
849# ifdef YYPRINT
850/* YYTOKNUM[NUM] -- (External) token number corresponding to the
851   (internal) symbol number NUM (which must be that of a token).  */
852static const yytype_uint16 yytoknum[] =
853{
854       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
855     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
856     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
857     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
858     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
859     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,
860     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
861     325,   326,   327,   328,   329,   330,   331,   332,   333,   334,
862     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,
863     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
864     355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
865     365,   366,   367,   368,   369,   370,   371,   372,   373,   374,
866     375,   376,   377,   378,   379,   380,   381,   382,   383,   384,
867     385,   386,   387,   388,   389,   390,   391,   392,   393,   394,
868     395,   396,   397,   398,   399,   400,   401,   402,   403,   404,
869     405,   406,   407
870};
871# endif
872
873#define YYPACT_NINF -392
874
875#define yypact_value_is_default(Yystate) \
876  (!!((Yystate) == (-392)))
877
878#define YYTABLE_NINF -259
879
880#define yytable_value_is_error(Yytable_value) \
881  0
882
883  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
884     STATE-NUM.  */
885static const yytype_int16 yypact[] =
886{
887    -392,    13,    66,  -392,  -392,    -2,    22,   -57,    12,   100,
888     358,   358,    -1,    11,   107,    43,    98,    -3,    -3,   124,
889       4,    18,    29,  -392,   130,   140,   143,   150,   231,   294,
890     358,   358,   358,   358,   153,   156,   209,   217,   219,   358,
891     222,   358,    15,    15,   358,   358,   358,   225,   358,   358,
892     358,   358,   358,   358,    72,   358,   358,   358,   358,   358,
893     358,   358,   358,   358,   358,   358,   358,   163,   358,   358,
894      85,   358,   358,   358,   168,  -392,  -392,  -392,  -392,  -392,
895    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
896    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
897    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
898    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
899    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
900    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,   218,
901    -392,   220,  -392,  -392,   227,  -392,   241,  -392,  -392,  -392,
902    -392,  -392,  -392,  -392,  -392,  -392,  -392,   253,  -392,  -392,
903    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
904    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
905    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
906    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
907    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
908    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
909    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
910    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
911    -392,  -392,  -392,  -392,  -392,  -392,   258,   264,   281,   284,
912     275,   206,   398,   456,    48,    73,   240,   203,   302,   253,
913    -392,  -392,    41,  -392,  -392,  -392,   304,   265,    -3,   280,
914     208,   308,   352,   354,    -3,    -3,     2,   257,  -392,  -392,
915    -392,  -392,  -392,  -392,   357,  -392,   410,  -392,   160,  -392,
916     413,    -3,    -3,   242,   451,    -3,    -3,    55,  -392,  -392,
917    -392,    -3,    -3,    88,  -392,  -392,  -392,   -18,  -392,  -392,
918    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,    -3,    -3,
919      47,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
920    -392,   455,   457,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
921    -392,  -392,  -392,  -392,   466,  -392,   358,   358,   358,   358,
922     358,   356,   412,   358,   358,   358,   358,   358,   358,   358,
923     358,   358,   358,   194,  -392,  -392,   196,  -392,  -392,   292,
924    -392,   469,   479,   296,  -392,  -392,  -392,  -392,   251,  -392,
925    -392,  -392,  -392,  -392,   485,  -392,  -392,  -392,  -392,   504,
926    -392,   285,    -3,   300,   214,   303,   307,   246,   508,  -392,
927     515,   115,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
928    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
929    -392,  -392,  -392,  -392,  -392,  -392,   326,  -392,  -392,  -392,
930    -392,  -392,   254,  -392,  -392,  -392,  -392,  -392,  -392,   296,
931    -392,  -392,  -392,  -392,  -392,  -392,  -392,   343,  -392,  -392,
932    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,    92,   320,
933    -392,  -392,  -392,  -392,  -392,   534,  -392,  -392,  -392,   527,
934    -392,  -392,  -392,  -392,  -392,  -392,  -392,   320,   320,   320,
935     295,  -392,   338,   374,   338,   310,  -392,    10,  -392,  -392,
936    -392,  -392,   338,   338,   338,   320,   320,   320,  -392,  -392,
937    -392,   338,   375,  -392,   177,   320,  -392,  -392
938};
939
940  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
941     Performed when YYTABLE does not specify something else to do.  Zero
942     means the default is an error.  */
943static const yytype_uint16 yydefact[] =
944{
945     271,     0,     0,     1,   270,     0,     0,     0,     0,     0,
946       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
947       0,     0,     0,   343,     0,     0,     0,     0,     0,     0,
948       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
949       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
950       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
951       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
952       0,     0,     0,     0,     0,   278,   280,   281,   282,   283,
953     336,   338,   337,   284,   285,   286,   287,   288,   289,   290,
954     291,   279,   277,   292,   320,   321,   322,   301,   302,   300,
955     303,   304,   305,   306,   307,   308,   309,   310,   311,   312,
956     313,   314,   315,   316,   317,   318,   319,   323,   295,   296,
957     297,   298,   299,   293,   294,   325,   324,   326,   327,   328,
958     329,   330,   331,   333,   332,   335,   334,   339,   276,   273,
959     275,     0,   274,   340,     0,   341,     0,   342,   344,   272,
960      32,    28,    29,    30,    27,    31,    68,     0,     4,     3,
961      70,    69,    10,     8,     9,    25,    26,     5,    97,    94,
962      95,    96,    93,   231,   230,   193,    71,    72,   242,   148,
963      34,    33,    37,    35,    36,    77,    76,    74,    75,    67,
964      66,    65,    64,    11,    12,    13,    14,    59,    60,    61,
965      62,    63,    15,    16,    17,     6,     7,    38,    39,    40,
966      49,    48,    41,    47,    43,    44,    45,    46,    81,    21,
967      20,    22,    18,    19,    50,    51,    52,    53,    54,    55,
968      56,    57,    58,    42,    23,    24,    80,    79,    78,    73,
969      82,    83,    99,   150,   233,   244,     0,     0,     0,    91,
970       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
971      92,   192,     0,   201,   194,    98,     0,     0,     0,     0,
972       0,     0,     0,     0,     0,     0,     0,     0,   100,   149,
973     175,   176,   183,   218,     0,   225,     0,   184,     0,   188,
974       0,     0,     0,     0,     0,     0,     0,     0,   151,   232,
975     235,     0,     0,     0,   234,   257,   243,   249,   255,   245,
976      84,    86,    87,    85,    89,    88,    90,   195,     0,     0,
977       0,   122,   121,   103,   102,   101,   104,   107,   106,   105,
978     110,     0,     0,   109,   108,   116,   115,   118,   117,   120,
979     119,   123,   124,   147,     0,   146,     0,     0,     0,     0,
980       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
981       0,     0,     0,   169,   171,   170,   172,   174,   173,   152,
982     188,     0,     0,   153,   156,   155,   159,   160,     0,   162,
983     161,   177,   178,   182,     0,   181,   236,   237,   241,     0,
984     240,     0,     0,     0,     0,     0,     0,   198,     0,   212,
985       0,     0,   202,   112,   111,   114,   113,   145,   144,   133,
986     134,   125,   128,   126,   130,   132,   135,   143,   136,   137,
987     138,   139,   140,   141,   142,   127,     0,   221,   224,   223,
988     222,   219,     0,   228,   229,   226,   187,   186,   185,   154,
989     158,   157,   164,   163,   191,   190,   189,     0,   180,   179,
990     239,   238,   247,   250,   253,   267,   269,   256,   262,   266,
991     196,   197,   199,   205,   204,   203,   207,   206,   211,     0,
992     210,   220,   227,   168,   165,   166,   167,     0,     0,     0,
993       0,   268,   261,     0,   265,     0,   213,     0,   217,   214,
994     209,   208,   248,   251,   254,   264,     0,     0,   201,   215,
995     216,   263,     0,   260,     0,     0,   200,   259
996};
997
998  /* YYPGOTO[NTERM-NUM].  */
999static const yytype_int16 yypgoto[] =
1000{
1001    -392,  -392,    -9,  -392,   345,    -8,  -392,  -392,  -392,  -392,
1002    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
1003    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
1004    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
1005    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
1006    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
1007    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
1008     131,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,
1009    -392,    23,  -392,  -392,  -392,  -392,  -392,   -93,  -392,  -392,
1010    -392,   -11,  -392,   -14,  -392,  -392,  -392,  -392,  -392,  -392,
1011    -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -392,  -369,
1012    -392,  -392,   -61,  -391,  -392,  -392,  -392,  -392
1013};
1014
1015  /* YYDEFGOTO[NTERM-NUM].  */
1016static const yytype_int16 yydefgoto[] =
1017{
1018      -1,     1,   446,    75,   207,   165,    76,    77,    78,    79,
1019      80,    81,    82,    83,    84,    85,    86,    87,    88,    89,
1020      90,   155,    91,    92,    93,    94,    95,    96,    97,    98,
1021      99,   100,   101,   102,   103,   104,   105,   106,   107,   108,
1022     109,   110,   111,   112,   113,   114,   115,   116,   117,   118,
1023     119,   120,   121,   122,   123,   124,   125,   126,   127,   128,
1024     129,   130,   131,   132,   133,   134,   135,   136,   137,   249,
1025     250,   138,   139,   140,   252,   278,   141,   142,   253,   298,
1026     369,   373,   143,   251,   263,   264,   485,   320,   402,   465,
1027     363,   431,   366,   435,   144,   145,   254,   304,   146,   147,
1028     255,   309,   391,   477,   392,   478,   393,   479,   394,   482,
1029     496,   457,   458,   483,   459,   148,     2,   149
1030};
1031
1032  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
1033     positive, shift that token.  If negative, reduce the rule whose
1034     number is the opposite.  If YYTABLE_NINF, syntax error.  */
1035static const yytype_int16 yytable[] =
1036{
1037     161,   158,   150,   166,   172,   174,   158,  -252,   178,   179,
1038     181,  -246,   168,     3,   158,   158,   156,   499,   169,   190,
1039     192,   159,   193,   194,   195,   196,   159,   343,   151,   152,
1040     153,   202,   154,   204,   159,   159,   209,   210,   211,   157,
1041     213,   214,   215,   216,   217,   218,   220,   221,   222,   223,
1042     224,   225,   226,   227,   228,   229,   230,   231,   232,   158,
1043     234,   235,   237,   238,   239,   240,    -2,     4,   317,     5,
1044     175,     6,   167,   162,   305,   397,   299,   182,   398,   159,
1045     383,   163,   164,     7,     8,     9,   162,    10,    11,    12,
1046     484,   183,   158,   344,   163,   164,    13,    14,    15,    16,
1047      17,   306,   184,   480,   158,   502,   503,    18,   492,   493,
1048     494,   158,   159,   388,   507,    19,   170,   171,    20,   158,
1049     205,   206,   399,   400,   159,   300,   501,   481,   158,   318,
1050     319,   159,   173,    21,   185,    22,   301,   302,    23,   159,
1051     468,   401,   303,   160,   186,   219,   384,   187,   159,   180,
1052      24,    25,    26,    27,   188,   307,   308,   197,   236,    28,
1053     198,    29,    30,    31,    32,    33,    34,    35,    36,    37,
1054      38,   176,   177,    39,    40,    41,    42,    43,    44,   389,
1055      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
1056      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
1057      65,    66,    67,    68,    69,   506,   469,   158,   398,   426,
1058     158,   432,   158,   199,    70,    71,    72,    73,    74,   330,
1059     331,   200,   332,   201,   370,   371,   203,   159,   311,   212,
1060     159,   372,   159,   333,   261,   158,   233,   427,   428,   429,
1061     430,   241,   262,   433,   434,   242,   312,   243,   313,   315,
1062     455,   456,   399,   400,   244,   159,   189,   322,   325,   326,
1063     329,   334,   336,   338,   340,   341,   342,   345,   245,   158,
1064     246,   401,   247,   248,   256,   365,   323,   368,   346,   347,
1065     257,   375,   376,   377,   158,   380,   381,   382,   385,   159,
1066     324,   327,   386,   387,   390,   348,   158,   258,   158,   259,
1067     158,   433,   434,   260,   159,   328,   158,   436,   158,   395,
1068     396,   444,   158,   310,   452,   378,   159,   437,   159,   191,
1069     159,   445,   404,   406,   447,   454,   159,   314,   159,   321,
1070     460,   455,   159,   335,   461,   408,   462,   498,   409,   410,
1071     411,   412,   413,   414,   415,   416,   417,   418,   419,   420,
1072     421,   422,   423,   424,   425,   481,   158,   162,   158,   162,
1073     438,   158,   441,   443,   349,   163,   164,   163,   164,   427,
1074     428,   429,   430,  -258,   350,   449,   159,   337,   159,   339,
1075     451,   159,   364,   453,  -129,   497,   505,  -129,   208,   464,
1076     316,   467,   470,   439,   351,   352,   353,   354,   355,   356,
1077     357,   358,   359,   360,   361,   504,  -129,  -129,   362,  -129,
1078    -129,  -129,  -129,   162,   158,   471,   473,   158,   472,   495,
1079       0,   163,   164,   474,   475,   476,   265,     0,     0,   266,
1080       0,     0,  -129,     0,   159,   367,     0,   159,   374,     0,
1081    -131,     0,     0,  -131,  -129,  -129,     0,     0,   267,   268,
1082    -129,   269,   270,   271,   272,   158,   489,     0,     0,   158,
1083     491,   158,  -131,  -131,     0,  -131,  -131,  -131,  -131,  -129,
1084     158,     0,     0,   158,   273,   159,   379,     0,   500,   159,
1085     403,   159,   405,   158,   279,     0,   274,   275,  -131,   158,
1086     159,   407,   276,   159,   440,   280,   281,     0,   282,     0,
1087    -131,  -131,     0,   159,   442,     0,  -131,     0,   158,   159,
1088     448,   277,   158,   283,   284,   285,   286,   287,   288,   158,
1089     289,   290,   291,     0,   292,  -131,   293,   294,   159,   450,
1090       0,   158,   159,   463,     0,     0,     0,     0,   158,   159,
1091     466,   486,     0,     0,   295,   296,     0,   487,     0,   488,
1092     297,   159,   490,     0,     0,     0,     0,     0,   159
1093};
1094
1095static const yytype_int16 yycheck[] =
1096{
1097       9,     4,     4,    11,    13,    14,     4,    25,    17,    18,
1098      19,    29,     1,     0,     4,     4,    73,     7,     7,    28,
1099      29,    24,    30,    31,    32,    33,    24,    25,     6,     7,
1100       8,    39,    10,    41,    24,    24,    44,    45,    46,    27,
1101      48,    49,    50,    51,    52,    53,    54,    55,    56,    57,
1102      58,    59,    60,    61,    62,    63,    64,    65,    66,     4,
1103      68,    69,    70,    71,    72,    73,     0,     1,    27,     3,
1104      27,     5,    73,     1,     1,    28,    28,    73,    31,    24,
1105      25,     9,    10,    17,    18,    19,     1,    21,    22,    23,
1106     459,    73,     4,    91,     9,    10,    30,    31,    32,    33,
1107      34,    28,    73,    11,     4,   496,   497,    41,   477,   478,
1108     479,     4,    24,    25,   505,    49,   105,   106,    52,     4,
1109     105,   106,    75,    76,    24,    77,   495,    35,     4,    88,
1110      89,    24,    25,    67,     4,    69,    88,    89,    72,    24,
1111      25,    94,    94,    43,     4,    73,    91,     4,    24,    25,
1112      84,    85,    86,    87,     4,    82,    83,     4,    73,    93,
1113       4,    95,    96,    97,    98,    99,   100,   101,   102,   103,
1114     104,    73,    74,   107,   108,   109,   110,   111,   112,    91,
1115     114,   115,   116,   117,   118,   119,   120,   121,   122,   123,
1116     124,   125,   126,   127,   128,   129,   130,   131,   132,   133,
1117     134,   135,   136,   137,   138,    28,    91,     4,    31,    15,
1118       4,    15,     4,     4,   148,   149,   150,   151,   152,    11,
1119      12,     4,    14,     4,    64,    65,     4,    24,    25,     4,
1120      24,    71,    24,    25,    28,     4,    73,    43,    44,    45,
1121      46,    73,   251,    47,    48,    27,    43,    27,   257,   258,
1122      36,    37,    75,    76,    27,    24,    25,   266,   267,   268,
1123     269,   270,   271,   272,   273,   274,   275,   276,    27,     4,
1124      17,    94,    19,    20,    16,   284,    11,   286,    21,    22,
1125      16,   290,   291,   292,     4,   294,   295,   296,   297,    24,
1126      25,    11,   301,   302,   303,    38,     4,    16,     4,    15,
1127       4,    47,    48,    28,    24,    25,     4,    15,     4,   318,
1128     319,    15,     4,    73,    29,    73,    24,    25,    24,    25,
1129      24,    25,   331,   332,    73,    25,    24,    25,    24,    25,
1130      27,    36,    24,    25,    27,   344,    90,    27,   346,   347,
1131     348,   349,   350,   351,   352,   353,   354,   355,   356,   357,
1132     358,   359,   360,   361,   362,    35,     4,     1,     4,     1,
1133     369,     4,   371,   372,   107,     9,    10,     9,    10,    43,
1134      44,    45,    46,    35,   117,   384,    24,    25,    24,    25,
1135     389,    24,    25,   392,    28,    11,    11,    31,    43,   398,
1136     259,   400,   401,   370,   137,   138,   139,   140,   141,   142,
1137     143,   144,   145,   146,   147,   498,    50,    51,   151,    53,
1138      54,    55,    56,     1,     4,   426,    73,     4,   432,   480,
1139      -1,     9,    10,    80,    81,    82,    28,    -1,    -1,    31,
1140      -1,    -1,    76,    -1,    24,    25,    -1,    24,    25,    -1,
1141      28,    -1,    -1,    31,    88,    89,    -1,    -1,    50,    51,
1142      94,    53,    54,    55,    56,     4,   465,    -1,    -1,     4,
1143     469,     4,    50,    51,    -1,    53,    54,    55,    56,   113,
1144       4,    -1,    -1,     4,    76,    24,    25,    -1,   487,    24,
1145      25,    24,    25,     4,    28,    -1,    88,    89,    76,     4,
1146      24,    25,    94,    24,    25,    39,    40,    -1,    42,    -1,
1147      88,    89,    -1,    24,    25,    -1,    94,    -1,     4,    24,
1148      25,   113,     4,    57,    58,    59,    60,    61,    62,     4,
1149      64,    65,    66,    -1,    68,   113,    70,    71,    24,    25,
1150      -1,     4,    24,    25,    -1,    -1,    -1,    -1,     4,    24,
1151      25,     7,    -1,    -1,    88,    89,    -1,    13,    -1,    15,
1152      94,    24,    25,    -1,    -1,    -1,    -1,    -1,    24
1153};
1154
1155  /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
1156     symbol of state STATE-NUM.  */
1157static const yytype_uint16 yystos[] =
1158{
1159       0,   154,   269,     0,     1,     3,     5,    17,    18,    19,
1160      21,    22,    23,    30,    31,    32,    33,    34,    41,    49,
1161      52,    67,    69,    72,    84,    85,    86,    87,    93,    95,
1162      96,    97,    98,    99,   100,   101,   102,   103,   104,   107,
1163     108,   109,   110,   111,   112,   114,   115,   116,   117,   118,
1164     119,   120,   121,   122,   123,   124,   125,   126,   127,   128,
1165     129,   130,   131,   132,   133,   134,   135,   136,   137,   138,
1166     148,   149,   150,   151,   152,   156,   159,   160,   161,   162,
1167     163,   164,   165,   166,   167,   168,   169,   170,   171,   172,
1168     173,   175,   176,   177,   178,   179,   180,   181,   182,   183,
1169     184,   185,   186,   187,   188,   189,   190,   191,   192,   193,
1170     194,   195,   196,   197,   198,   199,   200,   201,   202,   203,
1171     204,   205,   206,   207,   208,   209,   210,   211,   212,   213,
1172     214,   215,   216,   217,   218,   219,   220,   221,   224,   225,
1173     226,   229,   230,   235,   247,   248,   251,   252,   268,   270,
1174       4,     6,     7,     8,    10,   174,    73,    27,     4,    24,
1175      43,   155,     1,     9,    10,   158,   158,    73,     1,     7,
1176     105,   106,   155,    25,   155,    27,    73,    74,   155,   155,
1177      25,   155,    73,    73,    73,     4,     4,     4,     4,    25,
1178     155,    25,   155,   158,   158,   158,   158,     4,     4,     4,
1179       4,     4,   158,     4,   158,   105,   106,   157,   157,   158,
1180     158,   158,     4,   158,   158,   158,   158,   158,   158,    73,
1181     158,   158,   158,   158,   158,   158,   158,   158,   158,   158,
1182     158,   158,   158,    73,   158,   158,    73,   158,   158,   158,
1183     158,    73,    27,    27,    27,    27,    17,    19,    20,   222,
1184     223,   236,   227,   231,   249,   253,    16,    16,    16,    15,
1185      28,    28,   155,   237,   238,    28,    31,    50,    51,    53,
1186      54,    55,    56,    76,    88,    89,    94,   113,   228,    28,
1187      39,    40,    42,    57,    58,    59,    60,    61,    62,    64,
1188      65,    66,    68,    70,    71,    88,    89,    94,   232,    28,
1189      77,    88,    89,    94,   250,     1,    28,    82,    83,   254,
1190      73,    25,    43,   155,    25,   155,   223,    27,    88,    89,
1191     240,    25,   155,    11,    25,   155,   155,    11,    25,   155,
1192      11,    12,    14,    25,   155,    25,   155,    25,   155,    25,
1193     155,   155,   155,    25,    91,   155,    21,    22,    38,   107,
1194     117,   137,   138,   139,   140,   141,   142,   143,   144,   145,
1195     146,   147,   151,   243,    25,   155,   245,    25,   155,   233,
1196      64,    65,    71,   234,    25,   155,   155,   155,    73,    25,
1197     155,   155,   155,    25,    91,   155,   155,   155,    25,    91,
1198     155,   255,   257,   259,   261,   155,   155,    28,    31,    75,
1199      76,    94,   241,    25,   155,    25,   155,    25,   155,   158,
1200     158,   158,   158,   158,   158,   158,   158,   158,   158,   158,
1201     158,   158,   158,   158,   158,   158,    15,    43,    44,    45,
1202      46,   244,    15,    47,    48,   246,    15,    25,   155,   234,
1203      25,   155,    25,   155,    15,    25,   155,    73,    25,   155,
1204      25,   155,    29,   155,    25,    36,    37,   264,   265,   267,
1205      27,    27,    90,    25,   155,   242,    25,   155,    25,    91,
1206     155,   244,   246,    73,    80,    81,    82,   256,   258,   260,
1207      11,    35,   262,   266,   262,   239,     7,    13,    15,   155,
1208      25,   155,   262,   262,   262,   265,   263,    11,    27,     7,
1209     155,   262,   266,   266,   240,    11,    28,   266
1210};
1211
1212  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
1213static const yytype_uint16 yyr1[] =
1214{
1215       0,   153,   154,   155,   155,   156,   157,   157,   158,   158,
1216     158,   159,   160,   161,   162,   163,   164,   165,   166,   167,
1217     168,   168,   169,   170,   171,   172,   173,   174,   174,   174,
1218     174,   175,   176,   177,   177,   178,   179,   180,   181,   182,
1219     183,   184,   185,   186,   187,   188,   189,   190,   191,   192,
1220     193,   194,   195,   196,   197,   198,   199,   200,   201,   202,
1221     203,   204,   205,   206,   207,   207,   208,   208,   209,   210,
1222     210,   211,   211,   212,   213,   214,   215,   216,   217,   218,
1223     218,   219,   220,   221,   222,   222,   222,   222,   222,   222,
1224     223,   223,   224,   225,   225,   225,   225,   225,   226,   227,
1225     227,   228,   228,   228,   228,   228,   228,   228,   228,   228,
1226     228,   228,   228,   228,   228,   228,   228,   228,   228,   228,
1227     228,   228,   228,   228,   228,   228,   228,   228,   228,   228,
1228     228,   228,   228,   228,   228,   228,   228,   228,   228,   228,
1229     228,   228,   228,   228,   228,   228,   228,   228,   229,   230,
1230     231,   231,   232,   232,   232,   232,   232,   232,   232,   232,
1231     232,   232,   232,   232,   232,   232,   232,   232,   232,   232,
1232     232,   232,   232,   232,   232,   232,   232,   232,   232,   232,
1233     232,   232,   232,   232,   233,   233,   233,   233,   234,   234,
1234     234,   234,   235,   236,   236,   237,   237,   237,   238,   239,
1235     238,   240,   240,   241,   241,   241,   241,   241,   241,   241,
1236     241,   241,   242,   242,   242,   242,   242,   242,   243,   243,
1237     243,   244,   244,   244,   244,   245,   245,   245,   246,   246,
1238     247,   247,   248,   249,   249,   250,   250,   250,   250,   250,
1239     250,   250,   251,   252,   253,   253,   255,   256,   254,   257,
1240     258,   254,   259,   260,   254,   261,   254,   254,   263,   262,
1241     262,   264,   264,   264,   264,   264,   264,   265,   266,   267,
1242     268,   269,   269,   270,   270,   270,   270,   270,   270,   270,
1243     270,   270,   270,   270,   270,   270,   270,   270,   270,   270,
1244     270,   270,   270,   270,   270,   270,   270,   270,   270,   270,
1245     270,   270,   270,   270,   270,   270,   270,   270,   270,   270,
1246     270,   270,   270,   270,   270,   270,   270,   270,   270,   270,
1247     270,   270,   270,   270,   270,   270,   270,   270,   270,   270,
1248     270,   270,   270,   270,   270,   270,   270,   270,   270,   270,
1249     270,   270,   270,   270,   270
1250};
1251
1252  /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
1253static const yytype_uint8 yyr2[] =
1254{
1255       0,     2,     1,     1,     1,     2,     1,     1,     1,     1,
1256       1,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1257       2,     2,     2,     2,     2,     2,     2,     1,     1,     1,
1258       1,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1259       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1260       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1261       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1262       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1263       2,     2,     2,     2,     3,     3,     3,     3,     3,     3,
1264       3,     1,     4,     2,     2,     2,     2,     2,     4,     0,
1265       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1266       2,     3,     3,     3,     3,     2,     2,     2,     2,     2,
1267       2,     2,     2,     2,     2,     3,     3,     3,     3,     2,
1268       3,     2,     3,     3,     3,     3,     3,     3,     3,     3,
1269       3,     3,     3,     3,     3,     3,     2,     2,     2,     4,
1270       0,     2,     2,     2,     3,     2,     2,     3,     3,     2,
1271       2,     2,     2,     3,     3,     4,     4,     4,     4,     2,
1272       2,     2,     2,     2,     2,     1,     1,     2,     2,     3,
1273       3,     2,     2,     1,     0,     2,     2,     2,     0,     2,
1274       2,     2,     4,     0,     2,     2,     4,     4,     3,     0,
1275       8,     0,     2,     2,     2,     2,     2,     2,     3,     3,
1276       2,     2,     0,     2,     2,     3,     3,     2,     0,     2,
1277       3,     1,     1,     1,     1,     0,     2,     3,     1,     1,
1278       2,     2,     4,     0,     2,     1,     2,     2,     3,     3,
1279       2,     2,     2,     4,     0,     2,     0,     0,     5,     0,
1280       0,     5,     0,     0,     5,     0,     3,     1,     0,     5,
1281       3,     2,     1,     4,     3,     2,     1,     1,     1,     1,
1282       1,     0,     2,     1,     1,     1,     1,     1,     1,     1,
1283       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
1284       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
1285       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
1286       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
1287       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
1288       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
1289       1,     1,     1,     1,     1
1290};
1291
1292
1293#define yyerrok         (yyerrstatus = 0)
1294#define yyclearin       (yychar = YYEMPTY)
1295#define YYEMPTY         (-2)
1296#define YYEOF           0
1297
1298#define YYACCEPT        goto yyacceptlab
1299#define YYABORT         goto yyabortlab
1300#define YYERROR         goto yyerrorlab
1301
1302
1303#define YYRECOVERING()  (!!yyerrstatus)
1304
1305#define YYBACKUP(Token, Value)                                  \
1306do                                                              \
1307  if (yychar == YYEMPTY)                                        \
1308    {                                                           \
1309      yychar = (Token);                                         \
1310      yylval = (Value);                                         \
1311      YYPOPSTACK (yylen);                                       \
1312      yystate = *yyssp;                                         \
1313      goto yybackup;                                            \
1314    }                                                           \
1315  else                                                          \
1316    {                                                           \
1317      yyerror (YY_("syntax error: cannot back up")); \
1318      YYERROR;                                                  \
1319    }                                                           \
1320while (0)
1321
1322/* Error token number */
1323#define YYTERROR        1
1324#define YYERRCODE       256
1325
1326
1327
1328/* Enable debugging if requested.  */
1329#if YYDEBUG
1330
1331# ifndef YYFPRINTF
1332#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
1333#  define YYFPRINTF fprintf
1334# endif
1335
1336# define YYDPRINTF(Args)                        \
1337do {                                            \
1338  if (yydebug)                                  \
1339    YYFPRINTF Args;                             \
1340} while (0)
1341
1342/* This macro is provided for backward compatibility. */
1343#ifndef YY_LOCATION_PRINT
1344# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
1345#endif
1346
1347
1348# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
1349do {                                                                      \
1350  if (yydebug)                                                            \
1351    {                                                                     \
1352      YYFPRINTF (stderr, "%s ", Title);                                   \
1353      yy_symbol_print (stderr,                                            \
1354                  Type, Value); \
1355      YYFPRINTF (stderr, "\n");                                           \
1356    }                                                                     \
1357} while (0)
1358
1359
1360/*----------------------------------------.
1361| Print this symbol's value on YYOUTPUT.  |
1362`----------------------------------------*/
1363
1364static void
1365yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
1366{
1367  FILE *yyo = yyoutput;
1368  YYUSE (yyo);
1369  if (!yyvaluep)
1370    return;
1371# ifdef YYPRINT
1372  if (yytype < YYNTOKENS)
1373    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
1374# endif
1375  YYUSE (yytype);
1376}
1377
1378
1379/*--------------------------------.
1380| Print this symbol on YYOUTPUT.  |
1381`--------------------------------*/
1382
1383static void
1384yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
1385{
1386  YYFPRINTF (yyoutput, "%s %s (",
1387             yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
1388
1389  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
1390  YYFPRINTF (yyoutput, ")");
1391}
1392
1393/*------------------------------------------------------------------.
1394| yy_stack_print -- Print the state stack from its BOTTOM up to its |
1395| TOP (included).                                                   |
1396`------------------------------------------------------------------*/
1397
1398static void
1399yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
1400{
1401  YYFPRINTF (stderr, "Stack now");
1402  for (; yybottom <= yytop; yybottom++)
1403    {
1404      int yybot = *yybottom;
1405      YYFPRINTF (stderr, " %d", yybot);
1406    }
1407  YYFPRINTF (stderr, "\n");
1408}
1409
1410# define YY_STACK_PRINT(Bottom, Top)                            \
1411do {                                                            \
1412  if (yydebug)                                                  \
1413    yy_stack_print ((Bottom), (Top));                           \
1414} while (0)
1415
1416
1417/*------------------------------------------------.
1418| Report that the YYRULE is going to be reduced.  |
1419`------------------------------------------------*/
1420
1421static void
1422yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
1423{
1424  unsigned long int yylno = yyrline[yyrule];
1425  int yynrhs = yyr2[yyrule];
1426  int yyi;
1427  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
1428             yyrule - 1, yylno);
1429  /* The symbols being reduced.  */
1430  for (yyi = 0; yyi < yynrhs; yyi++)
1431    {
1432      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
1433      yy_symbol_print (stderr,
1434                       yystos[yyssp[yyi + 1 - yynrhs]],
1435                       &(yyvsp[(yyi + 1) - (yynrhs)])
1436                                              );
1437      YYFPRINTF (stderr, "\n");
1438    }
1439}
1440
1441# define YY_REDUCE_PRINT(Rule)          \
1442do {                                    \
1443  if (yydebug)                          \
1444    yy_reduce_print (yyssp, yyvsp, Rule); \
1445} while (0)
1446
1447/* Nonzero means print parse trace.  It is left uninitialized so that
1448   multiple parsers can coexist.  */
1449int yydebug;
1450#else /* !YYDEBUG */
1451# define YYDPRINTF(Args)
1452# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
1453# define YY_STACK_PRINT(Bottom, Top)
1454# define YY_REDUCE_PRINT(Rule)
1455#endif /* !YYDEBUG */
1456
1457
1458/* YYINITDEPTH -- initial size of the parser's stacks.  */
1459#ifndef YYINITDEPTH
1460# define YYINITDEPTH 200
1461#endif
1462
1463/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
1464   if the built-in stack extension method is used).
1465
1466   Do not make this value too large; the results are undefined if
1467   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
1468   evaluated with infinite-precision integer arithmetic.  */
1469
1470#ifndef YYMAXDEPTH
1471# define YYMAXDEPTH 10000
1472#endif
1473
1474
1475#if YYERROR_VERBOSE
1476
1477# ifndef yystrlen
1478#  if defined __GLIBC__ && defined _STRING_H
1479#   define yystrlen strlen
1480#  else
1481/* Return the length of YYSTR.  */
1482static YYSIZE_T
1483yystrlen (const char *yystr)
1484{
1485  YYSIZE_T yylen;
1486  for (yylen = 0; yystr[yylen]; yylen++)
1487    continue;
1488  return yylen;
1489}
1490#  endif
1491# endif
1492
1493# ifndef yystpcpy
1494#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
1495#   define yystpcpy stpcpy
1496#  else
1497/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
1498   YYDEST.  */
1499static char *
1500yystpcpy (char *yydest, const char *yysrc)
1501{
1502  char *yyd = yydest;
1503  const char *yys = yysrc;
1504
1505  while ((*yyd++ = *yys++) != '\0')
1506    continue;
1507
1508  return yyd - 1;
1509}
1510#  endif
1511# endif
1512
1513# ifndef yytnamerr
1514/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
1515   quotes and backslashes, so that it's suitable for yyerror.  The
1516   heuristic is that double-quoting is unnecessary unless the string
1517   contains an apostrophe, a comma, or backslash (other than
1518   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
1519   null, do not copy; instead, return the length of what the result
1520   would have been.  */
1521static YYSIZE_T
1522yytnamerr (char *yyres, const char *yystr)
1523{
1524  if (*yystr == '"')
1525    {
1526      YYSIZE_T yyn = 0;
1527      char const *yyp = yystr;
1528
1529      for (;;)
1530        switch (*++yyp)
1531          {
1532          case '\'':
1533          case ',':
1534            goto do_not_strip_quotes;
1535
1536          case '\\':
1537            if (*++yyp != '\\')
1538              goto do_not_strip_quotes;
1539            /* Fall through.  */
1540          default:
1541            if (yyres)
1542              yyres[yyn] = *yyp;
1543            yyn++;
1544            break;
1545
1546          case '"':
1547            if (yyres)
1548              yyres[yyn] = '\0';
1549            return yyn;
1550          }
1551    do_not_strip_quotes: ;
1552    }
1553
1554  if (! yyres)
1555    return yystrlen (yystr);
1556
1557  return yystpcpy (yyres, yystr) - yyres;
1558}
1559# endif
1560
1561/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
1562   about the unexpected token YYTOKEN for the state stack whose top is
1563   YYSSP.
1564
1565   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
1566   not large enough to hold the message.  In that case, also set
1567   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
1568   required number of bytes is too large to store.  */
1569static int
1570yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
1571                yytype_int16 *yyssp, int yytoken)
1572{
1573  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
1574  YYSIZE_T yysize = yysize0;
1575  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1576  /* Internationalized format string. */
1577  const char *yyformat = YY_NULLPTR;
1578  /* Arguments of yyformat. */
1579  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1580  /* Number of reported tokens (one for the "unexpected", one per
1581     "expected"). */
1582  int yycount = 0;
1583
1584  /* There are many possibilities here to consider:
1585     - If this state is a consistent state with a default action, then
1586       the only way this function was invoked is if the default action
1587       is an error action.  In that case, don't check for expected
1588       tokens because there are none.
1589     - The only way there can be no lookahead present (in yychar) is if
1590       this state is a consistent state with a default action.  Thus,
1591       detecting the absence of a lookahead is sufficient to determine
1592       that there is no unexpected or expected token to report.  In that
1593       case, just report a simple "syntax error".
1594     - Don't assume there isn't a lookahead just because this state is a
1595       consistent state with a default action.  There might have been a
1596       previous inconsistent state, consistent state with a non-default
1597       action, or user semantic action that manipulated yychar.
1598     - Of course, the expected token list depends on states to have
1599       correct lookahead information, and it depends on the parser not
1600       to perform extra reductions after fetching a lookahead from the
1601       scanner and before detecting a syntax error.  Thus, state merging
1602       (from LALR or IELR) and default reductions corrupt the expected
1603       token list.  However, the list is correct for canonical LR with
1604       one exception: it will still contain any token that will not be
1605       accepted due to an error action in a later state.
1606  */
1607  if (yytoken != YYEMPTY)
1608    {
1609      int yyn = yypact[*yyssp];
1610      yyarg[yycount++] = yytname[yytoken];
1611      if (!yypact_value_is_default (yyn))
1612        {
1613          /* Start YYX at -YYN if negative to avoid negative indexes in
1614             YYCHECK.  In other words, skip the first -YYN actions for
1615             this state because they are default actions.  */
1616          int yyxbegin = yyn < 0 ? -yyn : 0;
1617          /* Stay within bounds of both yycheck and yytname.  */
1618          int yychecklim = YYLAST - yyn + 1;
1619          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1620          int yyx;
1621
1622          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1623            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
1624                && !yytable_value_is_error (yytable[yyx + yyn]))
1625              {
1626                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1627                  {
1628                    yycount = 1;
1629                    yysize = yysize0;
1630                    break;
1631                  }
1632                yyarg[yycount++] = yytname[yyx];
1633                {
1634                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
1635                  if (! (yysize <= yysize1
1636                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1637                    return 2;
1638                  yysize = yysize1;
1639                }
1640              }
1641        }
1642    }
1643
1644  switch (yycount)
1645    {
1646# define YYCASE_(N, S)                      \
1647      case N:                               \
1648        yyformat = S;                       \
1649      break
1650      YYCASE_(0, YY_("syntax error"));
1651      YYCASE_(1, YY_("syntax error, unexpected %s"));
1652      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
1653      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
1654      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
1655      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
1656# undef YYCASE_
1657    }
1658
1659  {
1660    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
1661    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1662      return 2;
1663    yysize = yysize1;
1664  }
1665
1666  if (*yymsg_alloc < yysize)
1667    {
1668      *yymsg_alloc = 2 * yysize;
1669      if (! (yysize <= *yymsg_alloc
1670             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
1671        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
1672      return 1;
1673    }
1674
1675  /* Avoid sprintf, as that infringes on the user's name space.
1676     Don't have undefined behavior even if the translation
1677     produced a string with the wrong number of "%s"s.  */
1678  {
1679    char *yyp = *yymsg;
1680    int yyi = 0;
1681    while ((*yyp = *yyformat) != '\0')
1682      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
1683        {
1684          yyp += yytnamerr (yyp, yyarg[yyi++]);
1685          yyformat += 2;
1686        }
1687      else
1688        {
1689          yyp++;
1690          yyformat++;
1691        }
1692  }
1693  return 0;
1694}
1695#endif /* YYERROR_VERBOSE */
1696
1697/*-----------------------------------------------.
1698| Release the memory associated to this symbol.  |
1699`-----------------------------------------------*/
1700
1701static void
1702yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1703{
1704  YYUSE (yyvaluep);
1705  if (!yymsg)
1706    yymsg = "Deleting";
1707  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1708
1709  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1710  YYUSE (yytype);
1711  YY_IGNORE_MAYBE_UNINITIALIZED_END
1712}
1713
1714
1715
1716
1717/* The lookahead symbol.  */
1718int yychar;
1719
1720/* The semantic value of the lookahead symbol.  */
1721YYSTYPE yylval;
1722/* Number of syntax errors so far.  */
1723int yynerrs;
1724
1725
1726/*----------.
1727| yyparse.  |
1728`----------*/
1729
1730int
1731yyparse (void)
1732{
1733    int yystate;
1734    /* Number of tokens to shift before error messages enabled.  */
1735    int yyerrstatus;
1736
1737    /* The stacks and their tools:
1738       'yyss': related to states.
1739       'yyvs': related to semantic values.
1740
1741       Refer to the stacks through separate pointers, to allow yyoverflow
1742       to reallocate them elsewhere.  */
1743
1744    /* The state stack.  */
1745    yytype_int16 yyssa[YYINITDEPTH];
1746    yytype_int16 *yyss;
1747    yytype_int16 *yyssp;
1748
1749    /* The semantic value stack.  */
1750    YYSTYPE yyvsa[YYINITDEPTH];
1751    YYSTYPE *yyvs;
1752    YYSTYPE *yyvsp;
1753
1754    YYSIZE_T yystacksize;
1755
1756  int yyn;
1757  int yyresult;
1758  /* Lookahead token as an internal (translated) token number.  */
1759  int yytoken = 0;
1760  /* The variables used to return semantic value and location from the
1761     action routines.  */
1762  YYSTYPE yyval;
1763
1764#if YYERROR_VERBOSE
1765  /* Buffer for error messages, and its allocated size.  */
1766  char yymsgbuf[128];
1767  char *yymsg = yymsgbuf;
1768  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1769#endif
1770
1771#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
1772
1773  /* The number of symbols on the RHS of the reduced rule.
1774     Keep to zero when no symbol should be popped.  */
1775  int yylen = 0;
1776
1777  yyssp = yyss = yyssa;
1778  yyvsp = yyvs = yyvsa;
1779  yystacksize = YYINITDEPTH;
1780
1781  YYDPRINTF ((stderr, "Starting parse\n"));
1782
1783  yystate = 0;
1784  yyerrstatus = 0;
1785  yynerrs = 0;
1786  yychar = YYEMPTY; /* Cause a token to be read.  */
1787  goto yysetstate;
1788
1789/*------------------------------------------------------------.
1790| yynewstate -- Push a new state, which is found in yystate.  |
1791`------------------------------------------------------------*/
1792 yynewstate:
1793  /* In all cases, when you get here, the value and location stacks
1794     have just been pushed.  So pushing a state here evens the stacks.  */
1795  yyssp++;
1796
1797 yysetstate:
1798  *yyssp = yystate;
1799
1800  if (yyss + yystacksize - 1 <= yyssp)
1801    {
1802      /* Get the current used size of the three stacks, in elements.  */
1803      YYSIZE_T yysize = yyssp - yyss + 1;
1804
1805#ifdef yyoverflow
1806      {
1807        /* Give user a chance to reallocate the stack.  Use copies of
1808           these so that the &'s don't force the real ones into
1809           memory.  */
1810        YYSTYPE *yyvs1 = yyvs;
1811        yytype_int16 *yyss1 = yyss;
1812
1813        /* Each stack pointer address is followed by the size of the
1814           data in use in that stack, in bytes.  This used to be a
1815           conditional around just the two extra args, but that might
1816           be undefined if yyoverflow is a macro.  */
1817        yyoverflow (YY_("memory exhausted"),
1818                    &yyss1, yysize * sizeof (*yyssp),
1819                    &yyvs1, yysize * sizeof (*yyvsp),
1820                    &yystacksize);
1821
1822        yyss = yyss1;
1823        yyvs = yyvs1;
1824      }
1825#else /* no yyoverflow */
1826# ifndef YYSTACK_RELOCATE
1827      goto yyexhaustedlab;
1828# else
1829      /* Extend the stack our own way.  */
1830      if (YYMAXDEPTH <= yystacksize)
1831        goto yyexhaustedlab;
1832      yystacksize *= 2;
1833      if (YYMAXDEPTH < yystacksize)
1834        yystacksize = YYMAXDEPTH;
1835
1836      {
1837        yytype_int16 *yyss1 = yyss;
1838        union yyalloc *yyptr =
1839          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1840        if (! yyptr)
1841          goto yyexhaustedlab;
1842        YYSTACK_RELOCATE (yyss_alloc, yyss);
1843        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1844#  undef YYSTACK_RELOCATE
1845        if (yyss1 != yyssa)
1846          YYSTACK_FREE (yyss1);
1847      }
1848# endif
1849#endif /* no yyoverflow */
1850
1851      yyssp = yyss + yysize - 1;
1852      yyvsp = yyvs + yysize - 1;
1853
1854      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1855                  (unsigned long int) yystacksize));
1856
1857      if (yyss + yystacksize - 1 <= yyssp)
1858        YYABORT;
1859    }
1860
1861  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1862
1863  if (yystate == YYFINAL)
1864    YYACCEPT;
1865
1866  goto yybackup;
1867
1868/*-----------.
1869| yybackup.  |
1870`-----------*/
1871yybackup:
1872
1873  /* Do appropriate processing given the current state.  Read a
1874     lookahead token if we need one and don't already have one.  */
1875
1876  /* First try to decide what to do without reference to lookahead token.  */
1877  yyn = yypact[yystate];
1878  if (yypact_value_is_default (yyn))
1879    goto yydefault;
1880
1881  /* Not known => get a lookahead token if don't already have one.  */
1882
1883  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
1884  if (yychar == YYEMPTY)
1885    {
1886      YYDPRINTF ((stderr, "Reading a token: "));
1887      yychar = yylex ();
1888    }
1889
1890  if (yychar <= YYEOF)
1891    {
1892      yychar = yytoken = YYEOF;
1893      YYDPRINTF ((stderr, "Now at end of input.\n"));
1894    }
1895  else
1896    {
1897      yytoken = YYTRANSLATE (yychar);
1898      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1899    }
1900
1901  /* If the proper action on seeing token YYTOKEN is to reduce or to
1902     detect an error, take that action.  */
1903  yyn += yytoken;
1904  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1905    goto yydefault;
1906  yyn = yytable[yyn];
1907  if (yyn <= 0)
1908    {
1909      if (yytable_value_is_error (yyn))
1910        goto yyerrlab;
1911      yyn = -yyn;
1912      goto yyreduce;
1913    }
1914
1915  /* Count tokens shifted since error; after three, turn off error
1916     status.  */
1917  if (yyerrstatus)
1918    yyerrstatus--;
1919
1920  /* Shift the lookahead token.  */
1921  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1922
1923  /* Discard the shifted token.  */
1924  yychar = YYEMPTY;
1925
1926  yystate = yyn;
1927  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1928  *++yyvsp = yylval;
1929  YY_IGNORE_MAYBE_UNINITIALIZED_END
1930
1931  goto yynewstate;
1932
1933
1934/*-----------------------------------------------------------.
1935| yydefault -- do the default action for the current state.  |
1936`-----------------------------------------------------------*/
1937yydefault:
1938  yyn = yydefact[yystate];
1939  if (yyn == 0)
1940    goto yyerrlab;
1941  goto yyreduce;
1942
1943
1944/*-----------------------------.
1945| yyreduce -- Do a reduction.  |
1946`-----------------------------*/
1947yyreduce:
1948  /* yyn is the number of a rule to reduce with.  */
1949  yylen = yyr2[yyn];
1950
1951  /* If YYLEN is nonzero, implement the default value of the action:
1952     '$$ = $1'.
1953
1954     Otherwise, the following line sets YYVAL to garbage.
1955     This behavior is undocumented and Bison
1956     users should not rely upon it.  Assigning to YYVAL
1957     unconditionally makes the parser a bit smaller, and it avoids a
1958     GCC warning that YYVAL may be used uninitialized.  */
1959  yyval = yyvsp[1-yylen];
1960
1961
1962  YY_REDUCE_PRINT (yyn);
1963  switch (yyn)
1964    {
1965        case 3:
1966#line 230 "grammar.y" /* yacc.c:1646  */
1967    { (yyval.string) = (yyvsp[0].string); }
1968#line 1969 "grammar.tab.c" /* yacc.c:1646  */
1969    break;
1970
1971  case 4:
1972#line 231 "grammar.y" /* yacc.c:1646  */
1973    { (yyval.string) = (yyvsp[0].string); }
1974#line 1975 "grammar.tab.c" /* yacc.c:1646  */
1975    break;
1976
1977  case 5:
1978#line 235 "grammar.y" /* yacc.c:1646  */
1979    { ufdbNewGV.httpsConnectionCacheSize = atoi( (yyvsp[0].string) );
1980		                                         ufdbFree( (yyvsp[0].string) ); }
1981#line 1982 "grammar.tab.c" /* yacc.c:1646  */
1982    break;
1983
1984  case 6:
1985#line 240 "grammar.y" /* yacc.c:1646  */
1986    { (yyval.integer) = UFDB_ALLOW; }
1987#line 1988 "grammar.tab.c" /* yacc.c:1646  */
1988    break;
1989
1990  case 7:
1991#line 241 "grammar.y" /* yacc.c:1646  */
1992    { (yyval.integer) = UFDB_DENY; }
1993#line 1994 "grammar.tab.c" /* yacc.c:1646  */
1994    break;
1995
1996  case 8:
1997#line 245 "grammar.y" /* yacc.c:1646  */
1998    { (yyval.integer) = 1; }
1999#line 2000 "grammar.tab.c" /* yacc.c:1646  */
2000    break;
2001
2002  case 9:
2003#line 246 "grammar.y" /* yacc.c:1646  */
2004    { (yyval.integer) = 0; }
2005#line 2006 "grammar.tab.c" /* yacc.c:1646  */
2006    break;
2007
2008  case 10:
2009#line 247 "grammar.y" /* yacc.c:1646  */
2010    { ufdbLogFatalError( "syntax error at line %d: expected 'on' or 'off'", lineno );   }
2011#line 2012 "grammar.tab.c" /* yacc.c:1646  */
2012    break;
2013
2014  case 11:
2015#line 251 "grammar.y" /* yacc.c:1646  */
2016    { ufdbNewGV.logPass = (yyvsp[0].integer); }
2017#line 2018 "grammar.tab.c" /* yacc.c:1646  */
2018    break;
2019
2020  case 12:
2021#line 255 "grammar.y" /* yacc.c:1646  */
2022    { ufdbNewGV.logBlock = (yyvsp[0].integer); }
2023#line 2024 "grammar.tab.c" /* yacc.c:1646  */
2024    break;
2025
2026  case 13:
2027#line 259 "grammar.y" /* yacc.c:1646  */
2028    { ufdbNewGV.logAllRequests = (yyvsp[0].integer); }
2029#line 2030 "grammar.tab.c" /* yacc.c:1646  */
2030    break;
2031
2032  case 14:
2033#line 263 "grammar.y" /* yacc.c:1646  */
2034    { ufdbNewGV.debugHttpd = (yyvsp[0].integer); }
2035#line 2036 "grammar.tab.c" /* yacc.c:1646  */
2036    break;
2037
2038  case 15:
2039#line 267 "grammar.y" /* yacc.c:1646  */
2040    { ufdbNewGV.YoutubeEdufilter = (yyvsp[0].integer); }
2041#line 2042 "grammar.tab.c" /* yacc.c:1646  */
2042    break;
2043
2044  case 16:
2045#line 271 "grammar.y" /* yacc.c:1646  */
2046    { ufdbNewGV.YoutubeEdufilterID = (yyvsp[0].string); }
2047#line 2048 "grammar.tab.c" /* yacc.c:1646  */
2048    break;
2049
2050  case 17:
2051#line 275 "grammar.y" /* yacc.c:1646  */
2052    { ufdbNewGV.allowGoogleHTTPSusingIP = (yyvsp[0].integer); }
2053#line 2054 "grammar.tab.c" /* yacc.c:1646  */
2054    break;
2055
2056  case 18:
2057#line 279 "grammar.y" /* yacc.c:1646  */
2058    { ufdbNewGV.madviseHugePages = (yyvsp[0].integer); }
2059#line 2060 "grammar.tab.c" /* yacc.c:1646  */
2060    break;
2061
2062  case 19:
2063#line 283 "grammar.y" /* yacc.c:1646  */
2064    { ufdbNewGV.fastRefresh = (yyvsp[0].integer); }
2065#line 2066 "grammar.tab.c" /* yacc.c:1646  */
2066    break;
2067
2068  case 20:
2069#line 287 "grammar.y" /* yacc.c:1646  */
2070    { ufdbNewGV.debug = ufdbGV.debug = (yyvsp[0].integer); }
2071#line 2072 "grammar.tab.c" /* yacc.c:1646  */
2072    break;
2073
2074  case 21:
2075#line 288 "grammar.y" /* yacc.c:1646  */
2076    { ufdbNewGV.debug = ufdbGV.debug = atoi( (yyvsp[0].string) );
2077		                                  ufdbFree( (yyvsp[0].string) ); }
2078#line 2079 "grammar.tab.c" /* yacc.c:1646  */
2079    break;
2080
2081  case 22:
2082#line 293 "grammar.y" /* yacc.c:1646  */
2083    { ufdbNewGV.debugCoreDump = (yyvsp[0].integer); }
2084#line 2085 "grammar.tab.c" /* yacc.c:1646  */
2085    break;
2086
2087  case 23:
2088#line 298 "grammar.y" /* yacc.c:1646  */
2089    { ufdbLogError( "line %d: option enforce-https-with-hostname must be part of "
2090                                    "the security category", lineno );  }
2091#line 2092 "grammar.tab.c" /* yacc.c:1646  */
2092    break;
2093
2094  case 24:
2095#line 304 "grammar.y" /* yacc.c:1646  */
2096    { ufdbLogError( "line %d: option enforce-https-official-certificate must be part of "
2097                                  "the security category", lineno );  }
2098#line 2099 "grammar.tab.c" /* yacc.c:1646  */
2099    break;
2100
2101  case 25:
2102#line 310 "grammar.y" /* yacc.c:1646  */
2103    { ufdbLogError( "line %d: option https-prohibit-insecure-sslv2 must be part of "
2104                                    "the security category", lineno );  }
2105#line 2106 "grammar.tab.c" /* yacc.c:1646  */
2106    break;
2107
2108  case 26:
2109#line 316 "grammar.y" /* yacc.c:1646  */
2110    { ufdbLogError( "line %d: option https-prohibit-insecure-sslv3 must be part of "
2111                                    "the security category", lineno );  }
2112#line 2113 "grammar.tab.c" /* yacc.c:1646  */
2113    break;
2114
2115  case 27:
2116#line 322 "grammar.y" /* yacc.c:1646  */
2117    { (yyval.integer) = UFDB_API_HTTPS_CHECK_OFF; }
2118#line 2119 "grammar.tab.c" /* yacc.c:1646  */
2119    break;
2120
2121  case 28:
2122#line 323 "grammar.y" /* yacc.c:1646  */
2123    { (yyval.integer) = UFDB_API_HTTPS_CHECK_QUEUE_CHECKS; }
2124#line 2125 "grammar.tab.c" /* yacc.c:1646  */
2125    break;
2126
2127  case 29:
2128#line 324 "grammar.y" /* yacc.c:1646  */
2129    { (yyval.integer) = UFDB_API_HTTPS_CHECK_AGGRESSIVE; }
2130#line 2131 "grammar.tab.c" /* yacc.c:1646  */
2131    break;
2132
2133  case 30:
2134#line 325 "grammar.y" /* yacc.c:1646  */
2135    { (yyval.integer) = UFDB_API_HTTPS_LOG_ONLY; }
2136#line 2137 "grammar.tab.c" /* yacc.c:1646  */
2137    break;
2138
2139  case 31:
2140#line 329 "grammar.y" /* yacc.c:1646  */
2141    { ufdbNewGV.tunnelCheckMethod = (yyvsp[0].integer); }
2142#line 2143 "grammar.tab.c" /* yacc.c:1646  */
2143    break;
2144
2145  case 32:
2146#line 333 "grammar.y" /* yacc.c:1646  */
2147    { setAdministrator( (yyvsp[0].string) ); }
2148#line 2149 "grammar.tab.c" /* yacc.c:1646  */
2149    break;
2150
2151  case 33:
2152#line 337 "grammar.y" /* yacc.c:1646  */
2153    { setDBhome( (yyvsp[0].string) ); }
2154#line 2155 "grammar.tab.c" /* yacc.c:1646  */
2155    break;
2156
2157  case 34:
2158#line 338 "grammar.y" /* yacc.c:1646  */
2159    { setDBhome( (yyvsp[0].string) ); }
2160#line 2161 "grammar.tab.c" /* yacc.c:1646  */
2161    break;
2162
2163  case 35:
2164#line 342 "grammar.y" /* yacc.c:1646  */
2165    { setRefreshUserlist( atoi((yyvsp[0].string)) );
2166		                                ufdbFree( (yyvsp[0].string) ); }
2167#line 2168 "grammar.tab.c" /* yacc.c:1646  */
2168    break;
2169
2170  case 36:
2171#line 347 "grammar.y" /* yacc.c:1646  */
2172    { setRefreshIPlist( atoi((yyvsp[0].string)) );
2173		                                ufdbFree( (yyvsp[0].string) ); }
2174#line 2175 "grammar.tab.c" /* yacc.c:1646  */
2175    break;
2176
2177  case 37:
2178#line 352 "grammar.y" /* yacc.c:1646  */
2179    { setRefreshDomainlist( atoi((yyvsp[0].string)) );
2180		                                ufdbFree( (yyvsp[0].string) ); }
2181#line 2182 "grammar.tab.c" /* yacc.c:1646  */
2182    break;
2183
2184  case 38:
2185#line 358 "grammar.y" /* yacc.c:1646  */
2186    { ufdbNewGV.URLlookupResultDBreload = (yyvsp[0].integer); }
2187#line 2188 "grammar.tab.c" /* yacc.c:1646  */
2188    break;
2189
2190  case 39:
2191#line 362 "grammar.y" /* yacc.c:1646  */
2192    { ufdbNewGV.URLlookupResultFatalError = (yyvsp[0].integer); }
2193#line 2194 "grammar.tab.c" /* yacc.c:1646  */
2194    break;
2195
2196  case 40:
2197#line 366 "grammar.y" /* yacc.c:1646  */
2198    { ufdbNewGV.URLlookupDelayDBreload = (yyvsp[0].integer); }
2199#line 2200 "grammar.tab.c" /* yacc.c:1646  */
2200    break;
2201
2202  case 41:
2203#line 370 "grammar.y" /* yacc.c:1646  */
2204    { ufdbFree( ufdbNewGV.SquidVersion );  ufdbNewGV.SquidVersion = (yyvsp[0].string);  }
2205#line 2206 "grammar.tab.c" /* yacc.c:1646  */
2206    break;
2207
2208  case 42:
2209#line 375 "grammar.y" /* yacc.c:1646  */
2210    { int new_n_workers;
2211					  /* ONLY increase #workers */
2212					  new_n_workers = atoi( (yyvsp[0].string) );
2213		                          ufdbFree( (yyvsp[0].string) );
2214					  if (new_n_workers < UFDB_MIN_THREADS)
2215					  {
2216					     ufdbLogError( "num-worker-threads must be at least %d",
2217                                                           UFDB_MIN_THREADS );
2218					     new_n_workers = UFDB_MIN_THREADS;
2219					  }
2220					  else if (new_n_workers > UFDB_MAX_THREADS)
2221					  {
2222					     ufdbLogError( "num-worker-threads can be at most %d",
2223                                                           UFDB_MAX_THREADS );
2224					     new_n_workers = UFDB_MAX_THREADS;
2225					  }
2226					  if (new_n_workers > ufdbNewGV.nWorkers)
2227					     ufdbNewGV.nWorkers = new_n_workers;
2228					}
2229#line 2230 "grammar.tab.c" /* yacc.c:1646  */
2230    break;
2231
2232  case 43:
2233#line 398 "grammar.y" /* yacc.c:1646  */
2234    { ufdbNewGV.uploadCrashReports = (yyvsp[0].integer);  }
2235#line 2236 "grammar.tab.c" /* yacc.c:1646  */
2236    break;
2237
2238  case 44:
2239#line 403 "grammar.y" /* yacc.c:1646  */
2240    { ufdbNewGV.lookupReverseIP = (yyvsp[0].integer);  }
2241#line 2242 "grammar.tab.c" /* yacc.c:1646  */
2242    break;
2243
2244  case 45:
2245#line 408 "grammar.y" /* yacc.c:1646  */
2246    { ufdbNewGV.useAlsoIPv6onWan = (yyvsp[0].integer);  }
2247#line 2248 "grammar.tab.c" /* yacc.c:1646  */
2248    break;
2249
2250  case 46:
2251#line 413 "grammar.y" /* yacc.c:1646  */
2252    { ufdbNewGV.parseURLparameters = (yyvsp[0].integer);  }
2253#line 2254 "grammar.tab.c" /* yacc.c:1646  */
2254    break;
2255
2256  case 47:
2257#line 418 "grammar.y" /* yacc.c:1646  */
2258    { ufdbNewGV.SquidUsesActiveBumping = (yyvsp[0].integer);  }
2259#line 2260 "grammar.tab.c" /* yacc.c:1646  */
2260    break;
2261
2262  case 48:
2263#line 422 "grammar.y" /* yacc.c:1646  */
2264    { ufdbNewGV.logURLdetails = (yyvsp[0].integer); }
2265#line 2266 "grammar.tab.c" /* yacc.c:1646  */
2266    break;
2267
2268  case 49:
2269#line 426 "grammar.y" /* yacc.c:1646  */
2270    { ufdbNewGV.showURLdetails = (yyvsp[0].integer); }
2271#line 2272 "grammar.tab.c" /* yacc.c:1646  */
2272    break;
2273
2274  case 50:
2275#line 430 "grammar.y" /* yacc.c:1646  */
2276    { ufdbNewGV.debugSkype = (yyvsp[0].integer); }
2277#line 2278 "grammar.tab.c" /* yacc.c:1646  */
2278    break;
2279
2280  case 51:
2281#line 434 "grammar.y" /* yacc.c:1646  */
2282    { ufdbNewGV.debugGtalk = (yyvsp[0].integer); }
2283#line 2284 "grammar.tab.c" /* yacc.c:1646  */
2284    break;
2285
2286  case 52:
2287#line 438 "grammar.y" /* yacc.c:1646  */
2288    { ufdbNewGV.debugYahooMsg = (yyvsp[0].integer); }
2289#line 2290 "grammar.tab.c" /* yacc.c:1646  */
2290    break;
2291
2292  case 53:
2293#line 442 "grammar.y" /* yacc.c:1646  */
2294    { ufdbNewGV.debugAim = (yyvsp[0].integer); }
2295#line 2296 "grammar.tab.c" /* yacc.c:1646  */
2296    break;
2297
2298  case 54:
2299#line 446 "grammar.y" /* yacc.c:1646  */
2300    { ufdbNewGV.debugFBchat = (yyvsp[0].integer); }
2301#line 2302 "grammar.tab.c" /* yacc.c:1646  */
2302    break;
2303
2304  case 55:
2305#line 450 "grammar.y" /* yacc.c:1646  */
2306    { ufdbNewGV.debugCitrixOnline = (yyvsp[0].integer); }
2307#line 2308 "grammar.tab.c" /* yacc.c:1646  */
2308    break;
2309
2310  case 56:
2311#line 454 "grammar.y" /* yacc.c:1646  */
2312    { ufdbNewGV.expressionOptimisation = (yyvsp[0].integer); }
2313#line 2314 "grammar.tab.c" /* yacc.c:1646  */
2314    break;
2315
2316  case 57:
2317#line 458 "grammar.y" /* yacc.c:1646  */
2318    { ufdbNewGV.debugRegexp = (yyvsp[0].integer); }
2319#line 2320 "grammar.tab.c" /* yacc.c:1646  */
2320    break;
2321
2322  case 58:
2323#line 462 "grammar.y" /* yacc.c:1646  */
2324    { ufdbNewGV.debugExternalScripts = (yyvsp[0].integer); }
2325#line 2326 "grammar.tab.c" /* yacc.c:1646  */
2326    break;
2327
2328  case 59:
2329#line 466 "grammar.y" /* yacc.c:1646  */
2330    { ufdbFree( ufdbNewGV.emailServer ); ufdbNewGV.emailServer = (yyvsp[0].string); }
2331#line 2332 "grammar.tab.c" /* yacc.c:1646  */
2332    break;
2333
2334  case 60:
2335#line 470 "grammar.y" /* yacc.c:1646  */
2336    { ufdbFree( ufdbNewGV.myHostname ); ufdbNewGV.myHostname = (yyvsp[0].string); }
2337#line 2338 "grammar.tab.c" /* yacc.c:1646  */
2338    break;
2339
2340  case 61:
2341#line 474 "grammar.y" /* yacc.c:1646  */
2342    { ufdbFree( ufdbNewGV.adminEmail ); ufdbNewGV.adminEmail = (yyvsp[0].string); }
2343#line 2344 "grammar.tab.c" /* yacc.c:1646  */
2344    break;
2345
2346  case 62:
2347#line 478 "grammar.y" /* yacc.c:1646  */
2348    { ufdbFree( ufdbNewGV.senderEmail ); ufdbNewGV.senderEmail = (yyvsp[0].string); }
2349#line 2350 "grammar.tab.c" /* yacc.c:1646  */
2350    break;
2351
2352  case 63:
2353#line 482 "grammar.y" /* yacc.c:1646  */
2354    {  ufdbFree( ufdbNewGV.externalStatusCommand );
2355		                                       ufdbNewGV.externalStatusCommand = (yyvsp[0].string); }
2356#line 2357 "grammar.tab.c" /* yacc.c:1646  */
2357    break;
2358
2359  case 64:
2360#line 487 "grammar.y" /* yacc.c:1646  */
2361    { setLogdir( (yyvsp[0].string) ); }
2362#line 2363 "grammar.tab.c" /* yacc.c:1646  */
2363    break;
2364
2365  case 65:
2366#line 488 "grammar.y" /* yacc.c:1646  */
2367    { setLogdir( (yyvsp[0].string) ); }
2368#line 2369 "grammar.tab.c" /* yacc.c:1646  */
2369    break;
2370
2371  case 66:
2372#line 492 "grammar.y" /* yacc.c:1646  */
2373    { setPidfile( (yyvsp[0].string) ); }
2374#line 2375 "grammar.tab.c" /* yacc.c:1646  */
2375    break;
2376
2377  case 67:
2378#line 493 "grammar.y" /* yacc.c:1646  */
2379    { setPidfile( (yyvsp[0].string) ); }
2380#line 2381 "grammar.tab.c" /* yacc.c:1646  */
2381    break;
2382
2383  case 68:
2384#line 497 "grammar.y" /* yacc.c:1646  */
2385    { ufdbNewGV.portNum = atoi( (yyvsp[0].string) );  ufdbFree( (yyvsp[0].string) );
2386                                         if (ufdbNewGV.portNum <= 0)
2387                                         {
2388                                            ufdbLogError( "port number must be > 0, using default port %d",
2389                                                          UFDB_DAEMON_PORT );
2390                                            ufdbNewGV.portNum = UFDB_DAEMON_PORT;
2391                                         }
2392                                       }
2393#line 2394 "grammar.tab.c" /* yacc.c:1646  */
2394    break;
2395
2396  case 69:
2397#line 508 "grammar.y" /* yacc.c:1646  */
2398    {
2399#if HAVE_UNIX_SOCKETS
2400                                             ufdbLogError( "ufdbguardd is configured to use UNIX sockets.  "
2401					                   "\"interface\" is ignored." );
2402#else
2403		                             if (strcmp( (yyvsp[0].string), "all" ) == 0)
2404						strcpy( ufdbNewGV.interface, "all" );
2405					     else
2406					        ufdbLogFatalError( "interface must be \"all\" or IP address" );
2407#endif
2408					     ufdbFree( (yyvsp[0].string) );
2409					   }
2410#line 2411 "grammar.tab.c" /* yacc.c:1646  */
2411    break;
2412
2413  case 70:
2414#line 520 "grammar.y" /* yacc.c:1646  */
2415    { strcpy( ufdbNewGV.interface, (yyvsp[0].string) );  ufdbFree( (yyvsp[0].string) ); }
2416#line 2417 "grammar.tab.c" /* yacc.c:1646  */
2417    break;
2418
2419  case 71:
2420#line 524 "grammar.y" /* yacc.c:1646  */
2421    { ufdbSetCPU( (yyvsp[0].string) ); ufdbFree( (yyvsp[0].string) ); }
2422#line 2423 "grammar.tab.c" /* yacc.c:1646  */
2423    break;
2424
2425  case 72:
2426#line 525 "grammar.y" /* yacc.c:1646  */
2427    { ufdbSetCPU( (yyvsp[0].string) ); ufdbFree( (yyvsp[0].string) ); }
2428#line 2429 "grammar.tab.c" /* yacc.c:1646  */
2429    break;
2430
2431  case 73:
2432#line 530 "grammar.y" /* yacc.c:1646  */
2433    { ufdbNewGV.uploadStats = (yyvsp[0].integer);   }
2434#line 2435 "grammar.tab.c" /* yacc.c:1646  */
2435    break;
2436
2437  case 74:
2438#line 535 "grammar.y" /* yacc.c:1646  */
2439    { strcpy( ufdbNewGV.redirectHttps, (yyvsp[0].string) );  ufdbFree( (yyvsp[0].string) );  }
2440#line 2441 "grammar.tab.c" /* yacc.c:1646  */
2441    break;
2442
2443  case 75:
2444#line 540 "grammar.y" /* yacc.c:1646  */
2445    { strcpy( ufdbNewGV.redirectBumpedHttps, (yyvsp[0].string) );  ufdbFree( (yyvsp[0].string) );  }
2446#line 2447 "grammar.tab.c" /* yacc.c:1646  */
2447    break;
2448
2449  case 76:
2450#line 545 "grammar.y" /* yacc.c:1646  */
2451    { strcpy( ufdbNewGV.loadingDatabaseRedirect, (yyvsp[0].string) );  ufdbFree( (yyvsp[0].string) );  }
2452#line 2453 "grammar.tab.c" /* yacc.c:1646  */
2453    break;
2454
2455  case 77:
2456#line 550 "grammar.y" /* yacc.c:1646  */
2457    { strcpy( ufdbNewGV.fatalErrorRedirect, (yyvsp[0].string) );  ufdbFree( (yyvsp[0].string) );  }
2458#line 2459 "grammar.tab.c" /* yacc.c:1646  */
2459    break;
2460
2461  case 78:
2462#line 555 "grammar.y" /* yacc.c:1646  */
2463    {
2464			ufdbNewGV.logUncategorisedURLs = (yyvsp[0].integer);
2465		     }
2466#line 2467 "grammar.tab.c" /* yacc.c:1646  */
2467    break;
2468
2469  case 79:
2470#line 562 "grammar.y" /* yacc.c:1646  */
2471    {
2472			ufdbNewGV.analyseUncategorisedURLs = (yyvsp[0].integer);
2473		     }
2474#line 2475 "grammar.tab.c" /* yacc.c:1646  */
2475    break;
2476
2477  case 80:
2478#line 567 "grammar.y" /* yacc.c:1646  */
2479    {
2480			ufdbNewGV.analyseUncategorisedURLs = atoi( (yyvsp[0].string) );
2481			ufdbFree( (yyvsp[0].string) );
2482		     }
2483#line 2484 "grammar.tab.c" /* yacc.c:1646  */
2484    break;
2485
2486  case 81:
2487#line 575 "grammar.y" /* yacc.c:1646  */
2488    {
2489		        ufdbNewGV.stripDomainFromUsername = (yyvsp[0].integer);
2490		     }
2491#line 2492 "grammar.tab.c" /* yacc.c:1646  */
2492    break;
2493
2494  case 82:
2495#line 582 "grammar.y" /* yacc.c:1646  */
2496    { ufdbNewGV.safeSearch = (yyvsp[0].integer); }
2497#line 2498 "grammar.tab.c" /* yacc.c:1646  */
2498    break;
2499
2500  case 83:
2501#line 587 "grammar.y" /* yacc.c:1646  */
2502    {
2503		       ufdbNewGV.maxLogfileSize = strtoul( (yyvsp[0].string), NULL, 10 );
2504		       ufdbFree( (yyvsp[0].string) );
2505		       if (ufdbNewGV.maxLogfileSize < 2 * 1024 * 1024)		// minimum is 2 MB
2506		          ufdbNewGV.maxLogfileSize = 2 * 1024 * 1024;
2507		       if (ufdbNewGV.maxLogfileSize > 2000000000)		        // maximum is 2 GB
2508		          ufdbNewGV.maxLogfileSize = 2000000000;
2509		     }
2510#line 2511 "grammar.tab.c" /* yacc.c:1646  */
2511    break;
2512
2513  case 84:
2514#line 598 "grammar.y" /* yacc.c:1646  */
2515    { ufdbNewGV.httpdPort = atoi( (yyvsp[0].string) ); ufdbFree( (yyvsp[0].string) ); }
2516#line 2517 "grammar.tab.c" /* yacc.c:1646  */
2517    break;
2518
2519  case 85:
2520#line 599 "grammar.y" /* yacc.c:1646  */
2521    { if (strcmp((yyvsp[0].string),"all")== 0)
2522						strcpy( ufdbNewGV.httpdInterface, "all" );
2523					     else
2524					        ufdbLogFatalError( "http-server interface must be \"all\" or IP address" );
2525					     ufdbFree( (yyvsp[0].string) );
2526					   }
2527#line 2528 "grammar.tab.c" /* yacc.c:1646  */
2528    break;
2529
2530  case 86:
2531#line 605 "grammar.y" /* yacc.c:1646  */
2532    { if (strcmp((yyvsp[0].string),"all")== 0)
2533						strcpy( ufdbNewGV.httpdInterface, "all" );
2534					     else
2535					        ufdbLogFatalError( "http-server interface must be \"all\" or IP address" );
2536					     ufdbFree( (yyvsp[0].string) );
2537					   }
2538#line 2539 "grammar.tab.c" /* yacc.c:1646  */
2539    break;
2540
2541  case 87:
2542#line 611 "grammar.y" /* yacc.c:1646  */
2543    { strcpy( ufdbNewGV.httpdInterface, (yyvsp[0].string) );       ufdbFree( (yyvsp[0].string) ); }
2544#line 2545 "grammar.tab.c" /* yacc.c:1646  */
2545    break;
2546
2547  case 88:
2548#line 612 "grammar.y" /* yacc.c:1646  */
2549    { strcpy( ufdbNewGV.httpdImagesDirectory, (yyvsp[0].string) ); ufdbFree( (yyvsp[0].string) ); }
2550#line 2551 "grammar.tab.c" /* yacc.c:1646  */
2551    break;
2552
2553  case 89:
2554#line 613 "grammar.y" /* yacc.c:1646  */
2555    { strcpy( ufdbNewGV.httpdImagesDirectory, (yyvsp[0].string) ); ufdbFree( (yyvsp[0].string) ); }
2556#line 2557 "grammar.tab.c" /* yacc.c:1646  */
2557    break;
2558
2559  case 93:
2560#line 626 "grammar.y" /* yacc.c:1646  */
2561    { ufdbCategory( (yyvsp[0].string) ); }
2562#line 2563 "grammar.tab.c" /* yacc.c:1646  */
2563    break;
2564
2565  case 94:
2566#line 627 "grammar.y" /* yacc.c:1646  */
2567    { ufdbCategory( ufdbStrdup("aggressive") );
2568		                         yyerror( (char *) "\"aggressive\" is a keyword and must be surrounded by quotes" ); }
2569#line 2570 "grammar.tab.c" /* yacc.c:1646  */
2570    break;
2571
2572  case 95:
2573#line 629 "grammar.y" /* yacc.c:1646  */
2574    { ufdbCategory( ufdbStrdup("allow") );
2575		                         yyerror( (char *) "\"allow\" is a keyword and must be surrounded by quotes" ); }
2576#line 2577 "grammar.tab.c" /* yacc.c:1646  */
2577    break;
2578
2579  case 96:
2580#line 631 "grammar.y" /* yacc.c:1646  */
2581    { ufdbCategory( ufdbStrdup("deny") );
2582		                         yyerror( (char *) "\"deny\" is a keyword and must be surrounded by quotes" ); }
2583#line 2584 "grammar.tab.c" /* yacc.c:1646  */
2584    break;
2585
2586  case 97:
2587#line 633 "grammar.y" /* yacc.c:1646  */
2588    { ufdbCategory( ufdbStrdup("syntax-error") );
2589		                         yyerror( (char *) "erroneous category definition.  Perhaps the category ID is a reserved word?" ); }
2590#line 2591 "grammar.tab.c" /* yacc.c:1646  */
2591    break;
2592
2593  case 98:
2594#line 639 "grammar.y" /* yacc.c:1646  */
2595    { ufdbCategoryEnd(); }
2596#line 2597 "grammar.tab.c" /* yacc.c:1646  */
2597    break;
2598
2599  case 101:
2600#line 647 "grammar.y" /* yacc.c:1646  */
2601    { ufdbCategoryDomainList( (yyvsp[0].string) ); }
2602#line 2603 "grammar.tab.c" /* yacc.c:1646  */
2603    break;
2604
2605  case 102:
2606#line 648 "grammar.y" /* yacc.c:1646  */
2607    { ufdbCategoryDomainList( (yyvsp[0].string) ); }
2608#line 2609 "grammar.tab.c" /* yacc.c:1646  */
2609    break;
2610
2611  case 103:
2612#line 649 "grammar.y" /* yacc.c:1646  */
2613    { ufdbCategoryDomainList( NULL ); }
2614#line 2615 "grammar.tab.c" /* yacc.c:1646  */
2615    break;
2616
2617  case 104:
2618#line 650 "grammar.y" /* yacc.c:1646  */
2619    { ufdbCategoryExecDomainList( (yyvsp[0].string) ); }
2620#line 2621 "grammar.tab.c" /* yacc.c:1646  */
2621    break;
2622
2623  case 105:
2624#line 651 "grammar.y" /* yacc.c:1646  */
2625    { ufdbCategoryUrlList( (yyvsp[0].string) ); }
2626#line 2627 "grammar.tab.c" /* yacc.c:1646  */
2627    break;
2628
2629  case 106:
2630#line 652 "grammar.y" /* yacc.c:1646  */
2631    { ufdbCategoryUrlList( (yyvsp[0].string) ); }
2632#line 2633 "grammar.tab.c" /* yacc.c:1646  */
2633    break;
2634
2635  case 107:
2636#line 653 "grammar.y" /* yacc.c:1646  */
2637    { ufdbCategoryUrlList( NULL ); }
2638#line 2639 "grammar.tab.c" /* yacc.c:1646  */
2639    break;
2640
2641  case 108:
2642#line 654 "grammar.y" /* yacc.c:1646  */
2643    { ufdbCategoryExpressionList( (yyvsp[0].string), "n" ); }
2644#line 2645 "grammar.tab.c" /* yacc.c:1646  */
2645    break;
2646
2647  case 109:
2648#line 655 "grammar.y" /* yacc.c:1646  */
2649    { ufdbCategoryExpressionList( (yyvsp[0].string), "n" ); }
2650#line 2651 "grammar.tab.c" /* yacc.c:1646  */
2651    break;
2652
2653  case 110:
2654#line 656 "grammar.y" /* yacc.c:1646  */
2655    { ufdbCategoryExpressionList( NULL, NULL ); }
2656#line 2657 "grammar.tab.c" /* yacc.c:1646  */
2657    break;
2658
2659  case 111:
2660#line 657 "grammar.y" /* yacc.c:1646  */
2661    { ufdbCategoryExpressionList( (yyvsp[0].string), "i" ); }
2662#line 2663 "grammar.tab.c" /* yacc.c:1646  */
2663    break;
2664
2665  case 112:
2666#line 658 "grammar.y" /* yacc.c:1646  */
2667    { ufdbCategoryExpressionList( (yyvsp[0].string), "i" ); }
2668#line 2669 "grammar.tab.c" /* yacc.c:1646  */
2669    break;
2670
2671  case 113:
2672#line 659 "grammar.y" /* yacc.c:1646  */
2673    { ufdbCategoryExpressionList( (yyvsp[0].string), "i" ); }
2674#line 2675 "grammar.tab.c" /* yacc.c:1646  */
2675    break;
2676
2677  case 114:
2678#line 660 "grammar.y" /* yacc.c:1646  */
2679    { ufdbCategoryExpressionList( (yyvsp[0].string), "i" ); }
2680#line 2681 "grammar.tab.c" /* yacc.c:1646  */
2681    break;
2682
2683  case 115:
2684#line 661 "grammar.y" /* yacc.c:1646  */
2685    { ufdbCategoryCACertsFile( (yyvsp[0].string) );  ufdbFree( (yyvsp[0].string) ); }
2686#line 2687 "grammar.tab.c" /* yacc.c:1646  */
2687    break;
2688
2689  case 116:
2690#line 662 "grammar.y" /* yacc.c:1646  */
2691    { ufdbCategoryCACertsFile( (yyvsp[0].string) );  ufdbFree( (yyvsp[0].string) ); }
2692#line 2693 "grammar.tab.c" /* yacc.c:1646  */
2693    break;
2694
2695  case 117:
2696#line 663 "grammar.y" /* yacc.c:1646  */
2697    { ufdbCategoryCACertsDir( (yyvsp[0].string) );  ufdbFree( (yyvsp[0].string) ); }
2698#line 2699 "grammar.tab.c" /* yacc.c:1646  */
2699    break;
2700
2701  case 118:
2702#line 664 "grammar.y" /* yacc.c:1646  */
2703    { ufdbCategoryCACertsDir( (yyvsp[0].string) );  ufdbFree( (yyvsp[0].string) ); }
2704#line 2705 "grammar.tab.c" /* yacc.c:1646  */
2705    break;
2706
2707  case 119:
2708#line 665 "grammar.y" /* yacc.c:1646  */
2709    { ufdbCategoryRedirect( (yyvsp[0].string) ); }
2710#line 2711 "grammar.tab.c" /* yacc.c:1646  */
2711    break;
2712
2713  case 120:
2714#line 666 "grammar.y" /* yacc.c:1646  */
2715    { ufdbCategoryRedirect( (yyvsp[0].string) ); }
2716#line 2717 "grammar.tab.c" /* yacc.c:1646  */
2717    break;
2718
2719  case 121:
2720#line 667 "grammar.y" /* yacc.c:1646  */
2721    { ufdbCategoryRewrite( (yyvsp[0].string) ); }
2722#line 2723 "grammar.tab.c" /* yacc.c:1646  */
2723    break;
2724
2725  case 122:
2726#line 668 "grammar.y" /* yacc.c:1646  */
2727    { ufdbCategoryRewrite( (yyvsp[0].string) ); }
2728#line 2729 "grammar.tab.c" /* yacc.c:1646  */
2729    break;
2730
2731  case 123:
2732#line 669 "grammar.y" /* yacc.c:1646  */
2733    { ufdbCategoryTime( (yyvsp[0].string), UFDB_ACL_WITHIN ); }
2734#line 2735 "grammar.tab.c" /* yacc.c:1646  */
2735    break;
2736
2737  case 124:
2738#line 670 "grammar.y" /* yacc.c:1646  */
2739    { ufdbCategoryTime( (yyvsp[0].string), UFDB_ACL_OUTSIDE ); }
2740#line 2741 "grammar.tab.c" /* yacc.c:1646  */
2741    break;
2742
2743  case 125:
2744#line 671 "grammar.y" /* yacc.c:1646  */
2745    { ufdbCategoryBlockConnect( (yyvsp[0].integer) ); }
2746#line 2747 "grammar.tab.c" /* yacc.c:1646  */
2747    break;
2748
2749  case 126:
2750#line 672 "grammar.y" /* yacc.c:1646  */
2751    { ufdbCategoryActiveBumping( (yyvsp[0].integer) ); }
2752#line 2753 "grammar.tab.c" /* yacc.c:1646  */
2753    break;
2754
2755  case 127:
2756#line 673 "grammar.y" /* yacc.c:1646  */
2757    { ufdbCategoryOption( (yyvsp[0].integer), UFDB_OPT_SAFE_SEARCH );  }
2758#line 2759 "grammar.tab.c" /* yacc.c:1646  */
2759    break;
2760
2761  case 128:
2762#line 674 "grammar.y" /* yacc.c:1646  */
2763    { ufdbCategoryOption( (yyvsp[0].integer), UFDB_OPT_YOUTUBE_EDUFILTER );  }
2764#line 2765 "grammar.tab.c" /* yacc.c:1646  */
2765    break;
2766
2767  case 129:
2768#line 675 "grammar.y" /* yacc.c:1646  */
2769    { ufdbCategoryOption(  1, UFDB_OPT_HTTPS_WITH_HOSTNAME );  }
2770#line 2771 "grammar.tab.c" /* yacc.c:1646  */
2771    break;
2772
2773  case 130:
2774#line 676 "grammar.y" /* yacc.c:1646  */
2775    { ufdbCategoryOption( (yyvsp[0].integer), UFDB_OPT_HTTPS_WITH_HOSTNAME );  }
2776#line 2777 "grammar.tab.c" /* yacc.c:1646  */
2777    break;
2778
2779  case 131:
2780#line 677 "grammar.y" /* yacc.c:1646  */
2781    { ufdbCategoryOption(  1, UFDB_OPT_HTTPS_OFFICAL_CERTIFICATE );  }
2782#line 2783 "grammar.tab.c" /* yacc.c:1646  */
2783    break;
2784
2785  case 132:
2786#line 678 "grammar.y" /* yacc.c:1646  */
2787    { ufdbCategoryOption( (yyvsp[0].integer), UFDB_OPT_HTTPS_OFFICAL_CERTIFICATE );  }
2788#line 2789 "grammar.tab.c" /* yacc.c:1646  */
2789    break;
2790
2791  case 133:
2792#line 679 "grammar.y" /* yacc.c:1646  */
2793    { ufdbCategoryOption( (yyvsp[0].integer), UFDB_OPT_PROHIBIT_INSECURE_SSLV2 );  }
2794#line 2795 "grammar.tab.c" /* yacc.c:1646  */
2795    break;
2796
2797  case 134:
2798#line 680 "grammar.y" /* yacc.c:1646  */
2799    { ufdbCategoryOption( (yyvsp[0].integer), UFDB_OPT_PROHIBIT_INSECURE_SSLV3 );  }
2800#line 2801 "grammar.tab.c" /* yacc.c:1646  */
2801    break;
2802
2803  case 135:
2804#line 681 "grammar.y" /* yacc.c:1646  */
2805    { ufdbCategoryOption( (yyvsp[0].integer), UFDB_OPT_SKYPE_OVER_HTTPS );  }
2806#line 2807 "grammar.tab.c" /* yacc.c:1646  */
2807    break;
2808
2809  case 136:
2810#line 682 "grammar.y" /* yacc.c:1646  */
2811    { ufdbCategoryOption( (yyvsp[0].integer), UFDB_OPT_GTALK_OVER_HTTPS );  }
2812#line 2813 "grammar.tab.c" /* yacc.c:1646  */
2813    break;
2814
2815  case 137:
2816#line 683 "grammar.y" /* yacc.c:1646  */
2817    { ufdbCategoryOption( (yyvsp[0].integer), UFDB_OPT_YAHOOMSG_OVER_HTTPS );  }
2818#line 2819 "grammar.tab.c" /* yacc.c:1646  */
2819    break;
2820
2821  case 138:
2822#line 684 "grammar.y" /* yacc.c:1646  */
2823    { ufdbCategoryOption( (yyvsp[0].integer), UFDB_OPT_AIM_OVER_HTTPS );  }
2824#line 2825 "grammar.tab.c" /* yacc.c:1646  */
2825    break;
2826
2827  case 139:
2828#line 685 "grammar.y" /* yacc.c:1646  */
2829    { ufdbCategoryOption( (yyvsp[0].integer), UFDB_OPT_FBCHAT_OVER_HTTPS );  }
2830#line 2831 "grammar.tab.c" /* yacc.c:1646  */
2831    break;
2832
2833  case 140:
2834#line 686 "grammar.y" /* yacc.c:1646  */
2835    { ufdbCategoryOption( (yyvsp[0].integer), UFDB_OPT_CITRIXONLINE_OVER_HTTPS );  }
2836#line 2837 "grammar.tab.c" /* yacc.c:1646  */
2837    break;
2838
2839  case 141:
2840#line 687 "grammar.y" /* yacc.c:1646  */
2841    { ufdbCategoryOption( (yyvsp[0].integer), UFDB_OPT_ANYDESK_OVER_HTTPS );  }
2842#line 2843 "grammar.tab.c" /* yacc.c:1646  */
2843    break;
2844
2845  case 142:
2846#line 688 "grammar.y" /* yacc.c:1646  */
2847    { ufdbCategoryOption( (yyvsp[0].integer), UFDB_OPT_TEAMVIEWER_OVER_HTTPS );  }
2848#line 2849 "grammar.tab.c" /* yacc.c:1646  */
2849    break;
2850
2851  case 143:
2852#line 689 "grammar.y" /* yacc.c:1646  */
2853    { ufdbCategoryOption( (yyvsp[0].integer), UFDB_OPT_UNKNOWN_PROTOCOL_OVER_HTTPS );  }
2854#line 2855 "grammar.tab.c" /* yacc.c:1646  */
2855    break;
2856
2857  case 144:
2858#line 690 "grammar.y" /* yacc.c:1646  */
2859    { ufdbLogError( "line %d: unsupported logfile context for %s", lineno, (yyvsp[0].string) );
2860		                                  ufdbFree( (yyvsp[0].string) ); }
2861#line 2862 "grammar.tab.c" /* yacc.c:1646  */
2862    break;
2863
2864  case 145:
2865#line 692 "grammar.y" /* yacc.c:1646  */
2866    { ufdbLogError( "line %d: unsupported logfile context for %s", lineno, (yyvsp[0].string) );
2867		                                  ufdbFree( (yyvsp[0].string) ); }
2868#line 2869 "grammar.tab.c" /* yacc.c:1646  */
2869    break;
2870
2871  case 146:
2872#line 694 "grammar.y" /* yacc.c:1646  */
2873    { ufdbLogError( "line %d: unsupported logfile context for %s", lineno, (yyvsp[0].string) );
2874		                                  ufdbFree( (yyvsp[0].string) ); }
2875#line 2876 "grammar.tab.c" /* yacc.c:1646  */
2876    break;
2877
2878  case 147:
2879#line 696 "grammar.y" /* yacc.c:1646  */
2880    { ufdbLogError( "line %d: unsupported logfile context for %s", lineno, (yyvsp[0].string) );
2881		                                  ufdbFree( (yyvsp[0].string) ); }
2882#line 2883 "grammar.tab.c" /* yacc.c:1646  */
2883    break;
2884
2885  case 148:
2886#line 701 "grammar.y" /* yacc.c:1646  */
2887    { defSource( (yyvsp[0].string) ); }
2888#line 2889 "grammar.tab.c" /* yacc.c:1646  */
2889    break;
2890
2891  case 149:
2892#line 705 "grammar.y" /* yacc.c:1646  */
2893    { defSourceEnd(); }
2894#line 2895 "grammar.tab.c" /* yacc.c:1646  */
2895    break;
2896
2897  case 155:
2898#line 717 "grammar.y" /* yacc.c:1646  */
2899    { ufdbSourceUserList( (yyvsp[0].string) ); }
2900#line 2901 "grammar.tab.c" /* yacc.c:1646  */
2901    break;
2902
2903  case 156:
2904#line 718 "grammar.y" /* yacc.c:1646  */
2905    { ufdbSourceUserList( (yyvsp[0].string) ); }
2906#line 2907 "grammar.tab.c" /* yacc.c:1646  */
2907    break;
2908
2909  case 157:
2910#line 719 "grammar.y" /* yacc.c:1646  */
2911    { ufdbSourceUserList( (yyvsp[0].string) ); }
2912#line 2913 "grammar.tab.c" /* yacc.c:1646  */
2913    break;
2914
2915  case 158:
2916#line 720 "grammar.y" /* yacc.c:1646  */
2917    { ufdbSourceUserList( (yyvsp[0].string) ); }
2918#line 2919 "grammar.tab.c" /* yacc.c:1646  */
2919    break;
2920
2921  case 159:
2922#line 721 "grammar.y" /* yacc.c:1646  */
2923    { ufdbSourceExecUserList( (yyvsp[0].string) ); }
2924#line 2925 "grammar.tab.c" /* yacc.c:1646  */
2925    break;
2926
2927  case 160:
2928#line 722 "grammar.y" /* yacc.c:1646  */
2929    { ufdbSourceExecIPList( (yyvsp[0].string) ); }
2930#line 2931 "grammar.tab.c" /* yacc.c:1646  */
2931    break;
2932
2933  case 161:
2934#line 723 "grammar.y" /* yacc.c:1646  */
2935    { ufdbSourceGroup( UFDB_GROUPTYPE_UNIX, (yyvsp[0].string) ); }
2936#line 2937 "grammar.tab.c" /* yacc.c:1646  */
2937    break;
2938
2939  case 162:
2940#line 724 "grammar.y" /* yacc.c:1646  */
2941    { ufdbSourceGroup( UFDB_GROUPTYPE_UNIX, (yyvsp[0].string) ); }
2942#line 2943 "grammar.tab.c" /* yacc.c:1646  */
2943    break;
2944
2945  case 163:
2946#line 725 "grammar.y" /* yacc.c:1646  */
2947    { ufdbSourceGroup( UFDB_GROUPTYPE_UNIX, (yyvsp[0].string) ); }
2948#line 2949 "grammar.tab.c" /* yacc.c:1646  */
2949    break;
2950
2951  case 164:
2952#line 726 "grammar.y" /* yacc.c:1646  */
2953    { ufdbSourceGroup( UFDB_GROUPTYPE_UNIX, (yyvsp[0].string) ); }
2954#line 2955 "grammar.tab.c" /* yacc.c:1646  */
2955    break;
2956
2957  case 165:
2958#line 727 "grammar.y" /* yacc.c:1646  */
2959    { ufdbSourceUserQuota( (yyvsp[-2].string), (yyvsp[-1].string), "3600" );
2960		                                   ufdbFree( (yyvsp[-2].string) ); ufdbFree( (yyvsp[-1].string) ); }
2961#line 2962 "grammar.tab.c" /* yacc.c:1646  */
2962    break;
2963
2964  case 166:
2965#line 729 "grammar.y" /* yacc.c:1646  */
2966    { ufdbSourceUserQuota( (yyvsp[-2].string), (yyvsp[-1].string), "86400" );
2967		                                   ufdbFree( (yyvsp[-2].string) ); ufdbFree( (yyvsp[-1].string) ); }
2968#line 2969 "grammar.tab.c" /* yacc.c:1646  */
2969    break;
2970
2971  case 167:
2972#line 731 "grammar.y" /* yacc.c:1646  */
2973    { ufdbSourceUserQuota( (yyvsp[-2].string), (yyvsp[-1].string), "604800" );
2974		                                   ufdbFree( (yyvsp[-2].string) ); ufdbFree( (yyvsp[-1].string) ); }
2975#line 2976 "grammar.tab.c" /* yacc.c:1646  */
2976    break;
2977
2978  case 168:
2979#line 733 "grammar.y" /* yacc.c:1646  */
2980    { ufdbSourceUserQuota( (yyvsp[-2].string), (yyvsp[-1].string), (yyvsp[0].string) );
2981		                                   ufdbFree( (yyvsp[-2].string) ); ufdbFree( (yyvsp[-1].string) ); ufdbFree( (yyvsp[0].string) ); }
2982#line 2983 "grammar.tab.c" /* yacc.c:1646  */
2983    break;
2984
2985  case 170:
2986#line 736 "grammar.y" /* yacc.c:1646  */
2987    { defSourceIPV4List( (yyvsp[0].string) ); }
2988#line 2989 "grammar.tab.c" /* yacc.c:1646  */
2989    break;
2990
2991  case 171:
2992#line 737 "grammar.y" /* yacc.c:1646  */
2993    { defSourceIPV4List( (yyvsp[0].string) ); }
2994#line 2995 "grammar.tab.c" /* yacc.c:1646  */
2995    break;
2996
2997  case 173:
2998#line 739 "grammar.y" /* yacc.c:1646  */
2999    { defSourceIPV6List( (yyvsp[0].string) ); }
3000#line 3001 "grammar.tab.c" /* yacc.c:1646  */
3001    break;
3002
3003  case 174:
3004#line 740 "grammar.y" /* yacc.c:1646  */
3005    { defSourceIPV6List( (yyvsp[0].string) ); }
3006#line 3007 "grammar.tab.c" /* yacc.c:1646  */
3007    break;
3008
3009  case 175:
3010#line 741 "grammar.y" /* yacc.c:1646  */
3011    { ufdbSourceEval( UFDB_EVAL_AND ); }
3012#line 3013 "grammar.tab.c" /* yacc.c:1646  */
3013    break;
3014
3015  case 176:
3016#line 742 "grammar.y" /* yacc.c:1646  */
3017    { ufdbSourceEval( UFDB_EVAL_OR ); }
3018#line 3019 "grammar.tab.c" /* yacc.c:1646  */
3019    break;
3020
3021  case 177:
3022#line 743 "grammar.y" /* yacc.c:1646  */
3023    { defSourceTime( (yyvsp[0].string), UFDB_ACL_WITHIN ); }
3024#line 3025 "grammar.tab.c" /* yacc.c:1646  */
3025    break;
3026
3027  case 178:
3028#line 744 "grammar.y" /* yacc.c:1646  */
3029    { defSourceTime( (yyvsp[0].string), UFDB_ACL_OUTSIDE ); }
3030#line 3031 "grammar.tab.c" /* yacc.c:1646  */
3031    break;
3032
3033  case 179:
3034#line 745 "grammar.y" /* yacc.c:1646  */
3035    { ufdbLogError( "line %d: unsupported logfile context for %s",
3036                                                                 lineno, (yyvsp[0].string) );
3037						   ufdbFree( (yyvsp[0].string) ); }
3038#line 3039 "grammar.tab.c" /* yacc.c:1646  */
3039    break;
3040
3041  case 180:
3042#line 748 "grammar.y" /* yacc.c:1646  */
3043    { ufdbLogError( "line %d: unsupported logfile context for %s",
3044                                                                 lineno, (yyvsp[0].string) );
3045						   ufdbFree( (yyvsp[0].string) ); }
3046#line 3047 "grammar.tab.c" /* yacc.c:1646  */
3047    break;
3048
3049  case 181:
3050#line 751 "grammar.y" /* yacc.c:1646  */
3051    { ufdbLogError( "line %d: unsupported logfile context for %s",
3052                                                                 lineno, (yyvsp[0].string) );
3053						   ufdbFree( (yyvsp[0].string) ); }
3054#line 3055 "grammar.tab.c" /* yacc.c:1646  */
3055    break;
3056
3057  case 182:
3058#line 754 "grammar.y" /* yacc.c:1646  */
3059    { ufdbLogError( "line %d: unsupported logfile context for %s",
3060                                                                 lineno, (yyvsp[0].string) );
3061						   ufdbFree( (yyvsp[0].string) ); }
3062#line 3063 "grammar.tab.c" /* yacc.c:1646  */
3063    break;
3064
3065  case 183:
3066#line 757 "grammar.y" /* yacc.c:1646  */
3067    { ufdbNewGV.lastSource->cont_search = 1; }
3068#line 3069 "grammar.tab.c" /* yacc.c:1646  */
3069    break;
3070
3071  case 185:
3072#line 763 "grammar.y" /* yacc.c:1646  */
3073    { defSourceDomain( (yyvsp[0].string) ); }
3074#line 3075 "grammar.tab.c" /* yacc.c:1646  */
3075    break;
3076
3077  case 186:
3078#line 764 "grammar.y" /* yacc.c:1646  */
3079    { defSourceDomain( (yyvsp[0].string) ); }
3080#line 3081 "grammar.tab.c" /* yacc.c:1646  */
3081    break;
3082
3083  case 189:
3084#line 770 "grammar.y" /* yacc.c:1646  */
3085    { ufdbSourceUser( (yyvsp[0].string) ); }
3086#line 3087 "grammar.tab.c" /* yacc.c:1646  */
3087    break;
3088
3089  case 190:
3090#line 771 "grammar.y" /* yacc.c:1646  */
3091    { ufdbSourceUser( (yyvsp[0].string) ); }
3092#line 3093 "grammar.tab.c" /* yacc.c:1646  */
3093    break;
3094
3095  case 195:
3096#line 784 "grammar.y" /* yacc.c:1646  */
3097    { ufdbAcl( (yyvsp[-1].string), NULL, UFDB_ACL_NONE );  }
3098#line 3099 "grammar.tab.c" /* yacc.c:1646  */
3099    break;
3100
3101  case 196:
3102#line 785 "grammar.y" /* yacc.c:1646  */
3103    { ufdbAcl( (yyvsp[-3].string), (yyvsp[-1].string), UFDB_ACL_WITHIN );  }
3104#line 3105 "grammar.tab.c" /* yacc.c:1646  */
3105    break;
3106
3107  case 197:
3108#line 786 "grammar.y" /* yacc.c:1646  */
3109    { ufdbAcl( (yyvsp[-3].string), (yyvsp[-1].string), UFDB_ACL_OUTSIDE ); }
3110#line 3111 "grammar.tab.c" /* yacc.c:1646  */
3111    break;
3112
3113  case 199:
3114#line 792 "grammar.y" /* yacc.c:1646  */
3115    { ufdbAcl( NULL, NULL, UFDB_ACL_ELSE );    }
3116#line 3117 "grammar.tab.c" /* yacc.c:1646  */
3117    break;
3118
3119  case 203:
3120#line 802 "grammar.y" /* yacc.c:1646  */
3121    { if (ufdbNewGV.lastAcl != NULL  &&
3122                                                      ufdbNewGV.lastAcl->pass == NULL)
3123                                                  {
3124                                                     ufdbLogMessage( "line %d: acl has an empty pass statement."
3125                                                                     "  Adding 'any'.", lineno );
3126                                                     ufdbAclSetValue( "pass", ufdbStrdup("any"), 1 );
3127                                                  }
3128                                                }
3129#line 3130 "grammar.tab.c" /* yacc.c:1646  */
3130    break;
3131
3132  case 204:
3133#line 810 "grammar.y" /* yacc.c:1646  */
3134    { ufdbAclSetValue( "rewrite", (yyvsp[0].string), 0 ); }
3135#line 3136 "grammar.tab.c" /* yacc.c:1646  */
3136    break;
3137
3138  case 205:
3139#line 811 "grammar.y" /* yacc.c:1646  */
3140    { ufdbAclSetValue( "rewrite", (yyvsp[0].string), 0 ); }
3141#line 3142 "grammar.tab.c" /* yacc.c:1646  */
3142    break;
3143
3144  case 206:
3145#line 812 "grammar.y" /* yacc.c:1646  */
3146    { ufdbAclSetValue( "redirect", (yyvsp[0].string), 0 ); }
3147#line 3148 "grammar.tab.c" /* yacc.c:1646  */
3148    break;
3149
3150  case 207:
3151#line 813 "grammar.y" /* yacc.c:1646  */
3152    { ufdbAclSetValue( "redirect", (yyvsp[0].string), 0 ); }
3153#line 3154 "grammar.tab.c" /* yacc.c:1646  */
3154    break;
3155
3156  case 208:
3157#line 814 "grammar.y" /* yacc.c:1646  */
3158    { ufdbLogError( "line %d: unsupported logfile context for %s",
3159                                                                lineno, (yyvsp[0].string) );
3160						  ufdbFree( (yyvsp[0].string) ); }
3161#line 3162 "grammar.tab.c" /* yacc.c:1646  */
3162    break;
3163
3164  case 209:
3165#line 817 "grammar.y" /* yacc.c:1646  */
3166    { ufdbLogError( "line %d: unsupported logfile context for %s",
3167                                                                lineno, (yyvsp[0].string) );
3168						  ufdbFree( (yyvsp[0].string) ); }
3169#line 3170 "grammar.tab.c" /* yacc.c:1646  */
3170    break;
3171
3172  case 210:
3173#line 820 "grammar.y" /* yacc.c:1646  */
3174    { ufdbLogError( "line %d: unsupported logfile context for %s",
3175                                                                lineno, (yyvsp[0].string) );
3176						  ufdbFree( (yyvsp[0].string) ); }
3177#line 3178 "grammar.tab.c" /* yacc.c:1646  */
3178    break;
3179
3180  case 211:
3181#line 823 "grammar.y" /* yacc.c:1646  */
3182    { ufdbLogError( "line %d: unsupported logfile context for %s",
3183                                                                lineno, (yyvsp[0].string) );
3184						  ufdbFree( (yyvsp[0].string) ); }
3185#line 3186 "grammar.tab.c" /* yacc.c:1646  */
3186    break;
3187
3188  case 213:
3189#line 830 "grammar.y" /* yacc.c:1646  */
3190    { yyerror( (char *) "\"aggressive\" is a keyword and must be surrounded by quotes" ); }
3191#line 3192 "grammar.tab.c" /* yacc.c:1646  */
3192    break;
3193
3194  case 214:
3195#line 831 "grammar.y" /* yacc.c:1646  */
3196    { ufdbAclSetValue( "pass", (yyvsp[0].string), 1 ); }
3197#line 3198 "grammar.tab.c" /* yacc.c:1646  */
3198    break;
3199
3200  case 215:
3201#line 832 "grammar.y" /* yacc.c:1646  */
3202    { yyerror( (char *) "\"aggressive\" is a keyword and must be surrounded by quotes" ); }
3203#line 3204 "grammar.tab.c" /* yacc.c:1646  */
3204    break;
3205
3206  case 216:
3207#line 833 "grammar.y" /* yacc.c:1646  */
3208    { ufdbAclSetValue( "pass", (yyvsp[0].string), 0 ); }
3209#line 3210 "grammar.tab.c" /* yacc.c:1646  */
3210    break;
3211
3212  case 221:
3213#line 844 "grammar.y" /* yacc.c:1646  */
3214    { sgIpv4( (yyvsp[0].string), SG_IPTYPE_HOST, ufdbNewGV.configFile, lineno );
3215		                                  ufdbFree( (yyvsp[0].string) );  }
3216#line 3217 "grammar.tab.c" /* yacc.c:1646  */
3217    break;
3218
3219  case 222:
3220#line 846 "grammar.y" /* yacc.c:1646  */
3221    { sgIpv4( (yyvsp[0].string), SG_IPTYPE_RANGE, ufdbNewGV.configFile, lineno );
3222		                                  ufdbFree( (yyvsp[0].string) );  }
3223#line 3224 "grammar.tab.c" /* yacc.c:1646  */
3224    break;
3225
3226  case 223:
3227#line 848 "grammar.y" /* yacc.c:1646  */
3228    { sgIpv4( (yyvsp[0].string), SG_IPTYPE_CLASS, ufdbNewGV.configFile, lineno );
3229		                                  ufdbFree( (yyvsp[0].string) ); }
3230#line 3231 "grammar.tab.c" /* yacc.c:1646  */
3231    break;
3232
3233  case 224:
3234#line 850 "grammar.y" /* yacc.c:1646  */
3235    { sgIpv4( (yyvsp[0].string), SG_IPTYPE_CIDR, ufdbNewGV.configFile, lineno );
3236		                                  ufdbFree( (yyvsp[0].string) ); }
3237#line 3238 "grammar.tab.c" /* yacc.c:1646  */
3238    break;
3239
3240  case 228:
3241#line 861 "grammar.y" /* yacc.c:1646  */
3242    { sgIpv6( (yyvsp[0].string), SG_IPV6TYPE_HOST, ufdbNewGV.configFile, lineno );
3243                                                  ufdbFree( (yyvsp[0].string) );  }
3244#line 3245 "grammar.tab.c" /* yacc.c:1646  */
3245    break;
3246
3247  case 229:
3248#line 863 "grammar.y" /* yacc.c:1646  */
3249    { sgIpv6( (yyvsp[0].string), SG_IPV6TYPE_CIDR, ufdbNewGV.configFile, lineno );
3250                                                  ufdbFree( (yyvsp[0].string) );  }
3251#line 3252 "grammar.tab.c" /* yacc.c:1646  */
3252    break;
3253
3254  case 230:
3255#line 868 "grammar.y" /* yacc.c:1646  */
3256    { sgRewrite( (yyvsp[0].string) ); }
3257#line 3258 "grammar.tab.c" /* yacc.c:1646  */
3258    break;
3259
3260  case 231:
3261#line 869 "grammar.y" /* yacc.c:1646  */
3262    { sgRewrite( (yyvsp[0].string) ); }
3263#line 3264 "grammar.tab.c" /* yacc.c:1646  */
3264    break;
3265
3266  case 235:
3267#line 883 "grammar.y" /* yacc.c:1646  */
3268    { sgRewriteSubstitute( (yyvsp[0].string) ); ufdbFree( (yyvsp[0].string) ); }
3269#line 3270 "grammar.tab.c" /* yacc.c:1646  */
3270    break;
3271
3272  case 236:
3273#line 884 "grammar.y" /* yacc.c:1646  */
3274    { sgRewriteTime( (yyvsp[0].string), UFDB_ACL_WITHIN ); }
3275#line 3276 "grammar.tab.c" /* yacc.c:1646  */
3276    break;
3277
3278  case 237:
3279#line 885 "grammar.y" /* yacc.c:1646  */
3280    { sgRewriteTime( (yyvsp[0].string), UFDB_ACL_OUTSIDE ); }
3281#line 3282 "grammar.tab.c" /* yacc.c:1646  */
3282    break;
3283
3284  case 238:
3285#line 886 "grammar.y" /* yacc.c:1646  */
3286    { ufdbLogError( "line %d: unsupported logfile context for %s",
3287		                                                lineno, (yyvsp[0].string) );
3288								ufdbFree( (yyvsp[0].string) ); }
3289#line 3290 "grammar.tab.c" /* yacc.c:1646  */
3290    break;
3291
3292  case 239:
3293#line 889 "grammar.y" /* yacc.c:1646  */
3294    { ufdbLogError( "line %d: unsupported logfile context for %s",
3295		                                                lineno, (yyvsp[0].string) );
3296								ufdbFree( (yyvsp[0].string) ); }
3297#line 3298 "grammar.tab.c" /* yacc.c:1646  */
3298    break;
3299
3300  case 240:
3301#line 892 "grammar.y" /* yacc.c:1646  */
3302    { ufdbLogError( "line %d: unsupported logfile context for %s",
3303		                                                lineno, (yyvsp[0].string) );
3304								ufdbFree( (yyvsp[0].string) ); }
3305#line 3306 "grammar.tab.c" /* yacc.c:1646  */
3306    break;
3307
3308  case 241:
3309#line 895 "grammar.y" /* yacc.c:1646  */
3310    { ufdbLogError( "line %d: unsupported logfile context for %s",
3311		                                                lineno, (yyvsp[0].string) );
3312								ufdbFree( (yyvsp[0].string) ); }
3313#line 3314 "grammar.tab.c" /* yacc.c:1646  */
3314    break;
3315
3316  case 242:
3317#line 902 "grammar.y" /* yacc.c:1646  */
3318    { sgTime( (yyvsp[0].string) ); }
3319#line 3320 "grammar.tab.c" /* yacc.c:1646  */
3320    break;
3321
3322  case 246:
3323#line 916 "grammar.y" /* yacc.c:1646  */
3324    { sgTimeElementInit(); }
3325#line 3326 "grammar.tab.c" /* yacc.c:1646  */
3326    break;
3327
3328  case 247:
3329#line 916 "grammar.y" /* yacc.c:1646  */
3330    { sgTimeElementAdd((yyvsp[0].string),T_WEEKDAY); }
3331#line 3332 "grammar.tab.c" /* yacc.c:1646  */
3332    break;
3333
3334  case 249:
3335#line 917 "grammar.y" /* yacc.c:1646  */
3336    { sgTimeElementInit(); }
3337#line 3338 "grammar.tab.c" /* yacc.c:1646  */
3338    break;
3339
3340  case 250:
3341#line 917 "grammar.y" /* yacc.c:1646  */
3342    { sgTimeElementAdd((yyvsp[0].string),T_WEEKLY); }
3343#line 3344 "grammar.tab.c" /* yacc.c:1646  */
3344    break;
3345
3346  case 252:
3347#line 918 "grammar.y" /* yacc.c:1646  */
3348    { sgTimeElementInit(); }
3349#line 3350 "grammar.tab.c" /* yacc.c:1646  */
3350    break;
3351
3352  case 253:
3353#line 918 "grammar.y" /* yacc.c:1646  */
3354    { sgTimeElementAdd((yyvsp[0].string),T_WEEKLY); }
3355#line 3356 "grammar.tab.c" /* yacc.c:1646  */
3356    break;
3357
3358  case 255:
3359#line 919 "grammar.y" /* yacc.c:1646  */
3360    { sgTimeElementInit(); }
3361#line 3362 "grammar.tab.c" /* yacc.c:1646  */
3362    break;
3363
3364  case 256:
3365#line 919 "grammar.y" /* yacc.c:1646  */
3366    { sgTimeElementEnd(); }
3367#line 3368 "grammar.tab.c" /* yacc.c:1646  */
3368    break;
3369
3370  case 257:
3371#line 920 "grammar.y" /* yacc.c:1646  */
3372    { ufdbLogFatalError( "invalid time specification at line %d", lineno );   }
3373#line 3374 "grammar.tab.c" /* yacc.c:1646  */
3374    break;
3375
3376  case 258:
3377#line 924 "grammar.y" /* yacc.c:1646  */
3378    { sgTimeElementClone(); }
3379#line 3380 "grammar.tab.c" /* yacc.c:1646  */
3380    break;
3381
3382  case 267:
3383#line 937 "grammar.y" /* yacc.c:1646  */
3384    { sgTimeElementAdd( (yyvsp[0].string), T_DVAL ); }
3385#line 3386 "grammar.tab.c" /* yacc.c:1646  */
3386    break;
3387
3388  case 268:
3389#line 940 "grammar.y" /* yacc.c:1646  */
3390    { sgTimeElementAdd( (yyvsp[0].tval), T_TVAL ); }
3391#line 3392 "grammar.tab.c" /* yacc.c:1646  */
3392    break;
3393
3394  case 269:
3395#line 943 "grammar.y" /* yacc.c:1646  */
3396    { sgTimeElementAdd( (yyvsp[0].string), T_DVALCRON ); }
3397#line 3398 "grammar.tab.c" /* yacc.c:1646  */
3398    break;
3399
3400  case 270:
3401#line 947 "grammar.y" /* yacc.c:1646  */
3402    {  yyerror( (char *) "syntax error" );
3403                                   if (ufdbNewGV.serialno > 1  &&  ufdbNewGV.debug)
3404                                      logConfig();
3405                                }
3406#line 3407 "grammar.tab.c" /* yacc.c:1646  */
3407    break;
3408
3409
3410#line 3411 "grammar.tab.c" /* yacc.c:1646  */
3411      default: break;
3412    }
3413  /* User semantic actions sometimes alter yychar, and that requires
3414     that yytoken be updated with the new translation.  We take the
3415     approach of translating immediately before every use of yytoken.
3416     One alternative is translating here after every semantic action,
3417     but that translation would be missed if the semantic action invokes
3418     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
3419     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
3420     incorrect destructor might then be invoked immediately.  In the
3421     case of YYERROR or YYBACKUP, subsequent parser actions might lead
3422     to an incorrect destructor call or verbose syntax error message
3423     before the lookahead is translated.  */
3424  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
3425
3426  YYPOPSTACK (yylen);
3427  yylen = 0;
3428  YY_STACK_PRINT (yyss, yyssp);
3429
3430  *++yyvsp = yyval;
3431
3432  /* Now 'shift' the result of the reduction.  Determine what state
3433     that goes to, based on the state we popped back to and the rule
3434     number reduced by.  */
3435
3436  yyn = yyr1[yyn];
3437
3438  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
3439  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
3440    yystate = yytable[yystate];
3441  else
3442    yystate = yydefgoto[yyn - YYNTOKENS];
3443
3444  goto yynewstate;
3445
3446
3447/*--------------------------------------.
3448| yyerrlab -- here on detecting error.  |
3449`--------------------------------------*/
3450yyerrlab:
3451  /* Make sure we have latest lookahead translation.  See comments at
3452     user semantic actions for why this is necessary.  */
3453  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
3454
3455  /* If not already recovering from an error, report this error.  */
3456  if (!yyerrstatus)
3457    {
3458      ++yynerrs;
3459#if ! YYERROR_VERBOSE
3460      yyerror (YY_("syntax error"));
3461#else
3462# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
3463                                        yyssp, yytoken)
3464      {
3465        char const *yymsgp = YY_("syntax error");
3466        int yysyntax_error_status;
3467        yysyntax_error_status = YYSYNTAX_ERROR;
3468        if (yysyntax_error_status == 0)
3469          yymsgp = yymsg;
3470        else if (yysyntax_error_status == 1)
3471          {
3472            if (yymsg != yymsgbuf)
3473              YYSTACK_FREE (yymsg);
3474            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
3475            if (!yymsg)
3476              {
3477                yymsg = yymsgbuf;
3478                yymsg_alloc = sizeof yymsgbuf;
3479                yysyntax_error_status = 2;
3480              }
3481            else
3482              {
3483                yysyntax_error_status = YYSYNTAX_ERROR;
3484                yymsgp = yymsg;
3485              }
3486          }
3487        yyerror (yymsgp);
3488        if (yysyntax_error_status == 2)
3489          goto yyexhaustedlab;
3490      }
3491# undef YYSYNTAX_ERROR
3492#endif
3493    }
3494
3495
3496
3497  if (yyerrstatus == 3)
3498    {
3499      /* If just tried and failed to reuse lookahead token after an
3500         error, discard it.  */
3501
3502      if (yychar <= YYEOF)
3503        {
3504          /* Return failure if at end of input.  */
3505          if (yychar == YYEOF)
3506            YYABORT;
3507        }
3508      else
3509        {
3510          yydestruct ("Error: discarding",
3511                      yytoken, &yylval);
3512          yychar = YYEMPTY;
3513        }
3514    }
3515
3516  /* Else will try to reuse lookahead token after shifting the error
3517     token.  */
3518  goto yyerrlab1;
3519
3520
3521/*---------------------------------------------------.
3522| yyerrorlab -- error raised explicitly by YYERROR.  |
3523`---------------------------------------------------*/
3524yyerrorlab:
3525
3526  /* Pacify compilers like GCC when the user code never invokes
3527     YYERROR and the label yyerrorlab therefore never appears in user
3528     code.  */
3529  if (/*CONSTCOND*/ 0)
3530     goto yyerrorlab;
3531
3532  /* Do not reclaim the symbols of the rule whose action triggered
3533     this YYERROR.  */
3534  YYPOPSTACK (yylen);
3535  yylen = 0;
3536  YY_STACK_PRINT (yyss, yyssp);
3537  yystate = *yyssp;
3538  goto yyerrlab1;
3539
3540
3541/*-------------------------------------------------------------.
3542| yyerrlab1 -- common code for both syntax error and YYERROR.  |
3543`-------------------------------------------------------------*/
3544yyerrlab1:
3545  yyerrstatus = 3;      /* Each real token shifted decrements this.  */
3546
3547  for (;;)
3548    {
3549      yyn = yypact[yystate];
3550      if (!yypact_value_is_default (yyn))
3551        {
3552          yyn += YYTERROR;
3553          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
3554            {
3555              yyn = yytable[yyn];
3556              if (0 < yyn)
3557                break;
3558            }
3559        }
3560
3561      /* Pop the current state because it cannot handle the error token.  */
3562      if (yyssp == yyss)
3563        YYABORT;
3564
3565
3566      yydestruct ("Error: popping",
3567                  yystos[yystate], yyvsp);
3568      YYPOPSTACK (1);
3569      yystate = *yyssp;
3570      YY_STACK_PRINT (yyss, yyssp);
3571    }
3572
3573  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
3574  *++yyvsp = yylval;
3575  YY_IGNORE_MAYBE_UNINITIALIZED_END
3576
3577
3578  /* Shift the error token.  */
3579  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
3580
3581  yystate = yyn;
3582  goto yynewstate;
3583
3584
3585/*-------------------------------------.
3586| yyacceptlab -- YYACCEPT comes here.  |
3587`-------------------------------------*/
3588yyacceptlab:
3589  yyresult = 0;
3590  goto yyreturn;
3591
3592/*-----------------------------------.
3593| yyabortlab -- YYABORT comes here.  |
3594`-----------------------------------*/
3595yyabortlab:
3596  yyresult = 1;
3597  goto yyreturn;
3598
3599#if !defined yyoverflow || YYERROR_VERBOSE
3600/*-------------------------------------------------.
3601| yyexhaustedlab -- memory exhaustion comes here.  |
3602`-------------------------------------------------*/
3603yyexhaustedlab:
3604  yyerror (YY_("memory exhausted"));
3605  yyresult = 2;
3606  /* Fall through.  */
3607#endif
3608
3609yyreturn:
3610  if (yychar != YYEMPTY)
3611    {
3612      /* Make sure we have latest lookahead translation.  See comments at
3613         user semantic actions for why this is necessary.  */
3614      yytoken = YYTRANSLATE (yychar);
3615      yydestruct ("Cleanup: discarding lookahead",
3616                  yytoken, &yylval);
3617    }
3618  /* Do not reclaim the symbols of the rule whose action triggered
3619     this YYABORT or YYACCEPT.  */
3620  YYPOPSTACK (yylen);
3621  YY_STACK_PRINT (yyss, yyssp);
3622  while (yyssp != yyss)
3623    {
3624      yydestruct ("Cleanup: popping",
3625                  yystos[*yyssp], yyvsp);
3626      YYPOPSTACK (1);
3627    }
3628#ifndef yyoverflow
3629  if (yyss != yyssa)
3630    YYSTACK_FREE (yyss);
3631#endif
3632#if YYERROR_VERBOSE
3633  if (yymsg != yymsgbuf)
3634    YYSTACK_FREE (yymsg);
3635#endif
3636  return yyresult;
3637}
3638#line 1032 "grammar.y" /* yacc.c:1906  */
3639
3640
3641int ufdbReadConfig(
3642   const char *      file )
3643{
3644   struct Source *   source;
3645   struct Category * cat;
3646   struct Acl *      acl;
3647
3648   lineno = 1;
3649   ufdbResetCPUs();
3650
3651   ufdbNewGV.configFile = file;
3652
3653   yyin = fopen( ufdbNewGV.configFile, "r" );
3654   if (yyin == NULL)
3655   {
3656      syslog( LOG_ALERT, "%s: cannot open configuration file %s", ufdbNewGV.progname, ufdbNewGV.configFile );
3657      ufdbLogFatalError( "cannot open configuration file %s", ufdbNewGV.configFile );
3658      return 0;
3659   }
3660
3661   ufdbLogMessage( "configuration file: %s", ufdbNewGV.configFile );
3662
3663   /* keep the old HTTPS redirection URL.  It is most likely that we need it during the database reload */
3664   /* dot not reset ufdbNewGV.RedirectHttps and ufdbNewGV.RedirectBumpedHttps. */
3665
3666   ufdbNewGV.debug = 0;
3667   ufdbNewGV.debugCoreDump = 0;
3668   strcpy( ufdbNewGV.interface, "all" );
3669   ufdbNewGV.portNum = UFDB_DAEMON_PORT;
3670   ufdbNewGV.nWorkers = UFDB_MIN_THREADS;
3671   ufdbNewGV.debugHttpd = 0;
3672   ufdbNewGV.logPass = 0;
3673   ufdbNewGV.logBlock = 0;
3674   ufdbNewGV.logAllRequests = 0;
3675   ufdbNewGV.YoutubeEdufilter = 0;
3676   ufdbFree( ufdbNewGV.YoutubeEdufilterID );
3677   ufdbNewGV.YoutubeEdufilterID = NULL;
3678   ufdbNewGV.allowGoogleHTTPSusingIP = 0;
3679
3680   /* When a database is reloaded, these variables may NOT be reset since they are used during the reload !! */
3681   ufdbNewGV.URLlookupDelayDBreload = 0;
3682   ufdbNewGV.URLlookupResultDBreload = UFDB_ALLOW;
3683   ufdbNewGV.URLlookupResultFatalError = UFDB_ALLOW;
3684   strcpy( ufdbNewGV.loadingDatabaseRedirect, "http://cgibin.urlfilterdb.com/cgi-bin/URLblocked.cgi?"
3685                "category=loading-database" );
3686   ufdbNewGV.SquidVersion = ufdbStrdup( UFDB_DEFAULT_SQUID_VERSION );
3687
3688   ufdbNewGV.showURLdetails = 0;
3689   ufdbNewGV.logURLdetails = 0;
3690   ufdbNewGV.uploadCrashReports = 1;
3691   ufdbNewGV.lookupReverseIP = 0;
3692   ufdbNewGV.useAlsoIPv6onWan = 1;
3693   ufdbNewGV.debugSkype = 0;
3694   ufdbNewGV.debugGtalk = 0;
3695   ufdbNewGV.debugYahooMsg = 0;
3696   ufdbNewGV.debugAim = 0;
3697   ufdbNewGV.debugFBchat = 0;
3698   ufdbNewGV.debugCitrixOnline = 0;
3699   ufdbNewGV.debugRegexp = 0;
3700   ufdbNewGV.debugExternalScripts = 0;
3701   ufdbNewGV.expressionOptimisation = 1;
3702   ufdbNewGV.refreshUserlistInterval = UFDB_DEFAULT_REFRESH_USERLIST;
3703   ufdbNewGV.refreshIPlistInterval = UFDB_DEFAULT_REFRESH_IPLIST;
3704   ufdbNewGV.refreshDomainlistInterval = UFDB_DEFAULT_REFRESH_DOMAINLIST;
3705   ufdbNewGV.analyseUncategorisedURLs = 1;
3706   ufdbNewGV.logUncategorisedURLs = 0;
3707   ufdbNewGV.uploadStats = 1;
3708   ufdbNewGV.safeSearch = 1;
3709   ufdbNewGV.skipSafeCategory = 0;
3710   ufdbNewGV.stripDomainFromUsername = 0;
3711   ufdbNewGV.tunnelCheckMethod = UFDB_API_HTTPS_CHECK_OFF;
3712   ufdbNewGV.SquidUsesActiveBumping = 0;
3713   ufdbNewGV.httpsWithHostname = 0;
3714   ufdbNewGV.httpsOfficialCertificate = 0;
3715   ufdbNewGV.unknownProtocolOverHttps = 1;
3716   ufdbNewGV.httpsNoSSLv2 = 1;
3717   ufdbNewGV.httpsNoSSLv3 = 1;
3718   ufdbNewGV.httpdPort = 0;
3719   ufdbNewGV.dateOfCheckedDB[0] = '\0';
3720   strcpy( ufdbNewGV.httpdInterface, "all" );
3721   strcpy( ufdbNewGV.httpdImagesDirectory, "." );
3722
3723   ufdbNewGV.databaseStatus = UFDB_API_STATUS_DATABASE_OK;
3724
3725   (void) yyparse();		/* parse the configuration file ********************/
3726   fclose( yyin );
3727
3728   ufdbNewGV.databaseLoadTime = time( NULL );
3729
3730   /*
3731    * For analysis of uncategorised URLs we also load a "checked" category
3732    * that contains URLs that are reviewed and checked not to be part of
3733    * any other category.
3734    */
3735   char * dbhome;
3736   char   dbfname[1024];
3737
3738   dbhome = ufdbNewGV.databaseDirectory;
3739
3740   /* TODO: check if "checked" was not already loaded... */
3741   if (ufdbNewGV.analyseUncategorisedURLs > 0)
3742   {
3743      int status;
3744      sprintf( dbfname, "%s/checked/domains.ufdb", dbhome );
3745      status = UFDBloadDatabase( &ufdbNewGV, &ufdbNewGV.checkedDB, dbfname );
3746      if (status != UFDB_API_OK  &&  status != UFDB_API_STATUS_DATABASE_OLD)
3747      {
3748         ufdbNewGV.checkedDB.mem = NULL;
3749         ufdbNewGV.checkedDB.index = NULL;
3750         ufdbNewGV.checkedDB.table.nNextLevels = 0;
3751         if (ufdbGV.debug)
3752            ufdbLogMessage( "The URL database appears not be from URLfilterDB. No problem." );
3753      }
3754      else
3755      {
3756         if (ufdbGV.debug)
3757            ufdbLogMessage( "table \"checked\" is loaded: %s %8.8s",
3758                            ufdbNewGV.checkedDB.date, ufdbNewGV.checkedDB.flags );
3759         sprintf( dbfname, "%s/checked/expressions", dbhome );
3760         (void) UFDBloadExpressions( &ufdbNewGV.checkedExpressions, dbfname );
3761         ufdbLogMessage( "The implicitly allowed URL category 'checked' is loaded." );
3762      }
3763   }
3764
3765   if (ufdbNewGV.defaultAcl == NULL)
3766      ufdbLogFatalError( "\"default\" ACL is not defined" );
3767   else if (ufdbNewGV.defaultAcl->pass == NULL)
3768      ufdbLogError( "\"default\" ACL is empty: by default all URLs are blocked." );
3769
3770   /* A configuration file may have a source definition which is not used in the ACL list.
3771    * This raises the question "what to do with this ?".
3772    * If we do nothing, the source is matched but has no ACL definition and is silently skipped.
3773    * Most likely the administrator overlooked something so a warning is useful.
3774    */
3775   source = ufdbNewGV.sourceList;
3776   if (source == NULL  &&  ufdbNewGV.defaultAcl == NULL)
3777      ufdbLogFatalError( "There are no sources and there is no default ACL" );
3778
3779   for ( ; source != NULL;  source = source->next)
3780   {
3781      int found;
3782
3783      found = 0;
3784      for (acl = ufdbNewGV.aclList;  acl != NULL;  acl = acl->next)
3785      {
3786         if (strcmp( acl->name, source->name ) == 0)
3787	 {
3788	    found = 1;
3789	    break;
3790	 }
3791      }
3792      if (!found)
3793      {
3794         ufdbLogError( "source \"%s\" has no ACL.  *****\n"
3795	               "This most likely may lead to unexpected results when the source is matched.  *****\n"
3796		       "It is strongly suggested to remove the source definition OR add the source to the acl.  *****",
3797		       source->name );
3798	 source->active = 0;
3799      }
3800      else if (acl->pass == NULL)
3801      {
3802         ufdbLogMessage( "source \"%s\" has an empty \"pass\" in its ACL *****", source->name );
3803      }
3804   }
3805
3806   for (cat = ufdbNewGV.catList;  cat != NULL;  cat = cat->next)
3807   {
3808      if (cat->options == 0  &&  cat->domainlist == NULL  &&  cat->execdomainlist == NULL  &&
3809          cat->expressionlist == NULL  &&  cat->rewrite == NULL  &&  cat->name != NULL)
3810      {
3811         ufdbLogError( "category \"%s\" has no content definition  *****", cat->name );
3812      }
3813   }
3814
3815   if (ufdbNewGV.adminEmail != NULL  &&  ufdbNewGV.emailServer == NULL)
3816   {
3817      ufdbLogError( "No email server is defined; cannot send email to \"%s\"  *****", ufdbNewGV.adminEmail );
3818   }
3819   if (ufdbNewGV.adminEmail != NULL  &&  ufdbNewGV.emailServer != NULL  &&  ufdbNewGV.senderEmail == NULL)
3820   {
3821      ufdbLogMessage( "WARNING: No sender email address is defined; using \"%s\" as sender",
3822                      ufdbNewGV.adminEmail );
3823   }
3824
3825   if (strncmp( ufdbNewGV.SquidVersion, "5.", 2 ) != 0  &&
3826       strncmp( ufdbNewGV.SquidVersion, "4.", 2 ) != 0  &&
3827       strncmp( ufdbNewGV.SquidVersion, "3.5", 3 ) != 0  &&
3828       strncmp( ufdbNewGV.SquidVersion, "3.4", 3 ) != 0  &&
3829       strncmp( ufdbNewGV.SquidVersion, "3.3", 3 ) != 0  &&
3830       strncmp( ufdbNewGV.SquidVersion, "3.2", 3 ) != 0  &&
3831       strncmp( ufdbNewGV.SquidVersion, "3.1", 3 ) != 0  &&
3832       strncmp( ufdbNewGV.SquidVersion, "3.0", 3 ) != 0  &&
3833       strncmp( ufdbNewGV.SquidVersion, "2.7", 3 ) != 0  &&
3834       strncmp( ufdbNewGV.SquidVersion, "2.6", 3 ) != 0)
3835   {
3836      ufdbLogFatalError( "Unsupported Squid version \"%s\"  *****\n"
3837                         "The supported values for squid-version are: "
3838                         "5.x, 4.x, 3.5, 3.4, 3.3, 3.2, 3.1, 3.0, 2.7, 2.6  *****\n"
3839			 "If the version of Squid is higher, it is recommended to upgrade ufdbGuard.  *****\n"
3840			 "Alternatively set squid-version to the highest supported version",
3841			 ufdbNewGV.SquidVersion );
3842   }
3843   if (strncmp( ufdbNewGV.SquidVersion, "5.", 2 ) == 0  ||
3844       strncmp( ufdbNewGV.SquidVersion, "4.", 2 ) == 0  ||
3845       strncmp( ufdbNewGV.SquidVersion, "3.5", 3 ) == 0  ||
3846       strncmp( ufdbNewGV.SquidVersion, "3.4", 3 ) == 0)
3847      ufdbNewGV.SquidHelperProtocol = UFDB_SQUID_HELPER_PROTOCOL3;
3848   else if (strncmp( ufdbNewGV.SquidVersion, "2.6", 3 ) == 0  ||
3849            strncmp( ufdbNewGV.SquidVersion, "2.7", 3 ) == 0)
3850      ufdbNewGV.SquidHelperProtocol = UFDB_SQUID_HELPER_PROTOCOL1;
3851   else
3852      ufdbNewGV.SquidHelperProtocol = UFDB_SQUID_HELPER_PROTOCOL2;	/* 3.0 - 3.3 */
3853
3854   BuildImplicitPassLists( &ufdbNewGV );
3855
3856   return 1;
3857}
3858
3859
3860static void setDBhome( char * dbhome )
3861{
3862   struct stat dirbuf;
3863
3864   if (strlen(dbhome) > sizeof(ufdbNewGV.databaseDirectory)-1)
3865   {
3866      ufdbLogFatalError( "maximum length for dbhome is %d", (int) sizeof(ufdbNewGV.databaseDirectory)-1 );
3867      ufdbFree( dbhome );
3868      return;
3869   }
3870   strcpy( ufdbNewGV.databaseDirectory, dbhome );
3871
3872   if (stat( dbhome, &dirbuf ) != 0)
3873   {
3874      ufdbLogFatalError( "dbhome %s: directory does not exist or access rights are insufficient", dbhome );
3875   }
3876   else
3877   {
3878      if (!S_ISDIR(dirbuf.st_mode))
3879         ufdbLogFatalError( "dbhome: %s is not a directory", dbhome );
3880   }
3881
3882   ufdbFree( dbhome );
3883}
3884
3885
3886static void setAdministrator( char * value )
3887{
3888   char * p;
3889
3890   if (strlen(value) > sizeof(ufdbNewGV.administrator)-1)
3891   {
3892      ufdbLogError( "maximum length for administrator is %d", (int) sizeof(ufdbNewGV.administrator)-1 );
3893      return;
3894   }
3895
3896   while ((p = (char *) strchr( value, '?' )) != NULL)
3897      *p = '_';
3898   while ((p = (char *) strchr( value, '&' )) != NULL)
3899      *p = '_';
3900
3901   strcpy( ufdbNewGV.administrator, value );
3902   ufdbFree( value );
3903}
3904
3905
3906static void setLogdir( char * value )
3907{
3908   if (ufdbNewGV.logDir != NULL)
3909      ufdbFree( ufdbNewGV.logDir );
3910   ufdbNewGV.logDir = value;
3911
3912   ufdbSetGlobalErrorLogFile( ufdbNewGV.logDir, NULL, 0 );
3913}
3914
3915
3916static void setPidfile( char * value )
3917{
3918   if (ufdbNewGV.pidFilename != NULL)
3919      ufdbFree( ufdbNewGV.pidFilename );
3920   ufdbNewGV.pidFilename = value;
3921}
3922
3923
3924static void setRefreshUserlist( int nmin )
3925{
3926   if (nmin < 5  ||  nmin > 24*60)
3927   {
3928      ufdbLogError( "refreshuserlist must have a value between 5 and %d, resetting to %d.",
3929                    24*60, UFDB_DEFAULT_REFRESH_USERLIST );
3930      nmin = UFDB_DEFAULT_REFRESH_USERLIST;
3931   }
3932   ufdbNewGV.refreshUserlistInterval = nmin;
3933}
3934
3935
3936static void setRefreshIPlist( int nmin )
3937{
3938   if (nmin < 5  ||  nmin > 24*60)
3939   {
3940      ufdbLogError( "refreshiplist must have a value between 5 and %d, resetting to %d.",
3941                    24*60, UFDB_DEFAULT_REFRESH_IPLIST );
3942      nmin = UFDB_DEFAULT_REFRESH_IPLIST;
3943   }
3944   ufdbNewGV.refreshIPlistInterval = nmin;
3945}
3946
3947
3948static void setRefreshDomainlist( int nmin )
3949{
3950   if (nmin < 5  ||  nmin > 24*60)
3951   {
3952      ufdbLogError( "refreshdomainlist must have a value between 5 and %d, resetting to %d.",
3953                    24*60, UFDB_DEFAULT_REFRESH_DOMAINLIST );
3954      nmin = UFDB_DEFAULT_REFRESH_DOMAINLIST;
3955   }
3956   ufdbNewGV.refreshDomainlistInterval = nmin;
3957}
3958
3959
3960/*
3961 * Source functions
3962 */
3963
3964static void defSource(
3965   char *          source )
3966{
3967   struct Source * sp;
3968
3969   if (ufdbGV.debug)
3970      ufdbLogMessage( "defSource: defining source \"%s\"", source );
3971
3972   if ((struct Source *) defSourceFindName(ufdbNewGV.sourceList,source) != NULL)
3973   {
3974      ufdbLogFatalError( "line %d: source %s is already defined in configuration file %s",
3975			 lineno, source, ufdbNewGV.configFile );
3976      ufdbFree( source );
3977      return;
3978   }
3979
3980   sp = (struct Source *) ufdbMallocAligned( UFDB_CACHELINE_SIZE, sizeof(struct Source) );
3981   sp->name = source;
3982   sp->active = 1;
3983   sp->evaluationMethod = UFDB_EVAL_OR;
3984   sp->ipv4hosts = NULL;
3985   sp->ipv4 = NULL;
3986   sp->ipv6hosts = NULL;
3987   sp->ipv6 = NULL;
3988   sp->domainDb = NULL;
3989   sp->userDb = NULL;
3990   sp->time = NULL;
3991   sp->within = UFDB_ACL_NONE;
3992   sp->cont_search = 0;
3993   sp->sarg0 = NULL;
3994   sp->execiplistCommand = NULL;
3995   sp->next = NULL;
3996   sp->nblocks = 0;
3997   sp->nmatches = 0;
3998
3999   if (ufdbNewGV.sourceList == NULL)
4000   {
4001      if (ufdbGV.debug)
4002         ufdbLogMessage( "defSource: SourceList is set to point to \"%s\"", source );
4003      ufdbNewGV.sourceList = sp;
4004      ufdbNewGV.lastSource = sp;
4005   }
4006   else
4007   {
4008      ufdbNewGV.lastSource->next = sp;
4009      ufdbNewGV.lastSource = sp;
4010   }
4011}
4012
4013
4014static void defSourceEnd( void )
4015{
4016   struct Source * s;
4017
4018   s = ufdbNewGV.lastSource;
4019   if (s->ipv4 == NULL  &&  s->ipv4hosts == NULL  &&
4020       s->ipv6 == NULL  &&  s->ipv6hosts == NULL  &&
4021       s->domainDb == NULL  &&  s->userDb == NULL)
4022   {
4023      if (s->execiplistCommand == NULL)
4024      {
4025	 ufdbLogError( "source \"%s\" missing active content, set inactive  *****", s->name );
4026	 s->time = NULL;
4027	 s->active = 0;
4028      }
4029      else
4030	 ufdbLogError( "source \"%s\" has an execiplist command but the list is empty and set inactive   *****",
4031	               s->name );
4032   }
4033}
4034
4035
4036static void ufdbSourceUser(
4037   char *          user )
4038{
4039   char *          lc;
4040   struct Source * sp;
4041
4042   sp = ufdbNewGV.lastSource;
4043   if (sp->userDb != NULL  &&  sp->userDb->type != SGDBTYPE_USERLIST)
4044   {
4045      ufdbLogFatalError( "user \"%s\" in source \"%s\" on line %d: "
4046                         "found mix of exec and non-exec userlists",
4047                         user, sp->name, lineno );
4048      return;
4049   }
4050   if (sp->userDb == NULL)
4051   {
4052      sp->userDb = (struct sgDb *) ufdbMalloc( sizeof(struct sgDb) );
4053      sp->userDb->dbhome = NULL;
4054      sp->userDb->dbcp = (void *) UFDBmemDBinit();
4055      sp->userDb->type = SGDBTYPE_USERLIST;
4056      sp->userDb->entries = 0;
4057   }
4058
4059   for (lc = user;  *lc != '\0';  lc++)    // convert username to lowercase
4060   {
4061      if (*lc <= 'Z'  &&  *lc >= 'A')
4062         *lc += 'a' - 'A';
4063   }
4064
4065   if (ufdbGV.debug > 1)
4066      ufdbLogMessage( "ufdbSourceUser: adding user \"%s\"", user );
4067
4068   sp->userDb->entries++;
4069   UFDBmemDBinsert( (struct UFDBmemDB *) sp->userDb->dbcp, user, NULL );
4070   ufdbFree( user );
4071}
4072
4073
4074static void ufdbSourceUnixGroup(
4075   char *          groupName  )
4076{
4077   struct Source * sp;
4078   struct group *  grp;
4079   int             n;
4080   char *          user;
4081
4082   sp = ufdbNewGV.lastSource;
4083   if (sp->userDb != NULL  &&  sp->userDb->type != SGDBTYPE_USERLIST)
4084   {
4085      ufdbLogFatalError( "unix group \"%s\" in source \"%s\" on line %d: "
4086                         "found mix of exec and non-exec userlists",
4087                         groupName, sp->name, lineno );
4088      return;
4089   }
4090   if (sp->userDb == NULL)
4091   {
4092      sp->userDb = (struct sgDb *) ufdbMalloc( sizeof(struct sgDb) );
4093      sp->userDb->dbhome = NULL;
4094      sp->userDb->dbcp = (void *) UFDBmemDBinit();
4095      sp->userDb->type = SGDBTYPE_USERLIST;
4096      sp->userDb->entries = 0;
4097   }
4098
4099   n = 0;
4100   setgrent();
4101   errno = 0;
4102   grp = getgrnam( groupName );
4103   if (grp != NULL)
4104   {
4105      if (ufdbGV.debug > 1)
4106         ufdbLogMessage( "found group \"%s\"", grp->gr_name );
4107
4108      while ((user = grp->gr_mem[n]) != NULL)
4109      {
4110	 char * lc;
4111
4112	 if (ufdbGV.debug > 1)
4113	    ufdbLogMessage( "group \"%s\" has user \"%s\"", grp->gr_name, user );
4114	 for (lc = user;  *lc != '\0';  lc++)  	// convert username to lowercase
4115	 {
4116	    if (*lc <= 'Z'  &&  *lc >= 'A')
4117	       *lc += 'a' - 'A';
4118	 }
4119	 UFDBmemDBinsert( (struct UFDBmemDB *) sp->userDb->dbcp, user, NULL );
4120	 sp->userDb->entries++;
4121	 n++;
4122      }
4123      ufdbLogMessage( "source \"%s\": unix group \"%s\" has %d members", sp->name, groupName, n );
4124      if (n == 0)
4125	 ufdbLogMessage( "WARNING: source \"%s\": \"%s\" is an empty group  +++++", sp->name, groupName );
4126   }
4127   else
4128   {
4129      ufdbLogFatalError( "source \"%s\": \"%s\" is not a unix group", sp->name, groupName );
4130      if (errno)
4131	 ufdbLogError( "ufdbSourceUnixGroup: getgrnam returned error %d: %s", errno, strerror(errno) );
4132   }
4133   endgrent();
4134}
4135
4136
4137static void ufdbSourceGroup(
4138   int    groupType,
4139   char * groupName  )
4140{
4141   switch (groupType)
4142   {
4143   case UFDB_GROUPTYPE_UNIX:
4144      ufdbSourceUnixGroup( groupName );
4145      break;
4146   default:
4147      ufdbLogFatalError( "ufdbSourceGroup: unknown group type %d", groupType );
4148   }
4149
4150   ufdbFree( groupName );
4151}
4152
4153
4154struct sgDb * UFDBretrieveExecDomainlist( struct Category * cat )       // uses ufdbGV
4155{
4156   char *        t;
4157   FILE *        fp;
4158   struct sgDb * newdb;
4159   int           exitcode;
4160   struct stat   Stat0;
4161   struct stat   Stat1;
4162   char          line[1024];
4163   char          basefilename[1024];
4164   char          fullfilename[1024];
4165   char          command[3000];
4166
4167   if (cat == NULL)
4168   {
4169      ufdbLogFatalError( "UFDBretrieveExecDomainlist: category is NULL" );
4170      return NULL;
4171   }
4172
4173   if (cat->domainlist == NULL)
4174   {
4175      ufdbLogError( "will not execute command for category %s since domainlist is undefined", cat->name );
4176      return NULL;
4177   }
4178
4179   if (cat->execdomainlist == NULL)
4180   {
4181      ufdbLogError( "can't execute command for category %s since execdomainlist is undefined", cat->name );
4182      return NULL;
4183   }
4184
4185   if (cat->domainlist[0] == '/')
4186   {
4187      strcpy( basefilename, cat->domainlist );
4188   }
4189   else
4190   {
4191      char * dbhome;
4192      dbhome = ufdbGV.databaseDirectory;
4193      sprintf( basefilename, "%s/%s", dbhome, cat->domainlist );
4194   }
4195   strcpy( fullfilename, basefilename );
4196   strcat( fullfilename, UFDBfileSuffix );
4197
4198   if (stat( fullfilename, &Stat0 ) != 0)
4199   {
4200      Stat0.st_mtime = 0;
4201      ufdbLogMessage( "category %s: pre-execdomainlist: domainlist does not exist (%s)",
4202                      cat->name, fullfilename );
4203   }
4204
4205   /* The script that we will call needs the directory where the files reside,
4206    * so the popen-command contains a "cd" just before executing the script.
4207    * (note that we are multithreaded and cannot use chdir() here)
4208    */
4209   strcpy( command, "cd " );
4210   strcat( command, basefilename );
4211   t = strrchr( command, '/' );
4212   if (t != NULL)
4213      *t = '\0';
4214   strcat( command, " ; " );
4215   strcat( command, cat->execdomainlist );
4216
4217   errno = 0;
4218   if ((fp = popen(command,"r")) == NULL)
4219   {
4220      ufdbLogFatalError( "category %s: can't execute command of execdomainlist \"%s\": popen failed: %s  *****",
4221                         cat->name, cat->execdomainlist, strerror(errno) );
4222      return NULL;
4223   }
4224
4225   while (UFDBfgetsNoNL(line,sizeof(line)-1,fp) != NULL)
4226   {
4227      ufdbLogMessage( "execdomainlist for %s produced: %s", cat->name, line );
4228   }
4229   errno = 0;
4230   exitcode = pclose( fp );
4231
4232   if (exitcode == -1  &&  errno == ECHILD)
4233      exitcode = 0;
4234      /* most likely the child handler thread already did a wait() */
4235
4236   if (exitcode == 0)
4237   {
4238      if (ufdbGV.debug || ufdbGV.debugExternalScripts)
4239         ufdbLogMessage( "   execdomainlist for %s: exit 0 (OK)", cat->name );
4240   }
4241   else if (exitcode == -1)
4242   {
4243      ufdbLogError( "execdomainlist for %s: pclose error: %d (%s)", cat->name, errno, strerror(errno) );
4244      return NULL;
4245   }
4246   else if (exitcode > 0)
4247   {
4248      ufdbLogError( "execdomainlist for %s: command (%s) terminated with an error exit code %d",
4249                    cat->name, cat->execdomainlist, exitcode );
4250      return NULL;
4251   }
4252
4253   /* The command defined by 'execdomainlist' has been executed and the exit code was 0 (OK), so
4254    * now it is verified if the file timestamp of domains.ufdb is newer.
4255    */
4256
4257   if (stat( fullfilename, &Stat1 ) != 0)
4258   {
4259      ufdbLogError( "execdomainlist for %s: command failed to produce a .ufdb file (%s)",
4260                    cat->name, fullfilename );
4261      return NULL;
4262   }
4263
4264   newdb = (struct sgDb *) ufdbCalloc( sizeof(struct sgDb), 1 );
4265   newdb->dbhome = NULL;
4266   newdb->dbcp = NULL;
4267   newdb->type = SGDBTYPE_DOMAINLIST;
4268
4269   sgDbInit( newdb, basefilename );
4270   if (newdb->dbcp == NULL)
4271   {
4272      ufdbLogError( "execdomainlist for %s: command produced a .ufdb file but I failed to load it", cat->name );
4273      ufdbFree( newdb );
4274      return NULL;
4275   }
4276
4277   if (ufdbGV.debug || ufdbGV.debugExternalScripts)
4278      ufdbLogMessage( "execdomainlist for %s: new URL table is loaded", cat->name );
4279
4280   return newdb;
4281}
4282
4283
4284static void ufdbSourceExecUserList(
4285   char *          command )            // must be malloced
4286{
4287   time_t          t0, te;
4288   struct Source * sp;
4289
4290   /* execuserlist is used to dynamically retrieve a list of usernames and
4291    * is executed every 15 minutes to refresh the list of usernames.
4292    */
4293
4294   sp = ufdbNewGV.lastSource;
4295   if (sp->userDb != NULL  &&  sp->userDb->type != SGDBTYPE_EXECUSERLIST)
4296   {
4297      ufdbLogFatalError( "execuserlist \"%s\" in source \"%s\" on line %d: "
4298                         "found mix of exec and non-exec userlists",
4299                         command, sp->name, lineno );
4300      return;
4301   }
4302   if (sp->userDb != NULL)
4303   {
4304      ufdbLogFatalError( "execuserlist \"%s\" in source \"%s\" on line %d: "
4305                         "more than one execuserlist is not supported.  Merge the userlists in the script.",
4306                         command, sp->name, lineno );
4307      return;
4308   }
4309   ufdbLogMessage( "execuserlist \"%s\"", command );
4310
4311   t0 = time( NULL );
4312   sp->userDb = UFDBretrieveExecUserlist( &ufdbNewGV, command );
4313   sp->sarg0 = command;				/* command is already malloc-ed */
4314   te = time( NULL );
4315
4316   if (te - t0 > 4)
4317      ufdbLogMessage( "WARNING: it took %ld seconds to execute \"%s\"  *****", te - t0, command );
4318
4319   if (ufdbGV.debug>1 || ufdbGV.debugExternalScripts)
4320   {
4321      UFDBmemDBprintUserDB( "user", (struct UFDBmemDB *) sp->userDb->dbcp );
4322   }
4323}
4324
4325
4326static void ufdbSourceExecIPList(
4327   char *          command )            // must be malloced
4328{
4329   time_t          t0, te;
4330   struct Source * sp;
4331
4332   /* execiplist is used to dynamically retrieve a list of IP addresses and
4333    * is executed every 15 minutes to refresh the list of IP addresses.
4334    */
4335
4336   sp = ufdbNewGV.lastSource;
4337   if (sp->ipv4 != NULL  ||  sp->ipv6 != NULL)
4338   {
4339      ufdbLogFatalError( "execiplist \"%s\" in source \"%s\" on line %d: "
4340                         "found mix of exec and non-exec iplists",
4341                         command, sp->name, lineno );
4342      return;
4343   }
4344   ufdbLogMessage( "execiplist \"%s\"", command );
4345
4346   t0 = time( NULL );
4347   UFDBretrieveExecIPlist( &ufdbNewGV, command, &sp->ipv4hosts, &sp->ipv4, &sp->ipv6hosts, &sp->ipv6 );
4348   sp->execiplistCommand = command;			/* command is already malloc-ed */
4349   te = time( NULL );
4350
4351   if (te - t0 > 4)
4352      ufdbLogMessage( "WARNING: it took %ld seconds to execute \"%s\"  *****", te - t0, command );
4353
4354   if (ufdbGV.debug>1 || ufdbGV.debugExternalScripts)
4355   {
4356      UFDBlogIPv4( sp->ipv4 );
4357      UFDBlogIPv6( sp->ipv6 );
4358   }
4359}
4360
4361
4362static void ufdbSourceUserList(
4363   char * file  )
4364{
4365   char * dbhome;
4366   char * f;
4367   FILE * fp;
4368   char * p;
4369   char * c;
4370   char * s;
4371   char * lc;
4372   char * lineptr;
4373   int    ullineno;
4374   struct sgDb * udb;
4375   struct Source * sp;
4376   char   line[10000];
4377
4378   sp = ufdbNewGV.lastSource;
4379   if (ufdbGV.debug)
4380      ufdbLogMessage( "ufdbSourceUserList: source \"%s\"  file \"%s\"",
4381       		      sp->name != NULL ? sp->name : "nosource", file );
4382   udb = sp->userDb;
4383   if (udb != NULL  &&  udb->type != SGDBTYPE_USERLIST)
4384   {
4385      ufdbLogFatalError( "userlist \"%s\" in source \"%s\" on line %d: "
4386                         "found mix of exec and non-exec userlists",
4387                         file, sp->name, lineno );
4388      return;
4389   }
4390   if (udb == NULL)
4391   {
4392      udb = sp->userDb = (struct sgDb *) ufdbMalloc( sizeof(struct sgDb) );
4393      udb->dbhome = NULL;
4394      udb->dbcp = (void *) UFDBmemDBinit();
4395      udb->type = SGDBTYPE_USERLIST;
4396      udb->entries = 0;
4397   }
4398
4399   dbhome = ufdbNewGV.databaseDirectory;
4400
4401   if (file[0] == '/')
4402      f = file;
4403   else
4404   {
4405      f = (char *) ufdbMalloc( strlen(dbhome) + strlen(file) + 2 );
4406      strcpy( f, dbhome );
4407      strcat( f, "/" );
4408      strcat( f, file );
4409      ufdbFree( file );
4410   }
4411
4412   if ((fp = fopen(f,"r")) == NULL)
4413   {
4414      ufdbLogError( "line %d: can't open userlist %s: %s  *****", lineno, f, strerror(errno) );
4415      ufdbFree( f );
4416      return;
4417   }
4418   ullineno = 0;
4419
4420   ufdbLogMessage( "userlist \"%s\"", f );
4421
4422   while (fgets(line,sizeof(line),fp) != NULL)
4423   {
4424      ullineno++;
4425      if (line[0] == '#')			/* skip comments */
4426         continue;
4427
4428      p = strchr( line, '\n' );
4429      if (p != NULL)
4430      {
4431         *p = '\0';
4432         if (p != line)
4433         {
4434  	    if (*(p - 1) == '\r') 		/* remove ^M  */
4435  	       *(p-1) = '\0';
4436         }
4437      }
4438
4439      if (line[0] == '\0')
4440      {
4441         ufdbLogError( "userlist %s: line %d: line is empty", f, ullineno );
4442         continue;
4443      }
4444
4445      c = strchr( line, '#' );		        /* remove comment */
4446      if (c != NULL)
4447         *c = '\0';
4448
4449      p = strtok_r( line, " \t,", &lineptr );
4450      if (p == NULL  ||  *p == '\0')
4451         continue;
4452
4453      /* we may have a passwd-style formatted file. Ignore ':' and everything else that follows. */
4454      if ((s = strchr(p,':')) != NULL)
4455         *s = '\0';
4456
4457      do
4458      {
4459         for (lc = p;  *lc != '\0';  lc++)      // convert username to lowercase
4460         {
4461  	    if (*lc <= 'Z'  &&  *lc >= 'A')
4462  	       *lc += 'a' - 'A';
4463         }
4464         if (*p != '\0')
4465 	 {
4466	    udb->entries++;
4467  	    UFDBmemDBinsert( (struct UFDBmemDB *) udb->dbcp, p, NULL );
4468         }
4469      } while ((p = strtok_r(NULL," \t,",&lineptr)) != NULL  &&  *p != '\0');
4470   }
4471   fclose( fp );
4472
4473   if (ufdbGV.debug > 1)
4474   {
4475      ufdbLogMessage( "just read userlist \"%s\"", f );
4476      UFDBmemDBprintUserDB( "user", (struct UFDBmemDB *) udb->dbcp );
4477   }
4478
4479   ufdbFree( f );
4480}
4481
4482
4483static void ufdbSourceUserQuota(
4484   const char * seconds,
4485   const char * sporadic,
4486   const char * renew )
4487{
4488   if (seconds == NULL || sporadic == NULL || renew == NULL)
4489      { ; }      // prevent compiler warning
4490
4491   ufdbLogError( "line %d: userquota is not supported", lineno );
4492}
4493
4494
4495static void defSourceDomain(
4496   char * domain )
4497{
4498   struct Source * sp;
4499
4500   sp = ufdbNewGV.lastSource;
4501   if (sp->domainDb == NULL)
4502      sp->domainDb = (struct sgDb *) UFDBmemDBinit();
4503
4504   if (ufdbGV.debug)
4505      ufdbLogMessage( "defSourceDomain \"%s\"", domain );
4506
4507   UFDBmemDBinsert( (struct UFDBmemDB *) sp->domainDb, domain, NULL );
4508
4509   ufdbFree( domain );
4510}
4511
4512
4513static void ufdbSourceEval(
4514   int method  )
4515{
4516   if (ufdbNewGV.lastSource != NULL)
4517   {
4518      if (ufdbGV.debug)
4519         ufdbLogMessage( "ufdbSourceEval %d: %s", method,
4520	                 method == UFDB_EVAL_OR ? "evaluate-or" : "evaluate-and" );
4521      ufdbNewGV.lastSource->evaluationMethod = method;
4522   }
4523}
4524
4525
4526static void defSourceTime(
4527   char *         name,
4528   int            within )
4529{
4530   struct ufdbTime *  t;
4531
4532   if ((t = sgTimeFindName(name)) == NULL)
4533   {
4534      ufdbLogFatalError( "line %d: time \"%s\" is not defined in configuration file %s",
4535		         lineno, name, ufdbNewGV.configFile );
4536      ufdbFree( name );
4537      return;
4538   }
4539
4540   ufdbNewGV.lastSource->within = within;
4541   ufdbNewGV.lastSource->time = t;
4542   ufdbFree( name );
4543}
4544
4545
4546static struct Source * defSourceFindName(
4547   struct Source * slist,
4548   const char *    name )
4549{
4550   for ( ;  slist != NULL;  slist = slist->next)
4551   {
4552      if (strcmp(name,slist->name) == 0)
4553         return slist;
4554   }
4555   return NULL;
4556}
4557
4558
4559static void defSourceIPV4List(
4560   char * file )
4561{
4562   char * dbhome;
4563   char * f;
4564   FILE * fp;
4565   char * p;
4566   char * c;
4567   char * cidr;
4568   int    i;
4569   int    l = 0;
4570   char * lineptr;
4571   char   line[UFDB_MAX_URL_LENGTH];
4572
4573   dbhome = ufdbNewGV.databaseDirectory;
4574
4575   if (file[0] == '/')
4576   {
4577      f = file;
4578   }
4579   else
4580   {
4581      f = (char *) ufdbMalloc( strlen(dbhome) + strlen(file) + 2 );
4582      strcpy( f, dbhome );
4583      strcat( f, "/" );
4584      strcat( f, file );
4585      ufdbFree( file );
4586   }
4587
4588   if ((fp = fopen(f,"r")) == NULL)
4589   {
4590      ufdbLogError( "line %d: can't open ipv4list %s: %s", lineno, f, strerror(errno) );
4591      ufdbFree( f );
4592      return;
4593   }
4594
4595   ufdbLogMessage( "ipv4list \"%s\"", f );
4596
4597   while (fgets(line,sizeof(line),fp) != NULL)
4598   {
4599      l++;
4600      if (*line == '#')
4601         continue;
4602      p = strchr( line, '\n' );
4603      if (p != NULL && p != line)
4604      {
4605         if (*(p - 1) == '\r') 		        // remove ^M
4606            p--;
4607         *p = '\0';
4608      }
4609      c = strchr( line, '#' );
4610      p = strtok_r( line, " \t,", &lineptr );
4611      do {
4612         if (c != NULL && p >= c) 		// find the comment
4613            break;
4614         i = strspn( p, ".0123456789/-" );
4615         if (i == 0)
4616            break;
4617         *(p + i) = '\0';
4618         if ((cidr = strchr(p,'/')) != NULL)
4619         {
4620            *cidr = '\0';
4621            cidr++;
4622            if (strchr(cidr,'.') == NULL)
4623               sgIpv4( p, SG_IPTYPE_CIDR, f, l );
4624            else
4625               sgIpv4( p, SG_IPTYPE_CLASS, f, l );
4626          }
4627          else if ((cidr = strchr(p,'-')) != NULL)
4628          {
4629             sgIpv4( p, SG_IPTYPE_RANGE, f, l );
4630          }
4631          else
4632          {
4633             sgIpv4( p, SG_IPTYPE_HOST, f, l );
4634          }
4635      } while ((p = strtok_r(NULL," \t,",&lineptr)) != NULL);
4636   }
4637
4638   fclose( fp );
4639   ufdbFree( f );
4640}
4641
4642
4643static void defSourceIPV6List(
4644   char * file )
4645{
4646   char * dbhome;
4647   char * f;
4648   FILE * fp;
4649   char * p;
4650   char * c;
4651   int    i;
4652   int    l = 0;
4653   char * lineptr;
4654   char   line[UFDB_MAX_URL_LENGTH];
4655
4656   dbhome = ufdbNewGV.databaseDirectory;
4657
4658   if (file[0] == '/')
4659   {
4660      f = file;
4661   }
4662   else
4663   {
4664      f = (char *) ufdbMalloc( strlen(dbhome) + strlen(file) + 2 );
4665      strcpy( f, dbhome );
4666      strcat( f, "/" );
4667      strcat( f, file );
4668      ufdbFree( file );
4669   }
4670
4671   if ((fp = fopen(f,"r")) == NULL)
4672   {
4673      ufdbLogError( "line %d: can't open ipv6list %s: %s", lineno, f, strerror(errno) );
4674      ufdbFree( f );
4675      return;
4676   }
4677
4678   ufdbLogMessage( "ipv6list \"%s\"", f );
4679
4680   while (fgets(line,sizeof(line),fp) != NULL)
4681   {
4682      l++;
4683      if (*line == '#')
4684         continue;
4685      p = strchr( line, '\n' );
4686      if (p != NULL && p != line)
4687      {
4688         if (*(p - 1) == '\r') 		        // remove ^M
4689            p--;
4690         *p = '\0';
4691      }
4692      c = strchr( line, '#' );
4693      p = strtok_r( line, " \t,", &lineptr );
4694      do {
4695         if (c != NULL && p >= c) 		// find the comment
4696            break;
4697         i = strspn( p, ":.0123456789ABCDEFabcdef/" );
4698         if (i == 0)
4699            break;
4700         *(p + i) = '\0';
4701         if (strchr(p,'/') != NULL)
4702         {
4703            sgIpv6( p, SG_IPV6TYPE_CIDR, f, l );
4704         }
4705         else
4706         {
4707            sgIpv6( p, SG_IPV6TYPE_HOST, f, l );
4708         }
4709      } while ((p = strtok_r(NULL," \t,",&lineptr)) != NULL);
4710   }
4711
4712   fclose( fp );
4713   ufdbFree( f );
4714}
4715
4716
4717/* category block functions */
4718
4719void ufdbCategory(
4720  char *            cat )
4721{
4722  struct Category * sp;
4723
4724#if UFDB_DEBUG
4725   ufdbLogMessage( "ufdbCategory %s", cat );
4726#endif
4727
4728  if (ufdbNewGV.catList != NULL)
4729  {
4730    if ((struct Category *) ufdbCategoryFindByName(&ufdbNewGV,cat) != NULL)
4731    {
4732      ufdbLogFatalError( "line %d: category %s is already defined in configuration file %s",
4733		         lineno, cat, ufdbNewGV.configFile );
4734      ufdbFree( cat );
4735      return;
4736    }
4737  }
4738
4739  sp = (struct Category *) ufdbMallocAligned( UFDB_CACHELINE_SIZE, sizeof(struct Category) );
4740  sp->active = 1;
4741  sp->within = UFDB_ACL_NONE;
4742  sp->activeBumping = UFDB_ACTIVE_BUMPING_NOTSET;
4743  sp->blockBumpedConnect = 0;
4744  sp->options = 0;
4745  sp->name = cat;
4746  sp->domainlist = NULL;
4747  sp->domainlistDb = NULL;
4748  sp->execdomainlist = NULL;
4749  sp->expressionlist = NULL;
4750  sp->regExp = NULL;
4751  sp->redirect = NULL;
4752  sp->time = NULL;
4753  sp->rewrite = NULL;
4754  sp->next = NULL;
4755  sp->nblocks = 0;
4756  sp->nmatches = 0;
4757
4758  if (ufdbNewGV.catList == NULL) {
4759    ufdbNewGV.catList = sp;
4760    ufdbNewGV.lastCat = sp;
4761  } else {
4762    ufdbNewGV.lastCat->next = sp;
4763    ufdbNewGV.lastCat = sp;
4764  }
4765
4766   /* category "security" is a special case: the options cannot be set default to 0
4767    * because the default value for allow-unknown-protocol-over-https is ON.
4768    */
4769   if (strcmp( cat, "security" ) == 0)
4770      sp->options = UFDB_OPT_UNKNOWN_PROTOCOL_OVER_HTTPS;
4771}
4772
4773
4774void ufdbCategoryEnd( void )
4775{
4776  struct Category * d;
4777
4778  d = ufdbNewGV.lastCat;
4779  if (d->domainlist == NULL  &&  d->expressionlist == NULL  &&
4780      d->redirect == NULL  &&  d->rewrite == NULL  &&
4781      d->options == 0)
4782  {
4783    ufdbLogError( "category \"%s\" is missing content, set inactive  *****", d->name );
4784    d->time = NULL;
4785    d->active = 0;
4786  }
4787}
4788
4789
4790static void ufdbCategoryOption( int value, int option )
4791{
4792   struct Category * sp;
4793
4794   sp = ufdbNewGV.lastCat;
4795   if (value)
4796      sp->options = sp->options | option;
4797   else
4798      sp->options = sp->options & (~option);
4799
4800   if (option == UFDB_OPT_HTTPS_WITH_HOSTNAME)
4801      ufdbNewGV.httpsWithHostname = value;
4802   else if (option == UFDB_OPT_HTTPS_OFFICAL_CERTIFICATE)
4803      ufdbNewGV.httpsOfficialCertificate = value;
4804   else if (option == UFDB_OPT_SKYPE_OVER_HTTPS)
4805      ufdbNewGV.SkypeOverHttps = value;
4806   else if (option == UFDB_OPT_GTALK_OVER_HTTPS)
4807      ufdbNewGV.GtalkOverHttps = value;
4808   else if (option == UFDB_OPT_YAHOOMSG_OVER_HTTPS)
4809      ufdbNewGV.YahooMsgOverHttps = value;
4810   else if (option == UFDB_OPT_AIM_OVER_HTTPS)
4811      ufdbNewGV.AimOverHttps = value;
4812   else if (option == UFDB_OPT_FBCHAT_OVER_HTTPS)
4813      ufdbNewGV.FBchatOverHttps = value;
4814   else if (option == UFDB_OPT_CITRIXONLINE_OVER_HTTPS)
4815      ufdbNewGV.CitrixOnlineOverHttps = value;
4816   else if (option == UFDB_OPT_ANYDESK_OVER_HTTPS)
4817      ufdbNewGV.AnydeskOverHttps = value;
4818   else if (option == UFDB_OPT_TEAMVIEWER_OVER_HTTPS)
4819      ufdbNewGV.TeamviewerOverHttps = value;
4820   else if (option == UFDB_OPT_PROHIBIT_INSECURE_SSLV2)
4821      ufdbNewGV.httpsNoSSLv2 = value;
4822   else if (option == UFDB_OPT_PROHIBIT_INSECURE_SSLV3)
4823      ufdbNewGV.httpsNoSSLv3 = value;
4824   else if (option == UFDB_OPT_UNKNOWN_PROTOCOL_OVER_HTTPS)
4825      ufdbNewGV.unknownProtocolOverHttps = value;
4826   else if (option == UFDB_OPT_SAFE_SEARCH)
4827      ;
4828   else if (option == UFDB_OPT_YOUTUBE_EDUFILTER)
4829      ;
4830   else
4831      ufdbLogError( "ufdbCategoryOption: unrecognised option %d *****", option );
4832
4833   if (ufdbGV.debug > 1)
4834      ufdbLogMessage( "ufdbCategoryOption: %s: option %d set to %d", sp->name, option, value );
4835}
4836
4837
4838void ufdbCategoryDomainList(
4839  char * domainlist )
4840{
4841  struct Category * sp;
4842  const char *      dbhome;
4843        char *      dl;
4844  const char *      name;
4845
4846  if (ufdbGV.debug > 1)
4847     ufdbLogMessage( "ufdbCategoryDomainList %s", domainlist==NULL ? "NULL" : domainlist );
4848
4849  if (ufdbNewGV.terminating)
4850     return;
4851
4852  sp = ufdbNewGV.lastCat;
4853
4854  if (sp->domainlistDb != NULL)
4855  {
4856     ufdbLogFatalError( "line %d: specify only one domainlist per category in configuration file %s",
4857		        lineno, ufdbNewGV.configFile );
4858     return;
4859  }
4860
4861  dbhome = ufdbNewGV.databaseDirectory;
4862
4863  if (domainlist == NULL)
4864  {
4865    name = sp->name;
4866    dl = (char *) ufdbMalloc( sizeof("/dest/") + strlen(name) + sizeof("/domainlist") + 2 );
4867    strcpy(dl,"/dest/");
4868    strcat(dl,name);
4869    strcat(dl,"/domainlist");
4870
4871    sp->domainlist = (char *) ufdbMalloc( strlen(dbhome) + strlen(dl) + 2 );
4872    strcpy(sp->domainlist,dbhome);
4873    strcat(sp->domainlist,"/");
4874    strcat(sp->domainlist,dl);
4875  }
4876  else
4877  {
4878    if (domainlist[0] == '/')
4879      sp->domainlist = domainlist;
4880    else
4881    {
4882       sp->domainlist = (char *) ufdbMalloc( strlen(dbhome) + strlen(domainlist) + 2 );
4883       strcpy( sp->domainlist, dbhome );
4884       strcat( sp->domainlist, "/" );
4885       strcat( sp->domainlist, domainlist );
4886       ufdbFree( (void*) domainlist );
4887    }
4888  }
4889
4890  sp->domainlistDb = (struct sgDb *) ufdbCalloc( 1, sizeof(struct sgDb) );
4891  sp->domainlistDb->type = SGDBTYPE_DOMAINLIST;
4892  ufdbLogMessage( "loading URL table from \"%s\"", sp->domainlist );
4893  sgDbInit( sp->domainlistDb, sp->domainlist );
4894  if (sp->domainlistDb->dbcp == NULL  ||
4895      ((struct UFDBmemTable *) sp->domainlistDb->dbcp)->table.nNextLevels == 0)
4896  {
4897    ufdbLogError( "URL database table \"%s\" is empty and is ignored   *****", sp->domainlist );
4898    ufdbFreeDomainDb( sp->domainlistDb );
4899    sp->domainlistDb = NULL;
4900  }
4901}
4902
4903
4904static void ufdbCategoryExecDomainList(
4905   char * command )
4906{
4907   struct Category * sp;
4908
4909#if UFDB_DEBUG
4910   ufdbLogMessage( "ufdbCategoryExecDomainList %s", command );
4911#endif
4912
4913   sp = ufdbNewGV.lastCat;
4914
4915   if (sp == NULL)
4916   {
4917      ufdbLogFatalError( "execdomainlist is not within a URL category" );
4918      return;
4919   }
4920   sp->execdomainlist = command;
4921
4922   if (ufdbGV.debug)
4923      ufdbLogMessage( "execdomainlist for category %s: \"%s\"", sp->name, command );
4924}
4925
4926
4927void ufdbFreeDomainDb(
4928   struct sgDb * dbp )
4929{
4930   struct UFDBmemTable * mt;
4931
4932   if (dbp == NULL)
4933      return;
4934
4935   mt = (struct UFDBmemTable *) dbp->dbcp;
4936   if (mt != NULL)
4937   {
4938      if (mt->index != NULL)
4939      {
4940	 ufdbFree( mt->index );				/* version 2.x */
4941	 ufdbFree( mt->table.nextLevel );
4942      }
4943      else
4944	 UFDBfreeTableIndex_1_2( &(mt->table) ); 	/* version 1.2 */
4945#if HAVE_MADVISE && !UFDB_BARE_METAL_SUPPORT && __linux__
4946      if (mt->madvisedSize)
4947         madvise( mt->mem, mt->madvisedSize, MADV_NORMAL );
4948#endif
4949      if (mt->memStatus == UFDB_MEMSTATUS_MALLOC)
4950         ufdbFree( (void *) mt->mem );
4951      ufdbFree( mt );
4952   }
4953   ufdbFree( dbp );
4954}
4955
4956
4957void ufdbFreeIpv4List( struct Ipv4 * ipv4 )
4958{
4959   struct Ipv4 * tmp;
4960
4961   while (ipv4 != NULL)
4962   {
4963      tmp = ipv4->next;
4964      ufdbFree( (void*) ipv4 );
4965      ipv4 = tmp;
4966   }
4967}
4968
4969
4970void ufdbFreeIpv6List( struct Ipv6 * ipv6 )
4971{
4972   struct Ipv6 * tmp;
4973
4974   while (ipv6 != NULL)
4975   {
4976      tmp = ipv6->next;
4977      ufdbFree( (void*) ipv6 );
4978      ipv6 = tmp;
4979   }
4980}
4981
4982
4983static void ufdbFreeSourceList( struct Source * src )
4984{
4985   struct Source * tmp;
4986
4987   while (src != NULL)
4988   {
4989      if (src->ipv4hosts != NULL)
4990         UFDBmemDBdeleteDB( src->ipv4hosts );
4991      ufdbFreeIpv4List( src->ipv4 );
4992      if (src->ipv6hosts != NULL)
4993         UFDBmemDBdeleteDB( src->ipv6hosts );
4994      ufdbFreeIpv6List( src->ipv6 );
4995
4996      ufdbFree( (void*) src->name );
4997      if (src->domainDb != NULL)
4998	 UFDBmemDBdeleteDB( (struct UFDBmemDB *) src->domainDb );
4999
5000      /* execuserlist content is saved during a reload except when ufdbguardd terminates */
5001      if (src->userDb != NULL  &&  src->userDb->type != SGDBTYPE_EXECUSERLIST)
5002      {
5003	 UFDBmemDBdeleteDB( (struct UFDBmemDB *) src->userDb->dbcp );
5004	 ufdbFree( (void*) src->userDb );
5005      }
5006      ufdbFree( (void*) src->sarg0 );
5007      ufdbFree( (void*) src->execiplistCommand );
5008
5009      tmp = src->next;
5010      ufdbFree( (void*) src );
5011      src = tmp;
5012   }
5013}
5014
5015
5016static void ufdbFreeAclCategoryList( struct AclCategory * ac )
5017{
5018   struct AclCategory * tmp;
5019
5020   while (ac != NULL)
5021   {
5022      ufdbFree( (void*) ac->name );
5023      tmp = ac->next;
5024      ufdbFree( (void*) ac );
5025      ac = tmp;
5026   }
5027}
5028
5029
5030static void ufdbFreeAclList( struct Acl * acl )
5031{
5032   struct Acl * tmp;
5033
5034   while (acl != NULL)
5035   {
5036      ufdbFree( (void*) acl->name );
5037      ufdbFreeAclCategoryList( acl->pass );
5038      ufdbFreeAclCategoryList( acl->implicitPass );
5039      ufdbFree( (void*) acl->redirect );
5040      tmp = acl->next;
5041      ufdbFree( (void*) acl );
5042      acl = tmp;
5043   }
5044}
5045
5046
5047static void ufdbFreeCategoryList( struct Category * cat )
5048{
5049   struct Category * tmp;
5050
5051   while (cat != NULL)
5052   {
5053      if (ufdbGV.debug > 1  ||  ufdbGV.debugRegexp)
5054         ufdbLogMessage( "ufdbFreeCategoryList: freeing regexp of category %s", cat->name );
5055      ufdbFreeRegExprList( cat->regExp );
5056      ufdbFree( (void*) cat->name );
5057      ufdbFree( (void*) cat->domainlist );
5058      ufdbFreeDomainDb( cat->domainlistDb );
5059      ufdbFree( (void*) cat->execdomainlist );
5060      ufdbFree( (void*) cat->expressionlist );
5061      ufdbFree( (void*) cat->redirect );
5062      /* ufdbFree( cat->rewrite );  freed in ufdbFreeRewriteList() */
5063      tmp = cat->next;
5064      ufdbFree( (void*) cat );
5065      cat = tmp;
5066   }
5067}
5068
5069
5070static void ufdbFreeRewriteList(
5071   struct sgRewrite * p )
5072{
5073   struct sgRewrite * tmp;
5074
5075   while (p != NULL)
5076   {
5077      ufdbFreeRegExprList( p->rewrite );
5078      ufdbFree( (void*) p->name );
5079      tmp = p->next;
5080      ufdbFree( (void*) p );
5081      p = tmp;
5082   }
5083}
5084
5085
5086static void ufdbFreeTimeElement(
5087   struct TimeElement * p )
5088{
5089   struct TimeElement * tmp;
5090
5091   while (p != NULL)
5092   {
5093      tmp = p->next;
5094      ufdbFree( (void*) p );
5095      p = tmp;
5096   }
5097}
5098
5099
5100static void ufdbFreeTime(
5101   struct ufdbTime * p )
5102{
5103   struct ufdbTime * tmp;
5104
5105   while (p != NULL)
5106   {
5107      ufdbFree( (void*) p->name );
5108      ufdbFreeTimeElement( p->element );
5109      tmp = p->next;
5110      ufdbFree( (void*) p );
5111      p = tmp;
5112   }
5113}
5114
5115
5116void ufdbFreeLastBits( struct ufdbGV * gv )
5117{
5118   /* we may need these variables during a reload */
5119   if (gv->pidFilename != NULL)
5120   {
5121      ufdbFree( (void*) gv->pidFilename );
5122      gv->pidFilename = NULL;
5123   }
5124   if (gv->emailServer != NULL)
5125   {
5126      ufdbFree( (void*) gv->emailServer );
5127      gv->emailServer = NULL;
5128   }
5129   if (gv->myHostname != NULL)
5130   {
5131      ufdbFree( (void*) gv->myHostname );
5132      gv->myHostname = NULL;
5133   }
5134   if (gv->adminEmail != NULL)
5135   {
5136      ufdbFree( (void*) gv->adminEmail );
5137      gv->adminEmail = NULL;
5138   }
5139   if (gv->senderEmail != NULL)
5140   {
5141      ufdbFree( (void*) gv->senderEmail );
5142      gv->senderEmail = NULL;
5143   }
5144   if (gv->externalStatusCommand != NULL)
5145   {
5146      ufdbFree( (void*) gv->externalStatusCommand );
5147      gv->externalStatusCommand = NULL;
5148   }
5149}
5150
5151
5152void ufdbFreeAllMemory( struct ufdbGV * gv )
5153{
5154   if (gv->logDir != NULL)
5155      ufdbFree( gv->logDir );
5156   gv->logDir = NULL;
5157
5158   ufdbFreeRewriteList( gv->rewrite );
5159   gv->rewrite = NULL;
5160   gv->lastRewrite = NULL;
5161   gv->lastRewriteRegExec = NULL;
5162
5163   ufdbFreeCategoryList( gv->catList );
5164   gv->catList = NULL;
5165   gv->lastCat = NULL;
5166
5167   ufdbFreeAclList( gv->aclList );
5168   gv->aclList = NULL;
5169   gv->lastAcl = NULL;
5170   gv->defaultAcl = NULL;
5171   gv->lastAclCategory = NULL;
5172
5173   ufdbFreeSourceList( (struct Source *) gv->sourceList );
5174   gv->sourceList = NULL;
5175   gv->lastSource = NULL;
5176
5177   /* free ufdbNewGV.checkedDB */
5178   if (gv->checkedDB.mem != NULL)
5179   {
5180      if (gv->checkedDB.index != NULL)
5181      {
5182         ufdbFree( (void*) gv->checkedDB.index );
5183	 ufdbFree( gv->checkedDB.table.nextLevel );
5184      }
5185      else
5186	 UFDBfreeTableIndex_1_2( &(gv->checkedDB.table) );
5187#if HAVE_MADVISE && !UFDB_BARE_METAL_SUPPORT && __linux__
5188      if (gv->checkedDB.madvisedSize)
5189         madvise( gv->checkedDB.mem, gv->checkedDB.madvisedSize, MADV_NORMAL );
5190#endif
5191      gv->checkedDB.madvisedSize = 0;
5192      if (gv->checkedDB.memStatus == UFDB_MEMSTATUS_MALLOC)
5193         ufdbFree( (void*) gv->checkedDB.mem );
5194   }
5195   gv->checkedDB.table.nextLevel = NULL;
5196   gv->checkedDB.table.nNextLevels = 0;
5197   gv->checkedDB.mem = NULL;
5198   gv->checkedDB.index = NULL;
5199
5200   if (gv->checkedExpressions != NULL)
5201   {
5202      ufdbFreeRegExprList( gv->checkedExpressions );
5203      gv->checkedExpressions = NULL;
5204   }
5205
5206   ufdbFreeTime( gv->timeList );
5207   gv->timeList = NULL;
5208   gv->lastTime = NULL;
5209
5210   gv->lastTimeElement = NULL;
5211   gv->timeElement = NULL;
5212
5213   gv->lastRegExpDest = NULL;
5214
5215   ufdbFree( (void*) gv->SquidVersion );
5216   gv->SquidVersion = NULL;
5217}
5218
5219
5220static void ufdbCategoryUrlList(
5221   char * urllist )
5222{
5223   if (urllist == NULL)
5224      urllist = (char *) "-";
5225   ufdbLogError( "line %d: \"urllist %s\" is deprecated and ignored *****\n"
5226                 "ufdbGenTable should be called with the -u option to include URLs\n"
5227		 "ufdbGenTable combines URLs and domains in one table file so only the domainlist is required",
5228		 lineno, urllist );
5229   if (urllist[0] != '-')
5230      ufdbFree( (void*) urllist );
5231}
5232
5233
5234void ufdbCategoryExpressionList(
5235  char * exprlist,
5236  const char * chcase  )
5237{
5238  FILE * fp;
5239  char * dbhome;
5240  char * dl;
5241  const char * name;
5242  char * p;
5243  int    flags;
5244  struct stat         statbuf;
5245  struct Category *   sp;
5246  struct ufdbRegExp * regexp;
5247  char   buf[UFDB_MAX_URL_LENGTH];
5248  char   errbuf[256];
5249
5250#if UFDB_DEBUG
5251   ufdbLogMessage( "ufdbCategoryExpressionList %s", exprlist );
5252#endif
5253
5254  flags = REG_EXTENDED | REG_NOSUB;
5255  sp = ufdbNewGV.lastCat;
5256  dbhome = ufdbNewGV.databaseDirectory;
5257
5258  if (exprlist == NULL)
5259  {
5260    name = sp->name;
5261    dl = (char *) ufdbMalloc( sizeof("/dest/") + strlen(name) + sizeof("/expressionlist") + 2 );
5262    strcpy(dl,"/dest/");
5263    strcat(dl,name);
5264    strcat(dl,"/expressionlist");
5265
5266    flags |= REG_ICASE; 	/* default case insensitive */
5267
5268    sp->expressionlist = (char *) ufdbMalloc( strlen(dbhome) + strlen(dl) + 2 );
5269    strcpy(sp->expressionlist,dbhome);
5270    strcat(sp->expressionlist,"/");
5271    strcat(sp->expressionlist,dl);
5272  }
5273  else
5274  {
5275    if (exprlist[0] == '/')
5276    {
5277      sp->expressionlist = exprlist;
5278    }
5279    else
5280    {
5281       sp->expressionlist = (char *) ufdbMalloc( strlen(dbhome) + strlen(exprlist) + 2 );
5282       strcpy( sp->expressionlist, dbhome );
5283       strcat( sp->expressionlist, "/" );
5284       strcat( sp->expressionlist, exprlist );
5285       ufdbFree( (void*) exprlist );
5286    }
5287    if (*chcase == 'i')
5288       flags |= REG_ICASE;     /* set case insensitive */
5289  }
5290
5291  ufdbLogMessage( "loading regular expressions from \"%s\"", sp->expressionlist );
5292
5293  if ((fp = fopen(sp->expressionlist, "r")) == NULL)
5294  {
5295    ufdbLogFatalError( "cannot open expression list %s: %s", sp->expressionlist, strerror(errno) );
5296    return;
5297  }
5298
5299  if (0 == fstat( fileno(fp), &statbuf ))
5300  {
5301     if (!S_ISREG(statbuf.st_mode))
5302     {
5303        ufdbLogFatalError( "expression list %s: not a regular file", sp->expressionlist );
5304	fclose( fp );
5305	return;
5306     }
5307  }
5308
5309  while (!feof(fp)  &&  fgets(buf, sizeof(buf), fp) != NULL)
5310  {
5311    if (buf[0] == '#')
5312       continue;
5313
5314    p = (char *) strchr( buf, '\n' );
5315    if (p != NULL  &&  p != buf)
5316    {
5317      if (*(p-1) == '\r') 	/* removing ^M  */
5318	p--;
5319      *p = '\0';
5320    }
5321    /* TO-DO: warn about leading and trailing spaces */
5322    regexp = ufdbNewPatternBuffer( buf, flags );
5323    if (regexp->error)
5324    {
5325      regerror( regexp->error, (regex_t*) regexp->compiled[0], errbuf, sizeof(errbuf) );
5326      ufdbLogError( "regular expression error in %s:\n%s : %s   *****", sp->expressionlist, errbuf, buf );
5327    }
5328    if (ufdbNewGV.lastCat->regExp == NULL)
5329    {
5330      ufdbNewGV.lastCat->regExp = regexp;
5331      ufdbNewGV.lastRegExpDest = regexp;
5332    }
5333    else
5334    {
5335      ufdbNewGV.lastRegExpDest->next = regexp;
5336      ufdbNewGV.lastRegExpDest = regexp;
5337    }
5338  }
5339  fclose( fp );
5340
5341  if (ufdbNewGV.expressionOptimisation)
5342     ufdbNewGV.lastCat->regExp = UFDBoptimizeExprList( sp->expressionlist, ufdbNewGV.lastCat->regExp );
5343}
5344
5345
5346static void ufdbCategoryCACertsFile(
5347   char *              cacertsFile )
5348{
5349   struct Category *   cat;
5350
5351   cat = ufdbNewGV.lastCat;
5352   if (cat == NULL  ||  strcmp( cat->name, "security" ) != 0)
5353   {
5354      ufdbLogFatalError( "cacerts can only be defined inside the \"security\" category" );
5355      return;
5356   }
5357
5358   if (*cacertsFile == '/')
5359      strcpy( ufdbNewGV.CAcertsFile, cacertsFile );
5360   else
5361   {
5362      char * dbh;
5363      dbh = ufdbNewGV.databaseDirectory;
5364      strcpy( ufdbNewGV.CAcertsFile, dbh );
5365      strcat( ufdbNewGV.CAcertsFile, "/" );
5366      strcat( ufdbNewGV.CAcertsFile, cacertsFile );
5367   }
5368}
5369
5370
5371static void ufdbCategoryCACertsDir(
5372   char *              cacertsDir )
5373{
5374   struct Category *   cat;
5375
5376   cat = ufdbNewGV.lastCat;
5377   if (cat == NULL  ||  strcmp( cat->name, "security" ) != 0)
5378   {
5379      ufdbLogFatalError( "cacerts-dir can only be defined inside the \"security\" category" );
5380      return;
5381   }
5382
5383   if (*cacertsDir == '/')
5384      strcpy( ufdbNewGV.CAcertsDir, cacertsDir );
5385   else
5386   {
5387      char * dbh;
5388      dbh = ufdbNewGV.databaseDirectory;
5389      strcpy( ufdbNewGV.CAcertsDir, dbh );
5390      strcat( ufdbNewGV.CAcertsDir, "/" );
5391      strcat( ufdbNewGV.CAcertsDir, cacertsDir );
5392   }
5393}
5394
5395
5396static void ufdbCategoryRedirect(
5397   char * value )
5398{
5399   struct Category * sp;
5400
5401#if UFDB_DEBUG
5402   ufdbLogMessage( "ufdbCategoryRedirect %s", value );
5403#endif
5404
5405   sp = ufdbNewGV.lastCat;
5406   sp->redirect = value;
5407   /* TODO: check that "localhost" is not here if no 302 is used */
5408}
5409
5410
5411static void ufdbCategoryRewrite(
5412  char *              value )
5413{
5414  struct sgRewrite *  rewrite;
5415
5416  if ((rewrite = sgRewriteFindName(value)) == NULL)
5417  {
5418    ufdbLogFatalError( "line %d: rewrite %s is not defined in configuration file %s",
5419		       lineno, value, ufdbNewGV.configFile );
5420    return;
5421  }
5422
5423  ufdbNewGV.lastCat->rewrite = rewrite;
5424}
5425
5426
5427static void ufdbCategoryBlockConnect(
5428   int flag  )
5429{
5430   ufdbNewGV.lastCat->blockBumpedConnect = flag;
5431
5432   if (ufdbGV.debug > 1)
5433      ufdbLogMessage( "ufdbCategoryBlockConnect: category \"%s\" : block-bumped-connect %s",
5434                      ufdbNewGV.lastCat->name, flag ? "on" : "off" );
5435}
5436
5437
5438static void ufdbCategoryActiveBumping(
5439   int flag  )
5440{
5441   ufdbNewGV.lastCat->activeBumping = flag ? UFDB_ACTIVE_BUMPING_ON : UFDB_ACTIVE_BUMPING_OFF;
5442
5443   if (ufdbGV.debug > 1)
5444      ufdbLogMessage( "ufdbCategoryActiveBumping: category \"%s\" : squid-uses-active-bumping %s",
5445                      ufdbNewGV.lastCat->name, flag ? "on" : "off" );
5446}
5447
5448
5449static void ufdbCategoryTime(
5450   char *       name,
5451   int  	within )
5452{
5453   struct ufdbTime * t;
5454
5455   if ((t = sgTimeFindName(name)) == NULL)
5456   {
5457      ufdbLogFatalError( "line %d: time \"%s\" is not defined in configuration file %s",
5458   		         lineno, name, ufdbNewGV.configFile );
5459      ufdbFree( (void*) name );
5460      return;
5461   }
5462
5463   ufdbNewGV.lastCat->within = within;
5464   ufdbNewGV.lastCat->time = t;
5465   ufdbFree( (void*) name );
5466}
5467
5468
5469struct Category * ufdbCategoryFindByName(
5470   struct ufdbGV *   gv,
5471   const char *      name )
5472{
5473   struct Category * p;
5474
5475   for (p = gv->catList;  p != NULL;  p = p->next)
5476   {
5477      if (strcmp(name,p->name) == 0)
5478         return p;
5479   }
5480   return NULL;
5481}
5482
5483
5484static void sgRewrite(
5485  char * rewrite )
5486{
5487  struct sgRewrite * rew;
5488
5489#if UFDB_DEBUG
5490   ufdbLogMessage( "sgRewrite %s", rewrite );
5491#endif
5492
5493  if (ufdbNewGV.rewrite != NULL)
5494  {
5495    if ((struct sgRewrite *) sgRewriteFindName(rewrite) != NULL)
5496    {
5497      ufdbLogFatalError( "line %d: rewrite \"%s\" is not defined in configuration file %s",
5498		         lineno, rewrite, ufdbNewGV.configFile );
5499      ufdbFree( (void*) rewrite );
5500      return;
5501    }
5502  }
5503
5504  rew = (struct sgRewrite *) ufdbMalloc( sizeof(struct sgRewrite) );
5505  rew->name = rewrite;
5506  rew->active = 1;
5507  rew->rewrite = NULL;
5508  rew->time = NULL;
5509  rew->within = UFDB_ACL_NONE;
5510  rew->next = NULL;
5511
5512  if (ufdbNewGV.rewrite == NULL)
5513  {
5514    ufdbNewGV.rewrite = rew;
5515    ufdbNewGV.lastRewrite = rew;
5516  }
5517  else
5518  {
5519    ufdbNewGV.lastRewrite->next = rew;
5520    ufdbNewGV.lastRewrite = rew;
5521  }
5522}
5523
5524
5525static void sgRewriteTime(
5526  char * name,
5527  int    within )
5528{
5529  struct ufdbTime * t;
5530
5531#if UFDB_DEBUG
5532   ufdbLogMessage( "sgRewriteTime %s %d", name, within );
5533#endif
5534
5535  if ((t = sgTimeFindName(name)) == NULL)
5536  {
5537    ufdbLogFatalError( "line %d: time \"%s\" is not defined in configuration file %s",
5538		       lineno, name, ufdbNewGV.configFile );
5539    ufdbFree( (void*) name );
5540    return;
5541  }
5542
5543  ufdbNewGV.lastRewrite->within = within;
5544  ufdbNewGV.lastRewrite->time = t;
5545  ufdbFree( (void*) name );
5546}
5547
5548
5549static void sgRewriteSubstitute(
5550  char * string )
5551{
5552  char * pattern;
5553  char * subst = NULL;
5554  char * p;
5555  int    flags = REG_EXTENDED;
5556  int    global = 0;
5557  char * httpcode = NULL;
5558  struct ufdbRegExp * regexp;
5559  char   errbuf[256];
5560
5561  pattern = string + 2; 	/* skipping s@ */
5562  p = pattern;
5563  while ((p = strchr(p,'@')) != NULL)
5564  {
5565    if (*(p - 1) != '\\')
5566    {
5567      *p = '\0';
5568      subst = p + 1;
5569      break;
5570    }
5571    p++;
5572  }
5573
5574  p = strrchr( subst, '@' );
5575  while (p != NULL  &&  *p != '\0')
5576  {
5577    if (*p == 'r' )
5578      httpcode =  (char *) REDIRECT_TEMPORARILY;
5579    if (*p == 'R' )
5580      httpcode =  (char *) REDIRECT_PERMANENT;
5581    if (*p == 'i' || *p == 'I')
5582      flags |= REG_ICASE;
5583    if (*p == 'g')
5584      global = 1;
5585    *p = '\0'; 		/* removes @i from string */
5586    p++;
5587  }
5588
5589  regexp = ufdbNewPatternBuffer( pattern, flags );
5590  if (regexp->error)
5591  {
5592      regerror( regexp->error, (regex_t*) regexp->compiled[0], errbuf, sizeof(errbuf) );
5593      ufdbLogError( "line %d: regular expression error in %s:\n%s   *****", lineno, pattern, errbuf );
5594  }
5595  else {
5596    regexp->substitute = ufdbStrdup( subst );
5597  }
5598
5599  if (ufdbNewGV.lastRewrite->rewrite == NULL)
5600    ufdbNewGV.lastRewrite->rewrite = regexp;
5601  else
5602    ufdbNewGV.lastRewriteRegExec->next = regexp;
5603  regexp->httpcode = httpcode;
5604  regexp->global = global;
5605  ufdbNewGV.lastRewriteRegExec = regexp;
5606}
5607
5608
5609static struct sgRewrite * sgRewriteFindName(
5610   const char * name )
5611{
5612   struct sgRewrite * p;
5613
5614   for (p = ufdbNewGV.rewrite;  p != NULL;  p = p->next)
5615   {
5616      if (strcmp(name,p->name) == 0)
5617         return p;
5618   }
5619   return NULL;
5620}
5621
5622
5623/*
5624 * Time functions
5625 */
5626
5627/*
5628 * sgTime - parse configuration time statement.
5629 */
5630static void sgTime(
5631  char *        name )
5632{
5633  struct ufdbTime * t;
5634
5635  if (ufdbGV.debug > 1)
5636     ufdbLogMessage( "sgTime %s", name );
5637
5638  if (ufdbNewGV.timeList != NULL)
5639  {
5640    if ((struct ufdbTime *) sgTimeFindName(name) != NULL)
5641    {
5642      ufdbLogFatalError( "line %d: time \"%s\" is not defined in configuration file %s",
5643		         lineno, name, ufdbNewGV.configFile );
5644      ufdbFree( (void*) name );
5645      return;
5646    }
5647  }
5648  else
5649    numTimeElements = 0;
5650
5651  t = (struct ufdbTime *) ufdbMalloc( sizeof(struct ufdbTime) );
5652  t->name = name;
5653  t->active = 1;
5654  t->element = NULL;
5655  t->next = NULL;
5656
5657  ufdbNewGV.timeElement = NULL;
5658  ufdbNewGV.lastTimeElement = NULL;
5659  if (ufdbNewGV.timeList == NULL)
5660  {
5661    ufdbNewGV.timeList = t;
5662    ufdbNewGV.lastTime = t;
5663  }
5664  else
5665  {
5666    ufdbNewGV.lastTime->next = t;
5667    ufdbNewGV.lastTime = t;
5668  }
5669}
5670
5671
5672/*
5673 * sgTimeElementInit - initialise parsing of a configuration time element.
5674 */
5675static void sgTimeElementInit( void )
5676{
5677   struct TimeElement * te;
5678
5679   te = (struct TimeElement *) ufdbCalloc( 1, sizeof(struct TimeElement) );
5680   numTimeElements++;
5681
5682   if (ufdbNewGV.lastTime->element == NULL)
5683     ufdbNewGV.lastTime->element = te;
5684   if (ufdbNewGV.lastTimeElement != NULL)
5685     ufdbNewGV.lastTimeElement->next = te;
5686   ufdbNewGV.lastTimeElement = te;
5687}
5688
5689
5690/*
5691 * sgTimeElementEnd - finalise parsing of configuration time element.
5692 */
5693static void sgTimeElementEnd( void )
5694{
5695  time_switch = 0;
5696  date_switch = 0;
5697
5698  if (ufdbNewGV.lastTimeElement->fromdate != 0)
5699  {
5700    if (ufdbNewGV.lastTimeElement->todate == 0)
5701      ufdbNewGV.lastTimeElement->todate = ufdbNewGV.lastTimeElement->fromdate + 86399;
5702    else
5703      ufdbNewGV.lastTimeElement->todate = ufdbNewGV.lastTimeElement->todate + 86399;
5704  }
5705
5706  if (ufdbNewGV.lastTimeElement->from == 0  &&  ufdbNewGV.lastTimeElement->to == 0)
5707    ufdbNewGV.lastTimeElement->to = 1439;  /* set time to 23:59 */
5708}
5709
5710
5711/*
5712 * sgTimeElementAdd - add configuration time element.
5713 */
5714static void sgTimeElementAdd(
5715  char * element,
5716  char   type )
5717{
5718  struct TimeElement * te;
5719  char * p;
5720  char   wday;
5721  int    h, m, Y, M, D;
5722  time_t sec;
5723  char * lineptr;
5724
5725  wday = 0;
5726  M = 0;
5727  D = -1;
5728  te = ufdbNewGV.lastTimeElement;
5729
5730  switch (type)
5731  {
5732  case T_WEEKDAY:
5733    p = strtok_r( element, " \t,", &lineptr );
5734    do {
5735      if (*p == '*') {
5736	wday = 0x7F;
5737      } else if (!strncmp(p,"sun",3)) {
5738	wday = wday | 0x01;
5739      } else if (!strncmp(p,"mon",3)) {
5740	wday = wday | 0x02;
5741      } else if (!strncmp(p,"tue",3)) {
5742	wday = wday | 0x04;
5743      } else if (!strncmp(p,"wed",3)) {
5744	wday = wday | 0x08;
5745      } else if (!strncmp(p,"thu",3)) {
5746	wday = wday | 0x10;
5747      } else if (!strncmp(p,"fri",3)) {
5748	wday = wday | 0x20;
5749      } else if (!strncmp(p,"sat",3)) {
5750	wday = wday | 0x40;
5751      }
5752      p = strtok_r( NULL, " \t,", &lineptr );
5753    } while (p != NULL);
5754    te->wday = wday;
5755    break;
5756
5757  case T_TVAL:
5758    h = -1;
5759    m = -1;
5760    sscanf( element, "%d:%d", &h, &m );
5761    if ((h < 0 || h > 24) || (m < 0 || m > 59))
5762    {
5763      ufdbLogFatalError( "line %d: time format error in %s", lineno, ufdbNewGV.configFile );
5764      h = 0;
5765      m = 0;
5766    }
5767    if (time_switch == 0)
5768    {
5769      time_switch++;
5770      te->from = (h * 60) + m ;
5771    }
5772    else
5773    {
5774      time_switch = 0;
5775      te->to = (h * 60) + m ;
5776    }
5777    break;
5778
5779  case T_DVAL:
5780    sec = date2sec( element );
5781    if (sec == -1)
5782    {
5783      ufdbLogFatalError( "line %d: date format error in %s", lineno, ufdbNewGV.configFile );
5784      sec = 1;
5785    }
5786    if (date_switch == 0) {
5787      date_switch++;
5788      te->fromdate = sec;
5789    } else {
5790      date_switch = 0;
5791      te->todate = sec;
5792    }
5793    break;
5794
5795  case T_DVALCRON:
5796    p = strtok_r( element, "-./", &lineptr );
5797    Y = atoi(p);
5798    if (*p == '*')
5799      Y = -1;
5800    else
5801      Y = atoi(p);
5802    while ((p=strtok_r(NULL,"-./",&lineptr)) != NULL)
5803    {
5804      if (*p == '*')
5805	if (M == 0)
5806	  M = -1;
5807	else
5808	  D = -1;
5809      else
5810	if (M == 0)
5811	  M = atoi(p);
5812	else
5813	  D = atoi(p);
5814    }
5815    te->y = Y;
5816    te->m = M;
5817    te->d = D;
5818    break;
5819
5820  case T_WEEKLY:
5821    p = element;
5822    while (*p != '\0')
5823    {
5824      switch (*p) {
5825      case 'S':
5826      case 's':
5827	wday = wday | 0x01;
5828	break;
5829      case 'M':
5830      case 'm':
5831	wday = wday | 0x02;
5832	break;
5833      case 'T':
5834      case 't':
5835	wday = wday | 0x04;
5836	break;
5837      case 'W':
5838      case 'w':
5839	wday = wday | 0x08;
5840	break;
5841      case 'H':
5842      case 'h':
5843	wday = wday | 0x10;
5844	break;
5845      case 'F':
5846      case 'f':
5847	wday = wday | 0x20;
5848	break;
5849      case 'A':
5850      case 'a':
5851	wday = wday | 0x40;
5852	break;
5853      default:
5854	ufdbLogFatalError( "line %d: weekday format error in %s", lineno, ufdbNewGV.configFile );
5855	break;
5856      }
5857      p++;
5858    }
5859    te->wday = wday;
5860    break;
5861  }
5862
5863  ufdbFree( (void*) element );
5864}
5865
5866
5867/*
5868 * lookup a ufdbTime element by name.
5869 */
5870static struct ufdbTime * sgTimeFindName(
5871   const char * name )
5872{
5873   struct ufdbTime * p;
5874
5875   for (p = ufdbNewGV.timeList;  p != NULL;  p = p->next)
5876   {
5877      if (strcmp(name,p->name) == 0)
5878         return p;
5879   }
5880   return NULL;
5881}
5882
5883
5884/*
5885 * sgTimeCmp - Time array sort function.
5886 */
5887static int sgTimeCmp( const void * a, const void * b )
5888{
5889   const int * aa = (const int *) a;
5890   const int * bb = (const int *) b;
5891
5892   return *aa - *bb;
5893}
5894
5895
5896/*
5897 * _getSortedTimeElementTimes - produce a sorted array of time element times
5898 */
5899static void _getSortedTimeElementTimes( void )           // uses ufdbGV
5900{
5901   struct ufdbTime *    p;
5902   struct TimeElement * te;
5903   int                  i, j;
5904   int                  totalNumElems;
5905
5906   if (ufdbGV.debug > 1)
5907      ufdbLogMessage( "_getSortedTimeElementEvents" );
5908
5909   if (ufdbGV.timeList == NULL)
5910      return;
5911
5912   /* find total number of time elements */
5913   totalNumElems = 0;
5914   for (p = ufdbGV.timeList;  p != NULL;  p = p->next)
5915      for (te = p->element;  te != NULL;  te = te->next)
5916         totalNumElems++;
5917
5918   TimeElementsEvents = (int *) ufdbCalloc( totalNumElems * 2 , sizeof(int) );
5919
5920   i = 0;
5921   for (p = ufdbGV.timeList;  p != NULL;  p = p->next)
5922   {
5923      for (te = p->element;  te != NULL;  te = te->next)
5924      {
5925         TimeElementsEvents[i++] = te->from == 0 ? 1440 : te->from;
5926         TimeElementsEvents[i++] = te->to == 0   ? 1440 : te->to;
5927      }
5928   }
5929
5930   qsort( TimeElementsEvents, totalNumElems * 2, sizeof(int), sgTimeCmp );
5931
5932   if (ufdbGV.debug > 1)
5933      ufdbLogMessage( "   _getSortedTimeElementEvents: after qsort" );
5934
5935   /* remove identical time elements */
5936   for (i=1,j=1;  i < totalNumElems * 2;  i++)
5937   {
5938      if (TimeElementsEvents[i] > TimeElementsEvents[i-1])
5939      {
5940	 TimeElementsEvents[j] = TimeElementsEvents[i];
5941         j++;
5942      }
5943   }
5944
5945   numTimeElements = j;			/* #unique time elements */
5946}
5947
5948
5949/*
5950 * _TimeEvaluateElements - evaluate all elements if they match the current time/date and mark them active.
5951 */
5952static void _TimeEvaluateElements(              // uses ufdbGV
5953  struct tm * tm_now,
5954  time_t      now )
5955{
5956  struct ufdbTime *    tlist;
5957  struct TimeElement * te;
5958  int                  min;
5959
5960  if (ufdbGV.debug > 1)
5961     ufdbLogMessage( "      _TimeEvaluateElements" );
5962
5963  for (tlist = ufdbGV.timeList;  tlist != NULL;  tlist = tlist->next)
5964  {
5965    tlist->active = 0;
5966    for (te = tlist->element;  te != NULL;  te = te->next)
5967    {
5968      if (te->wday != 0) 			/* check wday */
5969      {
5970	if (((1 << tm_now->tm_wday) & te->wday) != 0)
5971	{
5972	  min = (tm_now->tm_hour * 60) + tm_now->tm_min;
5973	  if (min >= te->from  &&  min < te->to)
5974	  {
5975	    tlist->active = 1;
5976	    break;
5977	  }
5978	}
5979      }
5980      else if (te->fromdate != 0)		/* check date */
5981      {
5982	if (now >= te->fromdate  &&  now <= te->todate)
5983	{
5984	  min = (tm_now->tm_hour * 60) + tm_now->tm_min;
5985	  if (min >= te->from  &&  min < te->to)
5986	  {
5987	    tlist->active = 1;
5988	    break;
5989	  }
5990	}
5991      }
5992      else					/* check crondate */
5993      {
5994	if (te->y == -1  ||  te->y == (tm_now->tm_year + 1900))
5995	{
5996	  if (te->m == -1  ||  te->m == (tm_now->tm_mon + 1))
5997	  {
5998	    if (te->d == -1  ||  te->d == (tm_now->tm_mday))
5999	    {
6000	      min = (tm_now->tm_hour * 60) + tm_now->tm_min;
6001	      if (min >= te->from  &&  min < te->to)
6002	      {
6003		tlist->active = 1;
6004		break;
6005	      }
6006	    }
6007	  }
6008	}
6009      }
6010    }
6011    if (ufdbGV.debug > 1)
6012       ufdbLogMessage( "      _TimeEvaluateElements: time %s is %sactive", tlist->name, tlist->active?"":"not " );
6013  }
6014}
6015
6016
6017/*
6018 * _TimeSetAclSrcDestRew - mark all acl/source/dest/rew (in)active.
6019 */
6020static void _TimeSetAclSrcDestRew( void )               // uses ufdbGV
6021{
6022  struct Acl *         acl;
6023  struct Category *    cat;
6024  struct Source *      s;
6025  struct sgRewrite *   rew;
6026  int                  a;
6027
6028  if (ufdbGV.debug > 1)
6029     ufdbLogMessage( "   _TimeSetAclSrcDestRew" );
6030
6031  for (acl = ufdbGV.aclList;  acl != NULL;  acl = acl->next)
6032  {
6033    if (acl->time != NULL  &&  acl->within != UFDB_ACL_ELSE)
6034    {
6035      /* Be careful here: we are multithreaded and other threads use the value
6036       * of acl->active at the same time.
6037       */
6038      a = acl->time->active;
6039      if (acl->within == UFDB_ACL_OUTSIDE)
6040	a = !a;
6041      if (acl->next != NULL  &&  acl->next->within == UFDB_ACL_ELSE)
6042	acl->next->active = !a;
6043      acl->active = a;
6044    }
6045#if 0
6046    if (acl->pass == NULL)
6047       acl->active = 0;			/* it can have a 'continue' so do not make it inactive */
6048#endif
6049    if (ufdbGV.debug > 1)
6050       ufdbLogMessage( "      _TimeSetAclSrcDestRew: acl %s %s is %sactive", acl->name,
6051		       acl->within==UFDB_ACL_ELSE ? "ELSE" :
6052			  acl->within==UFDB_ACL_WITHIN ? "WITHIN" :
6053			     acl->within==UFDB_ACL_OUTSIDE ? "OUTSIDE" : "",
6054		       acl->active?"":"not " );
6055  }
6056
6057  for (cat = ufdbGV.catList;  cat != NULL;  cat = cat->next)
6058  {
6059    if (cat->time != NULL)
6060    {
6061      cat->active = cat->time->active;
6062      if (cat->within == UFDB_ACL_OUTSIDE)
6063	cat->active = !cat->active;
6064    }
6065    if (ufdbGV.debug > 1)
6066       ufdbLogMessage( "      _TimeSetAclSrcDestRew: category %s is %sactive", cat->name, cat->active?"":"not " );
6067  }
6068
6069  for (s = ufdbGV.sourceList;  s != NULL;  s = s->next)
6070  {
6071    if (s->time != NULL)
6072    {
6073      s->active = s->time->active;
6074      if (s->within == UFDB_ACL_OUTSIDE)
6075	s->active = !s->active;
6076    }
6077    if (ufdbGV.debug > 1)
6078       ufdbLogMessage( "      _TimeSetAclSrcDestRew: source %s is %sactive", s->name, s->active?"":"not " );
6079  }
6080
6081  for (rew = ufdbGV.rewrite; rew != NULL; rew = rew->next)
6082  {
6083    if (rew->time != NULL)
6084    {
6085      rew->active = rew->time->active;
6086      if (rew->within == UFDB_ACL_OUTSIDE)
6087	 rew->active = !rew->active;
6088    }
6089    if (ufdbGV.debug > 1)
6090       ufdbLogMessage( "      _TimeSetAclSrcDestRew: rewrite %s is %sactive", rew->name, rew->active?"":"not " );
6091  }
6092}
6093
6094
6095static void sgAlarm( int s )
6096{
6097   if (s) { ; }         // prevent compiler warning
6098   // do nothing; there is a thread that waits for a SIGALRM which calls ufdbHandleAlarmForTimeEvents()
6099}
6100
6101
6102/*
6103 *  ufdbHandleAlarmForTimeEvents - the alarm for the next time event went off so
6104 *                                 recalculate the time-dependent active state.
6105 */
6106void ufdbHandleAlarmForTimeEvents(              // uses ufdbGV
6107   int        why )
6108{
6109   time_t     now;
6110   struct tm  tm_now;
6111   int        m;
6112   int        tindex;
6113   int        lastval;
6114
6115   if (ufdbGV.debug)
6116      ufdbLogMessage( "ufdbHandleAlarmForTimeEvents( why=%s )", why==UFDB_PARAM_INIT ? "init" : "alarm" );
6117
6118   if (why == UFDB_PARAM_INIT)
6119      ufdbLogMessage( "time definitions are used; evaluating current ACLs" );
6120   else
6121   {
6122      ufdbLogMessage( "alarm went off to recalculate time ACLs" );
6123      if (ufdbGV.terminating)
6124      {
6125	 ufdbLogMessage( "This alarm is ignored because ufdbguardd is exiting" );
6126	 return;
6127      }
6128      if (ufdbGV.reconfig)
6129      {
6130	 ufdbLogMessage( "This alarm is ignored because the configuration is being reloaded"
6131	                 " and a new alarm is set to go off in 15 seconds" );
6132	 alarm( 15 );
6133	 return;
6134      }
6135   }
6136
6137   if (ufdbGV.timeList == NULL)
6138   {
6139      return;
6140   }
6141
6142   // NOTE: _getSortedTimeElementTimes() mallocs TimeElementsEvents[] and this function frees it.
6143   _getSortedTimeElementTimes();
6144
6145   now = UFDBtime() + 30;
6146   localtime_r( &now, &tm_now );
6147   m = (tm_now.tm_hour * 60) + tm_now.tm_min;
6148
6149   lastval = 0;
6150   for (tindex = 0;  tindex < numTimeElements;  tindex++)
6151   {
6152#if UFDB_TIME_DEBUG
6153      if (ufdbGV.debug > 1)
6154         ufdbLogMessage( "   TimeElementsEvents[%d] = %d", tindex, TimeElementsEvents[tindex] );
6155#endif
6156      lastval = TimeElementsEvents[tindex];
6157      if (TimeElementsEvents[tindex] >= m)
6158         break;
6159   }
6160
6161   if (ufdbGV.debug > 1)
6162      ufdbLogMessage( "   ufdbHandleAlarmForTimeEvents: m = %d  tindex = %d, lastval = %d", m, tindex, lastval );
6163
6164   if (lastval < m)
6165      m = (((1440 - m) + TimeElementsEvents[0]) * 60) - tm_now.tm_sec;
6166   else
6167      m = ((lastval - m) * 60) - tm_now.tm_sec;
6168
6169   if (m <= 0)
6170      m = 30;
6171
6172   _TimeEvaluateElements( &tm_now, now );
6173   _TimeSetAclSrcDestRew();
6174
6175   ufdbFree( (void*) TimeElementsEvents );
6176   TimeElementsEvents = NULL;
6177
6178   ufdbLogMessage( "next alarm is in %d seconds", (unsigned int) m );
6179   ufdbSetSignalHandler( SIGALRM, sgAlarm );
6180   (void) alarm( (unsigned int) m );
6181}
6182
6183
6184/*
6185 * sgTimeElementClone - copy a time specification.
6186 */
6187static void sgTimeElementClone( void )
6188{
6189  struct TimeElement * te;
6190  struct TimeElement * tmp;
6191
6192  te = ufdbNewGV.lastTimeElement;
6193  if (te == NULL)
6194  {
6195    ufdbLogFatalError( "No previous TimeElement in sgTimeElementClone !" );
6196    return;
6197  }
6198  else
6199  {
6200    sgTimeElementInit();
6201    ufdbNewGV.lastTimeElement->wday = te->wday;
6202    ufdbNewGV.lastTimeElement->from = te->from;
6203    ufdbNewGV.lastTimeElement->to = te->to;
6204    ufdbNewGV.lastTimeElement->y = te->y;
6205    ufdbNewGV.lastTimeElement->m = te->m;
6206    ufdbNewGV.lastTimeElement->d = te->d;
6207    ufdbNewGV.lastTimeElement->fromdate = te->fromdate;
6208    ufdbNewGV.lastTimeElement->todate = te->todate;
6209    tmp = ufdbNewGV.lastTimeElement;
6210    ufdbNewGV.lastTimeElement = te;
6211    sgTimeElementEnd();
6212    ufdbNewGV.lastTimeElement = tmp;
6213  }
6214}
6215
6216
6217/*
6218 * IP functions
6219 */
6220
6221static struct Ipv4 * sgIpv4Last(
6222   struct Source * s )
6223{
6224   struct Ipv4 * ipv4;
6225   struct Ipv4 * last;
6226
6227   last = NULL;
6228   for (ipv4 = s->ipv4;  ipv4 != NULL;  ipv4 = ipv4->next)
6229      last = ipv4;
6230
6231   return last;
6232}
6233
6234
6235static void sgIpv4(
6236   const char *   addr,
6237   int            type,
6238   const char *   file,
6239   int            lineno )
6240{
6241   struct Ipv4 *  ipv4;
6242   char *         addr2;
6243   char *         cidr;
6244   char *         end;
6245   unsigned int   octet;
6246
6247#if 1
6248   if (ufdbGV.debug> 1)
6249      ufdbLogMessage( "   sgIpv4( %s %d %s %d )", addr, type, file, lineno );
6250#endif
6251
6252   switch (type)
6253   {
6254   case SG_IPTYPE_HOST:
6255	 if (ufdbNewGV.lastSource->ipv4hosts == NULL)
6256	    ufdbNewGV.lastSource->ipv4hosts = UFDBmemDBinit();
6257	 UFDBmemDBinsert( ufdbNewGV.lastSource->ipv4hosts, addr, NULL );
6258  	 break;
6259
6260   case SG_IPTYPE_RANGE:
6261	 addr2 = strchr( addr, '-' );
6262	 *addr2 = '\0';
6263	 end = addr2;
6264	 while (*(end-1) == ' '  ||  *(end-1) == '\t')
6265	 {
6266	    *(end-1) = '\0';
6267	    end--;
6268	 }
6269	 addr2++;
6270	 while (*addr2 == ' ' || *addr2 == '\t')
6271	    addr2++;
6272
6273         ipv4 = (struct Ipv4 *) ufdbMalloc( sizeof(struct Ipv4) );
6274	 ipv4->type = SG_IPTYPE_RANGE;
6275         ipv4->net_is_set = 1;
6276	 ipv4->next = NULL;
6277	 if (ufdbNewGV.lastSource->ipv4 == NULL)
6278	    ufdbNewGV.lastSource->ipv4 = ipv4;
6279	 else
6280	    sgIpv4Last( ufdbNewGV.lastSource )->next = ipv4;
6281
6282	 if (sgConvDot(addr,&ipv4->net) == NULL)
6283	 {
6284	    ufdbLogFatalError( "IPv4 address error in %s line %d: %s - %s", file, lineno, addr, addr2 );
6285	    ipv4->net = 0;
6286	    ipv4->net_is_set = 0;
6287	 }
6288	 if (sgConvDot(addr2,&ipv4->mask) == NULL)
6289	 {
6290	    ufdbLogFatalError( "IPv4 address error in %s line %d: %s - %s", file, lineno, addr, addr2 );
6291	    ipv4->mask = 0;
6292	    ipv4->net_is_set = 0;
6293	 }
6294
6295	 if ((unsigned int) ipv4->net > (unsigned int) ipv4->mask)
6296	     ufdbLogFatalError( "IPv4 range error in %s line %d: %s - %s", file, lineno, addr, addr2 );
6297  	 break;
6298
6299   case SG_IPTYPE_CLASS:
6300	 addr2 = strchr( addr, '/' );
6301	 *addr2 = '\0';
6302	 addr2++;
6303         ipv4 = (struct Ipv4 *) ufdbMalloc( sizeof(struct Ipv4) );
6304	 ipv4->type = SG_IPTYPE_CLASS;
6305         ipv4->net_is_set = 1;
6306	 ipv4->next = NULL;
6307	 if (ufdbNewGV.lastSource->ipv4 == NULL)
6308	    ufdbNewGV.lastSource->ipv4 = ipv4;
6309	 else
6310	    sgIpv4Last( ufdbNewGV.lastSource )->next = ipv4;
6311
6312	 if (sgConvDot(addr,&ipv4->net) == NULL)
6313	 {
6314	    ufdbLogFatalError( "IPv4 address error in %s line %d: %s/%s", file, lineno, addr, addr2 );
6315	    ipv4->net = 0;
6316	    ipv4->net_is_set = 0;
6317	 }
6318	 if (sgConvDot(addr2,&ipv4->mask) == NULL)
6319	 {
6320	    ufdbLogFatalError( "IPv4 address error in %s line %d: %s/%s", file, lineno, addr, addr2 );
6321	    ipv4->mask = 0;
6322	 }
6323  	 break;
6324
6325   case SG_IPTYPE_CIDR:
6326	 cidr = strchr( addr, '/' );
6327	 *cidr = '\0';
6328	 cidr++;
6329	 octet = (unsigned long) atoi( cidr );
6330	 if (octet > 32)
6331	 {
6332	    ufdbLogFatalError( "IPv4 address CIDR out of range in %s line %d: %s/%s",
6333	                       file, lineno, addr, cidr );
6334	    octet = 32;
6335	 }
6336         ipv4 = (struct Ipv4 *) ufdbMalloc( sizeof(struct Ipv4) );
6337	 ipv4->type = SG_IPTYPE_CIDR;
6338         ipv4->net_is_set = 1;
6339	 ipv4->next = NULL;
6340	 if (ufdbNewGV.lastSource->ipv4 == NULL)
6341	    ufdbNewGV.lastSource->ipv4 = ipv4;
6342	 else
6343	    sgIpv4Last( ufdbNewGV.lastSource )->next = ipv4;
6344
6345	 if (sgConvDot(addr,&ipv4->net) == NULL)
6346	 {
6347	    ufdbLogFatalError( "IPv4 address error in %s line %d: %s/%s", file, lineno, addr, cidr );
6348	    ipv4->net = 0;
6349	    ipv4->net_is_set = 0;
6350	 }
6351	 if (octet == 32)
6352	    ipv4->mask = 0xffffffff;
6353	 else
6354	    ipv4->mask = 0xffffffff ^ (0xffffffff >> octet);
6355	 ipv4->net = ipv4->net & ipv4->mask;
6356  	 break;
6357   }
6358}
6359
6360
6361static struct Ipv6 * sgIpv6Last(
6362   struct Source * s )
6363{
6364   struct Ipv6 * ipv6;
6365   struct Ipv6 * last;
6366
6367   last = NULL;
6368   for (ipv6 = s->ipv6;  ipv6 != NULL;  ipv6 = ipv6->next)
6369      last = ipv6;
6370
6371   return last;
6372}
6373
6374
6375
6376static void sgIpv6(
6377   const char * addr,
6378   int          type,
6379   const char * file,
6380   int          line  )
6381{
6382#if 1
6383   if (ufdbGV.debug > 1)
6384      ufdbLogMessage( "   sgIpv6( %s %d  %s %d/%d )", addr, type, file, line, lineno );
6385#endif
6386
6387   if (type == SG_IPV6TYPE_HOST)
6388   {
6389      struct in6_addr dummy;
6390      if (!sgValidateIPv6( addr, &dummy ))
6391      {
6392         ufdbLogFatalError( "incorrect IPv6 address \"%s\" in %s line %d", addr, file, lineno );
6393      }
6394      else
6395      {
6396         if (ufdbNewGV.lastSource->ipv6hosts == NULL)
6397	    ufdbNewGV.lastSource->ipv6hosts = UFDBmemDBinit();
6398	 UFDBmemDBinsert( ufdbNewGV.lastSource->ipv6hosts, addr, NULL );
6399      }
6400   }
6401   else if (type == SG_IPV6TYPE_CIDR)
6402   {
6403      char * s = (char*) strchr( addr, '/' );
6404      if (s == NULL)
6405      {
6406         ufdbLogFatalError( "IPv6 net has no '/' in \"%s\" in %s line %d", addr, file, lineno );
6407      }
6408      else
6409      {
6410	 struct Ipv6 *  ipv6;
6411
6412	 ipv6 = (struct Ipv6 *) ufdbMalloc( sizeof(struct Ipv6) );
6413	 ipv6->type = SG_IPV6TYPE_CIDR;
6414	 ipv6->next = NULL;
6415	 if (ufdbNewGV.lastSource->ipv6 == NULL)
6416	    ufdbNewGV.lastSource->ipv6 = ipv6;
6417	 else
6418	    sgIpv6Last( ufdbNewGV.lastSource )->next = ipv6;
6419
6420         *s = '\0';
6421         ipv6->cidr = (unsigned long) atoi( s+1 );
6422         if (ipv6->cidr < 1  ||  ipv6->cidr > 128)
6423         {
6424            ufdbLogFatalError( "IPv6 address CIDR out of range \"%s\" in %s line %d", addr, file, lineno );
6425            ipv6->cidr = 128;
6426         }
6427         if (!sgValidateIPv6( addr, &ipv6->ipv6 ))
6428         {
6429            ufdbLogFatalError( "incorrect IPv6 address \"%s\" in %s line %d", addr, file, lineno );
6430         }
6431         *s = '/';
6432      }
6433   }
6434   else
6435   {
6436      ufdbLogFatalError( "sgIpv6 called with unsupported type %d in %s line %d: %s", type, file, lineno, addr );
6437   }
6438}
6439
6440
6441/*
6442 * ACL functions
6443 */
6444
6445static void ufdbAcl(
6446   const char *    name,
6447   const char *    value,
6448   int             within )
6449{
6450   struct Acl *    acl;
6451   struct Source * source;
6452
6453#if UFDB_DEBUG
6454   ufdbLogMessage( "ufdbAcl name=\"%s\" value=\"%s\" within=%d line=%d",
6455                   name==NULL?"NULL":name,  value==NULL?"NULL":value, within, lineno );
6456#endif
6457
6458   if (ufdbNewGV.aclList != NULL)
6459   {
6460      if (ufdbAclFindByName(&ufdbNewGV,name) != NULL)
6461      {
6462	 ufdbLogFatalError( "line %d: ACL \"%s\" is already defined in configuration file %s",
6463			    lineno, name, ufdbNewGV.configFile );
6464      }
6465   }
6466
6467   if (within == UFDB_ACL_ELSE)
6468   {
6469      if (ufdbNewGV.lastAcl == NULL)
6470      {
6471         ufdbLogFatalError( "line %d: ACL \"else\" has no parent ACL", lineno );
6472         return;
6473      }
6474      if (name == NULL)
6475         name = ufdbStrdup( ufdbNewGV.lastAcl->name );
6476   }
6477
6478   acl = (struct Acl *) ufdbMalloc( sizeof(struct Acl) );
6479
6480   source = NULL;
6481   if (strcmp(name,"default") == 0)
6482   {
6483      ufdbNewGV.defaultAcl = acl;
6484   }
6485   else
6486   {
6487      if ((source = defSourceFindName(ufdbNewGV.sourceList,name)) == NULL)
6488      {
6489         ufdbLogFatalError( "line %d: ACL source \"%s\" is not defined in configuration file %s",
6490                            lineno, name, ufdbNewGV.configFile );
6491         if (ufdbNewGV.fastRefresh  &&  ufdbGV.fastRefresh  &&
6492             defSourceFindName(ufdbGV.sourceList,name) != NULL)
6493            ufdbLogError( "But ACL source \"%s\" is defined in the old configuration  *****", name );
6494         if (ufdbGV.debug > 1)
6495            UFDBlogConfig( &ufdbGV );
6496         ufdbFree( (void*) name );
6497         ufdbFree( (void*) acl );
6498         return;
6499      }
6500   }
6501
6502   acl->name = name;
6503   acl->active = within == UFDB_ACL_ELSE ? 0 : 1;
6504   acl->source = source;
6505   acl->pass = NULL;
6506   acl->implicitPass = NULL;
6507   acl->hasTerminatorNone = 0;
6508   acl->rewriteDefault = 1;
6509   acl->rewrite = NULL;
6510   acl->redirect = NULL;
6511   acl->time = NULL;
6512   acl->within = within;
6513   acl->next = NULL;
6514
6515   if (value != NULL)
6516   {
6517      struct ufdbTime * t;
6518      if ((t = sgTimeFindName(value)) == NULL)
6519      {
6520         ufdbLogFatalError( "line %d: ACL time %s is not defined in configuration file %s",
6521                            lineno, value, ufdbNewGV.configFile );
6522         return;
6523      }
6524      acl->time = t;
6525   }
6526
6527   if (ufdbNewGV.aclList == NULL)
6528   {
6529      ufdbNewGV.aclList = acl;
6530      ufdbNewGV.lastAcl = acl;
6531   }
6532   else
6533   {
6534      ufdbNewGV.lastAcl->next = acl;
6535      ufdbNewGV.lastAcl = acl;
6536   }
6537}
6538
6539
6540static void ufdbAclSetValue(
6541  const char *         what,
6542  const char *         value,
6543  int                  allowed )
6544{
6545  struct Category *    cat = NULL;
6546  struct AclCategory * aclcat;
6547  int                  type;
6548
6549#if UFDB_DEBUG
6550   ufdbLogMessage( "ufdbAclSetValue %s %s%s", what, allowed ? "" : "!", value );
6551#endif
6552
6553  if (ufdbNewGV.lastAcl == NULL)
6554  {
6555     ufdbLogError( "error in configuration file on line %d: "
6556                   "cannot set value for \"%s\" because there is no defined ACL",
6557                   lineno, what );
6558     ufdbFree( (void*) value );
6559     return;
6560  }
6561
6562  type = ACL_TYPE_TERMINATOR;
6563
6564  if (strcmp(what,"pass") == 0)
6565  {
6566    if (strcmp(value,"any")==0 || strcmp(value,"all")==0)
6567    {
6568       if (!allowed)
6569          ufdbLogFatalError( "error in configuration file on line %d: do not use '!any' or '!all'.  "
6570                             "Use 'none' instead.", lineno );
6571       allowed = 1;
6572    }
6573    else if (strcmp(value,"none") == 0)
6574    {
6575       if (!allowed)
6576          ufdbLogFatalError( "error in configuration file on line %d: do not use '!none'.  "
6577                             "Use 'any' instead.", lineno );
6578       allowed = 0;
6579    }
6580    else if (strcmp(value,"in-addr") == 0) {
6581      type = ACL_TYPE_INADDR;
6582    }
6583    else
6584    {
6585      if ((cat = ufdbCategoryFindByName(&ufdbNewGV,value)) == NULL)
6586      {
6587	 ufdbLogFatalError( "ACL category \"%s\" (line %d) is not defined in configuration file %s",
6588			    value, lineno, ufdbNewGV.configFile );
6589         if (ufdbNewGV.fastRefresh  &&  ufdbGV.fastRefresh  &&
6590             ufdbCategoryFindByName(&ufdbGV,value) != NULL)
6591            ufdbLogError( "But category \"%s\" is defined in the old configuration  *****", value );
6592         if (ufdbGV.debug > 1)
6593            UFDBlogConfig( &ufdbGV );
6594	 ufdbFree( (void*) value );
6595         return;
6596      }
6597      type = ACL_TYPE_DEFAULT;
6598    }
6599
6600    aclcat = (struct AclCategory *) ufdbMallocAligned( UFDB_CACHELINE_SIZE, sizeof(struct AclCategory) );
6601    aclcat->name = value;
6602    aclcat->cat = cat;
6603    aclcat->access = allowed;
6604    aclcat->type = type;
6605    aclcat->next = NULL;
6606    aclcat->nblocks = 0;
6607    aclcat->nmatches = 0;
6608
6609    if (ufdbNewGV.lastAcl->pass == NULL) {
6610      ufdbNewGV.lastAcl->pass = aclcat;
6611    } else {
6612      ufdbNewGV.lastAclCategory->next = aclcat;
6613    }
6614    ufdbNewGV.lastAclCategory = aclcat;
6615  }
6616  else if (strcmp(what,"redirect") == 0)
6617  {
6618    if (strcmp(value,"default") != 0)
6619    {
6620      ufdbNewGV.lastAcl->redirect = value;
6621    }
6622    else
6623    {
6624      ufdbNewGV.lastAcl->redirect = NULL;
6625      ufdbFree( (void*) value );
6626    }
6627  }
6628  else if (strcmp(what,"rewrite") == 0)
6629  {
6630    if (strcmp(value,"none") == 0)
6631    {
6632      ufdbNewGV.lastAcl->rewriteDefault = 0;
6633      ufdbNewGV.lastAcl->rewrite = NULL;
6634    }
6635    else
6636    {
6637      struct sgRewrite * rewrite;
6638
6639      if ((rewrite = sgRewriteFindName(value)) == NULL)
6640      {
6641	ufdbLogFatalError( "rewrite %s is not defined in configuration file %s",
6642			   value, ufdbNewGV.configFile );
6643      }
6644      ufdbNewGV.lastAcl->rewriteDefault = 0;
6645      ufdbNewGV.lastAcl->rewrite = rewrite;
6646    }
6647    ufdbFree( (void*) value );
6648  }
6649}
6650
6651
6652struct Acl * ufdbAclFindByName(
6653  struct ufdbGV * gv,
6654  const char *    name )
6655{
6656  struct Acl * p;
6657
6658  if (name == NULL)
6659     return NULL;
6660
6661  for (p = gv->aclList;  p != NULL;  p = p->next)
6662  {
6663    if (strcmp(name,p->name) == 0)
6664      return p;
6665  }
6666
6667  return NULL;
6668}
6669
6670
6671static void logConfig( void )
6672{
6673   int    lno;
6674   FILE * fin;
6675   char   line[32678];
6676
6677   if (ufdbNewGV.configLogged)
6678      return;
6679   ufdbNewGV.configLogged = 1;
6680
6681   fin = fopen( ufdbNewGV.configFile, "r" );
6682   if (fin == NULL)
6683      return;
6684
6685   ufdbLogMessage( "======== literal content of config file ========" );
6686   lno = 1;
6687   while (UFDBfgetsNoNL(line,sizeof(line)-1,fin) != NULL)
6688   {
6689      ufdbLogMessage( "%04d: %s", lno, line );
6690      lno++;
6691   }
6692   ufdbLogMessage( "======== end of literal content ========" );
6693   fclose( fin );
6694}
6695
6696
6697void yyerror( const char * s )
6698{
6699   ufdbLogFatalError( "line %d: %s in configuration file %s", lineno, s, ufdbNewGV.configFile );
6700}
6701
6702
6703int yywrap()
6704{
6705  return 1;
6706}
6707
6708