]> git.ipfire.org Git - thirdparty/sarg.git/blob - getconf.c
Include sub configuration files
[thirdparty/sarg.git] / getconf.c
1 /*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
3 * 1998, 2015
4 *
5 * SARG donations:
6 * please look at http://sarg.sourceforge.net/donations.php
7 * Support:
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
9 * ---------------------------------------------------------------------
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
24 *
25 */
26
27 #include "include/conf.h"
28 #include "include/defs.h"
29 #include "include/filelist.h"
30
31 #define SET_LIST(list) list,sizeof(list)/sizeof(list[0])
32
33 //! The configuration file from which the graph option was loaded
34 char GraphConfigFile[MAXLEN]="";
35
36 //! How many include directives were followed.
37 static int IncludeLevel=0;
38
39 extern numlist hours, weekdays;
40 extern FileListObject AccessLog;
41 extern int PerUserLimitsNumber;
42 extern struct PerUserLimitStruct PerUserLimits[MAX_USER_LIMITS];
43 extern enum PerUserFileCreationEnum PerUserFileCreation;
44 extern char ImageDir[MAXLEN];
45 extern FileListObject UserAgentLog;
46 extern bool UserAgentFromCmdLine;
47 extern char StripUserSuffix[MAX_USER_LEN];
48
49 struct param_list
50 {
51 //! The name of the value of the parameter.
52 const char *name;
53 //! The bit to set if the value is found.
54 unsigned long int value;
55 //! The value is invalid if any bit of this mask is set in the parameter.
56 unsigned long int exclude;
57 };
58
59 struct sort_list
60 {
61 //! The name of the value of the parameter.
62 const char *name;
63 //! The bit to set if the value is found.
64 unsigned long int value;
65 };
66
67 struct select_list
68 {
69 //! The name of the value of the parameter.
70 const char *name;
71 //! The value to assign when the name is selected.
72 int value;
73 };
74
75 static struct param_list report_type_values[]=
76 {
77 {"users_sites",REPORT_TYPE_USERS_SITES,0},
78 {"topusers",REPORT_TYPE_TOPUSERS,0},
79 {"topsites",REPORT_TYPE_TOPSITES,0},
80 {"sites_users",REPORT_TYPE_SITES_USERS,0},
81 {"date_time",REPORT_TYPE_DATE_TIME,0},
82 {"denied",REPORT_TYPE_DENIED,0},
83 {"auth_failures",REPORT_TYPE_AUTH_FAILURES,0},
84 {"site_user_time_date",REPORT_TYPE_SITE_USER_TIME_DATE,0},
85 {"downloads",REPORT_TYPE_DOWNLOADS,0},
86 };
87
88 static struct param_list data_field_values[]=
89 {
90 {"user",DATA_FIELD_USER,0},
91 {"date",DATA_FIELD_DATE,0},
92 {"time",DATA_FIELD_TIME,0},
93 {"url",DATA_FIELD_URL,0},
94 {"connect",DATA_FIELD_CONNECT,0},
95 {"bytes",DATA_FIELD_BYTES,0},
96 {"in_cache",DATA_FIELD_IN_CACHE,0},
97 {"out_cache",DATA_FIELD_OUT_CACHE,0},
98 {"elapsed",DATA_FIELD_ELAPSED,0},
99 };
100
101 static struct param_list topuserfields_values[]=
102 {
103 {"NUM",TOPUSERFIELDS_NUM,0},
104 {"DATE_TIME",TOPUSERFIELDS_DATE_TIME,0},
105 {"USERID",TOPUSERFIELDS_USERID,0},
106 {"USERIP",TOPUSERFIELDS_USERIP,0},
107 {"CONNECT",TOPUSERFIELDS_CONNECT,0},
108 {"BYTES",TOPUSERFIELDS_BYTES,0},
109 {"%BYTES",TOPUSERFIELDS_SETYB,0},
110 {"SETYB",TOPUSERFIELDS_SETYB,0},
111 {"IN-CACHE-OUT",TOPUSERFIELDS_IN_CACHE_OUT,0},
112 {"USED_TIME",TOPUSERFIELDS_USED_TIME,0},
113 {"MILISEC",TOPUSERFIELDS_MILISEC,0},
114 {"%TIME",TOPUSERFIELDS_PTIME,0},
115 {"TOTAL",TOPUSERFIELDS_TOTAL,0},
116 {"AVERAGE",TOPUSERFIELDS_AVERAGE,0},
117 };
118
119 static struct param_list userreportfields_values[]=
120 {
121 {"CONNECT",USERREPORTFIELDS_CONNECT,0},
122 {"BYTES",USERREPORTFIELDS_BYTES,0},
123 {"%BYTES",USERREPORTFIELDS_SETYB,0},
124 {"SETYB",USERREPORTFIELDS_SETYB,0},
125 {"IN-CACHE-OUT",USERREPORTFIELDS_IN_CACHE_OUT,0},
126 {"USED_TIME",USERREPORTFIELDS_USED_TIME,0},
127 {"MILISEC",USERREPORTFIELDS_MILISEC,0},
128 {"%TIME",USERREPORTFIELDS_PTIME,0},
129 {"TOTAL",USERREPORTFIELDS_TOTAL,0},
130 {"AVERAGE",USERREPORTFIELDS_AVERAGE,0},
131 };
132
133 static struct param_list index_values[]=
134 {
135 {"yes",INDEX_YES,~INDEX_YES},
136 {"no",INDEX_NO,~INDEX_NO},
137 {"only",INDEX_ONLY,~INDEX_ONLY},
138 };
139
140 static struct param_list index_tree_values[]=
141 {
142 {"date",INDEX_TREE_DATE,~INDEX_TREE_DATE},
143 {"file",INDEX_TREE_FILE,~INDEX_TREE_FILE},
144 };
145
146 static struct param_list indexfields_values[]=
147 {
148 {"DIRSIZE",INDEXFIELDS_DIRSIZE,0},
149 };
150
151 static struct param_list ntml_userformat_values[]=
152 {
153 {"user",NTLMUSERFORMAT_USER,~NTLMUSERFORMAT_USER},
154 {"domainname+username",NTLMUSERFORMAT_DOMAINUSER,~NTLMUSERFORMAT_DOMAINUSER},
155 };
156
157 static struct param_list recnouser_values[]=
158 {
159 {"ip",RECORDWITHOUTUSER_IP,~RECORDWITHOUTUSER_IP},
160 {"ignore",RECORDWITHOUTUSER_IGNORE,~RECORDWITHOUTUSER_IGNORE},
161 {"everybody",RECORDWITHOUTUSER_EVERYBODY,~RECORDWITHOUTUSER_EVERYBODY},
162 };
163
164 static struct param_list datafileurl_values[]=
165 {
166 {"ip",DATAFILEURL_IP,~DATAFILEURL_IP},
167 {"name",DATAFILEURL_NAME,~DATAFILEURL_NAME},
168 };
169
170 static struct param_list displayvalue_values[]=
171 {
172 {"bytes",DISPLAY_BYTES,~DISPLAY_BYTES},
173 {"abbreviation",DISPLAY_ABBREV,~DISPLAY_ABBREV},
174 };
175
176 static struct param_list datetime_values[]=
177 {
178 {"elap",DATETIME_ELAP,0},
179 {"bytes",DATETIME_BYTE,0},
180 };
181
182 static struct param_list realtime_unauth_values[]=
183 {
184 {"show",REALTIME_UNAUTH_REC_SHOW,~REALTIME_UNAUTH_REC_SHOW},
185 {"ignore",REALTIME_UNAUTH_REC_IGNORE,~REALTIME_UNAUTH_REC_IGNORE},
186 };
187
188 struct sort_list topuser_sort[]=
189 {
190 {"BYTES",TOPUSER_SORT_BYTES},
191 {"USER",TOPUSER_SORT_USER},
192 {"CONNECT",TOPUSER_SORT_CONNECT},
193 {"TIME",TOPUSER_SORT_TIME},
194 };
195
196 struct sort_list topsite_sort[]=
197 {
198 {"BYTES",TOPSITE_SORT_BYTES},
199 {"CONNECT",TOPSITE_SORT_CONNECT},
200 {"TIME",TOPSITE_SORT_TIME},
201 {"USER",TOPSITE_SORT_USER},
202 };
203
204 struct sort_list user_sort[]=
205 {
206 {"BYTES",USER_SORT_BYTES},
207 {"SITE",USER_SORT_SITE},
208 {"CONNECT",USER_SORT_CONNECT},
209 {"TIME",USER_SORT_TIME},
210 };
211
212 static struct select_list per_user_limit_create_file[]=
213 {
214 {"always",PUFC_Always}, //always create an empty file
215 {"as_required",PUFC_AsRequired}, //create the file if necessary (no empty file is created)
216 };
217
218 static int is_param(const char *param,const char *buf)
219 {
220 int plen;
221
222 plen=strlen(param);
223 if (strncmp(buf,param,plen) != 0) return(0);
224 buf+=plen;
225 if ((unsigned char)*buf>' ') return(0);
226 return(1);
227 }
228
229 static int getparam_string(const char *param,char *buf,char *value,int value_size)
230 {
231 int plen;
232
233 plen=strlen(param);
234 if (strncmp(buf,param,plen) != 0) return(0);
235 buf+=plen;
236 if ((unsigned char)*buf>' ') return(0);
237 while (*buf && (unsigned char)*buf<=' ') buf++;
238
239 if (strlen(buf)>=value_size) {
240 debuga(__FILE__,__LINE__,_("The string value of parameter \"%s\" is too long\n"),param);
241 exit(EXIT_FAILURE);
242 }
243 strcpy(value,buf);
244 fixnone(value);
245 return(1);
246 }
247
248 /*!
249 * Get a pointer to the beginning of the string value defined by the
250 * parameter. The returned value is NULL if the buffer doesn't contain
251 * the parameter.
252 *
253 * \param param The parameter to look for.
254 * \param buf The buffer containing the line read from the configuration
255 * file.
256 *
257 * \return A pointer to the beginning of the parameter value or NULL if
258 * the line is not for the requested parameter.
259 */
260 static char *getparam_stringptr(const char *param,char *buf)
261 {
262 int plen;
263
264 plen=strlen(param);
265 if (strncmp(buf,param,plen) != 0) return(NULL);
266 buf+=plen;
267 if ((unsigned char)*buf>' ') return(NULL);
268 while (*buf && (unsigned char)*buf<=' ') buf++;
269
270 return(buf);
271 }
272
273 static int getparam_quoted(const char *param,char *buf,char *value,int value_size)
274 {
275 int plen;
276 int i;
277
278 plen=strlen(param);
279 if (strncmp(buf,param,plen) != 0) return(0);
280 buf+=plen;
281 if ((unsigned char)*buf>' ') return(0);
282 while (*buf && (unsigned char)*buf<=' ') buf++;
283
284 if (*buf != '\"') {
285 debuga(__FILE__,__LINE__,_("Missing double quote after parameter \"%s\"\n"),param);
286 exit(EXIT_FAILURE);
287 }
288 buf++;
289
290 value_size--;
291 for (i=0 ; i<value_size && *buf && *buf!='\"' ; i++) {
292 value[i]=*buf++;
293 }
294 value[i]='\0';
295
296 if (*buf != '\"') {
297 debuga(__FILE__,__LINE__,_("Missing double quote after parameter \"%s\" or value is more than %d bytes long\n"),param,value_size);
298 exit(EXIT_FAILURE);
299 }
300 fixnone(value);
301 return(1);
302 }
303
304 static int getparam_2words(const char *param,char *buf,char *word1,int word1_size,char *word2,int word2_size)
305 {
306 int plen;
307 int i;
308
309 plen=strlen(param);
310 if (strncmp(buf,param,plen) != 0) return(0);
311 buf+=plen;
312 if ((unsigned char)*buf>' ') return(0);
313 while (*buf && (unsigned char)*buf<=' ') buf++;
314
315 for (i=0 ; i<word1_size && *buf && (unsigned char)*buf>' ' ; i++)
316 word1[i]=*buf++;
317 if (i>=word1_size) {
318 debuga(__FILE__,__LINE__,_("The first word of parameter \"%s\" is more than %d bytes long\n"),param,word1_size-1);
319 exit(EXIT_FAILURE);
320 }
321 if (*buf!=' ') {
322 debuga(__FILE__,__LINE__,_("Missing second word for parameter \"%s\"\n"),param);
323 exit(EXIT_FAILURE);
324 }
325 word1[i]=0;
326
327 while (*buf && (unsigned char)*buf<=' ') buf++;
328
329 for (i=0 ; i<word2_size && *buf && (unsigned char)*buf>' ' ; i++)
330 word2[i]=*buf++;
331 if (i>=word2_size) {
332 debuga(__FILE__,__LINE__,_("The second word of parameter \"%s\" is more than %d bytes long\n"),param,word2_size-1);
333 exit(EXIT_FAILURE);
334 }
335 word2[i]=0;
336
337 fixnone(word1);
338 fixnone(word2);
339 return(1);
340 }
341
342 static int getparam_int(const char *param,char *buf,int *value)
343 {
344 int plen;
345 int next;
346
347 plen=strlen(param);
348 if (strncmp(buf,param,plen) != 0) return(0);
349 buf+=plen;
350 if ((unsigned char)*buf>' ') return(0);
351 while (*buf && (unsigned char)*buf<=' ') buf++;
352
353 next=0;
354 if (sscanf(buf,"%d%n",value,&next) != 1 || (unsigned char)buf[next] > ' ') {
355 debuga(__FILE__,__LINE__,_("The integer value of parameter \"%s\" is invalid\n"),param);
356 exit(EXIT_FAILURE);
357 }
358 return(1);
359 }
360
361 static int getparam_bool(const char *param,char *buf,bool *value)
362 {
363 int plen;
364 int i;
365 const char *bool_str="yes,true,on,1";
366
367 plen=strlen(param);
368 if (strncmp(buf,param,plen) != 0) return(0);
369 buf+=plen;
370 if ((unsigned char)*buf>' ') return(0);
371 while (*buf && (unsigned char)*buf<=' ') buf++;
372
373 *value=false;
374 for ( ; *bool_str ; bool_str+=i) {
375 for (i=0 ; bool_str[i] && bool_str[i]!=',' ; i++);
376 if (strncasecmp(bool_str,buf,i)==0) {
377 *value=true;
378 break;
379 }
380 if (bool_str[i]==',') i++;
381 }
382 return(1);
383 }
384
385 static int getparam_list(const char *param,struct param_list *options,int noptions,char *buf,unsigned long int *value)
386 {
387 int plen;
388 char *str;
389 int i;
390
391 plen=strlen(param);
392 if (strncmp(buf,param,plen) != 0) return(0);
393 buf+=plen;
394 if ((unsigned char)*buf>' ') return(0);
395 while (*buf && (unsigned char)*buf<=' ') buf++;
396
397 *value=0UL;
398 while (*buf) {
399 str=buf;
400 while (*str && (unsigned char)*str>' ' && *str!=';') str++;
401 if (*str) {
402 *str++='\0';
403 while (*str && ((unsigned char)*str<=' ' || *str==';')) str++;
404 }
405 for (i=0 ; i<noptions && strcasecmp(buf,options[i].name) ; i++);
406 if (i>=noptions) {
407 debuga(__FILE__,__LINE__,_("Unknown value \"%s\" for parameter \"%s\"\n"),buf,param);
408 exit(EXIT_FAILURE);
409 }
410 if ((*value & options[i].exclude)!=0) {
411 debuga(__FILE__,__LINE__,_("Value \"%s\" conflicts with other selected values for parameter \"%s\"\n"),buf,param);
412 exit(EXIT_FAILURE);
413 }
414 *value|=options[i].value;
415 buf=str;
416 }
417 return(1);
418 }
419
420 static int getparam_sort(const char *param,struct sort_list *options,int noptions,char *buf,unsigned long int *value)
421 {
422 int plen;
423 char *str, *order;
424 int i;
425
426 plen=strlen(param);
427 if (strncmp(buf,param,plen) != 0) return(0);
428 buf+=plen;
429 if ((unsigned char)*buf>' ') return(0);
430 while (*buf && (unsigned char)*buf<=' ') buf++;
431
432 str=buf;
433 order=NULL;
434 while (*str && (unsigned char)*str>' ') str++;
435 if (*str) {
436 *str++='\0';
437 while (*str && (unsigned char)*str<=' ') str++;
438 order=str;
439 }
440 for (i=0 ; i<noptions && strcasecmp(buf,options[i].name) ; i++);
441 if (i>=noptions) {
442 debuga(__FILE__,__LINE__,_("Unknown sort criterion \"%s\" for parameter \"%s\"\n"),buf,param);
443 exit(EXIT_FAILURE);
444 }
445 *value=options[i].value;
446
447 if (order) {
448 str=order;
449 while (*str && (unsigned char)*str>' ') str++;
450 if (*str) {
451 *str++='\0';
452 while (*str && (unsigned char)*str<=' ') str++;
453 }
454 if (strcasecmp(order,"reverse")==0 || strcasecmp(order,"D")==0) {
455 *value|=SORT_REVERSE;
456 } else if (strcasecmp(order,"normal")!=0 && strcasecmp(order,"A")!=0) {
457 debuga(__FILE__,__LINE__,_("Unknown sort order \"%s\" for parameter \"%s\"\n"),order,param);
458 exit(EXIT_FAILURE);
459 }
460 }
461
462 buf=str;
463 return(1);
464 }
465
466 static int getparam_select(const char *param,struct select_list *options,int noptions,char *buf,int *value)
467 {
468 int plen;
469 char *str;
470 int i;
471
472 plen=strlen(param);
473 if (strncmp(buf,param,plen) != 0) return(0);
474 buf+=plen;
475 if ((unsigned char)*buf>' ') return(0);
476 while (*buf && (unsigned char)*buf<=' ') buf++;
477
478 str=buf;
479 while (*buf && (unsigned char)*buf>' ' && *buf!=';') buf++;
480 *buf='\0';
481 for (i=0 ; i<noptions && strcasecmp(str,options[i].name) ; i++);
482 if (i>=noptions) {
483 debuga(__FILE__,__LINE__,_("Unknown value \"%s\" for parameter \"%s\"\n"),str,param);
484 exit(EXIT_FAILURE);
485 }
486 *value=options[i].value;
487 return(1);
488 }
489
490 static int getparam_userlimit(const char *param,char *buf)
491 {
492 int plen;
493 char *file_begin,*file_end;
494 int limit;
495 int digit;
496 char *str;
497 int i;
498 enum PerUserOutputEnum output;
499 const struct
500 {
501 const char *name;
502 enum PerUserOutputEnum value;
503 } output_types[]=
504 {
505 {"id",PUOE_UserId},
506 {"ip",PUOE_UserIp},
507 };
508
509 plen=strlen(param);
510 if (strncmp(buf,param,plen) != 0) return(0);
511 buf+=plen;
512 if ((unsigned char)*buf>' ') return(0);
513 while (*buf && (unsigned char)*buf<=' ') buf++;
514
515 /*
516 options are made of a file name, an integer limit and an optional
517 integer flag. The file name may contain spaces. We keep searching
518 until a valid number is found after a space.
519 */
520 file_begin=buf;
521 do {
522 while (*buf && (unsigned char)*buf>' ') buf++;
523 if (*buf!=' ') {
524 debuga(__FILE__,__LINE__,_("Missing limit in per_user_limit\n"));
525 exit(EXIT_FAILURE);
526 }
527 file_end=buf;
528 while (*buf && (unsigned char)*buf<=' ') buf++;
529 limit=0;
530 while (*buf && isdigit(*buf)) {
531 digit=*buf-'0';
532 if (limit>=(INT_MAX-digit)/10) break;
533 limit=limit*10+digit;
534 buf++;
535 }
536 } while (*buf && *buf!=' ');
537
538 output=PUOE_UserId;
539 if (*buf==' ') {
540 while (*buf && (unsigned char)*buf<=' ') buf++;
541 str=buf;
542 while (*buf && (unsigned char)*buf>' ') buf++;
543 *buf='\0';
544 for (i=sizeof(output_types)/sizeof(output_types[0])-1 ; i>=0 ; i--)
545 if (strcasecmp(output_types[i].name,str)==0) {
546 output=output_types[i].value;
547 break;
548 }
549 if (i<0) {
550 debuga(__FILE__,__LINE__,_("Invalid output type in per_user_limit\n"));
551 exit(EXIT_FAILURE);
552 }
553 }
554
555 if (PerUserLimitsNumber>=MAX_USER_LIMITS) {
556 debuga(__FILE__,__LINE__,_("Too many per_user_limit\n"));
557 exit(EXIT_FAILURE);
558 }
559 *file_end='\0';
560 safe_strcpy(PerUserLimits[PerUserLimitsNumber].File,file_begin,sizeof(PerUserLimits[PerUserLimitsNumber].File));
561 PerUserLimits[PerUserLimitsNumber].Limit=limit;
562 PerUserLimits[PerUserLimitsNumber].Output=output;
563 PerUserLimitsNumber++;
564
565 return(1);
566 }
567
568 static void ccharset(char *CharSet)
569 {
570 if (strcmp(CharSet,"Latin2") == 0) strcpy(CharSet,"ISO-8859-2");
571 else if (strcmp(CharSet,"Latin3") == 0) strcpy(CharSet,"ISO-8859-3");
572 else if (strcmp(CharSet,"Latin4") == 0) strcpy(CharSet,"ISO-8859-4");
573 else if (strcmp(CharSet,"Cyrillic") == 0) strcpy(CharSet,"ISO-8859-5");
574 else if (strcmp(CharSet,"Arabic") == 0) strcpy(CharSet,"ISO-8859-6");
575 else if (strcmp(CharSet,"Greek") == 0) strcpy(CharSet,"ISO-8859-7");
576 else if (strcmp(CharSet,"Hebrew") == 0) strcpy(CharSet,"ISO-8859-8");
577 else if (strcmp(CharSet,"Latin5") == 0) strcpy(CharSet,"ISO-8859-9");
578 else if (strcmp(CharSet,"Latin6") == 0) strcpy(CharSet,"ISO-8859-10");
579 else if (strcmp(CharSet,"Japan") == 0) strcpy(CharSet,"EUC-JP");
580 else if (strcmp(CharSet,"Koi8-r") == 0) strcpy(CharSet,"KOI8-R");
581 /*
582 * Any other encoding name is left unchanged.
583 */
584 return;
585 }
586
587 static void parmtest(char *buf,const char *File)
588 {
589 char wbuf[2048];
590 struct getwordstruct gwarea;
591 int iVal;
592
593 while (*buf && (unsigned char)*buf<=' ') buf++;
594
595 if(*buf == '#' || *buf == '\0')
596 return;
597
598 if(debugz>=LogLevel_Process)
599 printf(_("SARG: TAG: %s\n"),buf);
600
601 if (getparam_string("background_color",buf,BgColor,sizeof(BgColor))>0) return;
602
603 if (getparam_string("text_color",buf,TxColor,sizeof(TxColor))>0) return;
604
605 if (getparam_string("text_bgcolor",buf,TxBgColor,sizeof(TxBgColor))>0) return;
606
607 if (getparam_string("title_color",buf,TiColor,sizeof(TiColor))>0) return;
608
609 if (getparam_string("logo_image",buf,LogoImage,sizeof(LogoImage))>0) return;
610
611 if (getparam_quoted("logo_text",buf,LogoText,sizeof(LogoText))>0) return;
612
613 if (getparam_string("logo_text_color",buf,LogoTextColor,sizeof(LogoTextColor))>0) return;
614
615 if (getparam_string("background_image",buf,BgImage,sizeof(BgImage))>0) return;
616
617 if (getparam_bool("show_sarg_info",buf,&ShowSargInfo)>0) return;
618
619 if (getparam_bool("show_sarg_logo",buf,&ShowSargLogo)>0) return;
620
621 if (getparam_string("font_face",buf,FontFace,sizeof(FontFace))>0) return;
622
623 if (getparam_string("header_color",buf,HeaderColor,sizeof(HeaderColor))>0) return;
624
625 if (getparam_string("header_bgcolor",buf,HeaderBgColor,sizeof(HeaderBgColor))>0) return;
626
627 if (getparam_string("font_size",buf,FontSize,sizeof(FontSize))>0) return;
628
629 if (getparam_string("header_font_size",buf,HeaderFontSize,sizeof(HeaderFontSize))>0) return;
630
631 if (getparam_string("title_font_size",buf,TitleFontSize,sizeof(TitleFontSize))>0) return;
632
633 if (getparam_2words("image_size",buf,Width,sizeof(Width),Height,sizeof(Height))>0) return;
634
635 if (getparam_quoted("title",buf,Title,sizeof(Title))>0) return;
636
637 if (strncasecmp(buf,"resolve_ip",10)==0) {
638 if (ip2name_config(buf+10)>0) return;
639 }
640
641 if (getparam_bool("user_ip",buf,&UserIp)>0) return;
642
643 if (getparam_string("max_elapsed",buf,MaxElapsed,sizeof(MaxElapsed))>0) return;
644
645 if (is_param("date_format",buf)) {
646 getword_start(&gwarea,buf);
647 if (getword_multisep(wbuf,sizeof(wbuf),&gwarea,' ')<0) {
648 debuga(__FILE__,__LINE__,_("Invalid record in \"date_format\" parameter\n"));
649 exit(EXIT_FAILURE);
650 }
651 DateFormat=gwarea.current[0];
652 return;
653 }
654
655 if (is_param("hours",buf)) {
656 if( getnumlist( buf, &hours, 24, 24 ) ) {
657 debuga(__FILE__,__LINE__,_("Error: Invalid syntax in hours tag!\n"));
658 exit( 1 );
659 }
660 return;
661 }
662
663 if (is_param("weekdays",buf)) {
664 if( getnumlist( buf, &weekdays, 7, 7 ) ) {
665 debuga(__FILE__,__LINE__,_("Error: Invalid syntax in weekdays tag!\n"));
666 exit( 1 );
667 }
668 return;
669 }
670
671 if (getparam_sort("topuser_sort_field",SET_LIST(topuser_sort),buf,&TopuserSort)>0) return;
672
673 if (getparam_sort("user_sort_field",SET_LIST(user_sort),buf,&UserSort)>0) return;
674
675 if (is_param("access_log",buf)>0) {
676 if (AccessLogFromCmdLine==0) {
677 char *FileName=getparam_stringptr("access_log",buf);
678 if (!AccessLog)
679 AccessLog=FileList_Create();
680 if (!FileList_AddFile(AccessLog,FileName)) {
681 debuga(__FILE__,__LINE__,_("Not enough memory to store the input log file names\n"));
682 exit(EXIT_FAILURE);
683 }
684 }
685 return;
686 }
687
688 if (is_param("redirector_log",buf)>0) {
689 if (RedirectorLogFromCmdLine==0) {
690 if (NRedirectorLogs>=MAX_REDIRECTOR_LOGS) {
691 debuga(__FILE__,__LINE__,_("Too many redirector log files in configuration file\n"));
692 exit(EXIT_FAILURE);
693 }
694 getparam_string("redirector_log",buf,RedirectorLogs[NRedirectorLogs],MAX_REDIRECTOR_FILELEN);
695 NRedirectorLogs++;
696 }
697 return;
698 }
699
700 if (is_param("useragent_log",buf)>0) {
701 if (!UserAgentFromCmdLine) {
702 if (!UserAgentLog)
703 UserAgentLog=FileList_Create();
704 char *FileName=getparam_stringptr("useragent_log",buf);
705 if (!FileList_AddFile(UserAgentLog,FileName)) {
706 debuga(__FILE__,__LINE__,_("Not enough memory to store a user agent file name\n"));
707 exit(EXIT_FAILURE);
708 }
709 }
710 return;
711 }
712
713 if (getparam_string("exclude_hosts",buf,ExcludeHosts,sizeof(ExcludeHosts))>0) return;
714
715 if (getparam_string("exclude_codes",buf,ExcludeCodes,sizeof(ExcludeCodes))>0) return;
716
717 if (getparam_string("exclude_users",buf,ExcludeUsers,sizeof(ExcludeUsers))>0) return;
718
719 if (getparam_string("password",buf,PasswdFile,sizeof(PasswdFile))>0) return;
720
721 if (getparam_string("temporary_dir",buf,TempDir,sizeof(TempDir))>0) return;
722
723 if (getparam_list("report_type",SET_LIST(report_type_values),buf,&ReportType)>0) return;
724
725 if (getparam_string("output_dir",buf,OutputDir,sizeof(OutputDir))>0) return;
726
727 if (getparam_bool("anonymous_output_files",buf,&AnonymousOutputFiles)>0) return;
728
729 if (getparam_string("output_email",buf,OutputEmail,sizeof(OutputEmail))>0) return;
730
731 if (getparam_userlimit("per_user_limit",buf)>0) return;
732
733 if (getparam_select("per_user_limit_file_create",SET_LIST(per_user_limit_create_file),buf,&iVal)>0) {
734 PerUserFileCreation=(enum PerUserFileCreationEnum)iVal;
735 return;
736 }
737
738 if (getparam_int("lastlog",buf,&LastLog)>0) return;
739
740 if (getparam_bool("remove_temp_files",buf,&RemoveTempFiles)>0) return;
741
742 if (getparam_string("replace_index",buf,ReplaceIndex,sizeof(ReplaceIndex))>0) return;
743
744 if (getparam_list("index_tree",SET_LIST(index_tree_values),buf,&IndexTree)>0) return;
745
746 if (getparam_list("index",SET_LIST(index_values),buf,&Index)>0) return;
747
748 if (getparam_list("index_fields",SET_LIST(indexfields_values),buf,&IndexFields)>0) return;
749
750 if (getparam_bool("overwrite_report",buf,&OverwriteReport)>0) return;
751
752 if (getparam_list("records_without_userid",SET_LIST(recnouser_values),buf,&RecordsWithoutUser)>0) return;
753
754 if (getparam_bool("use_comma",buf,&UseComma)>0) return;
755
756 if (getparam_string("mail_utility",buf,MailUtility,sizeof(MailUtility))>0) return;
757
758 if (getparam_int("topsites_num",buf,&TopSitesNum)>0) return;
759
760 if (getparam_int("topuser_num",buf,&TopUsersNum)>0) return;
761
762 if (getparam_string("usertab",buf,UserTabFile,sizeof(UserTabFile))>0) return;
763
764 if (getparam_string("index_sort_order",buf,IndexSortOrder,sizeof(IndexSortOrder))>0) return;
765
766 if (getparam_sort("topsites_sort_order",SET_LIST(topsite_sort),buf,&TopsitesSort)>0) return;
767
768 if (getparam_bool("long_url",buf,&LongUrl)>0) return;
769
770 if (getparam_string("dansguardian_conf",buf,DansGuardianConf,sizeof(DansGuardianConf))>0) return;
771
772 if (getparam_string("squidguard_conf",buf,SquidGuardConf,sizeof(SquidGuardConf))>0) return;
773
774 if (getparam_list("date_time_by",SET_LIST(datetime_values),buf,&datetimeby)>0) return;
775
776 if (getparam_string("charset",buf,CharSet,sizeof(CharSet))>0) {
777 ccharset(CharSet);
778 return;
779 }
780
781 if (getparam_quoted("user_invalid_char",buf,UserInvalidChar,sizeof(UserInvalidChar))>0) return;
782
783 if (getparam_quoted("include_users",buf,IncludeUsers+1,sizeof(IncludeUsers)-2)>0) {
784 IncludeUsers[0]=':';
785 strcat(IncludeUsers,":");
786 return;
787 }
788
789 if (getparam_quoted("exclude_string",buf,ExcludeString,sizeof(ExcludeString))>0) return;
790
791 if (getparam_bool("privacy",buf,&Privacy)>0) return;
792
793 if (getparam_quoted("privacy_string",buf,PrivacyString,sizeof(PrivacyString))>0) return;
794
795 if (getparam_string("privacy_string_color",buf,PrivacyStringColor,sizeof(PrivacyStringColor))>0) return;
796
797 if (getparam_bool("show_successful_message",buf,&SuccessfulMsg)>0) return;
798
799 if (getparam_bool("show_read_statistics",buf,&ShowReadStatistics)>0) return;
800
801 if (getparam_bool("show_read_percent",buf,&ShowReadPercent)>0) return;
802
803 if (getparam_list("topuser_fields",SET_LIST(topuserfields_values),buf,&TopUserFields)>0) return;
804
805 if (getparam_bool("bytes_in_sites_users_report",buf,&BytesInSitesUsersReport)>0) return;
806
807 if (getparam_list("user_report_fields",SET_LIST(userreportfields_values),buf,&UserReportFields)>0) return;
808
809 if (getparam_string("datafile",buf,DataFile,sizeof(DataFile))>0) return;
810
811 if (getparam_quoted("datafile_delimiter",buf,DataFileDelimiter,sizeof(DataFileDelimiter))>0) return;
812
813 if (getparam_list("datafile_fields",SET_LIST(data_field_values),buf,&DataFileFields)>0) return;
814
815 if (getparam_list("datafile_url",SET_LIST(datafileurl_values),buf,&DataFileUrl)>0) return;
816
817 if (getparam_string("parsed_output_log",buf,ParsedOutputLog,sizeof(ParsedOutputLog))>0) return;
818
819 if (getparam_string("parsed_output_log_compress",buf,ParsedOutputLogCompress,sizeof(ParsedOutputLogCompress))>0) return;
820
821 if (getparam_list("displayed_values",SET_LIST(displayvalue_values),buf,&DisplayedValues)>0) return;
822
823 if (getparam_int("authfail_report_limit",buf,&AuthfailReportLimit)>0) return;
824
825 if (getparam_int("denied_report_limit",buf,&DeniedReportLimit)>0) return;
826
827 if (getparam_int("siteusers_report_limit",buf,&SiteUsersReportLimit)>0) return;
828
829 if (getparam_int("dansguardian_report_limit",buf,&DansGuardianReportLimit)>0) return;
830
831 if (getparam_int("squidguard_report_limit",buf,&SquidGuardReportLimit)>0) return;
832
833 if (getparam_int("user_report_limit",buf,&UserReportLimit)>0) return;
834
835 if (getparam_int("download_report_limit",buf,&DownloadReportLimit)>0) return;
836
837 if (getparam_string("www_document_root",buf,wwwDocumentRoot,sizeof(wwwDocumentRoot))>0) return;
838
839 if (getparam_string("block_it",buf,BlockIt,sizeof(BlockIt))>0) return;
840
841 if (getparam_string("external_css_file",buf,ExternalCSSFile,sizeof(ExternalCSSFile))>0) return;
842
843 if (getparam_bool("user_authentication",buf,&UserAuthentication)>0) return;
844
845 if (getparam_string("AuthUserTemplateFile",buf,wbuf,sizeof(wbuf))>0) {
846 if (is_absolute(wbuf)) {
847 if (strlen(wbuf)>=sizeof(AuthUserTemplateFile)) {
848 debuga(__FILE__,__LINE__,_("Template file name is too long in parameter \"AuthUserTemplateFile\"\n"));
849 exit(EXIT_FAILURE);
850 }
851 safe_strcpy(AuthUserTemplateFile,wbuf,sizeof(AuthUserTemplateFile));
852 } else {
853 char dir[MAXLEN];
854
855 safe_strcpy(dir,File,sizeof(dir));
856 if (snprintf(AuthUserTemplateFile,sizeof(AuthUserTemplateFile),"%s/%s",dirname(dir),wbuf)>=sizeof(AuthUserTemplateFile)) {
857 debuga(__FILE__,__LINE__,_("Template file name is too long in parameter \"AuthUserTemplateFile\"\n"));
858 exit(EXIT_FAILURE);
859 }
860 }
861 return;
862 }
863
864 if (is_param("download_suffix",buf)) {
865 char warea[MAXLEN];
866
867 getparam_quoted("download_suffix",buf,warea,sizeof(warea));
868 set_download_suffix(warea);
869 return;
870 }
871
872 if (getparam_bool("graphs",buf,&Graphs)>0) {
873 #ifndef HAVE_GD
874 if (Graphs)
875 debugaz(__FILE__,__LINE__,_("No graphs available as sarg was not compiled with libgd. Set \"graphs\" to \"no\" in %s to disable this warning\n"),
876 File);
877 #endif
878 safe_strcpy(GraphConfigFile,File,sizeof(GraphConfigFile));
879 return;
880 }
881
882 if (getparam_string("graph_days_bytes_bar_color",buf,GraphDaysBytesBarColor,sizeof(GraphDaysBytesBarColor))>0) return;
883
884 if (getparam_string("redirector_log_format",buf,RedirectorLogFormat,sizeof(RedirectorLogFormat))>0) return;
885 if (getparam_string("squidguard_log_format",buf,RedirectorLogFormat,sizeof(RedirectorLogFormat))>0) {
886 debuga(__FILE__,__LINE__,_("squidguard_log_format is deprecated and has been replaced by redirector_log_format. Please update your configuration file.\n"));
887 return;
888 }
889
890 if (getparam_bool("redirector_filter_out_date",buf,&RedirectorFilterOutDate)>0) return;
891 if (getparam_bool("redirector_ignore_date",buf,&RedirectorFilterOutDate)>0) {
892 /*
893 Due to an old bug in sarg before version 2.3, the option was having the opposite action than implied by the name.
894 */
895 debuga(__FILE__,__LINE__,_("redirector_ignore_date is deprecated and has been replaced by redirector_filter_out_date that does the action implied by its name as opposed to redirector_ignore_date. Please update your configuration file.\n"));
896 RedirectorFilterOutDate=!RedirectorFilterOutDate;
897 return;
898 }
899 if (getparam_bool("squidguard_ignore_date",buf,&RedirectorFilterOutDate)>0) {
900 debuga(__FILE__,__LINE__,_("squidguard_ignore_date is deprecated and has been replaced by redirector_filter_out_date that does the action implied by its name as opposed to squidguard_ignore_date. Please update your configuration file.\n"));
901 RedirectorFilterOutDate=!RedirectorFilterOutDate;
902 return;
903 }
904
905 if (getparam_bool("dansguardian_filter_out_date",buf,&DansguardianFilterOutDate)>0) return;
906 if (getparam_bool("dansguardian_ignore_date",buf,&DansguardianFilterOutDate)>0) {
907 debuga(__FILE__,__LINE__,_("dansguardian_ignore_date is deprecated and has been replaced by dansguardian_filter_out_date that does the action implied by its name as opposed to dansguardian_ignore_date. Please update your configuration file.\n"));
908 DansguardianFilterOutDate=!DansguardianFilterOutDate;
909 return;
910 }
911
912 if (getparam_string("ulimit",buf,Ulimit,sizeof(Ulimit))>0) return;
913
914 if (getparam_list("ntlm_user_format",SET_LIST(ntml_userformat_values),buf,&NtlmUserFormat)>0) return;
915
916 if (getparam_string("strip_user_suffix",buf,StripUserSuffix,sizeof(StripUserSuffix))>0) return;
917
918 if (getparam_string("realtime_types",buf,RealtimeTypes,sizeof(RealtimeTypes))>0) return;
919
920 if (getparam_list("realtime_unauthenticated_records",SET_LIST(realtime_unauth_values),buf,&RealtimeUnauthRec)>0) return;
921
922 if (getparam_int("realtime_refresh_time",buf,&realtime_refresh)>0) return;
923
924 if (getparam_int("realtime_access_log_lines",buf,&realtime_access_log_lines)>0) return;
925
926 if (getparam_string("LDAPHost",buf,LDAPHost,sizeof(LDAPHost))>0) return;
927
928 if (getparam_int("LDAPPort",buf,&LDAPPort)>0) return;
929
930 if (getparam_int("LDAPProtocolVersion",buf,&LDAPProtocolVersion)>0) return;
931
932 if (getparam_string("LDAPBindDN",buf,LDAPBindDN,sizeof(LDAPBindDN))>0) return;
933
934 if (getparam_string("LDAPBindPW",buf,LDAPBindPW,sizeof(LDAPBindPW))>0) return;
935
936 if (getparam_string("LDAPBaseSearch",buf,LDAPBaseSearch,sizeof(LDAPBaseSearch))>0) return;
937
938 if (getparam_string("LDAPFilterSearch",buf,LDAPFilterSearch,sizeof(LDAPFilterSearch))>0) return;
939
940 if (getparam_string("LDAPTargetAttr",buf,LDAPTargetAttr,sizeof(LDAPTargetAttr))>0) return;
941
942 if (getparam_string("LDAPNativeCharset",buf,LDAPNativeCharset,sizeof(LDAPNativeCharset))>0) return;
943
944 if (getparam_string("graph_font",buf,GraphFont,sizeof(GraphFont))>0) return;
945
946 if (getparam_string("sorttable",buf,SortTableJs,sizeof(SortTableJs))>0) return;
947
948 if (getparam_string("hostalias",buf,HostAliasFile,sizeof(HostAliasFile))>0) return;
949
950 if (getparam_string("useralias",buf,UserAliasFile,sizeof(UserAliasFile))>0) return;
951
952 if (getparam_bool("keep_temp_log",buf,&KeepTempLog)>0) return;
953
954 if (getparam_int("max_successive_log_errors",buf,&NumLogSuccessiveErrors)>0) return;
955
956 if (getparam_int("max_total_log_errors",buf,&NumLogTotalErrors)>0) return;
957
958 if(strstr(buf,"squid24") != 0) {
959 squid24=true;
960 return;
961 }
962
963 if(strstr(buf,"byte_cost") != 0) {
964 getword_start(&gwarea,buf);
965 if (getword_multisep(wbuf,sizeof(wbuf),&gwarea,' ')<0) {
966 debuga(__FILE__,__LINE__,_("The \"byte_cost\" parameter of the configuration file is invalid\n"));
967 exit(EXIT_FAILURE);
968 }
969 cost=atol(gwarea.current);
970 if (getword_multisep(wbuf,sizeof(wbuf),&gwarea,' ')<0) {
971 debuga(__FILE__,__LINE__,_("The \"byte_cost\" parameter of the configuration file is invalid\n"));
972 exit(EXIT_FAILURE);
973 }
974 nocost=my_atoll(gwarea.current);
975 return;
976 }
977
978 if (getparam_string("image_dir",buf,ImageDir,sizeof(ImageDir))>0) return;
979
980 printf(_("SARG: Unknown option %s\n"),buf);
981 }
982
983 void getconf(const char *File)
984 {
985 FILE *fp_in;
986 char buf[MAXLEN];
987 char IncludeFile[MAXLEN];
988
989 IncludeLevel++;
990 if (debug) {
991 if (IncludeLevel<=1)
992 debuga(__FILE__,__LINE__,_("Loading configuration file \"%s\"\n"),File);
993 else
994 debuga(__FILE__,__LINE__,_("Including configuration file \"%s\"\n"),File);
995 }
996
997 // stop if include files are producing a loop
998 if (IncludeLevel>5) {
999 debuga(__FILE__,__LINE__,_("Too many nested configuration files included in \"%s\""),ConfigFile);
1000 exit(EXIT_FAILURE);
1001 }
1002
1003 if ((fp_in = fopen(File, "r")) == NULL) {
1004 debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),File,strerror(errno));
1005 exit(EXIT_FAILURE);
1006 }
1007
1008 while (fgets(buf, sizeof(buf), fp_in) != NULL) {
1009 fixendofline(buf);
1010
1011 if (getparam_string("include",buf,IncludeFile,sizeof(IncludeFile))>0) {
1012 getconf(IncludeFile);
1013 continue;
1014 }
1015
1016 if (debugz>=LogLevel_Data)
1017 printf("SYSCONFDIR %s\n",buf);
1018
1019 parmtest(buf,File);
1020 }
1021
1022 if (fclose(fp_in)==EOF) {
1023 debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),File,strerror(errno));
1024 exit(EXIT_FAILURE);
1025 }
1026 IncludeLevel--;
1027 }