]> git.ipfire.org Git - thirdparty/sarg.git/blame - util.c
Check the return code of every opendir.
[thirdparty/sarg.git] / util.c
CommitLineData
25697a35 1/*
94ff9470 2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
1164c474 3 * 1998, 2010
25697a35
GS
4 *
5 * SARG donations:
6 * please look at http://sarg.sourceforge.net/donations.php
1164c474
FM
7 * Support:
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
25697a35
GS
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// #define LEGACY_MY_ATOLL
28// #define LEGACY_TESTVALIDUSERCHAR
29
30#include "include/conf.h"
5f3cfd1d 31#include "include/defs.h"
25697a35 32
e6414a9d 33#if defined(HAVE_BACKTRACE)
ac422f9b 34#define USE_GETWORD_BACKTRACE 1
e6414a9d
FM
35#else
36#define USE_GETWORD_BACKTRACE 0
37#endif
38
25697a35 39static char mtab1[12][4]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
48864d28
FM
40
41//! The list of the HTTP codes to exclude from the report.
42static char *excludecode=NULL;
25697a35 43
d6e703cc
FM
44/*void fgetword(char *word, char *line, int stop)
45{
46 //VARIANT N1
47 int x;
2357ef77 48
d6e703cc
FM
49 for (x=0; line[x] && (line[x] != stop); x++) word[x] = line[x];
50 word[x] = '\0';
51
52 //VARIANT N2
53 char *tchar;
54 int difflen;
2357ef77 55
d6e703cc
FM
56 tchar = strchr(line, stop);
57 if (tchar == NULL) strcpy(word, line);
58 else
59 {
60 difflen = tchar - line;
61 strncpy(word, line, difflen);
62 word[difflen] = '\0';
63 }
64}*/
65
e6414a9d
FM
66#if USE_GETWORD_BACKTRACE
67static void getword_backtrace(void)
68{
69 void *buffer[5];
70 int i, n;
71 char **calls;
72
73 n=backtrace(buffer,sizeof(buffer)/sizeof(buffer[0]));
74 if (n<=0) return;
75 calls=backtrace_symbols(buffer,n);
76 if (calls) {
10210234 77 debuga(_("getword backtrace:\n"));
e6414a9d
FM
78 for (i=0 ; i<n ; i++) {
79 fprintf(stderr,"SARG: %d:%s\n",i+1,calls[i]);
80 }
81 free(calls);
82 }
83}
84#endif //USE_GETWORD_BACKTRACE
85
9c7c6346 86void getword_start(struct getwordstruct *gwarea, const char *line)
25697a35 87{
9c7c6346
FM
88 gwarea->beginning=line;
89 gwarea->current=line;
e5b2c6f0 90 gwarea->modified=0;
9c7c6346 91}
25697a35 92
9c7c6346 93void getword_restart(struct getwordstruct *gwarea)
25697a35 94{
e5b2c6f0 95 if (gwarea->modified) {
10210234 96 debuga(_("Cannot parse again the line as it was modified\n"));
06b39c87 97 exit(EXIT_FAILURE);
e5b2c6f0 98 }
9c7c6346
FM
99 gwarea->current=gwarea->beginning;
100}
25697a35 101
06b39c87 102int getword(char *word, int limit, struct getwordstruct *gwarea, char stop)
9c7c6346
FM
103{
104 int x;
25697a35 105
9c7c6346 106 for(x=0;((gwarea->current[x]) && (gwarea->current[x] != stop ));x++) {
4bcb77cf
FM
107 if(x>=limit) {
108 printf("SARG: getword loop detected after %d bytes.\n",x);
9c7c6346
FM
109 printf("SARG: Line=\"%s\"\n",gwarea->beginning);
110 printf("SARG: Record=\"%s\"\n",gwarea->current);
4bcb77cf
FM
111 printf("SARG: searching for \'x%x\'\n",stop);
112 //printf("SARG: Maybe you have a broken record or garbage in your access.log file.\n");
120d768c 113 word[(limit>0) ? limit-1 : 0]='\0';
e6414a9d
FM
114#if USE_GETWORD_BACKTRACE
115 getword_backtrace();
116#endif
4bcb77cf
FM
117 return(-1);
118 }
9c7c6346 119 word[x] = gwarea->current[x];
25697a35
GS
120 }
121
122 word[x] = '\0';
9c7c6346
FM
123 if (gwarea->current[x]) ++x;
124 gwarea->current+=x;
4bcb77cf 125 return(0);
25697a35
GS
126}
127
06b39c87 128int getword_limit(char *word, int limit, struct getwordstruct *gwarea, char stop)
e5b2c6f0
FM
129{
130 int x;
131
132 limit--;
133 for(x=0; x<limit && gwarea->current[x] && gwarea->current[x] != stop ;x++) {
134 word[x] = gwarea->current[x];
135 }
136 word[x] = '\0';
137 gwarea->current+=x;
138 while (*gwarea->current && *gwarea->current != stop) gwarea->current++;
139 if (*gwarea->current) ++gwarea->current;
140 return(0);
141}
142
06b39c87 143int getword_multisep(char *word, int limit, struct getwordstruct *gwarea, char stop)
4bcb77cf 144{
9c7c6346 145 int x;
4bcb77cf 146
9c7c6346 147 for(x=0;((gwarea->current[x]) && (gwarea->current[x] != stop ));x++) {
4bcb77cf
FM
148 if(x>=limit) {
149 printf("SARG: getword_multisep loop detected.\n");
9c7c6346
FM
150 printf("SARG: Line=\"%s\"\n",gwarea->beginning);
151 printf("SARG: Record=\"%s\"\n",gwarea->current);
4bcb77cf
FM
152 printf("SARG: searching for \'x%x\'\n",stop);
153 //printf("SARG: Maybe you have a broken record or garbage in your access.log file.\n");
154 if (limit>0) word[limit-1]='\0';
e6414a9d
FM
155#if USE_GETWORD_BACKTRACE
156 getword_backtrace();
157#endif
06b39c87 158 //exit(EXIT_FAILURE);
4bcb77cf
FM
159 return(-1);
160 }
9c7c6346 161 word[x] = gwarea->current[x];
4bcb77cf
FM
162 }
163
164 word[x] = '\0';
9c7c6346
FM
165 while (gwarea->current[x] && gwarea->current[x]==stop) ++x;
166 gwarea->current+=x;
4bcb77cf
FM
167 return(0);
168}
169
06b39c87 170int getword_skip(int limit, struct getwordstruct *gwarea, char stop)
076cbab8 171{
9c7c6346 172 int x;
076cbab8 173
9c7c6346 174 for(x=0;(gwarea->current[x] && (gwarea->current[x] != stop ));x++) {
076cbab8
FM
175 if(x>=limit) {
176 printf("SARG: getword_skip loop detected after %d bytes.\n",x);
9c7c6346
FM
177 printf("SARG: Line=\"%s\"\n",gwarea->beginning);
178 printf("SARG: Record=\"%s\"\n",gwarea->current);
076cbab8
FM
179 printf("SARG: searching for \'x%x\'\n",stop);
180 //printf("SARG: Maybe you have a broken record or garbage in your access.log file.\n");
e6414a9d
FM
181#if USE_GETWORD_BACKTRACE
182 getword_backtrace();
183#endif
076cbab8
FM
184 return(-1);
185 }
186 }
187
9c7c6346
FM
188 if (gwarea->current[x]) ++x;
189 gwarea->current+=x;
076cbab8
FM
190 return(0);
191}
192
06b39c87 193int getword_atoll(long long int *number, struct getwordstruct *gwarea, char stop)
25697a35 194{
0a4e18e1 195 int x;
e6414a9d 196 int sign=+1;
25697a35 197
e6414a9d
FM
198 if (gwarea->current[0] == '-') {
199 gwarea->current++;
200 sign=-1;
201 } else if (gwarea->current[0] == '+') {
202 gwarea->current++;
203 }
0a4e18e1
FM
204 *number=0LL;
205 for(x=0;isdigit(gwarea->current[x]);x++) {
206 *number=(*number * 10) + gwarea->current[x]-'0';
207 }
208 if(gwarea->current[x] && gwarea->current[x]!=stop) {
209 printf("SARG: getword_atoll loop detected after %d bytes.\n",x);
210 printf("SARG: Line=\"%s\"\n",gwarea->beginning);
211 printf("SARG: Record=\"%s\"\n",gwarea->current);
212 printf("SARG: searching for \'x%x\'\n",stop);
213 //printf("SARG: Maybe you have a broken record or garbage in your access.log file.\n");
e6414a9d
FM
214#if USE_GETWORD_BACKTRACE
215 getword_backtrace();
216#endif
0a4e18e1
FM
217 return(-1);
218 }
e6414a9d 219 *number*=sign;
25697a35 220
0a4e18e1
FM
221 if (gwarea->current[x]) ++x;
222 gwarea->current+=x;
223 return(0);
224}
25697a35 225
25697a35 226
06b39c87 227int getword_ptr(char *orig_line,char **word, struct getwordstruct *gwarea, char stop)
e5b2c6f0
FM
228{
229 /*!
230 \note Why pass the original buffer to the function ? Because we must modify it to
231 insert the terminating ASCII zero for the word we return and that's not compatible
232 with getword_restart(). Moreover, getword_start() sometime works on constant strings
233 so this function require the original buffer to detect any missuse.
234 */
235 int x;
236 int sep;
237 int start;
238
239 if (orig_line && orig_line!=gwarea->beginning) {
10210234 240 debuga(_("Invalid buffer passed to getword_ptr\n"));
e5b2c6f0
FM
241 return(-1);
242 }
243
244 start=(gwarea->current-gwarea->beginning);
245 if (word && orig_line) *word=orig_line+start;
246 for(x=0;((gwarea->current[x]) && (gwarea->current[x] != stop ));x++);
247 sep=(gwarea->current[x]!='\0');
248 if (word && orig_line) orig_line[start+x] = '\0';
249 if (sep) ++x;
250 gwarea->current+=x;
251 gwarea->modified=1;
252 return(0);
253}
254
48864d28 255#define MAXLLL 30 //!< Maximum number of digits in long long (a guess).
25697a35
GS
256long long int my_atoll (const char *nptr)
257{
0a4e18e1 258 long long int returnval=0LL;
25697a35
GS
259 int max_digits = MAXLLL ;
260
261 // Soak up all the white space
0a4e18e1
FM
262 while (isspace( *nptr )) {
263 nptr++;
264 }
25697a35
GS
265
266 //For each character left to right
267 //change the character to a single digit
268 //multiply what we had before by 10 and add the new digit
269
0a4e18e1 270 while (--max_digits && isdigit( *nptr ))
25697a35 271 {
0a4e18e1 272 returnval = ( returnval * 10 ) + ( *nptr++ - '0' ) ;
25697a35
GS
273 }
274
275 return returnval;
0a4e18e1 276}
25697a35 277
e6414a9d 278int is_absolute(const char *path)
6798f0a7
FM
279{
280 if (*path=='/') return(1);
281#ifdef WINDOWS
282 if (isalpha(path[0]) && path[1]==':') return(1);
283#endif
284 return(0);
285}
25697a35 286
32e71fa4 287void my_mkdir(const char *name)
25697a35 288{
a1de61fe
FM
289 char w0[MAXLEN];
290 int i;
291 int chars;
25697a35 292
6798f0a7 293 if(!is_absolute(name)) {
fcdc0918
FM
294 debuga(_("Invalid path (%s). Please, use absolute paths only.\n"),name);
295 debuga(_("process aborted.\n"));
06b39c87 296 exit(EXIT_FAILURE);
25697a35
GS
297 }
298
a1de61fe
FM
299 chars=0;
300 for (i=0 ; name[i] ; i++) {
301 if (i>=sizeof(w0)) {
fcdc0918 302 debuga(_("directory name too long: %s\n"),name);
06b39c87 303 exit(EXIT_FAILURE);
4bcb77cf 304 }
a1de61fe
FM
305 if (chars>0 && name[i] == '/') {
306 w0[i] = '\0';
307 if(access(w0, R_OK) != 0) {
308 if(mkdir(w0,0755)) {
fcdc0918
FM
309 debuga(_("mkdir %s %s\n"),w0,strerror(errno));
310 debuga(_("process aborted.\n"));
06b39c87 311 exit(EXIT_FAILURE);
a1de61fe 312 }
25697a35
GS
313 }
314 }
a1de61fe
FM
315 if (name[i] != '/') chars++;
316 w0[i] = name[i];
25697a35 317 }
a1de61fe
FM
318
319 if(access(name, R_OK) != 0) {
320 if(mkdir(name,0755)) {
fcdc0918
FM
321 debuga(_("mkdir %s %s\n"),name,strerror(errno));
322 debuga(_("process aborted.\n"));
06b39c87 323 exit(EXIT_FAILURE);
25697a35
GS
324 }
325 }
326}
327
328
e5b2c6f0 329void my_lltoa(unsigned long long int n, char *s, int ssize, int len)
25697a35 330{
0a4e18e1
FM
331 int i;
332 int slen = 0;
333 int j;
334 char c;
2357ef77 335
e5b2c6f0
FM
336 ssize--;
337 if (len>ssize) {
fcdc0918 338 debuga(_("The requested number of digits passed to my_lltoa (%d) is bigger than the output buffer size (%d)\n"),len,ssize);
e5b2c6f0
FM
339 abort();
340 }
341
0a4e18e1
FM
342 do {
343 s[slen++] = (n % 10) + '0';
e5b2c6f0 344 } while ((n /= 10) > 0 && slen<ssize);
0a4e18e1 345 s[slen] = '\0';
2357ef77 346
0a4e18e1
FM
347 for (i = 0, j = slen-1; i<j; i++, j--) {
348 c = s[i];
349 s[i] = s[j];
350 s[j] = c;
351 }
2357ef77 352
0a4e18e1
FM
353 if(len>slen) {
354 i=len-slen;
355 for(j=slen; j>=0; j--)
356 s[j+i]=s[j];
357 for(j=0 ; j<i ; j++)
358 s[j]='0';
359 }
25697a35
GS
360}
361
362
32e71fa4 363void builddia(char *dia, const char *mes, const char *ano, const char *df, char *wdata)
25697a35
GS
364{
365 char ndia[11];
48864d28 366 int nmes;
25697a35
GS
367
368 if(strlen(dia) < 1) return;
369
48864d28
FM
370 for(nmes=0; nmes<12; nmes++) {
371 if(strcmp(mtab1[nmes],mes) == 0) {
25697a35
GS
372 break;
373 }
374 }
48864d28 375 nmes++;
25697a35 376
48864d28 377 snprintf(wdata,9,"%s%02d%s",ano,nmes,dia);
25697a35 378
48864d28
FM
379 if(df[0]!='u')
380 snprintf(ndia,sizeof(ndia),"%s/%02d/%s",dia,nmes,ano);
25697a35 381 else
48864d28 382 snprintf(ndia,sizeof(ndia),"%02d/%s/%s",nmes,dia,ano);
25697a35
GS
383
384 strcpy(dia,ndia);
385
386}
387
388
32e71fa4 389void buildymd(const char *dia, const char *mes, const char *ano, char *wdata)
25697a35 390{
48864d28 391 int nmes;
25697a35 392
48864d28
FM
393 for(nmes=0; nmes<12; nmes++) {
394 if(strcmp(mtab1[nmes],mes) == 0)
395 break;
25697a35
GS
396 }
397
b25b96fe 398 sprintf(wdata,"%04d%02d%02d",atoi(ano),nmes+1,atoi(dia));
25697a35
GS
399
400}
401
402
403void conv_month(char *month)
404{
405 int x;
406
48864d28
FM
407 for(x=0; x<12 && strcmp(mtab1[x],month)!=0; x++);
408 sprintf(month,"%02d",x+1);
25697a35
GS
409}
410
411
412void conv_month_name(char *month)
413{
414 int x;
415
48864d28
FM
416 x=atoi(month);
417 if (x>=1 && x<=12)
418 strcpy(month,mtab1[x-1]);
25697a35
GS
419}
420
421
4bcb77cf 422void name_month(char *month,int month_len)
491b862f
GS
423{
424 int x, z=atoi(month)-1;
425 char m[255];
426 char w[20];
9c7c6346 427 struct getwordstruct gwarea;
491b862f 428
c36c7384 429 strcpy(m,_("January,February,March,April,May,June,July,August,September,October,November,December"));
9c7c6346 430 getword_start(&gwarea,m);
491b862f
GS
431
432 for(x=0; x<z; x++)
9c7c6346 433 if (getword_multisep(w,sizeof(w),&gwarea,',')<0) {
4bcb77cf 434 printf("SARG: Maybe you have a broken record or garbage in the names of the months.\n");
06b39c87 435 exit(EXIT_FAILURE);
4bcb77cf 436 }
9c7c6346 437 if (getword_multisep(month,month_len,&gwarea,',')<0) {
4bcb77cf 438 printf("SARG: Maybe you have a broken record or garbage in the name of the months.\n");
06b39c87 439 exit(EXIT_FAILURE);
4bcb77cf 440 }
491b862f
GS
441}
442
443
32e71fa4 444void fixper(char *tbuf, char *period, const char *duntil)
25697a35 445{
25697a35
GS
446 char warea[50];
447 char dia[5], mes[5], ano[5];
e6414a9d 448 int x;
25697a35
GS
449
450 strncpy(dia,duntil+6,2);
451 dia[2]='\0';
452 strncpy(mes,duntil+4,2);
453 mes[2]='\0';
454 strncpy(ano,duntil,4);
455 ano[4]='\0';
456
48864d28
FM
457 x=atoi(mes);
458 if (x>=1 && x<=12)
459 strcpy(mes,mtab1[x-1]);
25697a35
GS
460
461 if(strcmp(df,"e") == 0)
462 sprintf(warea,"%s%s%s",dia,mes,ano);
e6414a9d 463 else if(strcmp(df,"u") == 0)
6dcb1e18 464 sprintf(warea,"%s%s%s",ano,mes,dia);
e6414a9d
FM
465 else
466 warea[0]='\0';
25697a35 467
d6e703cc 468 strcat(period,warea);
25697a35
GS
469}
470
471
d2fe0c32 472void debuga(const char *msg,...)
25697a35 473{
d2fe0c32 474 va_list ap;
25697a35 475
f2ec8c75 476 fputs(_("SARG: "),stderr);
d2fe0c32
FM
477 va_start(ap,msg);
478 vfprintf(stderr,msg,ap);
479 va_end(ap);
25697a35
GS
480}
481
482
32e71fa4 483void debugaz(const char *head, const char *msg)
25697a35
GS
484{
485 fprintf(stderr, "SARG: (util) %s=%s\n",head, msg);
486
487}
488
489
25697a35 490char *fixnum(long long int value, int n)
25697a35 491{
32e71fa4 492#define MAXLEN_FIXNUM 1024
fabbc7cc 493 char num[MAXLEN_FIXNUM]="";
32e71fa4 494 char buf[MAXLEN_FIXNUM * 2];
25697a35 495 char *pbuf;
32e71fa4 496 static char ret[MAXLEN_FIXNUM * 2];
25697a35 497 char *pret;
25697a35 498 register int i, j, k;
fabbc7cc 499 int numlen;
25697a35 500 static char abbrev[30];
2357ef77 501
e5b2c6f0 502 my_lltoa(value, num, sizeof(num), 0);
25697a35
GS
503
504 if(strcmp(DisplayedValues,"abbreviation") == 0) {
fabbc7cc
FM
505 numlen = strlen(num);
506 if(numlen <= 3)
25697a35 507 sprintf(abbrev,"%s",num);
fabbc7cc 508 if(numlen == 4 || numlen == 7 || numlen == 10 || numlen == 13) {
25697a35
GS
509 snprintf(abbrev,2,"%s",num);
510 strncat(abbrev,".",1);
511 strncat(abbrev,num+1,2);
512 if(!n) return(abbrev);
fabbc7cc 513 if(numlen == 4)
25697a35 514 strncat(abbrev,"K",1);
fabbc7cc 515 else if(numlen == 7)
25697a35 516 strncat(abbrev,"M",1);
fabbc7cc 517 else if(numlen == 10)
25697a35 518 strncat(abbrev,"G",1);
fabbc7cc 519 else if(numlen == 13)
25697a35
GS
520 strncat(abbrev,"T",1);
521 }
fabbc7cc 522 if(numlen == 5 || numlen == 8 || numlen == 11 || numlen == 14) {
25697a35
GS
523 snprintf(abbrev,3,"%s",num);
524 strncat(abbrev,".",1);
525 strncat(abbrev,num+2,2);
526 if(!n) return(abbrev);
fabbc7cc 527 if(numlen == 5)
25697a35 528 strncat(abbrev,"K",1);
fabbc7cc 529 else if(numlen == 8)
25697a35 530 strncat(abbrev,"M",1);
fabbc7cc 531 else if(numlen == 11)
25697a35 532 strncat(abbrev,"G",1);
fabbc7cc 533 else if(numlen == 14)
25697a35
GS
534 strncat(abbrev,"T",1);
535 }
fabbc7cc 536 if(numlen == 6 || numlen == 9 || numlen == 12 || numlen == 15) {
25697a35
GS
537 snprintf(abbrev,4,"%s",num);
538 strncat(abbrev,".",1);
539 strncat(abbrev,num+3,2);
540 if(!n) return(abbrev);
fabbc7cc 541 if(numlen == 6)
25697a35 542 strncat(abbrev,"K",1);
fabbc7cc 543 else if(numlen == 9)
25697a35 544 strncat(abbrev,"M",1);
fabbc7cc 545 else if(numlen == 12)
25697a35 546 strncat(abbrev,"G",1);
fabbc7cc 547 else if(numlen == 15)
25697a35
GS
548 strncat(abbrev,"T",1);
549 }
550
551 return(abbrev);
552 }
553
32e71fa4 554 bzero(buf, MAXLEN_FIXNUM*2);
25697a35
GS
555
556 pbuf = buf;
557 pret = ret;
558 k = 0;
559
560 for ( i = strlen(num) - 1, j = 0 ; i > -1; i--) {
561 if ( k == 2 && i != 0 ) {
562 k = 0;
563 pbuf[j++] = num[i];
e6414a9d 564 pbuf[j++] = (UseComma) ? ',' : '.';
25697a35
GS
565 continue;
566 }
567 pbuf[j] = num[i];
568 j++;
569 k++;
570 }
571
572 pret[0]='\0';
573
574 for ( i = strlen(pbuf) - 1, j = 0 ; i > -1; i--, j++)
575 pret[j] = pbuf[i];
576
48864d28 577 pret[j] = '\0';
25697a35 578
48864d28 579 return pret;
25697a35
GS
580}
581
582
d6e703cc 583char *fixnum2(long long int value, int n)
d6e703cc 584{
32e71fa4
FM
585#define MAXLEN_FIXNUM2 1024
586 char num[MAXLEN_FIXNUM2];
587 char buf[MAXLEN_FIXNUM2 * 2];
d6e703cc 588 char *pbuf;
32e71fa4 589 static char ret[MAXLEN_FIXNUM2 * 2];
d6e703cc
FM
590 char *pret;
591 register int i, j, k;
2357ef77 592
e5b2c6f0 593 my_lltoa(value, num, sizeof(num), 0);
32e71fa4 594 bzero(buf, MAXLEN_FIXNUM2*2);
d6e703cc
FM
595
596 pbuf = buf;
597 pret = ret;
598 k = 0;
599
600 for ( i = strlen(num) - 1, j = 0 ; i > -1; i--) {
601 if ( k == 2 && i != 0 ) {
602 k = 0;
603 pbuf[j++] = num[i];
e6414a9d 604 pbuf[j++] = (UseComma) ? ',' : '.';
d6e703cc
FM
605 continue;
606 }
607 pbuf[j] = num[i];
608 j++;
609 k++;
610 }
611
612 pret[0]='\0';
613
614 for ( i = strlen(pbuf) - 1, j = 0 ; i > -1; i--, j++)
615 pret[j] = pbuf[i];
616
32e71fa4 617 pret[j] = '\0';
d6e703cc 618
32e71fa4 619 return pret;
d6e703cc
FM
620}
621
622
623
25697a35
GS
624void buildhref(char * href)
625{
626 char whref[MAXLEN];
627
628 if(strcmp(href,"./") == 0){
629 href[0]='\0';
630 strcat(href,"<a href='");
631 return;
632 }
633
634 href[strlen(href)-1]='\0';
635 sprintf(whref,"%s",strrchr(href,'/'));
636
637 strcpy(href,"<a href='");
638 strcat(href,whref);
639 strcat(href,"/");
640
641 return;
642
643}
644
645
646char *buildtime(long long int elap)
647{
648
649 int num = elap / 1000;
650 int hor = 0;
651 int min = 0;
652 int sec = 0;
653 static char buf[12];
654
655 buf[0]='\0';
656
657 hor=num / 3600;
658 min=(num % 3600) / 60;
659 sec=num % 60;
660 sprintf(buf,"%02d:%02d:%02d",hor,min,sec);
661
662 return(buf);
663
664}
665
666
32e71fa4 667void obtdate(const char *dirname, const char *name, char *data)
25697a35
GS
668{
669
670 FILE *fp_in;
671 char wdir[MAXLEN];
672
d6e703cc 673 sprintf(wdir,"%s%s/sarg-date",dirname,name);
6798f0a7 674 if ((fp_in = fopen(wdir, "rt")) == 0) {
d6e703cc 675 sprintf(wdir,"%s%s/date",dirname,name);
6798f0a7 676 if ((fp_in = fopen(wdir, "rt")) == 0) {
d6e703cc
FM
677 data[0]='\0';
678 return;
679 }
25697a35
GS
680 }
681
05b90947 682 if (!fgets(data,80,fp_in)) {
d5d021c5 683 debuga(_("Failed to read the date in %s\n"),wdir);
06b39c87 684 exit(EXIT_FAILURE);
05b90947 685 }
25697a35 686 fclose(fp_in);
05b90947 687 fixendofline(data);
25697a35
GS
688
689 return;
690
691}
692
693
a1de61fe 694void formatdate(char *date,int date_size,int year,int month,int day,int hour,int minute,int second,int dst)
9e41ca7e
FM
695{
696 struct tm ltm;
fabbc7cc
FM
697 time_t unixtime;
698 struct tm *fulltm;
9e41ca7e
FM
699
700 memset(&ltm,0,sizeof(ltm));
a1de61fe
FM
701 if (year>=1900) ltm.tm_year=year-1900;
702 if (month>=1 && month<=12) ltm.tm_mon=month-1;
703 if (day>=1 && day<=31) ltm.tm_mday=day;
704 if (hour>=0 && hour<24) ltm.tm_hour=hour;
705 if (minute>=0 && minute<60) ltm.tm_min=minute;
706 if (second>=0 && second<60) ltm.tm_sec=second;
707 ltm.tm_isdst=dst;
fabbc7cc
FM
708 unixtime=mktime(&ltm); //fill the missing entries
709 fulltm=localtime(&unixtime);
710 //strftime(date,date_size,"%a %b %d %H:%M:%S %Z %Y",fulltm);
711 strftime(date,date_size,"%c",fulltm);
9e41ca7e
FM
712}
713
714
9426efec
FM
715time_t computedate(const char *year,const char *month,const char *day)
716{
717 struct tm ltm;
718 int y,m,d;
719
720 y=atoi(year);
721 for(m=0; m<12 && strcmp(mtab1[m],month)!=0; m++);
722 d=atoi(day);
723
724 memset(&ltm,0,sizeof(ltm));
725 ltm.tm_year=y-1900;
726 ltm.tm_mon=m;
727 ltm.tm_mday=d;
728 ltm.tm_hour=12; //be sure to cope with dst
729
730 return(mktime(&ltm));
731}
732
733
d25d4e6a 734int obtuser(const char *dirname, const char *name)
25697a35
GS
735{
736
737 FILE *fp_in;
738 char wdir[MAXLEN];
d25d4e6a
FM
739 char tuser[20];
740 int nuser;
25697a35 741
d6e703cc 742 sprintf(wdir,"%s%s/sarg-users",dirname,name);
2357ef77 743 if((fp_in=fopen(wdir,"r"))==NULL) {
d6e703cc 744 sprintf(wdir,"%s%s/users",dirname,name);
2357ef77 745 if((fp_in=fopen(wdir,"r"))==NULL) {
d25d4e6a 746 return(0);
d6e703cc 747 }
25697a35
GS
748 }
749
d25d4e6a 750 if (!fgets(tuser,sizeof(tuser),fp_in)) {
10210234 751 debuga(_("Failed to read the number of users in %s\n"),wdir);
06b39c87 752 exit(EXIT_FAILURE);
05b90947 753 }
25697a35 754 fclose(fp_in);
d25d4e6a 755 nuser=atoi(tuser);
25697a35 756
d25d4e6a 757 return(nuser);
25697a35
GS
758}
759
760
d25d4e6a 761void obttotal(const char *dirname, const char *name, char *tbytes, int nuser, char *media)
25697a35 762{
25697a35 763 FILE *fp_in;
2240dcea 764 char *buf;
25697a35 765 char wdir[MAXLEN];
2240dcea 766 char user[MAX_USER_LEN];
0511cf2d 767 char sep;
25697a35 768 long long int med=0;
fabbc7cc 769 long long int twork=0;
9c7c6346 770 struct getwordstruct gwarea;
afaa3b67 771 longline line;
25697a35 772
0511cf2d
FM
773 twork=0;
774 tbytes[0]='\0';
775 media[0]='\0';
25697a35 776
d6e703cc 777 sprintf(wdir,"%s%s/sarg-general",dirname,name);
25697a35 778 if ((fp_in = fopen(wdir, "r")) == 0) {
d6e703cc
FM
779 sprintf(wdir,"%s%s/general",dirname,name);
780 if ((fp_in = fopen(wdir, "r")) == 0) {
d6e703cc
FM
781 return;
782 }
25697a35
GS
783 }
784
afaa3b67 785 if ((line=longline_create())==NULL) {
10210234 786 debuga(_("Not enough memory to read the file %s\n"),wdir);
06b39c87 787 exit(EXIT_FAILURE);
2240dcea
FM
788 }
789
afaa3b67 790 while((buf=longline_read(fp_in,line))!=NULL) {
0511cf2d
FM
791 if (strncmp(buf,"TOTAL\t",6) == 0)
792 sep='\t'; //new file
793 else if (strncmp(buf,"TOTAL ",6) == 0)
794 sep=' '; //old file
795 else
796 continue;
9c7c6346 797 getword_start(&gwarea,buf);
2240dcea 798 if (getword(user,sizeof(user),&gwarea,sep)<0) {
10210234 799 debuga(_("There is a invalid user in file %s\n"),wdir);
06b39c87 800 exit(EXIT_FAILURE);
4bcb77cf 801 }
ab6fadd0 802 if(strcmp(user,"TOTAL") != 0)
25697a35 803 continue;
0511cf2d 804 if (getword_skip(MAXLEN,&gwarea,sep)<0) {
10210234 805 debuga(_("There a broken total number of access in file %s\n"),wdir);
06b39c87 806 exit(EXIT_FAILURE);
4bcb77cf 807 }
0511cf2d 808 if (getword_atoll(&twork,&gwarea,sep)<0) {
10210234 809 debuga(_("There is a broken number of bytes in file %s\n"),wdir);
06b39c87 810 exit(EXIT_FAILURE);
4bcb77cf 811 }
48864d28 812 strcpy(tbytes,fixnum(twork,1));
6e792ade 813 break;
25697a35
GS
814 }
815 fclose(fp_in);
afaa3b67 816 longline_destroy(&line);
25697a35 817
d25d4e6a 818 if(nuser <= 0) {
48864d28 819 strcpy(media,"0");
25697a35
GS
820 return;
821 }
48864d28 822
d25d4e6a 823 med=twork / nuser;
48864d28 824 strcpy(media,fixnum(med,1));
25697a35
GS
825
826 return;
25697a35
GS
827}
828
829
48864d28 830void gperiod(const char *dirname, const char *period)
25697a35 831{
25697a35 832 FILE *fp_ou;
25697a35
GS
833 char wdirname[MAXLEN];
834
e21b6c02
FM
835 if(debug)
836 debuga(_("Making period file\n"));
837
838 if (snprintf(wdirname,sizeof(wdirname),"%s/sarg-period",dirname)>=sizeof(wdirname)) {
839 debuga(_("Output file name too long: %s/sarg-period"),dirname);
840 exit(EXIT_FAILURE);
841 }
25697a35
GS
842
843 if((fp_ou=fopen(wdirname,"w"))==NULL){
e21b6c02 844 debuga(_("Cannot open file %s for writing\n"),wdirname);
06b39c87 845 exit(EXIT_FAILURE);
25697a35 846 }
48864d28 847
e21b6c02
FM
848 if (fputs(period,fp_ou)==EOF) {
849 debuga(_("Failed to write the requested period in %s\n"),wdirname);
850 exit(EXIT_FAILURE);
851 }
25697a35 852
e21b6c02
FM
853 if (fclose(fp_ou)==EOF) {
854 debuga(_("Failed to close %s - %s\n"),wdirname,strerror(errno));
855 exit(EXIT_FAILURE);
856 }
48864d28 857
25697a35 858 return;
25697a35
GS
859}
860
06ced858 861static void copy_images(void)
25697a35
GS
862{
863 FILE *img_in, *img_ou;
06ced858
FM
864 char images[512];
865 char imgdir[MAXLEN];
866 char srcfile[MAXLEN];
867 char dstfile[MAXLEN];
868 DIR *dirp;
869 struct dirent *direntp;
870 char buffer[MAXLEN];
871 size_t nread;
872 struct stat info;
873
874 if (snprintf(images,sizeof(images),"%simages",outdir)>=sizeof(images)) {
10210234 875 debuga(_("Cannot copy images to target directory %simages\n"),outdir);
06b39c87 876 exit(EXIT_FAILURE);
06ced858
FM
877 }
878 if (access(images,R_OK)!=0) {
879 mkdir(images,0755);
880 }
881
882 strcpy(imgdir,IMAGEDIR);
883 dirp = opendir(imgdir);
884 if(dirp==NULL) {
10210234 885 debuga(_("(util) Can't open directory %s: %s\n"),imgdir,strerror(errno));
06ced858
FM
886 return;
887 }
888 while ((direntp = readdir( dirp )) != NULL ){
889 if(direntp->d_name[0]=='.')
890 continue;
891 sprintf(srcfile,"%s/%s",imgdir,direntp->d_name);
892 if (stat(srcfile,&info)) {
10210234 893 debuga(_("Cannot stat \"%s\" - %s\n"),srcfile,strerror(errno));
06ced858
FM
894 continue;
895 }
896 if (S_ISREG(info.st_mode)) {
897 sprintf(dstfile,"%s/%s",images,direntp->d_name);
898 img_in = fopen(srcfile, "rb");
899 if(img_in!=NULL) {
900 img_ou = fopen(dstfile, "wb");
901 if(img_ou!=NULL) {
902 while ((nread = fread(buffer,1,sizeof(buffer),img_in))>0) {
b5f13803 903 if (fwrite(buffer,1,nread,img_ou)!=nread) {
10210234 904 debuga(_("Failed to copy image %s to %s\n"),srcfile,dstfile);
b5f13803
FM
905 break;
906 }
06ced858
FM
907 }
908 fclose(img_ou);
909 } else
c36c7384 910 fprintf(stderr,"SARG: (util): %s %s: %s\n", _("Cannot open file")?_("Cannot open file"):"Can't open/create file", dstfile, strerror(errno));
06ced858
FM
911 fclose(img_in);
912 } else
c36c7384 913 fprintf(stderr,"SARG: (util): %s %s: %s\n", _("Cannot open file")?_("Cannot open file"):"Can't open file", srcfile, strerror(errno));
06ced858
FM
914 }
915 }
916 (void) closedir(dirp);
917
918 return;
919}
920
921void vrfydir(const char *per1, const char *addr, const char *site, const char *us, const char *form)
922{
6798f0a7 923 FILE *fp_ou;
25697a35 924 int num=1, count=0;
25697a35
GS
925 char wdir[MAXLEN];
926 char per2[MAXLEN];
927 char dirname2[MAXLEN];
32e71fa4
FM
928 char y1[5], y2[5];
929 char d1[3], d2[3];
e6414a9d 930 char m1[8], m2[8];
6798f0a7 931 time_t curtime;
a1de61fe 932 struct tm *loctm;
25697a35 933
0349fa24 934 if(IndexTree == INDEX_TREE_DATE) {
e6414a9d
FM
935 bzero(y1,sizeof(y1));
936 bzero(y2,sizeof(y2));
937 bzero(d1,sizeof(d1));
938 bzero(d2,sizeof(d2));
939 bzero(m1,sizeof(m1));
940 bzero(m2,sizeof(m2));
491b862f 941 if(strncmp(df,"u",1) == 0) {
d6e703cc
FM
942 strncpy(y1,period,4);
943 strncpy(y2,period+10,4);
944 strncpy(m1,period+4,3);
945 strncpy(m2,period+14,3);
946 strncpy(d1,period+7,2);
947 strncpy(d2,period+17,2);
491b862f 948 } else if(strncmp(df,"e",1) == 0) {
d6e703cc
FM
949 strncpy(d1,period+0,2);
950 strncpy(d2,period+10,2);
951 strncpy(m1,period+2,3);
952 strncpy(m2,period+12,3);
953 strncpy(y1,period+5,4);
954 strncpy(y2,period+15,4);
491b862f
GS
955 }
956 conv_month(m1);
957 conv_month(m2);
958
959 sprintf(wdir,"%s%s",outdir,y1);
960 if(strcmp(y1,y2) != 0) {
e6414a9d
FM
961 strcat(wdir,"-");
962 strcat(wdir,y2);
491b862f
GS
963 }
964 if(access(wdir, R_OK) != 0)
965 my_mkdir(wdir);
2357ef77 966
e6414a9d
FM
967 strcat(wdir,"/");
968 strcat(wdir,m1);
491b862f 969 if(strcmp(m1,m2) != 0) {
e6414a9d
FM
970 strcat(wdir,"-");
971 strcat(wdir,m2);
491b862f
GS
972 }
973 if(access(wdir, R_OK) != 0)
974 my_mkdir(wdir);
2357ef77 975
e6414a9d
FM
976 strcat(wdir,"/");
977 strcat(wdir,d1);
491b862f 978 if(strcmp(d1,d2) != 0) {
e6414a9d
FM
979 strcat(wdir,"-");
980 strcat(wdir,d2);
491b862f 981 }
e6414a9d
FM
982 } else {
983 sprintf(wdir, "%s%s", outdir, per1);
984 }
25697a35 985
e6414a9d 986 if(us[0] != '\0') {
25697a35
GS
987 strcat(wdir,"-");
988 strcat(wdir,us);
989 }
e6414a9d 990 if(addr[0] != '\0') {
25697a35
GS
991 strcat(wdir,"-");
992 strcat(wdir,addr);
993 }
e6414a9d 994 if(site[0] != '\0') {
25697a35
GS
995 strcat(wdir,"-");
996 strcat(wdir,site);
997 }
998
d5d021c5 999 strcpy(outdirname,wdir);
25697a35 1000
0349fa24 1001 if(IndexTree != INDEX_TREE_DATE) {
e6414a9d 1002 if(!OverwriteReport) {
491b862f
GS
1003 while(num) {
1004 if(access(wdir,R_OK) == 0) {
d5d021c5 1005 sprintf(wdir,"%s.%d",outdirname,num);
491b862f
GS
1006 sprintf(per2,"%s.%d",per1,num);
1007 num++;
1008 count++;
1009 } else
1010 break;
1011 }
25697a35 1012
491b862f
GS
1013 if(count > 0) {
1014 if(debug)
d5d021c5
FM
1015 debuga(_("File %s already exists, moved to %s\n"),outdirname,wdir);
1016 rename(outdirname,wdir);
491b862f
GS
1017 }
1018 } else {
d5d021c5
FM
1019 if(access(outdirname,R_OK) == 0) {
1020 unlinkdir(outdirname,1);
491b862f 1021 }
25697a35 1022 }
d5d021c5 1023 my_mkdir(outdirname);
25697a35 1024 } else {
491b862f 1025 strcpy(dirname2,wdir);
e6414a9d 1026 if(!OverwriteReport) {
491b862f
GS
1027 while(num) {
1028 if(access(wdir,R_OK) == 0) {
1029 sprintf(wdir,"%s.%d",dirname2,num);
1030 sprintf(per2,"%s.%d",per1,num);
1031 num++;
1032 count++;
1033 } else
1034 break;
1035 }
48864d28 1036
491b862f
GS
1037 if(count > 0) {
1038 if(debug)
d5d021c5 1039 debuga(_("File %s already exists, moved to %s\n"),dirname2,wdir);
491b862f
GS
1040 rename(dirname2,wdir);
1041 strcpy(dirname2,wdir);
1042 }
1043 } else {
1044 if(access(wdir,R_OK) == 0) {
51465d08 1045 unlinkdir(wdir,1);
491b862f 1046 }
25697a35 1047 }
48864d28 1048
491b862f
GS
1049 if(access(wdir, R_OK) != 0)
1050 my_mkdir(wdir);
25697a35
GS
1051 }
1052
25697a35 1053 strcpy(dirname2,wdir);
25697a35 1054
d5d021c5 1055 sprintf(wdir,"%s/sarg-date",outdirname);
6798f0a7 1056 if ((fp_ou = fopen(wdir, "wt")) == 0) {
d5d021c5 1057 debuga(_("cannot open %s for writing\n"),wdir);
6798f0a7 1058 perror("SARG:");
06b39c87 1059 exit(EXIT_FAILURE);
456d78a5 1060 }
6798f0a7 1061 time(&curtime);
fd4dbc54 1062 //strftime(wdir,sizeof(wdir),"%a %b %d %H:%M:%S %Z %Y",localtime(&curtime));
a1de61fe
FM
1063 loctm=localtime(&curtime);
1064 strftime(wdir,sizeof(wdir),"%Y-%m-%d %H:%M:%S",loctm);
1065 fprintf(fp_ou,"%s %d\n",wdir,loctm->tm_isdst);
6798f0a7 1066 fclose(fp_ou);
25697a35 1067
06ced858 1068 copy_images();
25697a35
GS
1069}
1070
25697a35
GS
1071void strip_latin(char *line)
1072{
9c7c6346
FM
1073 int i,j;
1074 int skip;
1075
1076 j=0;
1077 skip=0;
1078 for (i=0;line[i];i++){
1079 if (skip){
1080 if (line[i]==';') skip=0;
1081 } else {
1082 if (line[i]=='&')
1083 skip=1;
1084 else
1085 line[j++]=line[i];
4bcb77cf 1086 }
25697a35 1087 }
9c7c6346 1088 line[j]='\0';
25697a35
GS
1089 return;
1090
1091}
1092
120d768c 1093void zdate(char *ftime,int ftimesize, const char *DateFormat)
25697a35
GS
1094{
1095
1096 time_t t;
1097 struct tm *local;
1098
1099 t = time(NULL);
1100 local = localtime(&t);
1101 if(strcmp(DateFormat,"u") == 0)
120d768c 1102 strftime(ftime, ftimesize, "%b/%d/%Y %H:%M", local);
25697a35 1103 if(strcmp(DateFormat,"e") == 0)
120d768c 1104 strftime(ftime, ftimesize, "%d/%b/%Y-%H:%M", local);
25697a35 1105 if(strcmp(DateFormat,"w") == 0)
120d768c 1106 strftime(ftime, ftimesize, "%V-%H-%M", local);
25697a35
GS
1107 return;
1108}
1109
1110
1111char *fixtime(long int elap)
1112{
1113
1114 int num = elap / 1000;
1115 int hor = 0;
1116 int min = 0;
1117 int sec = 0;
1118 static char buf[12];
1119
1120 if(strcmp(datetimeby,"bytes") == 0) {
48864d28 1121 strcpy(buf,fixnum(elap,1));
25697a35
GS
1122 return buf;
1123 }
1124
25697a35
GS
1125 if(num<1) {
1126 sprintf(buf,"00:00:%02ld",elap);
1127 return buf;
1128 }
1129
1130 hor=num / 3600;
1131 min=(num % 3600) / 60;
1132 sec=num % 60;
1133
48864d28 1134 if(hor==0 && min==0 && sec==0)
25697a35 1135 strcpy(buf,"0");
48864d28
FM
1136 else
1137 sprintf(buf,"%01d:%02d:%02d",hor,min,sec);
25697a35
GS
1138
1139 return buf;
1140
1141}
1142
1143
1144void date_from(char *date, char *dfrom, char *duntil)
1145{
1146
9c7c6346
FM
1147 int diaf;
1148 int mesf;
1149 int anof;
1150 int diau;
1151 int mesu;
1152 int anou;
1153 char wdate[50];
25697a35 1154
9c7c6346
FM
1155 strncpy(wdate,date,sizeof(wdate)-1);
1156 wdate[sizeof(wdate)-1]='\0';
48864d28 1157 if(strchr(wdate,'-') == NULL) {
9c7c6346 1158 if (strlen(wdate)*2+1>=sizeof(wdate)) {
10210234 1159 debuga(_("Invalid date range passed as argument\n"));
06b39c87 1160 exit(EXIT_FAILURE);
9c7c6346 1161 }
25697a35
GS
1162 strcat(wdate,"-");
1163 strcat(wdate,date);
1164 strcpy(date,wdate);
1165 }
1166
9c7c6346 1167 if (sscanf(wdate,"%d/%d/%d-%d/%d/%d",&diaf,&mesf,&anof,&diau,&mesu,&anou)!=6) {
10210234 1168 debuga(_("The date range passed as argument is not formated as dd/mm/yyyy-dd/mm/yyyy\n"));
06b39c87 1169 exit(EXIT_FAILURE);
4bcb77cf 1170 }
25697a35 1171
9c7c6346
FM
1172 sprintf(dfrom,"%04d%02d%02d",anof,mesf,diaf);
1173 sprintf(duntil,"%04d%02d%02d",anou,mesu,diau);
25697a35
GS
1174 return;
1175}
1176
1177
1178char *strlow(char *string)
1179{
32e71fa4 1180 char *s;
25697a35 1181
32e71fa4
FM
1182 if (string)
1183 {
1184 for (s = string; *s; ++s)
1185 *s = tolower(*s);
1186 }
25697a35 1187
32e71fa4 1188 return string;
25697a35
GS
1189}
1190
1191
1192
1193
1194char *strup(char *string)
1195{
32e71fa4 1196 char *s;
25697a35 1197
32e71fa4
FM
1198 if (string)
1199 {
1200 for (s = string; *s; ++s)
1201 *s = toupper(*s);
1202 }
25697a35 1203
32e71fa4 1204 return string;
25697a35
GS
1205}
1206
1207
32e71fa4 1208void removetmp(const char *outdir)
25697a35
GS
1209{
1210
1211 FILE *fp_in;
1212 char warea[256];
06b39c87 1213 char buf[MAXLEN];
25697a35 1214
e6414a9d 1215 if(!RemoveTempFiles)
25697a35 1216 return;
48864d28 1217
32e71fa4 1218 if(debug) {
9f70c14e 1219 debuga(_("Removing temporary files sarg-general, sarg-period\n"));
32e71fa4 1220 }
48864d28 1221 if (snprintf(warea,sizeof(warea),"%s/sarg-general",outdir)>=sizeof(warea)) {
9f70c14e 1222 debuga(_("(removetmp) directory too long to remove %s/sarg-period\n"),outdir);
06b39c87 1223 exit(EXIT_FAILURE);
48864d28 1224 }
32e71fa4 1225 if((fp_in=fopen(warea,"r"))==NULL){
9f70c14e 1226 debuga(_("(removetmp) Cannot open file %s\n"),warea);
06b39c87 1227 exit(EXIT_FAILURE);
32e71fa4
FM
1228 }
1229 while(fgets(buf,sizeof(buf),fp_in)!=NULL) {
2240dcea 1230 if(strncmp(buf,"TOTAL",5) == 0 && (buf[6]=='\t' || buf[6]==' '))
32e71fa4
FM
1231 break;
1232 }
1233 fclose(fp_in);
1234 if((fp_in=fopen(warea,"w"))==NULL){
9f70c14e 1235 debuga(_("(removetmp) Cannot open file %s\n"),warea);
06b39c87 1236 exit(EXIT_FAILURE);
25697a35 1237 }
32e71fa4
FM
1238 fputs(buf,fp_in);
1239 fclose(fp_in);
1240 if (snprintf(warea,sizeof(warea),"%s/sarg-period",outdir)>=sizeof(warea)) {
9f70c14e 1241 debuga(_("(removetmp) directory too long to remove %s/sarg-period\n"),outdir);
06b39c87 1242 exit(EXIT_FAILURE);
32e71fa4
FM
1243 }
1244 unlink(warea);
48864d28 1245
25697a35
GS
1246 return;
1247}
1248
48864d28 1249void load_excludecodes(const char *ExcludeCodes)
25697a35
GS
1250{
1251
1252 FILE *fp_in;
1253 char data[80];
48864d28
FM
1254 int i;
1255
1256 if(ExcludeCodes[0] == '\0')
1257 return;
1258
1259 if((excludecode=(char *) malloc(1024))==NULL) {
fcdc0918 1260 debuga(_("malloc error (1024)\n"));
06b39c87 1261 exit(EXIT_FAILURE);
48864d28
FM
1262 }
1263 bzero(excludecode,1024);
25697a35
GS
1264
1265 if((fp_in=fopen(ExcludeCodes,"r"))==NULL) {
fcdc0918 1266 debuga(_("(util) Cannot open file %s (exclude_codes)\n"),ExcludeCodes);
06b39c87 1267 exit(EXIT_FAILURE);
25697a35
GS
1268 }
1269
32e71fa4 1270 while(fgets(data,sizeof(data),fp_in)!=NULL) {
48864d28
FM
1271 for (i=strlen(data)-1 ; i>=0 && (unsigned char)data[i]<=' ' ; i--) data[i]=0;
1272 if (i<0) continue;
25697a35
GS
1273 strcat(excludecode,data);
1274 strcat(excludecode,";");
25697a35
GS
1275 }
1276
1277 fclose(fp_in);
1278 return;
1279
1280}
1281
48864d28
FM
1282void free_excludecodes(void)
1283{
1284 if (excludecode) {
1285 free(excludecode);
1286 excludecode=NULL;
1287 }
1288}
1289
32e71fa4 1290int vercode(const char *code)
25697a35 1291{
48864d28
FM
1292 char *cod;
1293 int clen;
1294
1295 if (excludecode && excludecode[0]!=0) {
1296 clen=strlen(code);
1297 for (cod=excludecode ; cod ; cod=strchr(cod+1,';')) {
1298 if (strncmp(code,cod,clen)==0 && cod[clen]==';')
1299 return 1;
4bcb77cf 1300 }
25697a35
GS
1301 }
1302 return 0;
1303}
1304
1305void fixnone(char *str)
1306{
48864d28 1307 int i;
32e71fa4 1308
48864d28
FM
1309 for (i=strlen(str)-1 ; i>=0 && (unsigned char)str[i]<=' ' ; i--);
1310 if(i==3 && strncmp(str,"none",4) == 0)
25697a35
GS
1311 str[0]='\0';
1312
1313 return;
1314}
1315
2357ef77
FM
1316void fixendofline(char *str)
1317{
1318 int i;
1319
1320 for (i=strlen(str)-1 ; i>=0 && (unsigned char)str[i]<=' ' ; i--) str[i]=0;
1321}
1322
25697a35 1323#ifdef LEGACY_TESTVALIDUSERCHAR
32e71fa4 1324int testvaliduserchar(const char *user)
25697a35
GS
1325{
1326
1327 int x=0;
1328 int y=0;
1329
1330 for (y=0; y<strlen(UserInvalidChar); y++) {
1331 for (x=0; x<strlen(user); x++) {
1332 if(user[x] == UserInvalidChar[y])
1333 return 1;
1334 }
1335 }
1336 return 0;
1337}
1338#else
32e71fa4 1339int testvaliduserchar(const char *user)
25697a35
GS
1340{
1341
1342 char * p_UserInvalidChar = UserInvalidChar ;
32e71fa4 1343 const char * p_user ;
25697a35
GS
1344
1345 while( *p_UserInvalidChar ) {
1346 p_user = user ;
1347 while ( *p_user ) {
1348 if( *p_UserInvalidChar == *p_user )
1349 return 1;
1350 p_user++ ;
1351 }
1352 p_UserInvalidChar++ ;
1353 }
1354 return 0;
1355}
1356#endif
1357
1358int compar( const void *a, const void *b )
1359{ if( *(int *)a > *(int *)b ) return 1;
1360 if( *(int *)a < *(int *)b ) return -1;
1361 return 0;
1362}
1363
1364int getnumlist( char *buf, numlist *list, const int len, const int maxvalue )
48864d28
FM
1365{
1366 int i, j, d, flag, r1, r2;
1367 char *pbuf, **bp, *strbufs[ 24 ];
1368
1369 bp = strbufs;
1370 strtok( buf, " \t" );
1371 for( *bp = strtok( NULL, "," ), list->len = 0; *bp; *bp = strtok( NULL, "," ) ) {
1372 if( ++bp >= &strbufs[ 24 ] )
1373 break;
1374 list->len++;
25697a35 1375 }
48864d28
FM
1376 if( ! list->len )
1377 return -1;
1378 d = 0;
1379 for( i = 0; i < list->len; i++ ) {
1380 if( strchr( strbufs[ i ], '-' ) != 0 ) {
1381 pbuf = strbufs[ i ];
1382 strtok( pbuf, "-" );
1383 pbuf = strtok( NULL, "\0" );
1384 r1 = atoi( strbufs[ i ] );
1385 if( ( r2 = atoi( pbuf ) ) >= maxvalue || r1 >= r2 )
1386 return -1;
1387 if( i + d + ( r2 - r1 ) + 1 <= len ) {
1388 for( j = r1; j <= r2; j++ )
1389 list->list[ i + d++ ] = j;
1390 d--;
25697a35
GS
1391 }
1392 }
48864d28
FM
1393 else
1394 if( ( list->list[ i + d ] = atoi( strbufs[ i ] ) ) >= maxvalue )
1395 return 1;
25697a35 1396 }
48864d28
FM
1397 list->len += d;
1398 qsort( list->list, list->len, sizeof( int ), compar );
1399 do {
1400 flag = 0;
1401 for( i = 0; i < list->len - 1; i++ )
1402 if( list->list[ i ] == list->list[ i + 1 ] ) {
1403 for( j = i + 1; j < list->len; j++ )
1404 list->list[ j - 1 ] = list->list[ j ];
1405 list->len--;
1406 flag = 1;
1407 break;
1408 }
25697a35 1409 } while( flag );
48864d28 1410 return 0;
25697a35
GS
1411}
1412
1413
32e71fa4 1414char *get_size(const char *path, const char *file)
491b862f
GS
1415{
1416 FILE *fp;
9c7c6346 1417 static char response[255];
32e71fa4 1418 char cmd[255];
9c7c6346 1419 char *ptr;
491b862f 1420
32e71fa4 1421 if (snprintf(cmd,sizeof(cmd),"du -skh %s%s",path,file)>=sizeof(cmd)) {
10210234 1422 debuga(_("Cannot get disk space because the path %s%s is too long\n"),path,file);
06b39c87 1423 exit(EXIT_FAILURE);
32e71fa4 1424 }
491b862f 1425 fp = popen(cmd, "r");
05b90947 1426 if (!fgets(response, sizeof(response), fp)) {
10210234 1427 debuga(_("Cannot get disk size with command %s\n"),cmd);
06b39c87 1428 exit(EXIT_FAILURE);
05b90947 1429 }
9c7c6346
FM
1430 ptr=strchr(response,'\t');
1431 if (ptr==NULL) {
10210234 1432 debuga(_("The command %s failed\n"),cmd);
06b39c87 1433 exit(EXIT_FAILURE);
4bcb77cf 1434 }
491b862f 1435 pclose(fp);
9c7c6346 1436 *ptr='\0';
491b862f 1437
9c7c6346 1438 return (response);
491b862f
GS
1439}
1440
dfb337be
FM
1441void show_info(FILE *fp_ou)
1442{
1443 char ftime[127];
1444
e6414a9d 1445 if(!ShowSargInfo) return;
120d768c 1446 zdate(ftime, sizeof(ftime), DateFormat);
c36c7384 1447 fprintf(fp_ou,"<div class=\"info\">%s <a href='%s'>%s-%s</a> %s %s</div>\n",_("Generated by"),URL,PGM,VERSION,_("on"),ftime);
dfb337be
FM
1448}
1449
c0ec9cc7 1450void show_sarg(FILE *fp_ou, int depth)
dfb337be 1451{
c0ec9cc7
FM
1452 int i;
1453
1454 if(!ShowSargLogo) return;
1455 fputs("<div class=\"logo\"><a href=\"http://sarg.sourceforge.net\"><img src=\"",fp_ou);
1456 for (i=0 ; i<depth ; i++)
1457 fputs("../",fp_ou);
1458 fputs("images/sarg.png\" title=\"SARG, Squid Analysis Report Generator. Logo by Osamu Matsuzaki\" alt=\"Sarg\"></a>&nbsp;Squid Analysis Report Generator</div>\n",fp_ou);
dfb337be
FM
1459}
1460
1461void write_logo_image(FILE *fp_ou)
1462{
1463 if(LogoImage[0]!='\0')
c0ec9cc7 1464 fprintf(fp_ou, "<div class=\"logo\"><img src=\"%s\" width=\"%s\" height=\"%s\" alt=\"Logo\">&nbsp;%s</div>\n",LogoImage,Width,Height,LogoText);
dfb337be 1465}
491b862f 1466
c0ec9cc7 1467void write_html_header(FILE *fp_ou, int depth, const char *page_title)
491b862f 1468{
c0ec9cc7
FM
1469 //fputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n",fp_ou);
1470 fputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n<html>\n",fp_ou);
1471 fprintf(fp_ou, "<head>\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\">\n",CharSet);
1472 if (page_title) fprintf(fp_ou,"<title>%s</title>\n",page_title);
491b862f 1473 css(fp_ou);
dfb337be
FM
1474 fprintf(fp_ou,"</head>\n<body style=\"font-family:%s;font-size:%s;background-color:%s;background-image:url(%s)\">\n",FontFace,TitleFontSize,BgColor,BgImage);
1475 write_logo_image(fp_ou);
c0ec9cc7
FM
1476 show_sarg(fp_ou, depth);
1477 fprintf(fp_ou,"<div class=\"title\"><table cellpadding=\"0\" cellspacing=\"0\">\n<tr><th class=\"title_c\">%s</th></tr>\n",Title);
1478}
1479
1480void close_html_header(FILE *fp_ou)
1481{
1482 fputs("</table></div>\n",fp_ou);
1483}
1484
1485void write_html_trailer(FILE *fp_ou)
1486{
1487 show_info(fp_ou);
1488 fputs("</body>\n</html>\n",fp_ou);
dfb337be
FM
1489}
1490
ac422f9b 1491void output_html_string(FILE *fp_ou,const char *str,int maxlen)
dfb337be 1492{
ac422f9b 1493 int i=0;
dfb337be 1494
ac422f9b 1495 while (*str && (maxlen<=0 || i<maxlen)) {
dfb337be
FM
1496 switch (*str) {
1497 case '&':
1498 fputs("&amp;",fp_ou);
1499 break;
1500 case '<':
1501 fputs("&lt;",fp_ou);
1502 break;
1503 case '>':
1504 fputs("&gt;",fp_ou);
1505 break;
1506 case '"':
1507 fputs("&quot;",fp_ou);
1508 break;
1509 case '\'':
1510 fputs("&#39;",fp_ou);
1511 break;
1512 default:
1513 fputc(*str,fp_ou);
1514 }
1515 str++;
ac422f9b
FM
1516 i++;
1517 }
1518 if (maxlen>0 && i>=maxlen)
1519 fputs("&hellip;",fp_ou);
1520}
1521
1522void output_html_url(FILE *fp_ou,const char *url)
1523{
1524 while (*url) {
1525 if (*url=='&')
1526 fputs("&amp;",fp_ou);
1527 else
1528 fputc(*url,fp_ou);
1529 url++;
dfb337be 1530 }
491b862f
GS
1531}
1532
32e71fa4 1533void baddata(void)
491b862f 1534{
51465d08 1535 char dir[1024];
05b90947 1536
d6e703cc 1537 printf("SARG: ------------------------------------------------------------------------------\n");
10210234
FM
1538 printf(_("SARG: MALICIUS CODE DETECTED.\n"));
1539 printf(_("SARG: I think someone is trying to execute arbitrary code in your system using sarg.\n"));
1540 printf(_("SARG: please review your access.log and/or your useragent.log file.\n"));
1541 printf(_("SARG: process stoped. No actions taken.\n"));
d6e703cc
FM
1542 printf("SARG: ------------------------------------------------------------------------------\n");
1543
51465d08 1544 if (snprintf(dir,sizeof(dir),"%s/sarg",tmp)>=sizeof(dir)) {
10210234 1545 debuga(_("temporary directory too long: %s/sarg\n"),tmp);
06b39c87 1546 exit(EXIT_FAILURE);
05b90947 1547 }
51465d08 1548 unlinkdir(dir,0);
d5d021c5 1549 unlinkdir(outdirname,0);
d6e703cc 1550
06b39c87 1551 exit(EXIT_FAILURE);
491b862f
GS
1552}
1553
f84a35a3
FM
1554void url_hostname(const char *url,char *hostname,int hostsize)
1555{
1556 int i;
1557
1558 hostsize--;
1559 for (i=0 ; i<hostsize && url[i] && url[i]!='/' ; i++)
1560 hostname[i]=url[i];
1561 hostname[i]='\0';
1562}
491b862f 1563
48864d28 1564void url_module(const char *url, char *w2)
25697a35
GS
1565{
1566 int x, y;
1567 char w[255];
1568
25697a35
GS
1569 y=0;
1570 for(x=strlen(url)-1; x>=0; x--) {
48864d28
FM
1571 if(url[x] == '/' || y>=sizeof(w)-1) break;
1572 w[y++]=url[x];
25697a35 1573 }
4157aa09
FM
1574 if (x<0) {
1575 w2[0]='\0';
1576 return;
1577 }
25697a35 1578
48864d28
FM
1579 x=0;
1580 for(y=y-1; y>=0; y--) {
1581 w2[x++]=w[y];
25697a35 1582 }
4157aa09 1583 w2[x]='\0';
25697a35
GS
1584}
1585
e5b2c6f0
FM
1586void url_to_file(const char *url,char *file,int filesize)
1587{
1588 int i,skip;
1589
1590 filesize--;
1591 skip=0;
1592 for(i=0; i<filesize && *url; url++) {
1593 if(*url=='?' || *url=='-' || *url=='.' || *url==':' || *url=='/' || *url=='\\' ||
1594 *url=='*' || *url=='\'' || *url=='\"' || *url=='$') {
1595 if (!skip) file[i++]='_';
1596 skip=1;
1597 } else {
1598 file[i++]=*url;
1599 skip=0;
1600 }
1601 }
1602 file[i]='\0';
1603}
d6e703cc 1604
32e71fa4 1605void version(void)
25697a35 1606{
d25d4e6a 1607 printf(_("SARG Version: %s\n"),VERSION);
2824ec9b 1608 exit(EXIT_SUCCESS);
25697a35 1609}
5f3cfd1d
FM
1610
1611char *get_param_value(const char *param,char *line)
1612{
1613 int plen;
2357ef77 1614
5f3cfd1d
FM
1615 while (*line==' ' || *line=='\t') line++;
1616 plen=strlen(param);
1617 if (strncasecmp(line,param,plen)) return(NULL);
1618 if (line[plen]!=' ' && line[plen]!='\t') return(NULL);
1619 line+=plen;
1620 while (*line==' ' || *line=='\t') line++;
1621 return(line);
1622}
936c9905 1623
51465d08 1624void unlinkdir(const char *dir,int contentonly)
304a739d 1625{
51465d08
FM
1626 struct stat st;
1627 DIR *dirp;
1628 struct dirent *direntp;
1629 char dname[MAXLEN];
463f8e09 1630 int err;
51465d08
FM
1631
1632 dirp=opendir(dir);
1633 if (!dirp) return;
1634 while ((direntp = readdir(dirp)) != NULL) {
1635 if (direntp->d_name[0] == '.' && (direntp->d_name[1] == '\0' ||
1636 (direntp->d_name[1] == '.' && direntp->d_name[2] == '\0')))
1637 continue;
1638 if (snprintf(dname,sizeof(dname),"%s/%s",dir,direntp->d_name)>=sizeof(dname)) {
10210234 1639 debuga(_("directory name to delete too long: %s/%s\n"),dir,direntp->d_name);
06b39c87 1640 exit(EXIT_FAILURE);
51465d08 1641 }
463f8e09
FM
1642#ifdef HAVE_LSTAT
1643 err=lstat(dname,&st);
1644#else
1645 err=stat(dname,&st);
1646#endif
1647 if (err) {
10210234 1648 debuga(_("cannot stat %s\n"),dname);
06b39c87 1649 exit(EXIT_FAILURE);
51465d08
FM
1650 }
1651 if (S_ISREG(st.st_mode)) {
1652 if (unlink(dname)) {
10210234 1653 debuga(_("cannot delete %s - %s\n"),dname,strerror(errno));
06b39c87 1654 exit(EXIT_FAILURE);
304a739d 1655 }
51465d08 1656 } else if (S_ISDIR(st.st_mode)) {
0511cf2d 1657 unlinkdir(dname,0);
51465d08 1658 } else {
10210234 1659 debuga(_("unknown path type %s\n"),dname);
304a739d
FM
1660 }
1661 }
51465d08 1662 closedir(dirp);
304a739d 1663
51465d08
FM
1664 if (!contentonly) {
1665 if (rmdir(dir)) {
10210234 1666 debuga(_("cannot delete %s - %s\n"),dir,strerror(errno));
06b39c87 1667 exit(EXIT_FAILURE);
51465d08
FM
1668 }
1669 }
1670}
ac422f9b 1671