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