2 * AUTHOR: Pedro Lineu Orso pedro.orso@gmail.com
4 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
7 * please look at http://sarg.sourceforge.net/donations.php
8 * ---------------------------------------------------------------------
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
26 #include "include/conf.h"
27 #include "include/defs.h"
29 #define SET_LIST(list) list,sizeof(list)/sizeof(list[0])
31 extern numlist hours
, weekdays
;
35 //! The name of the value of the parameter.
37 //! The bit to set if the value is found.
38 unsigned long int value
;
39 //! The value is invalid if any bit of this mask is set in the parameter.
40 unsigned long int exclude
;
43 struct param_list report_type_values
[]=
45 {"users_sites",REPORT_TYPE_USERS_SITES
,0},
46 {"topusers",REPORT_TYPE_TOPUSERS
,0},
47 {"topsites",REPORT_TYPE_TOPSITES
,0},
48 {"sites_users",REPORT_TYPE_SITES_USERS
,0},
49 {"date_time",REPORT_TYPE_DATE_TIME
,0},
50 {"denied",REPORT_TYPE_DENIED
,0},
51 {"auth_failures",REPORT_TYPE_AUTH_FAILURES
,0},
52 {"site_user_time_date",REPORT_TYPE_SITE_USER_TIME_DATE
,0},
53 {"downloads",REPORT_TYPE_DOWNLOADS
,0},
56 struct param_list data_field_values
[]=
58 {"user",DATA_FIELD_USER
,0},
59 {"date",DATA_FIELD_DATE
,0},
60 {"time",DATA_FIELD_TIME
,0},
61 {"url",DATA_FIELD_URL
,0},
62 {"connect",DATA_FIELD_CONNECT
,0},
63 {"bytes",DATA_FIELD_BYTES
,0},
64 {"in_cache",DATA_FIELD_IN_CACHE
,0},
65 {"out_cache",DATA_FIELD_OUT_CACHE
,0},
66 {"elapsed",DATA_FIELD_ELAPSED
,0},
69 struct param_list topuserfields_values
[]=
71 {"NUM",TOPUSERFIELDS_NUM
,0},
72 {"DATE_TIME",TOPUSERFIELDS_DATE_TIME
,0},
73 {"USERID",TOPUSERFIELDS_USERID
,0},
74 {"CONNECT",TOPUSERFIELDS_CONNECT
,0},
75 {"BYTES",TOPUSERFIELDS_BYTES
,0},
76 {"%BYTES",TOPUSERFIELDS_SETYB
,0},
77 {"SETYB",TOPUSERFIELDS_SETYB
,0},
78 {"IN-CACHE-OUT",TOPUSERFIELDS_IN_CACHE_OUT
,0},
79 {"USED_TIME",TOPUSERFIELDS_USED_TIME
,0},
80 {"MILISEC",TOPUSERFIELDS_MILISEC
,0},
81 {"%TIME",TOPUSERFIELDS_PTIME
,0},
82 {"TOTAL",TOPUSERFIELDS_TOTAL
,0},
83 {"AVERAGE",TOPUSERFIELDS_AVERAGE
,0},
86 struct param_list userreportfields_values
[]=
88 {"CONNECT",USERREPORTFIELDS_CONNECT
,0},
89 {"BYTES",USERREPORTFIELDS_BYTES
,0},
90 {"%BYTES",USERREPORTFIELDS_SETYB
,0},
91 {"SETYB",USERREPORTFIELDS_SETYB
,0},
92 {"IN-CACHE-OUT",USERREPORTFIELDS_IN_CACHE_OUT
,0},
93 {"USED_TIME",USERREPORTFIELDS_USED_TIME
,0},
94 {"MILISEC",USERREPORTFIELDS_MILISEC
,0},
95 {"%TIME",USERREPORTFIELDS_PTIME
,0},
96 {"TOTAL",USERREPORTFIELDS_TOTAL
,0},
97 {"AVERAGE",USERREPORTFIELDS_AVERAGE
,0},
100 struct param_list index_values
[]=
102 {"yes",INDEX_YES
,~INDEX_YES
},
103 {"no",INDEX_NO
,~INDEX_NO
},
104 {"only",INDEX_ONLY
,~INDEX_ONLY
},
107 struct param_list index_tree_values
[]=
109 {"date",INDEX_TREE_DATE
,~INDEX_TREE_DATE
},
110 {"file",INDEX_TREE_FILE
,~INDEX_TREE_FILE
},
113 static int is_param(const char *param
,const char *buf
)
118 if (strncmp(buf
,param
,plen
) != 0) return(0);
120 if ((unsigned char)*buf
>' ') return(0);
124 static int getparam_string(const char *param
,char *buf
,char *value
,int value_size
)
129 if (strncmp(buf
,param
,plen
) != 0) return(0);
131 if ((unsigned char)*buf
>' ') return(0);
132 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
134 if (strlen(buf
)>=value_size
) {
135 printf("SARG: Maybe you have a broken record or garbage in %s parameter.\n",param
);
143 static int getparam_quoted(const char *param
,char *buf
,char *value
,int value_size
)
149 if (strncmp(buf
,param
,plen
) != 0) return(0);
151 if ((unsigned char)*buf
>' ') return(0);
152 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
155 printf("SARG: %s %s.\n",text
[139],param
);
161 for (i
=0 ; i
<value_size
&& *buf
&& *buf
!='\"' ; i
++) {
167 printf("SARG: Missing double quote after parameter %s or value is more than %d bytes long.\n",param
,value_size
);
174 static int getparam_2words(const char *param
,char *buf
,char *word1
,int word1_size
,char *word2
,int word2_size
)
180 if (strncmp(buf
,param
,plen
) != 0) return(0);
182 if ((unsigned char)*buf
>' ') return(0);
183 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
185 for (i
=0 ; i
<word1_size
&& *buf
&& (unsigned char)*buf
>' ' ; i
++)
188 printf("SARG: The first word of parameter %s is more than %d bytes long.\n",param
,word1_size
-1);
192 printf("SARG: Missing second word for parameter %s.\n",param
);
197 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
199 for (i
=0 ; i
<word2_size
&& *buf
&& (unsigned char)*buf
>' ' ; i
++)
202 printf("SARG: The second word of parameter %s is more than %d bytes long.\n",param
,word2_size
-1);
212 static int getparam_int(const char *param
,char *buf
,int *value
)
218 if (strncmp(buf
,param
,plen
) != 0) return(0);
220 if ((unsigned char)*buf
>' ') return(0);
221 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
224 if (sscanf(buf
,"%d%n",value
,&next
) != 1 || (unsigned char)buf
[next
] > ' ') {
225 printf("SARG: Maybe you have a broken record or garbage in %s parameter.\n",param
);
231 static int getparam_bool(const char *param
,char *buf
,int *value
)
235 const char *bool_str
="yes,true,on,1";
238 if (strncmp(buf
,param
,plen
) != 0) return(0);
240 if ((unsigned char)*buf
>' ') return(0);
241 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
244 for ( ; *bool_str
; bool_str
+=i
) {
245 for (i
=0 ; bool_str
[i
] && bool_str
[i
]!=',' ; i
++);
246 if (strncasecmp(bool_str
,buf
,i
)==0) {
250 if (bool_str
[i
]==',') i
++;
255 static int getparam_list(const char *param
,struct param_list
*options
,int noptions
,char *buf
,unsigned long int *value
)
262 if (strncmp(buf
,param
,plen
) != 0) return(0);
264 if ((unsigned char)*buf
>' ') return(0);
265 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
270 while (*str
&& (unsigned char)*str
>' ' && *str
!=';') str
++;
273 while (*str
&& ((unsigned char)*str
<=' ' || *str
==';')) str
++;
275 for (i
=0 ; i
<noptions
&& strcasecmp(buf
,options
[i
].name
) ; i
++);
277 fprintf(stderr
,"SARG: Unknown value %s for parameter %s\n",buf
,param
);
280 if ((*value
& options
[i
].exclude
)!=0) {
281 fprintf(stderr
,"SARG: Value %s conflicts with other selected values of parameter %s\n",buf
,param
);
284 *value
|=options
[i
].value
;
290 static void parmtest(char *buf
)
293 struct getwordstruct gwarea
;
295 while (*buf
&& (unsigned char)*buf
<=' ') buf
++;
297 if(*buf
== '#' || *buf
== '\0')
301 printf("SARG: TAG: %s\n",buf
);
303 if (getparam_string("background_color",buf
,BgColor
,sizeof(BgColor
))>0) return;
305 if (getparam_string("text_color",buf
,TxColor
,sizeof(TxColor
))>0) return;
307 if (getparam_string("text_bgcolor",buf
,TxBgColor
,sizeof(TxBgColor
))>0) return;
309 if (getparam_string("title_color",buf
,TiColor
,sizeof(TiColor
))>0) return;
311 if (getparam_string("logo_image",buf
,LogoImage
,sizeof(LogoImage
))>0) return;
313 if (getparam_quoted("logo_text",buf
,LogoText
,sizeof(LogoText
))>0) return;
315 if (getparam_string("logo_text_color",buf
,LogoTextColor
,sizeof(LogoTextColor
))>0) return;
317 if (getparam_string("background_image",buf
,BgImage
,sizeof(BgImage
))>0) return;
319 if (getparam_bool("show_sarg_info",buf
,&ShowSargInfo
)>0) return;
321 if (getparam_bool("show_sarg_logo",buf
,&ShowSargLogo
)>0) return;
323 if (getparam_string("font_face",buf
,FontFace
,sizeof(FontFace
))>0) return;
325 if (getparam_string("header_color",buf
,HeaderColor
,sizeof(HeaderColor
))>0) return;
327 if (getparam_string("header_bgcolor",buf
,HeaderBgColor
,sizeof(HeaderBgColor
))>0) return;
329 if (getparam_string("font_size",buf
,FontSize
,sizeof(FontSize
))>0) return;
331 if (getparam_string("header_font_size",buf
,HeaderFontSize
,sizeof(HeaderFontSize
))>0) return;
333 if (getparam_string("title_font_size",buf
,TitleFontSize
,sizeof(TitleFontSize
))>0) return;
335 if (getparam_2words("image_size",buf
,Width
,sizeof(Width
),Height
,sizeof(Height
))>0) return;
337 if (getparam_quoted("title",buf
,Title
,sizeof(Title
))>0) return;
339 if (getparam_bool("resolve_ip",buf
,&Ip2Name
)>0) return;
341 if (getparam_bool("user_ip",buf
,&UserIp
)>0) return;
343 if (getparam_string("max_elapsed",buf
,MaxElapsed
,sizeof(MaxElapsed
))>0) return;
345 if (is_param("date_format",buf
)) {
346 getword_start(&gwarea
,buf
);
347 if (getword_multisep(wbuf
,sizeof(wbuf
),&gwarea
,' ')<0) {
348 printf("SARG: Maybe you have a broken record or garbage in date_format parameter.\n");
351 strncpy(DateFormat
,gwarea
.current
,1);
356 if (is_param("hours",buf
)) {
357 if( getnumlist( buf
, &hours
, 24, 24 ) ) {
358 fprintf( stderr
, "Error: Invalid syntax in hours tag!\n" );
363 if (is_param("weekdays",buf
)) {
364 if( getnumlist( buf
, &weekdays
, 7, 7 ) ) {
365 fprintf( stderr
, "Error: Invalid syntax in weekdays tag!\n" );
370 if (getparam_2words("topuser_sort_field",buf
,TopuserSortField
,sizeof(TopuserSortField
),TopuserSortOrder
,sizeof(TopuserSortOrder
))>0) return;
372 if (getparam_2words("user_sort_field",buf
,UserSortField
,sizeof(UserSortField
),UserSortOrder
,sizeof(UserSortOrder
))>0) return;
374 if (is_param("access_log",buf
)>0) {
375 if (AccessLogFromCmdLine
==0) {
376 if (NAccessLog
>=MAXLOGS
) {
377 fprintf(stderr
,"SARG: Too many log files.\n");
380 getparam_string("access_log",buf
,AccessLog
[NAccessLog
],MAXLEN
);
386 if (getparam_string("useragent_log",buf
,UserAgentLog
,sizeof(UserAgentLog
))>0) return;
388 if (getparam_string("exclude_hosts",buf
,ExcludeHosts
,sizeof(ExcludeHosts
))>0) return;
390 if (getparam_string("exclude_codes",buf
,ExcludeCodes
,sizeof(ExcludeCodes
))>0) return;
392 if (getparam_string("exclude_users",buf
,ExcludeUsers
,sizeof(ExcludeUsers
))>0) return;
394 if (getparam_string("password",buf
,PasswdFile
,sizeof(PasswdFile
))>0) return;
396 if (getparam_string("temporary_dir",buf
,TempDir
,sizeof(TempDir
))>0) return;
398 if (getparam_list("report_type",SET_LIST(report_type_values
),buf
,&ReportType
)>0) return;
400 if (getparam_string("output_dir",buf
,OutputDir
,sizeof(OutputDir
))>0) return;
402 if (getparam_string("output_email",buf
,OutputEmail
,sizeof(OutputEmail
))>0) return;
404 if (getparam_2words("per_user_limit",buf
,PerUserLimitFile
,sizeof(PerUserLimitFile
),wbuf
,sizeof(wbuf
))>0) {
405 PerUserLimit
=atoi(wbuf
);
409 if (getparam_int("lastlog",buf
,&LastLog
)>0) return;
411 if (getparam_bool("remove_temp_files",buf
,&RemoveTempFiles
)>0) return;
413 if (getparam_string("replace_index",buf
,ReplaceIndex
,sizeof(ReplaceIndex
))>0) return;
415 if (getparam_list("index_tree",SET_LIST(index_tree_values
),buf
,&IndexTree
)>0) return;
417 if (getparam_list("index",SET_LIST(index_values
),buf
,&Index
)>0) return;
419 if (getparam_bool("overwrite_report",buf
,&OverwriteReport
)>0) return;
421 if (getparam_string("records_without_userid",buf
,RecordsWithoutUser
,sizeof(RecordsWithoutUser
))>0) return;
423 if (getparam_bool("use_comma",buf
,&UseComma
)>0) return;
425 if (getparam_string("mail_utility",buf
,MailUtility
,sizeof(MailUtility
))>0) return;
427 if (getparam_string("topsites_num",buf
,TopSitesNum
,sizeof(TopSitesNum
))>0) return;
429 if (getparam_int("topuser_num",buf
,&TopUsersNum
)>0) return;
431 if (getparam_string("usertab",buf
,UserTabFile
,sizeof(UserTabFile
))>0) return;
433 if (getparam_string("index_sort_order",buf
,IndexSortOrder
,sizeof(IndexSortOrder
))>0) return;
435 if (getparam_2words("topsites_sort_order",buf
,TopsitesSortField
,sizeof(TopsitesSortField
),TopsitesSortType
,sizeof(TopsitesSortType
))>0) return;
437 if (getparam_bool("long_url",buf
,&LongUrl
)>0) return;
439 if (getparam_string("language",buf
,language
,sizeof(language
))>0) return;
441 if (getparam_string("dansguardian_conf",buf
,DansGuardianConf
,sizeof(DansGuardianConf
))>0) return;
443 if (getparam_string("squidguard_conf",buf
,SquidGuardConf
,sizeof(SquidGuardConf
))>0) return;
445 if (getparam_string("date_time_by",buf
,datetimeby
,sizeof(datetimeby
))>0) return;
447 if (getparam_string("charset",buf
,CharSet
,sizeof(CharSet
))>0) {
452 if (getparam_quoted("user_invalid_char",buf
,UserInvalidChar
,sizeof(UserInvalidChar
))>0) return;
454 if (getparam_quoted("include_users",buf
,IncludeUsers
+1,sizeof(IncludeUsers
)-2)>0) {
456 strcat(IncludeUsers
,":");
460 if (getparam_quoted("exclude_string",buf
,ExcludeString
,sizeof(ExcludeString
))>0) return;
462 if (getparam_bool("privacy",buf
,&Privacy
)>0) return;
464 if (getparam_quoted("privacy_string",buf
,PrivacyString
,sizeof(PrivacyString
))>0) return;
466 if (getparam_string("privacy_string_color",buf
,PrivacyStringColor
,sizeof(PrivacyStringColor
))>0) return;
468 if (getparam_bool("show_successful_message",buf
,&SuccessfulMsg
)>0) return;
470 if (getparam_bool("show_read_statistics",buf
,&ShowReadStatistics
)>0) return;
472 if (getparam_list("topuser_fields",SET_LIST(topuserfields_values
),buf
,&TopUserFields
)>0) return;
474 if (getparam_bool("bytes_in_sites_users_report",buf
,&BytesInSitesUsersReport
)>0) return;
476 if (getparam_list("user_report_fields",SET_LIST(userreportfields_values
),buf
,&UserReportFields
)>0) return;
478 if (getparam_string("datafile",buf
,DataFile
,sizeof(DataFile
))>0) return;
480 if (getparam_quoted("datafile_delimiter",buf
,DataFileDelimiter
,sizeof(DataFileDelimiter
))>0) return;
482 if (getparam_list("datafile_fields",SET_LIST(data_field_values
),buf
,&DataFileFields
)>0) return;
484 if (getparam_string("datafile_url",buf
,DataFileUrl
,sizeof(DataFileUrl
))>0) return;
486 if (getparam_string("parsed_output_log",buf
,ParsedOutputLog
,sizeof(ParsedOutputLog
))>0) return;
488 if (getparam_string("parsed_output_log_compress",buf
,ParsedOutputLogCompress
,sizeof(ParsedOutputLogCompress
))>0) return;
490 if (getparam_string("displayed_values",buf
,DisplayedValues
,sizeof(DisplayedValues
))>0) return;
492 if (getparam_int("authfail_report_limit",buf
,&AuthfailReportLimit
)>0) return;
494 if (getparam_int("denied_report_limit",buf
,&DeniedReportLimit
)>0) return;
496 if (getparam_int("siteusers_report_limit",buf
,&SiteUsersReportLimit
)>0) return;
498 if (getparam_int("dansguardian_report_limit",buf
,&DansGuardianReportLimit
)>0) return;
500 if (getparam_int("squidguard_report_limit",buf
,&SquidGuardReportLimit
)>0) return;
502 if (getparam_int("user_report_limit",buf
,&UserReportLimit
)>0) return;
504 if (getparam_int("download_report_limit",buf
,&DownloadReportLimit
)>0) return;
506 if (getparam_string("www_document_root",buf
,wwwDocumentRoot
,sizeof(wwwDocumentRoot
))>0) return;
508 if (getparam_string("block_it",buf
,BlockIt
,sizeof(BlockIt
))>0) return;
510 if (getparam_string("external_css_file",buf
,ExternalCSSFile
,sizeof(ExternalCSSFile
))>0) return;
512 if (getparam_bool("user_authentication",buf
,&UserAuthentication
)>0) return;
514 if (getparam_string("AuthUserFile",buf
,AuthUserFile
,sizeof(AuthUserFile
))>0) return;
516 if (getparam_string("AuthName",buf
,AuthName
,sizeof(AuthName
))>0) return;
518 if (getparam_string("AuthType",buf
,AuthType
,sizeof(AuthType
))>0) return;
520 if (getparam_string("Require",buf
,Require
,sizeof(Require
))>0) return;
522 if (is_param("download_suffix",buf
)) {
525 getparam_quoted("download_suffix",buf
,warea
,sizeof(warea
));
526 set_download_suffix(warea
);
530 if (getparam_bool("graphs",buf
,&Graphs
)>0) return;
532 if (getparam_string("graph_days_bytes_bar_color",buf
,GraphDaysBytesBarColor
,sizeof(GraphDaysBytesBarColor
))>0) return;
534 if (getparam_string("squidguard_log_format",buf
,SquidGuardLogFormat
,sizeof(SquidGuardLogFormat
))>0) return;
536 if (getparam_bool("squidguard_ignore_date",buf
,&SquidguardIgnoreDate
)>0) return;
538 if (getparam_bool("dansguardian_ignore_date",buf
,&DansguardianIgnoreDate
)>0) return;
540 if (getparam_string("ulimit",buf
,Ulimit
,sizeof(Ulimit
))>0) return;
542 if (getparam_string("ntlm_user_format",buf
,NtlmUserFormat
,sizeof(NtlmUserFormat
))>0) return;
544 if (getparam_string("realtime_types",buf
,RealtimeTypes
,sizeof(RealtimeTypes
))>0) return;
546 if (getparam_string("realtime_unauthenticated_records",buf
,RealtimeUnauthRec
,sizeof(RealtimeUnauthRec
))>0) return;
548 if (getparam_int("realtime_refresh_time",buf
,&realtime_refresh
)>0) return;
550 if (getparam_int("realtime_access_log_lines",buf
,&realtime_access_log_lines
)>0) return;
552 if (getparam_string("LDAPHost",buf
,LDAPHost
,sizeof(LDAPHost
))>0) return;
554 if (getparam_int("LDAPPort",buf
,&LDAPPort
)>0) return;
556 if (getparam_int("LDAPProtocolVersion",buf
,&LDAPProtocolVersion
)>0) return;
558 if (getparam_string("LDAPBindDN",buf
,LDAPBindDN
,sizeof(LDAPBindDN
))>0) return;
560 if (getparam_string("LDAPBindPW",buf
,LDAPBindPW
,sizeof(LDAPBindPW
))>0) return;
562 if (getparam_string("LDAPBaseSearch",buf
,LDAPBaseSearch
,sizeof(LDAPBaseSearch
))>0) return;
564 if (getparam_string("LDAPFilterSearch",buf
,LDAPFilterSearch
,sizeof(LDAPFilterSearch
))>0) return;
566 if (getparam_string("LDAPTargetAttr",buf
,LDAPTargetAttr
,sizeof(LDAPTargetAttr
))>0) return;
568 if(strstr(buf
,"squid24") != 0) {
573 if(strstr(buf
,"byte_cost") != 0) {
574 getword_start(&gwarea
,buf
);
575 if (getword_multisep(wbuf
,sizeof(wbuf
),&gwarea
,' ')<0) {
576 printf("SARG: Maybe you have a broken record or garbage in byte_cost parameter.\n");
579 cost
=atol(gwarea
.current
);
580 if (getword_multisep(wbuf
,sizeof(wbuf
),&gwarea
,' ')<0) {
581 printf("SARG: Maybe you have a broken record or garbage in byte_cost parameter.\n");
584 nocost
=my_atoll(gwarea
.current
);
588 printf("SARG: %s %s\n",text
[140],buf
);
598 debuga("Loading configuration from: %s",ConfigFile
);
600 if ((fp_in
= fopen(ConfigFile
, "r")) == NULL
) {
601 fprintf(stderr
, "SARG: (getconf) Cannot open file: %s\n",ConfigFile
);
605 while (fgets(buf
, sizeof(buf
), fp_in
) != NULL
) {
609 printf("SYSCONFDIR %s\n",buf
);
616 language_load(language
);