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