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