2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
6 * please look at http://sarg.sourceforge.net/donations.php
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
9 * ---------------------------------------------------------------------
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.
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.
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.
27 #include "include/conf.h"
28 #include "include/defs.h"
29 #include "include/filelist.h"
31 #define SET_LIST(list) list,sizeof(list)/sizeof(list[0])
33 //! The configuration file from which the graph option was loaded
34 char GraphConfigFile
[MAXLEN
]="";
36 //! How many include directives were followed.
37 static int IncludeLevel
=0;
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 extern int StripSuffixLen
;
52 //! The name of the value of the parameter.
54 //! The bit to set if the value is found.
55 unsigned long int value
;
56 //! The value is invalid if any bit of this mask is set in the parameter.
57 unsigned long int exclude
;
62 //! The name of the value of the parameter.
64 //! The bit to set if the value is found.
65 unsigned long int value
;
70 //! The name of the value of the parameter.
72 //! The value to assign when the name is selected.
76 static struct param_list report_type_values
[]=
78 {"users_sites",REPORT_TYPE_USERS_SITES
,0},
79 {"topusers",REPORT_TYPE_TOPUSERS
,0},
80 {"topsites",REPORT_TYPE_TOPSITES
,0},
81 {"sites_users",REPORT_TYPE_SITES_USERS
,0},
82 {"date_time",REPORT_TYPE_DATE_TIME
,0},
83 {"denied",REPORT_TYPE_DENIED
,0},
84 {"auth_failures",REPORT_TYPE_AUTH_FAILURES
,0},
85 {"site_user_time_date",REPORT_TYPE_SITE_USER_TIME_DATE
,0},
86 {"downloads",REPORT_TYPE_DOWNLOADS
,0},
87 {"user_agent",REPORT_TYPE_USERAGENT
,0},
90 static struct param_list data_field_values
[]=
92 {"user",DATA_FIELD_USER
,0},
93 {"date",DATA_FIELD_DATE
,0},
94 {"time",DATA_FIELD_TIME
,0},
95 {"url",DATA_FIELD_URL
,0},
96 {"connect",DATA_FIELD_CONNECT
,0},
97 {"bytes",DATA_FIELD_BYTES
,0},
98 {"in_cache",DATA_FIELD_IN_CACHE
,0},
99 {"out_cache",DATA_FIELD_OUT_CACHE
,0},
100 {"elapsed",DATA_FIELD_ELAPSED
,0},
103 static struct param_list topuserfields_values
[]=
105 {"NUM",TOPUSERFIELDS_NUM
,0},
106 {"DATE_TIME",TOPUSERFIELDS_DATE_TIME
,0},
107 {"USERID",TOPUSERFIELDS_USERID
,0},
108 {"USERIP",TOPUSERFIELDS_USERIP
,0},
109 {"CONNECT",TOPUSERFIELDS_CONNECT
,0},
110 {"BYTES",TOPUSERFIELDS_BYTES
,0},
111 {"%BYTES",TOPUSERFIELDS_SETYB
,0},
112 {"SETYB",TOPUSERFIELDS_SETYB
,0},
113 {"IN-CACHE-OUT",TOPUSERFIELDS_IN_CACHE_OUT
,0},
114 {"USED_TIME",TOPUSERFIELDS_USED_TIME
,0},
115 {"MILISEC",TOPUSERFIELDS_MILISEC
,0},
116 {"%TIME",TOPUSERFIELDS_PTIME
,0},
117 {"TOTAL",TOPUSERFIELDS_TOTAL
,0},
118 {"AVERAGE",TOPUSERFIELDS_AVERAGE
,0},
121 static struct param_list userreportfields_values
[]=
123 {"CONNECT",USERREPORTFIELDS_CONNECT
,0},
124 {"BYTES",USERREPORTFIELDS_BYTES
,0},
125 {"%BYTES",USERREPORTFIELDS_SETYB
,0},
126 {"SETYB",USERREPORTFIELDS_SETYB
,0},
127 {"IN-CACHE-OUT",USERREPORTFIELDS_IN_CACHE_OUT
,0},
128 {"USED_TIME",USERREPORTFIELDS_USED_TIME
,0},
129 {"MILISEC",USERREPORTFIELDS_MILISEC
,0},
130 {"%TIME",USERREPORTFIELDS_PTIME
,0},
131 {"TOTAL",USERREPORTFIELDS_TOTAL
,0},
132 {"AVERAGE",USERREPORTFIELDS_AVERAGE
,0},
135 static struct param_list index_values
[]=
137 {"yes",INDEX_YES
,~INDEX_YES
},
138 {"no",INDEX_NO
,~INDEX_NO
},
139 {"only",INDEX_ONLY
,~INDEX_ONLY
},
142 static struct param_list index_tree_values
[]=
144 {"date",INDEX_TREE_DATE
,~INDEX_TREE_DATE
},
145 {"file",INDEX_TREE_FILE
,~INDEX_TREE_FILE
},
148 static struct param_list indexfields_values
[]=
150 {"DIRSIZE",INDEXFIELDS_DIRSIZE
,0},
153 static struct param_list ntml_userformat_values
[]=
155 {"user",NTLMUSERFORMAT_USER
,~NTLMUSERFORMAT_USER
},
156 {"domainname+username",NTLMUSERFORMAT_DOMAINUSER
,~NTLMUSERFORMAT_DOMAINUSER
},
159 static struct param_list recnouser_values
[]=
161 {"ip",RECORDWITHOUTUSER_IP
,~RECORDWITHOUTUSER_IP
},
162 {"ignore",RECORDWITHOUTUSER_IGNORE
,~RECORDWITHOUTUSER_IGNORE
},
163 {"everybody",RECORDWITHOUTUSER_EVERYBODY
,~RECORDWITHOUTUSER_EVERYBODY
},
166 static struct param_list datafileurl_values
[]=
168 {"ip",DATAFILEURL_IP
,~DATAFILEURL_IP
},
169 {"name",DATAFILEURL_NAME
,~DATAFILEURL_NAME
},
172 static struct param_list displayvalue_values
[]=
174 {"bytes",DISPLAY_BYTES
,~DISPLAY_BYTES
},
175 {"abbreviation",DISPLAY_ABBREV
,~DISPLAY_ABBREV
},
178 static struct param_list datetime_values
[]=
180 {"elap",DATETIME_ELAP
,0},
181 {"bytes",DATETIME_BYTE
,0},
184 static struct param_list realtime_unauth_values
[]=
186 {"show",REALTIME_UNAUTH_REC_SHOW
,~REALTIME_UNAUTH_REC_SHOW
},
187 {"ignore",REALTIME_UNAUTH_REC_IGNORE
,~REALTIME_UNAUTH_REC_IGNORE
},
190 struct sort_list topuser_sort
[]=
192 {"BYTES",TOPUSER_SORT_BYTES
},
193 {"USER",TOPUSER_SORT_USER
},
194 {"CONNECT",TOPUSER_SORT_CONNECT
},
195 {"TIME",TOPUSER_SORT_TIME
},
198 struct sort_list topsite_sort
[]=
200 {"BYTES",TOPSITE_SORT_BYTES
},
201 {"CONNECT",TOPSITE_SORT_CONNECT
},
202 {"TIME",TOPSITE_SORT_TIME
},
203 {"USER",TOPSITE_SORT_USER
},
206 struct sort_list user_sort
[]=
208 {"BYTES",USER_SORT_BYTES
},
209 {"SITE",USER_SORT_SITE
},
210 {"CONNECT",USER_SORT_CONNECT
},
211 {"TIME",USER_SORT_TIME
},
214 static struct select_list per_user_limit_create_file
[]=
216 {"always",PUFC_Always
}, //always create an empty file
217 {"as_required",PUFC_AsRequired
}, //create the file if necessary (no empty file is created)
220 static int is_param(const char *param
,const char *buf
)
225 if (strncmp(buf
,param
,plen
) != 0) return(0);
227 if ((unsigned char)*buf
>' ') return(0);
231 static int getparam_string(const char *param
,char *buf
,char *value
,int value_size
)
236 if (strncmp(buf
,param
,plen
) != 0) return(0);
238 if ((unsigned char)*buf
>' ') return(0);
239 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
241 if (strlen(buf
)>=value_size
) {
242 debuga(__FILE__
,__LINE__
,_("The string value of parameter \"%s\" is too long\n"),param
);
251 * Get a pointer to the beginning of the string value defined by the
252 * parameter. The returned value is NULL if the buffer doesn't contain
255 * \param param The parameter to look for.
256 * \param buf The buffer containing the line read from the configuration
259 * \return A pointer to the beginning of the parameter value or NULL if
260 * the line is not for the requested parameter.
262 static char *getparam_stringptr(const char *param
,char *buf
)
267 if (strncmp(buf
,param
,plen
) != 0) return(NULL
);
269 if ((unsigned char)*buf
>' ') return(NULL
);
270 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
275 static int getparam_quoted(const char *param
,char *buf
,char *value
,int value_size
)
281 if (strncmp(buf
,param
,plen
) != 0) return(0);
283 if ((unsigned char)*buf
>' ') return(0);
284 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
287 debuga(__FILE__
,__LINE__
,_("Missing double quote after parameter \"%s\"\n"),param
);
293 for (i
=0 ; i
<value_size
&& *buf
&& *buf
!='\"' ; i
++) {
299 debuga(__FILE__
,__LINE__
,_("Missing double quote after parameter \"%s\" or value is more than %d bytes long\n"),param
,value_size
);
306 static int getparam_2words(const char *param
,char *buf
,char *word1
,int word1_size
,char *word2
,int word2_size
)
312 if (strncmp(buf
,param
,plen
) != 0) return(0);
314 if ((unsigned char)*buf
>' ') return(0);
315 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
317 for (i
=0 ; i
<word1_size
&& *buf
&& (unsigned char)*buf
>' ' ; i
++)
320 debuga(__FILE__
,__LINE__
,_("The first word of parameter \"%s\" is more than %d bytes long\n"),param
,word1_size
-1);
324 debuga(__FILE__
,__LINE__
,_("Missing second word for parameter \"%s\"\n"),param
);
329 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
331 for (i
=0 ; i
<word2_size
&& *buf
&& (unsigned char)*buf
>' ' ; i
++)
334 debuga(__FILE__
,__LINE__
,_("The second word of parameter \"%s\" is more than %d bytes long\n"),param
,word2_size
-1);
344 static int getparam_int(const char *param
,char *buf
,int *value
)
350 if (strncmp(buf
,param
,plen
) != 0) return(0);
352 if ((unsigned char)*buf
>' ') return(0);
353 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
356 if (sscanf(buf
,"%d%n",value
,&next
) != 1 || (unsigned char)buf
[next
] > ' ') {
357 debuga(__FILE__
,__LINE__
,_("The integer value of parameter \"%s\" is invalid\n"),param
);
363 static int getparam_bool(const char *param
,char *buf
,bool *value
)
367 const char *bool_str
="yes,true,on,1";
370 if (strncmp(buf
,param
,plen
) != 0) return(0);
372 if ((unsigned char)*buf
>' ') return(0);
373 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
376 for ( ; *bool_str
; bool_str
+=i
) {
377 for (i
=0 ; bool_str
[i
] && bool_str
[i
]!=',' ; i
++);
378 if (strncasecmp(bool_str
,buf
,i
)==0) {
382 if (bool_str
[i
]==',') i
++;
387 static int getparam_list(const char *param
,struct param_list
*options
,int noptions
,char *buf
,unsigned long int *value
)
394 if (strncmp(buf
,param
,plen
) != 0) return(0);
396 if ((unsigned char)*buf
>' ') return(0);
397 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
402 while (*str
&& (unsigned char)*str
>' ' && *str
!=';') str
++;
405 while (*str
&& ((unsigned char)*str
<=' ' || *str
==';')) str
++;
407 for (i
=0 ; i
<noptions
&& strcasecmp(buf
,options
[i
].name
) ; i
++);
409 debuga(__FILE__
,__LINE__
,_("Unknown value \"%s\" for parameter \"%s\"\n"),buf
,param
);
412 if ((*value
& options
[i
].exclude
)!=0) {
413 debuga(__FILE__
,__LINE__
,_("Value \"%s\" conflicts with other selected values for parameter \"%s\"\n"),buf
,param
);
416 *value
|=options
[i
].value
;
422 static int getparam_sort(const char *param
,struct sort_list
*options
,int noptions
,char *buf
,unsigned long int *value
)
429 if (strncmp(buf
,param
,plen
) != 0) return(0);
431 if ((unsigned char)*buf
>' ') return(0);
432 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
436 while (*str
&& (unsigned char)*str
>' ') str
++;
439 while (*str
&& (unsigned char)*str
<=' ') str
++;
442 for (i
=0 ; i
<noptions
&& strcasecmp(buf
,options
[i
].name
) ; i
++);
444 debuga(__FILE__
,__LINE__
,_("Unknown sort criterion \"%s\" for parameter \"%s\"\n"),buf
,param
);
447 *value
=options
[i
].value
;
451 while (*str
&& (unsigned char)*str
>' ') str
++;
454 while (*str
&& (unsigned char)*str
<=' ') str
++;
456 if (strcasecmp(order
,"reverse")==0 || strcasecmp(order
,"D")==0) {
457 *value
|=SORT_REVERSE
;
458 } else if (strcasecmp(order
,"normal")!=0 && strcasecmp(order
,"A")!=0) {
459 debuga(__FILE__
,__LINE__
,_("Unknown sort order \"%s\" for parameter \"%s\"\n"),order
,param
);
468 static int getparam_select(const char *param
,struct select_list
*options
,int noptions
,char *buf
,int *value
)
475 if (strncmp(buf
,param
,plen
) != 0) return(0);
477 if ((unsigned char)*buf
>' ') return(0);
478 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
481 while (*buf
&& (unsigned char)*buf
>' ' && *buf
!=';') buf
++;
483 for (i
=0 ; i
<noptions
&& strcasecmp(str
,options
[i
].name
) ; i
++);
485 debuga(__FILE__
,__LINE__
,_("Unknown value \"%s\" for parameter \"%s\"\n"),str
,param
);
488 *value
=options
[i
].value
;
492 static int getparam_userlimit(const char *param
,char *buf
)
495 char *file_begin
,*file_end
;
500 enum PerUserOutputEnum output
;
504 enum PerUserOutputEnum value
;
512 if (strncmp(buf
,param
,plen
) != 0) return(0);
514 if ((unsigned char)*buf
>' ') return(0);
515 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
518 options are made of a file name, an integer limit and an optional
519 integer flag. The file name may contain spaces. We keep searching
520 until a valid number is found after a space.
524 while (*buf
&& (unsigned char)*buf
>' ') buf
++;
526 debuga(__FILE__
,__LINE__
,_("Missing limit in per_user_limit\n"));
530 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
532 while (*buf
&& isdigit(*buf
)) {
534 if (limit
>=(INT_MAX
-digit
)/10) break;
535 limit
=limit
*10+digit
;
538 } while (*buf
&& *buf
!=' ');
542 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
544 while (*buf
&& (unsigned char)*buf
>' ') buf
++;
546 for (i
=sizeof(output_types
)/sizeof(output_types
[0])-1 ; i
>=0 ; i
--)
547 if (strcasecmp(output_types
[i
].name
,str
)==0) {
548 output
=output_types
[i
].value
;
552 debuga(__FILE__
,__LINE__
,_("Invalid output type in per_user_limit\n"));
557 if (PerUserLimitsNumber
>=MAX_USER_LIMITS
) {
558 debuga(__FILE__
,__LINE__
,_("Too many per_user_limit\n"));
562 safe_strcpy(PerUserLimits
[PerUserLimitsNumber
].File
,file_begin
,sizeof(PerUserLimits
[PerUserLimitsNumber
].File
));
563 PerUserLimits
[PerUserLimitsNumber
].Limit
=limit
;
564 PerUserLimits
[PerUserLimitsNumber
].Output
=output
;
565 PerUserLimitsNumber
++;
570 static void ccharset(char *CharSet
)
572 if (strcmp(CharSet
,"Latin2") == 0) strcpy(CharSet
,"ISO-8859-2");
573 else if (strcmp(CharSet
,"Latin3") == 0) strcpy(CharSet
,"ISO-8859-3");
574 else if (strcmp(CharSet
,"Latin4") == 0) strcpy(CharSet
,"ISO-8859-4");
575 else if (strcmp(CharSet
,"Cyrillic") == 0) strcpy(CharSet
,"ISO-8859-5");
576 else if (strcmp(CharSet
,"Arabic") == 0) strcpy(CharSet
,"ISO-8859-6");
577 else if (strcmp(CharSet
,"Greek") == 0) strcpy(CharSet
,"ISO-8859-7");
578 else if (strcmp(CharSet
,"Hebrew") == 0) strcpy(CharSet
,"ISO-8859-8");
579 else if (strcmp(CharSet
,"Latin5") == 0) strcpy(CharSet
,"ISO-8859-9");
580 else if (strcmp(CharSet
,"Latin6") == 0) strcpy(CharSet
,"ISO-8859-10");
581 else if (strcmp(CharSet
,"Japan") == 0) strcpy(CharSet
,"EUC-JP");
582 else if (strcmp(CharSet
,"Koi8-r") == 0) strcpy(CharSet
,"KOI8-R");
584 * Any other encoding name is left unchanged.
589 static void parmtest(char *buf
,const char *File
)
592 struct getwordstruct gwarea
;
595 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
597 if(*buf
== '#' || *buf
== '\0')
600 if(debugz
>=LogLevel_Process
)
601 printf(_("SARG: TAG: %s\n"),buf
);
603 if (getparam_string("background_color",buf
,BgColor
,sizeof(BgColor
))>0) return;
605 if (getparam_string("text_color",buf
,TxColor
,sizeof(TxColor
))>0) return;
607 if (getparam_string("text_bgcolor",buf
,TxBgColor
,sizeof(TxBgColor
))>0) return;
609 if (getparam_string("title_color",buf
,TiColor
,sizeof(TiColor
))>0) return;
611 if (getparam_string("logo_image",buf
,LogoImage
,sizeof(LogoImage
))>0) return;
613 if (getparam_quoted("logo_text",buf
,LogoText
,sizeof(LogoText
))>0) return;
615 if (getparam_string("logo_text_color",buf
,LogoTextColor
,sizeof(LogoTextColor
))>0) return;
617 if (getparam_string("background_image",buf
,BgImage
,sizeof(BgImage
))>0) return;
619 if (getparam_bool("show_sarg_info",buf
,&ShowSargInfo
)>0) return;
621 if (getparam_bool("show_sarg_logo",buf
,&ShowSargLogo
)>0) return;
623 if (getparam_string("font_face",buf
,FontFace
,sizeof(FontFace
))>0) return;
625 if (getparam_string("header_color",buf
,HeaderColor
,sizeof(HeaderColor
))>0) return;
627 if (getparam_string("header_bgcolor",buf
,HeaderBgColor
,sizeof(HeaderBgColor
))>0) return;
629 if (getparam_string("font_size",buf
,FontSize
,sizeof(FontSize
))>0) return;
631 if (getparam_string("header_font_size",buf
,HeaderFontSize
,sizeof(HeaderFontSize
))>0) return;
633 if (getparam_string("title_font_size",buf
,TitleFontSize
,sizeof(TitleFontSize
))>0) return;
635 if (getparam_2words("image_size",buf
,Width
,sizeof(Width
),Height
,sizeof(Height
))>0) return;
637 if (getparam_quoted("title",buf
,Title
,sizeof(Title
))>0) return;
639 if (strncasecmp(buf
,"resolve_ip",10)==0) {
640 if (ip2name_config(buf
+10)>0) return;
643 if (getparam_bool("user_ip",buf
,&UserIp
)>0) return;
645 if (getparam_string("max_elapsed",buf
,MaxElapsed
,sizeof(MaxElapsed
))>0) return;
647 if (is_param("date_format",buf
)) {
648 getword_start(&gwarea
,buf
);
649 if (getword_multisep(wbuf
,sizeof(wbuf
),&gwarea
,' ')<0) {
650 debuga(__FILE__
,__LINE__
,_("Invalid record in \"date_format\" parameter\n"));
653 DateFormat
=gwarea
.current
[0];
657 if (is_param("hours",buf
)) {
658 if( getnumlist( buf
, &hours
, 24, 24 ) ) {
659 debuga(__FILE__
,__LINE__
,_("Error: Invalid syntax in hours tag!\n"));
665 if (is_param("weekdays",buf
)) {
666 if( getnumlist( buf
, &weekdays
, 7, 7 ) ) {
667 debuga(__FILE__
,__LINE__
,_("Error: Invalid syntax in weekdays tag!\n"));
673 if (getparam_sort("topuser_sort_field",SET_LIST(topuser_sort
),buf
,&TopuserSort
)>0) return;
675 if (getparam_sort("user_sort_field",SET_LIST(user_sort
),buf
,&UserSort
)>0) return;
677 if (is_param("access_log",buf
)>0) {
678 if (AccessLogFromCmdLine
==0) {
679 char *FileName
=getparam_stringptr("access_log",buf
);
681 AccessLog
=FileList_Create();
682 if (!FileList_AddFile(AccessLog
,FileName
)) {
683 debuga(__FILE__
,__LINE__
,_("Not enough memory to store the input log file names\n"));
690 if (is_param("redirector_log",buf
)>0) {
691 if (RedirectorLogFromCmdLine
==0) {
692 if (NRedirectorLogs
>=MAX_REDIRECTOR_LOGS
) {
693 debuga(__FILE__
,__LINE__
,_("Too many redirector log files in configuration file\n"));
696 getparam_string("redirector_log",buf
,RedirectorLogs
[NRedirectorLogs
],MAX_REDIRECTOR_FILELEN
);
702 if (is_param("useragent_log",buf
)>0) {
703 if (!UserAgentFromCmdLine
) {
705 UserAgentLog
=FileList_Create();
706 char *FileName
=getparam_stringptr("useragent_log",buf
);
707 if (!FileList_AddFile(UserAgentLog
,FileName
)) {
708 debuga(__FILE__
,__LINE__
,_("Not enough memory to store a user agent file name\n"));
715 if (getparam_string("exclude_hosts",buf
,ExcludeHosts
,sizeof(ExcludeHosts
))>0) return;
717 if (getparam_string("exclude_codes",buf
,ExcludeCodes
,sizeof(ExcludeCodes
))>0) return;
719 if (getparam_string("exclude_users",buf
,ExcludeUsers
,sizeof(ExcludeUsers
))>0) return;
721 if (getparam_string("password",buf
,PasswdFile
,sizeof(PasswdFile
))>0) return;
723 if (getparam_string("temporary_dir",buf
,TempDir
,sizeof(TempDir
))>0) return;
725 if (getparam_list("report_type",SET_LIST(report_type_values
),buf
,&ReportType
)>0) return;
727 if (getparam_string("output_dir",buf
,OutputDir
,sizeof(OutputDir
))>0) return;
729 if (getparam_bool("anonymous_output_files",buf
,&AnonymousOutputFiles
)>0) return;
731 if (getparam_string("output_email",buf
,OutputEmail
,sizeof(OutputEmail
))>0) return;
733 if (getparam_userlimit("per_user_limit",buf
)>0) return;
735 if (getparam_select("per_user_limit_file_create",SET_LIST(per_user_limit_create_file
),buf
,&iVal
)>0) {
736 PerUserFileCreation
=(enum PerUserFileCreationEnum
)iVal
;
740 if (getparam_int("lastlog",buf
,&LastLog
)>0) return;
742 if (getparam_bool("remove_temp_files",buf
,&RemoveTempFiles
)>0) return;
744 if (getparam_string("replace_index",buf
,ReplaceIndex
,sizeof(ReplaceIndex
))>0) return;
746 if (getparam_list("index_tree",SET_LIST(index_tree_values
),buf
,&IndexTree
)>0) return;
748 if (getparam_list("index",SET_LIST(index_values
),buf
,&Index
)>0) return;
750 if (getparam_list("index_fields",SET_LIST(indexfields_values
),buf
,&IndexFields
)>0) return;
752 if (getparam_bool("overwrite_report",buf
,&OverwriteReport
)>0) return;
754 if (getparam_list("records_without_userid",SET_LIST(recnouser_values
),buf
,&RecordsWithoutUser
)>0) return;
756 if (getparam_bool("use_comma",buf
,&UseComma
)>0) return;
758 if (getparam_string("mail_utility",buf
,MailUtility
,sizeof(MailUtility
))>0) return;
760 if (getparam_int("topsites_num",buf
,&TopSitesNum
)>0) return;
762 if (getparam_int("topuser_num",buf
,&TopUsersNum
)>0) return;
764 if (getparam_string("usertab",buf
,UserTabFile
,sizeof(UserTabFile
))>0) return;
766 if (getparam_string("index_sort_order",buf
,IndexSortOrder
,sizeof(IndexSortOrder
))>0) return;
768 if (getparam_sort("topsites_sort_order",SET_LIST(topsite_sort
),buf
,&TopsitesSort
)>0) return;
770 if (getparam_bool("long_url",buf
,&LongUrl
)>0) return;
772 if (getparam_string("dansguardian_conf",buf
,DansGuardianConf
,sizeof(DansGuardianConf
))>0) return;
774 if (getparam_string("squidguard_conf",buf
,SquidGuardConf
,sizeof(SquidGuardConf
))>0) return;
776 if (getparam_list("date_time_by",SET_LIST(datetime_values
),buf
,&datetimeby
)>0) return;
778 if (getparam_string("charset",buf
,CharSet
,sizeof(CharSet
))>0) {
783 if (getparam_quoted("user_invalid_char",buf
,UserInvalidChar
,sizeof(UserInvalidChar
))>0) return;
785 if (getparam_quoted("include_users",buf
,IncludeUsers
+1,sizeof(IncludeUsers
)-2)>0) {
787 strcat(IncludeUsers
,":");
791 if (getparam_quoted("exclude_string",buf
,ExcludeString
,sizeof(ExcludeString
))>0) return;
793 if (getparam_bool("privacy",buf
,&Privacy
)>0) return;
795 if (getparam_quoted("privacy_string",buf
,PrivacyString
,sizeof(PrivacyString
))>0) return;
797 if (getparam_string("privacy_string_color",buf
,PrivacyStringColor
,sizeof(PrivacyStringColor
))>0) return;
799 if (getparam_bool("show_successful_message",buf
,&SuccessfulMsg
)>0) return;
801 if (getparam_bool("show_read_statistics",buf
,&ShowReadStatistics
)>0) return;
803 if (getparam_bool("show_read_percent",buf
,&ShowReadPercent
)>0) return;
805 if (getparam_list("topuser_fields",SET_LIST(topuserfields_values
),buf
,&TopUserFields
)>0) return;
807 if (getparam_bool("bytes_in_sites_users_report",buf
,&BytesInSitesUsersReport
)>0) return;
809 if (getparam_list("user_report_fields",SET_LIST(userreportfields_values
),buf
,&UserReportFields
)>0) return;
811 if (getparam_string("datafile",buf
,DataFile
,sizeof(DataFile
))>0) return;
813 if (getparam_quoted("datafile_delimiter",buf
,DataFileDelimiter
,sizeof(DataFileDelimiter
))>0) return;
815 if (getparam_list("datafile_fields",SET_LIST(data_field_values
),buf
,&DataFileFields
)>0) return;
817 if (getparam_list("datafile_url",SET_LIST(datafileurl_values
),buf
,&DataFileUrl
)>0) return;
819 if (getparam_string("parsed_output_log",buf
,ParsedOutputLog
,sizeof(ParsedOutputLog
))>0) return;
821 if (getparam_string("parsed_output_log_compress",buf
,ParsedOutputLogCompress
,sizeof(ParsedOutputLogCompress
))>0) return;
823 if (getparam_list("displayed_values",SET_LIST(displayvalue_values
),buf
,&DisplayedValues
)>0) return;
825 if (getparam_int("authfail_report_limit",buf
,&AuthfailReportLimit
)>0) return;
827 if (getparam_int("denied_report_limit",buf
,&DeniedReportLimit
)>0) return;
829 if (getparam_int("siteusers_report_limit",buf
,&SiteUsersReportLimit
)>0) return;
831 if (getparam_int("dansguardian_report_limit",buf
,&DansGuardianReportLimit
)>0) return;
833 if (getparam_int("squidguard_report_limit",buf
,&SquidGuardReportLimit
)>0) return;
835 if (getparam_int("user_report_limit",buf
,&UserReportLimit
)>0) return;
837 if (getparam_int("download_report_limit",buf
,&DownloadReportLimit
)>0) return;
839 if (getparam_string("www_document_root",buf
,wwwDocumentRoot
,sizeof(wwwDocumentRoot
))>0) return;
841 if (getparam_string("block_it",buf
,BlockIt
,sizeof(BlockIt
))>0) return;
843 if (getparam_string("external_css_file",buf
,ExternalCSSFile
,sizeof(ExternalCSSFile
))>0) return;
845 if (getparam_bool("user_authentication",buf
,&UserAuthentication
)>0) return;
847 if (getparam_string("AuthUserTemplateFile",buf
,wbuf
,sizeof(wbuf
))>0) {
848 if (is_absolute(wbuf
)) {
849 if (strlen(wbuf
)>=sizeof(AuthUserTemplateFile
)) {
850 debuga(__FILE__
,__LINE__
,_("Template file name is too long in parameter \"AuthUserTemplateFile\"\n"));
853 safe_strcpy(AuthUserTemplateFile
,wbuf
,sizeof(AuthUserTemplateFile
));
857 safe_strcpy(dir
,File
,sizeof(dir
));
858 if (snprintf(AuthUserTemplateFile
,sizeof(AuthUserTemplateFile
),"%s/%s",dirname(dir
),wbuf
)>=sizeof(AuthUserTemplateFile
)) {
859 debuga(__FILE__
,__LINE__
,_("Template file name is too long in parameter \"AuthUserTemplateFile\"\n"));
866 if (is_param("download_suffix",buf
)) {
869 getparam_quoted("download_suffix",buf
,warea
,sizeof(warea
));
870 set_download_suffix(warea
);
874 if (getparam_bool("graphs",buf
,&Graphs
)>0) {
877 debugaz(__FILE__
,__LINE__
,_("No graphs available as sarg was not compiled with libgd. Set \"graphs\" to \"no\" in %s to disable this warning\n"),
880 safe_strcpy(GraphConfigFile
,File
,sizeof(GraphConfigFile
));
884 if (getparam_string("graph_days_bytes_bar_color",buf
,GraphDaysBytesBarColor
,sizeof(GraphDaysBytesBarColor
))>0) return;
886 if (getparam_string("redirector_log_format",buf
,RedirectorLogFormat
,sizeof(RedirectorLogFormat
))>0) return;
887 if (getparam_string("squidguard_log_format",buf
,RedirectorLogFormat
,sizeof(RedirectorLogFormat
))>0) {
888 debuga(__FILE__
,__LINE__
,_("squidguard_log_format is deprecated and has been replaced by redirector_log_format. Please update your configuration file.\n"));
892 if (getparam_bool("redirector_filter_out_date",buf
,&RedirectorFilterOutDate
)>0) return;
893 if (getparam_bool("redirector_ignore_date",buf
,&RedirectorFilterOutDate
)>0) {
895 Due to an old bug in sarg before version 2.3, the option was having the opposite action than implied by the name.
897 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"));
898 RedirectorFilterOutDate
=!RedirectorFilterOutDate
;
901 if (getparam_bool("squidguard_ignore_date",buf
,&RedirectorFilterOutDate
)>0) {
902 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"));
903 RedirectorFilterOutDate
=!RedirectorFilterOutDate
;
907 if (getparam_bool("dansguardian_filter_out_date",buf
,&DansguardianFilterOutDate
)>0) return;
908 if (getparam_bool("dansguardian_ignore_date",buf
,&DansguardianFilterOutDate
)>0) {
909 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"));
910 DansguardianFilterOutDate
=!DansguardianFilterOutDate
;
914 if (getparam_string("ulimit",buf
,Ulimit
,sizeof(Ulimit
))>0) return;
916 if (getparam_list("ntlm_user_format",SET_LIST(ntml_userformat_values
),buf
,&NtlmUserFormat
)>0) return;
918 if (getparam_string("strip_user_suffix",buf
,StripUserSuffix
,sizeof(StripUserSuffix
))>0) {
919 StripSuffixLen
=strlen(StripUserSuffix
);
923 if (getparam_string("realtime_types",buf
,RealtimeTypes
,sizeof(RealtimeTypes
))>0) return;
925 if (getparam_list("realtime_unauthenticated_records",SET_LIST(realtime_unauth_values
),buf
,&RealtimeUnauthRec
)>0) return;
927 if (getparam_int("realtime_refresh_time",buf
,&realtime_refresh
)>0) return;
929 if (getparam_int("realtime_access_log_lines",buf
,&realtime_access_log_lines
)>0) return;
931 if (getparam_string("LDAPHost",buf
,LDAPHost
,sizeof(LDAPHost
))>0) return;
933 if (getparam_int("LDAPPort",buf
,&LDAPPort
)>0) return;
935 if (getparam_int("LDAPProtocolVersion",buf
,&LDAPProtocolVersion
)>0) return;
937 if (getparam_string("LDAPBindDN",buf
,LDAPBindDN
,sizeof(LDAPBindDN
))>0) return;
939 if (getparam_string("LDAPBindPW",buf
,LDAPBindPW
,sizeof(LDAPBindPW
))>0) return;
941 if (getparam_string("LDAPBaseSearch",buf
,LDAPBaseSearch
,sizeof(LDAPBaseSearch
))>0) return;
943 if (getparam_string("LDAPFilterSearch",buf
,LDAPFilterSearch
,sizeof(LDAPFilterSearch
))>0) return;
945 if (getparam_string("LDAPTargetAttr",buf
,LDAPTargetAttr
,sizeof(LDAPTargetAttr
))>0) return;
947 if (getparam_string("LDAPNativeCharset",buf
,LDAPNativeCharset
,sizeof(LDAPNativeCharset
))>0) return;
949 if (getparam_string("graph_font",buf
,GraphFont
,sizeof(GraphFont
))>0) return;
951 if (getparam_string("sorttable",buf
,SortTableJs
,sizeof(SortTableJs
))>0) return;
953 if (getparam_string("hostalias",buf
,HostAliasFile
,sizeof(HostAliasFile
))>0) return;
955 if (getparam_string("useralias",buf
,UserAliasFile
,sizeof(UserAliasFile
))>0) return;
957 if (getparam_bool("keep_temp_log",buf
,&KeepTempLog
)>0) return;
959 if (getparam_int("max_successive_log_errors",buf
,&NumLogSuccessiveErrors
)>0) return;
961 if (getparam_int("max_total_log_errors",buf
,&NumLogTotalErrors
)>0) return;
963 if(strstr(buf
,"squid24") != 0) {
968 if(strstr(buf
,"byte_cost") != 0) {
969 getword_start(&gwarea
,buf
);
970 if (getword_multisep(wbuf
,sizeof(wbuf
),&gwarea
,' ')<0) {
971 debuga(__FILE__
,__LINE__
,_("The \"byte_cost\" parameter of the configuration file is invalid\n"));
974 cost
=atol(gwarea
.current
);
975 if (getword_multisep(wbuf
,sizeof(wbuf
),&gwarea
,' ')<0) {
976 debuga(__FILE__
,__LINE__
,_("The \"byte_cost\" parameter of the configuration file is invalid\n"));
979 nocost
=my_atoll(gwarea
.current
);
983 if (getparam_string("image_dir",buf
,ImageDir
,sizeof(ImageDir
))>0) return;
985 printf(_("SARG: Unknown option %s\n"),buf
);
988 void getconf(const char *File
)
992 char IncludeFile
[MAXLEN
];
997 debuga(__FILE__
,__LINE__
,_("Loading configuration file \"%s\"\n"),File
);
999 debuga(__FILE__
,__LINE__
,_("Including configuration file \"%s\"\n"),File
);
1002 // stop if include files are producing a loop
1003 if (IncludeLevel
>5) {
1004 debuga(__FILE__
,__LINE__
,_("Too many nested configuration files included in \"%s\""),ConfigFile
);
1008 if ((fp_in
= fopen(File
, "r")) == NULL
) {
1009 debuga(__FILE__
,__LINE__
,_("Cannot open file \"%s\": %s\n"),File
,strerror(errno
));
1013 while (fgets(buf
, sizeof(buf
), fp_in
) != NULL
) {
1016 if (getparam_string("include",buf
,IncludeFile
,sizeof(IncludeFile
))>0) {
1017 getconf(IncludeFile
);
1021 if (debugz
>=LogLevel_Data
)
1022 printf("SYSCONFDIR %s\n",buf
);
1027 if (fclose(fp_in
)==EOF
) {
1028 debuga(__FILE__
,__LINE__
,_("Read error in \"%s\": %s\n"),File
,strerror(errno
));