]> git.ipfire.org Git - thirdparty/sarg.git/blob - util.c
Moved all the functions declarations from conf.h to defs.h for consistency.
[thirdparty/sarg.git] / util.c
1 /*
2 * AUTHOR: Pedro Lineu Orso pedro.orso@gmail.com
3 * 1998, 2008
4 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
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"
30 #include "include/defs.h"
31
32 static char mtab1[12][4]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
33 static char mtab2[12][3]={"01","02","03","04","05","06","07","08","09","10","11","12"};
34
35 /*void fgetword(char *word, char *line, int stop)
36 {
37 //VARIANT N1
38 int x;
39
40 for (x=0; line[x] && (line[x] != stop); x++) word[x] = line[x];
41 word[x] = '\0';
42
43 //VARIANT N2
44 char *tchar;
45 int difflen;
46
47 tchar = strchr(line, stop);
48 if (tchar == NULL) strcpy(word, line);
49 else
50 {
51 difflen = tchar - line;
52 strncpy(word, line, difflen);
53 word[difflen] = '\0';
54 }
55 }*/
56
57 int getword(char *word, int limit, char *line, int stop)
58 {
59 int x = 0,y;
60
61 /*if(strlen(line) < 3) {
62 word[0]='\0';
63 return(0);
64 }*/
65
66 for(x=0;((line[x]) && (line[x] != stop ));x++) {
67 if(x>=limit) {
68 printf("SARG: getword loop detected after %d bytes.\n",x);
69 printf("SARG: Record=\"%s\"\n",line);
70 printf("SARG: searching for \'x%x\'\n",stop);
71 //printf("SARG: Maybe you have a broken record or garbage in your access.log file.\n");
72 if (limit>0) word[limit-1]='\0';
73 //exit(1);
74 return(-1);
75 }
76 word[x] = line[x];
77 }
78
79 word[x] = '\0';
80 if (line[x]) ++x;
81 y=0;
82
83 while((line[y++] = line[x++]));
84 return(0);
85 }
86
87 int getword_multisep(char *word, int limit, char *line, int stop)
88 {
89 int x = 0,y;
90
91 /*if(strlen(line) < 3) {
92 word[0]='\0';
93 return(0);
94 }*/
95
96 for(x=0;((line[x]) && (line[x] != stop ));x++) {
97 if(x>=limit) {
98 printf("SARG: getword_multisep loop detected.\n");
99 printf("SARG: Record=\"%s\"\n",line);
100 printf("SARG: searching for \'x%x\'\n",stop);
101 printf("SARG: searching for \'x%x\'\n",stop);
102 //printf("SARG: Maybe you have a broken record or garbage in your access.log file.\n");
103 if (limit>0) word[limit-1]='\0';
104 //exit(1);
105 return(-1);
106 }
107 word[x] = line[x];
108 }
109
110 word[x] = '\0';
111 while (line[x] && line[x]==stop) ++x;
112 y=0;
113
114 while((line[y++] = line[x++]));
115 return(0);
116 }
117
118 #if 0 //this function seems unused
119 char * getword2(char *word, int limit, char *line, int stop)
120 {
121 int x = 0;
122
123 if(strlen(line) < 3) {
124 word[0]='\0';
125 return( line ) ;
126 }
127
128 // printf( "IN Buffer <%s>\n" , line ) ;
129 for(x=0;((line[x]) && (line[x] != stop && limit ));x++ , limit-- ) word[x] = line[x];
130 if( ! limit) {
131 printf("SARG: getword2 loop detected.\n");
132 printf("SARG: Buffer=\"%s\"\n",line);
133 printf("SARG: searching for \'x%x\'\n",stop);
134 printf("SARG: Maybe you have a broken record or garbage in your access.log file.\n");
135 exit(1);
136 }
137
138 word[x] = '\0';
139 // printf( "Value <%s>\n" , word ) ;
140 // printf( "OUT Buffer <%s>\n" , line+x+1 ) ;
141 return( line + x +1) ;
142 }
143 #endif
144
145 int getword3(char *word, int limit, char *line, int stop)
146 {
147 int x = 0, y = 0;
148
149 for(x=0; x<limit && (line[x] && (line[x] != stop)) ; x++) word[x] = line[x];
150 if(x>=limit) {
151 printf("SARG: getword3 loop detected after %d bytes.\n",x);
152 printf("SARG: Buffer=\"%s\"\n",line);
153 printf("SARG: searching for \'x%x\'\n",stop);
154 //printf("SARG: Maybe you have a broken record or garbage in your access.log file.\n");
155 //exit(1);
156 return(-1);
157 }
158 word[x] = '\0';
159 if(line[x]) ++x;
160 while((line[y++] = line[x++]));
161 return(0);
162 }
163
164
165 #ifdef LEGACY_MY_ATOLL
166
167 // BMG (bguillory@email.com)
168 // 3 August 1999
169 long long int my_atoll (const char *nptr)
170 #define MAXLLL 30 //maximum number of digits in long long (a guess)
171 {
172 int offset=0, x;
173 long long int returnval=0;
174 char one_digit[2];
175
176 one_digit[1]='\0';
177
178 // Soak up all the white space
179 while (isspace(nptr[offset])) {
180 offset++;
181 } //while
182
183 //For each character left to right
184 //change the character to a single digit
185 //multiply what we had before by 10 and add the new digit
186 for(x=offset; x<=MAXLLL+offset && isdigit(nptr[x]); x++) {
187 sprintf(one_digit, "%c", nptr[x]); //I don't know how else to do this
188 returnval = (returnval * 10) + atoi(one_digit);
189 } //for
190
191 return returnval;
192
193 } //my_atoll
194
195 #else
196
197 #define MAXLLL 30 //maximum number of digits in long long (a guess)
198 long long int my_atoll (const char *nptr)
199 {
200 long long int returnval=0;
201 const char * t = nptr ;
202 int max_digits = MAXLLL ;
203
204 // Soak up all the white space
205 while (isspace( *t )) {
206 t++;
207 } //while
208
209 //For each character left to right
210 //change the character to a single digit
211 //multiply what we had before by 10 and add the new digit
212
213 for( ; --max_digits && isdigit( *t ) ; t++ )
214 {
215 returnval = ( returnval * 10 ) + ( *t - '0' ) ;
216 }
217
218 return returnval;
219
220 } //my_atoll
221
222 #endif
223
224
225 void my_mkdir(const char *name)
226 {
227 char w0[255];
228 char w1[255];
229 char w2[255];
230
231 if(strncmp(name,".",1) == 0 || strncmp(name,"/",1) != 0) {
232 fprintf(stderr,"SARG: Invalid path (%s). Please, use absolute paths only.\n",name);
233 fprintf(stderr,"SARG: process aborted.\n");
234 exit(1);
235 }
236
237 strcpy(w0,name);
238 strcpy(w2,"/");
239 if (getword_multisep(w1,sizeof(w1),w0,'/')<0) {
240 printf("SARG: Maybe you have a broken record or garbage in the directory name %s.\n",name);
241 exit(1);
242 }
243 while(strchr(w0,'/')) {
244 if (getword_multisep(w1,sizeof(w1),w0,'/')<0) {
245 printf("SARG: Maybe you have a broken record or garbage in the directory name %s.\n",name);
246 exit(1);
247 }
248 strcat(w2,w1);
249 if(access(w2, R_OK) != 0) {
250 if(mkdir(w2,0755)) {
251 fprintf(stderr,"SARG: mkdir %s %s\n",w2,strerror(errno));
252 fprintf(stderr,"SARG: process aborted.\n");
253 exit(1);
254 }
255 }
256 strcat(w2,"/");
257 }
258 strcat(w2,w0);
259 if(access(w2, R_OK) != 0) {
260 if(mkdir(w2,0755)) {
261 fprintf(stderr,"SARG: mkdir %s %s\n",w2,strerror(errno));
262 fprintf(stderr,"SARG: process aborted.\n");
263 exit(1);
264 }
265 }
266 }
267
268
269 void my_lltoa(unsigned long long int n, char s[], int len)
270 {
271 int i = 0;
272 int x = 0;
273 char ww[50];
274 do {
275 s[i++] = (n % 10) + '0';
276 } while ((n /= 10) > 0);
277 s[i] = '\0';
278 {
279 int c,i,j;
280 for (i = 0, j = strlen(s)-1; i<j; i++, j--)
281 {
282 c = s[i];
283 s[i] = s[j];
284 s[j] = c;
285 }
286 }
287
288 if(len) {
289 bzero(ww,sizeof(ww));
290 i=len-strlen(s)-1;
291 for(x=0; x<=i; x++)
292 ww[x]='0';
293 i=strlen(s);
294 strncat(ww,s,i>sizeof(ww)?sizeof(ww):i);
295 strcpy(s,ww);
296 }
297
298 }
299
300
301 void builddia(char *dia, const char *mes, const char *ano, const char *df, char *wdata)
302 {
303 char ndia[11];
304 char nmes[3];
305 int x;
306
307 if(strlen(dia) < 1) return;
308
309 ndia[0]='\0';
310 nmes[0]='\0';
311
312 for(x=0; x<12; x++) {
313 if(strcmp(mtab1[x],mes) == 0) {
314 strncpy(nmes,mtab2[x],sizeof(nmes)-1);
315 nmes[sizeof(nmes)-1]=0;
316 break;
317 }
318 }
319
320 snprintf(wdata,9,"%s%s%s",ano,nmes,dia);
321
322 if(strncmp(df,"u",1) != 0)
323 snprintf(ndia,sizeof(ndia),"%s/%s/%s",dia,nmes,ano);
324 else
325 snprintf(ndia,sizeof(ndia),"%s/%s/%s",nmes,dia,ano);
326
327 strcpy(dia,ndia);
328
329 }
330
331
332 void buildymd(const char *dia, const char *mes, const char *ano, char *wdata)
333 {
334 char nmes[3];
335 int x;
336
337 nmes[0]='\0';
338
339 for(x=0; x<12; x++) {
340 if(strcmp(mtab1[x],mes) == 0)
341 strcpy(nmes,mtab2[x]);
342 }
343
344 sprintf(wdata,"%s%s%s",ano,nmes,dia);
345
346 }
347
348
349 void conv_month(char *month)
350 {
351 int x;
352
353 for(x=0; x<12; x++) {
354 if(strcmp(mtab1[x],month) == 0)
355 strcpy(month,mtab2[x]);
356 }
357
358 }
359
360
361 void conv_month_name(char *month)
362 {
363 int x;
364
365 for(x=0; x<12; x++) {
366 if(strcmp(mtab2[x],month) == 0)
367 strcpy(month,mtab1[x]);
368 }
369 }
370
371
372 void name_month(char *month,int month_len)
373 {
374 int x, z=atoi(month)-1;
375 char m[255];
376 char w[20];
377
378 strcpy(m,text[133]);
379
380 for(x=0; x<z; x++)
381 if (getword_multisep(w,sizeof(w),m,',')<0) {
382 printf("SARG: Maybe you have a broken record or garbage in the names of the months.\n");
383 exit(1);
384 }
385 if (getword_multisep(month,month_len,m,',')<0) {
386 printf("SARG: Maybe you have a broken record or garbage in the name of the months.\n");
387 exit(1);
388 }
389 }
390
391
392 void fixper(char *tbuf, char *period, const char *duntil)
393 {
394
395 char warea[50];
396 char dia[5], mes[5], ano[5];
397 int x;
398
399 warea[0]='\0';
400
401 strncpy(dia,duntil+6,2);
402 dia[2]='\0';
403 strncpy(mes,duntil+4,2);
404 mes[2]='\0';
405 strncpy(ano,duntil,4);
406 ano[4]='\0';
407
408 for(x=0; x<12; x++) {
409 if(strcmp(mtab2[x],mes) == 0) {
410 strcpy(mes,mtab1[x]);
411 break;
412 }
413 }
414
415 if(strcmp(df,"e") == 0)
416 sprintf(warea,"%s%s%s",dia,mes,ano);
417 if(strcmp(df,"u") == 0)
418 sprintf(warea,"%s%s%s",ano,mes,dia);
419
420 strcat(period,warea);
421 }
422
423
424 void debuga(const char *msg)
425 {
426 fprintf(stderr, "SARG: %s\n",msg);
427
428 }
429
430
431 void debugaz(const char *head, const char *msg)
432 {
433 fprintf(stderr, "SARG: (util) %s=%s\n",head, msg);
434
435 }
436
437
438 void fixip(char *ip)
439 {
440 char n1[MAXLEN], n2[MAXLEN], n3[MAXLEN];
441 char wip[MAXLEN];
442 char sep[2]=".";
443 int iflag=0;
444
445 strcpy(wip,ip);
446
447 if(strstr(ip,".") != 0) {
448 strcpy(sep,"_");
449 iflag++;
450 }
451
452 if(iflag) {
453 if (getword(n1,sizeof(n1),wip,'.')<0 || getword(n2,sizeof(n2),wip,'.')<0 || getword(n3,sizeof(n3),wip,'.')<0) {
454 printf("SARG: Maybe you have a broken record or garbage in the IP address.\n");
455 exit(1);
456 }
457 } else {
458 if (getword(n1,sizeof(n1),wip,'_')<0 || getword(n2,sizeof(n2),wip,'_')<0 || getword(n3,sizeof(n3),wip,'_')<0) {
459 printf("SARG: Maybe you have a broken record or garbage in the IP address.\n");
460 exit(1);
461 }
462 }
463 ip[0]='\0';
464 sprintf(ip,"%s%s%s%s%s%s%s",n1,sep,n2,sep,n3,sep,wip);
465
466 }
467
468
469 char *fixnum(long long int value, int n)
470 {
471 #define MAXLEN_FIXNUM 1024
472 char num[MAXLEN_FIXNUM];
473 char buf[MAXLEN_FIXNUM * 2];
474 char *pbuf;
475 static char ret[MAXLEN_FIXNUM * 2];
476 char *pret;
477 register int i, j, k;
478 static char abbrev[30];
479
480 my_lltoa(value, num, 0);
481
482 if(strcmp(DisplayedValues,"abbreviation") == 0) {
483 if(strlen(num) <= 3)
484 sprintf(abbrev,"%s",num);
485 if(strlen(num) == 4 || strlen(num) == 7 || strlen(num) == 10 || strlen(num) == 13) {
486 snprintf(abbrev,2,"%s",num);
487 strncat(abbrev,".",1);
488 strncat(abbrev,num+1,2);
489 if(!n) return(abbrev);
490 if(strlen(num) == 4)
491 strncat(abbrev,"K",1);
492 else if(strlen(num) == 7)
493 strncat(abbrev,"M",1);
494 else if(strlen(num) == 10)
495 strncat(abbrev,"G",1);
496 else if(strlen(num) == 13)
497 strncat(abbrev,"T",1);
498 }
499 if(strlen(num) == 5 || strlen(num) == 8 || strlen(num) == 11 || strlen(num) == 14) {
500 snprintf(abbrev,3,"%s",num);
501 strncat(abbrev,".",1);
502 strncat(abbrev,num+2,2);
503 if(!n) return(abbrev);
504 if(strlen(num) == 5)
505 strncat(abbrev,"K",1);
506 else if(strlen(num) == 8)
507 strncat(abbrev,"M",1);
508 else if(strlen(num) == 11)
509 strncat(abbrev,"G",1);
510 else if(strlen(num) == 14)
511 strncat(abbrev,"T",1);
512 }
513 if(strlen(num) == 6 || strlen(num) == 9 || strlen(num) == 12 || strlen(num) == 15) {
514 snprintf(abbrev,4,"%s",num);
515 strncat(abbrev,".",1);
516 strncat(abbrev,num+3,2);
517 if(!n) return(abbrev);
518 if(strlen(num) == 6)
519 strncat(abbrev,"K",1);
520 else if(strlen(num) == 9)
521 strncat(abbrev,"M",1);
522 else if(strlen(num) == 12)
523 strncat(abbrev,"G",1);
524 else if(strlen(num) == 15)
525 strncat(abbrev,"T",1);
526 }
527
528 return(abbrev);
529 }
530
531 bzero(buf, MAXLEN_FIXNUM*2);
532
533 pbuf = buf;
534 pret = ret;
535 k = 0;
536
537 for ( i = strlen(num) - 1, j = 0 ; i > -1; i--) {
538 if ( k == 2 && i != 0 ) {
539 k = 0;
540 pbuf[j++] = num[i];
541 if(strcmp(UseComma,"yes") == 0)
542 pbuf[j++] = ',';
543 else pbuf[j++] = '.';
544 continue;
545 }
546 pbuf[j] = num[i];
547 j++;
548 k++;
549 }
550
551 pret[0]='\0';
552
553 for ( i = strlen(pbuf) - 1, j = 0 ; i > -1; i--, j++)
554 pret[j] = pbuf[i];
555
556 pret[j] = '\0';
557
558 return pret;
559 }
560
561
562 char *fixnum2(long long int value, int n)
563 {
564 #define MAXLEN_FIXNUM2 1024
565 char num[MAXLEN_FIXNUM2];
566 char buf[MAXLEN_FIXNUM2 * 2];
567 char *pbuf;
568 static char ret[MAXLEN_FIXNUM2 * 2];
569 char *pret;
570 register int i, j, k;
571
572 my_lltoa(value, num, 0);
573 bzero(buf, MAXLEN_FIXNUM2*2);
574
575 pbuf = buf;
576 pret = ret;
577 k = 0;
578
579 for ( i = strlen(num) - 1, j = 0 ; i > -1; i--) {
580 if ( k == 2 && i != 0 ) {
581 k = 0;
582 pbuf[j++] = num[i];
583 if(strcmp(UseComma,"yes") == 0)
584 pbuf[j++] = ',';
585 else pbuf[j++] = '.';
586 continue;
587 }
588 pbuf[j] = num[i];
589 j++;
590 k++;
591 }
592
593 pret[0]='\0';
594
595 for ( i = strlen(pbuf) - 1, j = 0 ; i > -1; i--, j++)
596 pret[j] = pbuf[i];
597
598 pret[j] = '\0';
599
600 return pret;
601 }
602
603
604
605 void buildhref(char * href)
606 {
607 char whref[MAXLEN];
608
609 if(strcmp(href,"./") == 0){
610 href[0]='\0';
611 strcat(href,"<a href='");
612 return;
613 }
614
615 href[strlen(href)-1]='\0';
616 sprintf(whref,"%s",strrchr(href,'/'));
617
618 strcpy(href,"<a href='");
619 strcat(href,whref);
620 strcat(href,"/");
621
622 return;
623
624 }
625
626
627 char *buildtime(long long int elap)
628 {
629
630 int num = elap / 1000;
631 int hor = 0;
632 int min = 0;
633 int sec = 0;
634 static char buf[12];
635
636 buf[0]='\0';
637
638 hor=num / 3600;
639 min=(num % 3600) / 60;
640 sec=num % 60;
641 sprintf(buf,"%02d:%02d:%02d",hor,min,sec);
642
643 return(buf);
644
645 }
646
647
648 void obtdate(const char *dirname, const char *name, char *data)
649 {
650
651 FILE *fp_in;
652 char wdir[MAXLEN];
653
654 sprintf(wdir,"%s%s/sarg-date",dirname,name);
655 if ((fp_in = fopen(wdir, "r")) == 0) {
656 sprintf(wdir,"%s%s/date",dirname,name);
657 if ((fp_in = fopen(wdir, "r")) == 0) {
658 data[0]='\0';
659 return;
660 }
661 }
662
663 fgets(data,80,fp_in);
664 fclose(fp_in);
665 data[strlen(data)-1]='\0';
666
667 return;
668
669 }
670
671
672 void obtuser(const char *dirname, const char *name, char *tuser)
673 {
674
675 FILE *fp_in;
676 char wdir[MAXLEN];
677
678 sprintf(wdir,"%s%s/sarg-users",dirname,name);
679 if((fp_in=fopen(wdir,"r"))==NULL) {
680 sprintf(wdir,"%s%s/users",dirname,name);
681 if((fp_in=fopen(wdir,"r"))==NULL) {
682 tuser[0]='\0';
683 return;
684 }
685 }
686
687 fgets(tuser,20,fp_in);
688 tuser[strlen(tuser)-1]='\0';
689 fclose(fp_in);
690
691 return;
692
693 }
694
695
696 void obttotal(const char *dirname, const char *name, char *tbytes, char *tuser, char *media)
697 {
698
699 FILE *fp_in;
700 char wdir[MAXLEN];
701 long long int med=0;
702 long long int wtuser=0;
703
704 sprintf(wdir,"%s%s/sarg-general",dirname,name);
705 if ((fp_in = fopen(wdir, "r")) == 0) {
706 sprintf(wdir,"%s%s/general",dirname,name);
707 if ((fp_in = fopen(wdir, "r")) == 0) {
708 tbytes=0;
709 return;
710 }
711 }
712
713 while(fgets(buf,sizeof(buf),fp_in)!=NULL) {
714 if (getword_multisep(warea,sizeof(warea),buf,' ')<0) {
715 printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir);
716 exit(1);
717 }
718 if(strcmp(warea,"TOTAL") != 0)
719 continue;
720 if (getword_multisep(warea,sizeof(warea),buf,' ')<0) {
721 printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir);
722 exit(1);
723 }
724 if (getword_multisep(warea,sizeof(warea),buf,' ')<0) {
725 printf("SARG: Maybe you have a broken record or garbage in your %s file.\n",wdir);
726 exit(1);
727 }
728 twork=my_atoll(warea);
729 sprintf(tbytes,"%s",fixnum(twork,1));
730 }
731 fclose(fp_in);
732
733 if(tuser[0] == '\0') {
734 wtuser=0;
735 sprintf(media,"%s","0");
736 return;
737 }
738
739 wtuser=my_atoll(tuser);
740 med=my_atoll(warea) / wtuser;
741 sprintf(media,"%s",fixnum(med,1));
742
743 return;
744
745 }
746
747
748 //void gperiod(char *dirname, const char *period)
749 void gperiod(void)
750 {
751
752 FILE *fp_ou;
753
754 char wdirname[MAXLEN];
755
756 strcpy(wdirname,dirname);
757 strcat(wdirname,"/");
758 strcat(wdirname,"sarg-period");
759
760 if((fp_ou=fopen(wdirname,"w"))==NULL){
761 fprintf(stderr, "SARG: (report) %s: %s\n",text[45],wdirname);
762 exit(1);
763 }
764
765 fputs(period,fp_ou);
766 fclose(fp_ou);
767
768 if(debug)
769 debuga((char *)text[50]);
770
771 return;
772
773 }
774
775 void vrfydir(const char *dir, const char *per1, const char *addr, const char *site, const char *us, const char *form)
776 {
777 FILE *img_in, *img_ou;
778 int num=1, count=0;
779 int c;
780 char wdir[MAXLEN];
781 char per2[MAXLEN];
782 char dirname2[MAXLEN];
783 char images[512];
784 DIR *dirp;
785 struct dirent *direntp;
786 int cstatus;
787 char y1[5], y2[5];
788 char d1[3], d2[3];
789 char m1[4], m2[4];
790
791 if(strcmp(IndexTree,"date") == 0) {
792 bzero(y1,5);
793 bzero(y2,5);
794 bzero(d1,3);
795 bzero(d2,3);
796 bzero(m1,4);
797 bzero(m2,4);
798 if(strncmp(df,"u",1) == 0) {
799 strncpy(y1,period,4);
800 strncpy(y2,period+10,4);
801 strncpy(m1,period+4,3);
802 strncpy(m2,period+14,3);
803 strncpy(d1,period+7,2);
804 strncpy(d2,period+17,2);
805 } else if(strncmp(df,"e",1) == 0) {
806 strncpy(d1,period+0,2);
807 strncpy(d2,period+10,2);
808 strncpy(m1,period+2,3);
809 strncpy(m2,period+12,3);
810 strncpy(y1,period+5,4);
811 strncpy(y2,period+15,4);
812 }
813 conv_month(m1);
814 conv_month(m2);
815
816 sprintf(wdir,"%s%s",outdir,y1);
817 if(strcmp(y1,y2) != 0) {
818 strncat(wdir,"-",1);
819 strncat(wdir,y2,strlen(y2));
820 }
821 if(access(wdir, R_OK) != 0)
822 my_mkdir(wdir);
823
824 strncat(wdir,"/",1);
825 strncat(wdir,m1,strlen(m1));
826 if(strcmp(m1,m2) != 0) {
827 strncat(wdir,"-",1);
828 strncat(wdir,m2,strlen(m2));
829 }
830 if(access(wdir, R_OK) != 0)
831 my_mkdir(wdir);
832
833 strncat(wdir,"/",1);
834 strncat(wdir,d1,strlen(d1));
835 if(strcmp(d1,d2) != 0) {
836 strncat(wdir,"-",1);
837 strncat(wdir,d2,strlen(d2));
838 }
839 } else
840 strcpy(wdir,dir);
841
842 if(strlen(us) > 0) {
843 strcat(wdir,"-");
844 strcat(wdir,us);
845 }
846 if(strlen(addr) > 0) {
847 strcat(wdir,"-");
848 strcat(wdir,addr);
849 }
850 if(strlen(site) > 0) {
851 strcat(wdir,"-");
852 strcat(wdir,site);
853 }
854
855 if(strcmp(dirname,wdir) != 0)
856 strcpy(dirname,wdir);
857
858 if(strcmp(IndexTree,"date") != 0) {
859 strcpy(dirname2,dirname);
860 if(strcmp(OverwriteReport,"no") == 0) {
861 while(num) {
862 if(access(wdir,R_OK) == 0) {
863 sprintf(wdir,"%s.%d",dirname,num);
864 sprintf(per2,"%s.%d",per1,num);
865 num++;
866 count++;
867 } else
868 break;
869 }
870
871 if(count > 0) {
872 if(debug)
873 fprintf(stderr, "SARG: %s: %s %s %s\n",text[51],dirname2,text[52],wdir);
874 rename(dirname2,wdir);
875 }
876 } else {
877 if(access(dir,R_OK) == 0) {
878 sprintf(csort,"rm -r %s",dir);
879 system(csort);
880 }
881 }
882 my_mkdir(dirname);
883 } else {
884 strcpy(dirname2,wdir);
885 if(strcmp(OverwriteReport,"no") == 0) {
886 while(num) {
887 if(access(wdir,R_OK) == 0) {
888 sprintf(wdir,"%s.%d",dirname2,num);
889 sprintf(per2,"%s.%d",per1,num);
890 num++;
891 count++;
892 } else
893 break;
894 }
895
896 if(count > 0) {
897 if(debug)
898 fprintf(stderr, "SARG: %s: %s %s %s\n",text[51],dirname2,text[52],wdir);
899 rename(dirname2,wdir);
900 strcpy(dirname2,wdir);
901 }
902 } else {
903 if(access(wdir,R_OK) == 0) {
904 sprintf(csort,"rm -r %s",wdir);
905 system(csort);
906 }
907 }
908
909 if(access(wdir, R_OK) != 0)
910 my_mkdir(wdir);
911 }
912
913 strcpy(dirname2,wdir);
914 sprintf(images,"%simages",outdir);
915 mkdir(images,0755);
916
917 sprintf(wdir,"date \"+%%a %%b %%d %%H:%%M:%%S %%Z %%Y\" >%s/sarg-date",dirname);
918 cstatus=system(wdir);
919 if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
920 fprintf(stderr, "SARG: command return status %d\n",WEXITSTATUS(cstatus));
921 fprintf(stderr, "SARG: command: %s\n",wdir);
922 exit(1);
923 }
924
925 sprintf(per2,"%s/images",SYSCONFDIR);
926
927 dirp = opendir(per2);
928 if(dirp==NULL) {
929 fprintf(stderr, "SARG: (util) %s %s: %s\n","Can't open directory", per2,strerror(errno));
930 return;
931 }
932 while ((direntp = readdir( dirp )) != NULL ){
933 if(strncmp(direntp->d_name,".",1) == 0)
934 continue;
935 sprintf(val10,"%s/%s",per2,direntp->d_name);
936 sprintf(val11,"%s/%s",images,direntp->d_name);
937 img_in = fopen(val10, "rb");
938 if(img_in!=NULL) {
939 img_ou = fopen(val11, "wb");
940 if(img_ou!=NULL) {
941 while (c!=EOF) {
942 c = fgetc(img_in);
943 if(c==EOF) break;
944 fputc(c,img_ou);
945 }
946 c=0;
947 fclose(img_ou);
948 } else
949 fprintf(stderr,"SARG: (util): %s %s: %s\n", text[45]?text[45]:"Can't open/create file", val11, strerror(errno));
950 } else
951 fprintf(stderr,"SARG: (util): %s %s: %s\n", text[45]?text[45]:"Can't open file", val10, strerror(errno));
952
953 fclose(img_in);
954 }
955 (void) rewinddir(dirp);
956 (void) closedir(dirp);
957
958 return;
959
960
961 }
962
963
964 void strip_latin(char *line)
965 {
966 char buf[255];
967 char warea[255];
968
969 while(strstr(line,"&") != 0){
970 if (getword_multisep(warea,sizeof(warea),line,'&')<0) {
971 printf("SARG: Maybe you have a broken record or garbage in a line to strip from HTML entities.\n");
972 exit(1);
973 }
974 strncat(warea,line,1);
975 if (getword_multisep(buf,sizeof(buf),line,';')<0) {
976 printf("SARG: Maybe you have a broken record or garbage in a line to strip from HTML entities.\n");
977 exit(1);
978 }
979 strcat(warea,line);
980 strcpy(line,warea);
981 }
982
983 return;
984
985 }
986
987 void zdate(char *ftime, const char *DateFormat)
988 {
989
990 time_t t;
991 struct tm *local;
992
993 t = time(NULL);
994 local = localtime(&t);
995 if(strcmp(DateFormat,"u") == 0)
996 strftime(ftime, 127, "%b/%d/%Y %H:%M", local);
997 if(strcmp(DateFormat,"e") == 0)
998 strftime(ftime, 127, "%d/%b/%Y-%H:%M", local);
999 if(strcmp(DateFormat,"w") == 0)
1000 strftime(ftime, 127, "%V-%H-%M", local);
1001
1002 return;
1003 }
1004
1005
1006 char *fixtime(long int elap)
1007 {
1008
1009 int num = elap / 1000;
1010 int hor = 0;
1011 int min = 0;
1012 int sec = 0;
1013 static char buf[12];
1014
1015 if(strcmp(datetimeby,"bytes") == 0) {
1016 sprintf(buf,"%s",fixnum(elap,1));
1017 return buf;
1018 }
1019
1020 buf[0]='\0';
1021
1022 if(num<1) {
1023 sprintf(buf,"00:00:%02ld",elap);
1024 return buf;
1025 }
1026
1027 hor=num / 3600;
1028 min=(num % 3600) / 60;
1029 sec=num % 60;
1030
1031 sprintf(buf,"%01d:%02d:%02d",hor,min,sec);
1032
1033 if(strcmp(buf,"0:00:00") == 0)
1034 strcpy(buf,"0");
1035
1036 return buf;
1037
1038 }
1039
1040
1041 void date_from(char *date, char *dfrom, char *duntil)
1042 {
1043
1044 char diaf[10];
1045 char mesf[10];
1046 char anof[10];
1047 char diau[10];
1048 char mesu[10];
1049 char anou[10];
1050 static char wdate[50];
1051
1052
1053 strcpy(wdate,date);
1054 if(strstr(wdate,"-") == 0) {
1055 strcat(wdate,"-");
1056 strcat(wdate,date);
1057 strcpy(date,wdate);
1058 }
1059
1060 if (getword(diaf,sizeof(diaf),wdate,'/')<0 || getword(mesf,sizeof(mesf),wdate,'/')<0 || getword(anof,sizeof(anof),wdate,'-')<0 ||
1061 getword(diau,sizeof(diau),wdate,'/')<0 || getword(mesu,sizeof(mesu),wdate,'/')<0 || getword(anou,sizeof(anou),wdate,0)<0) {
1062 printf("SARG: Maybe you have a broken record or garbage in a date.\n");
1063 exit(1);
1064 }
1065
1066 sprintf(dfrom,"%s%s%s",anof,mesf,diaf);
1067 sprintf(duntil,"%s%s%s",anou,mesu,diau);
1068 return;
1069 }
1070
1071
1072 char *strlow(char *string)
1073 {
1074 char *s;
1075
1076 if (string)
1077 {
1078 for (s = string; *s; ++s)
1079 *s = tolower(*s);
1080 }
1081
1082 return string;
1083 }
1084
1085
1086
1087
1088 char *strup(char *string)
1089 {
1090 char *s;
1091
1092 if (string)
1093 {
1094 for (s = string; *s; ++s)
1095 *s = toupper(*s);
1096 }
1097
1098 return string;
1099 }
1100
1101
1102 char *subs(char *str, char *from, char *to)
1103 {
1104 char *tmp;
1105 char *ret;
1106 unsigned int ss, st;
1107
1108 if(strstr(str,from) == 0)
1109 return (char *) str;
1110
1111 ss = strlen(str); st = strlen(to) + 10;
1112
1113 if((ret=(char *) malloc(ss + st))==NULL)
1114 {
1115 fprintf(stderr, "SARG: %s (%d):\n",text[59],ss+st);
1116 exit(1);
1117 }
1118
1119 bzero(ret,ss+st);
1120
1121 tmp = strstr(str, from);
1122 if ( tmp == (char *) NULL )
1123 return (char *) NULL;
1124 strncpy(ret, str, ss - strlen(tmp));
1125 strcat(ret, to);
1126 strcat(ret, (tmp+strlen(from)));
1127 return (char *) ret;
1128 }
1129
1130
1131 void removetmp(const char *outdir)
1132 {
1133
1134 FILE *fp_in;
1135 char warea[256];
1136
1137 if(strcmp(RemoveTempFiles,"yes") != 0)
1138 return;
1139
1140 if(debug) {
1141 sprintf(msg,"%s: sarg-general, sarg-period",text[82]);
1142 debuga(msg);
1143 }
1144 sprintf(warea,"%s/sarg-general",outdir);
1145 if((fp_in=fopen(warea,"r"))==NULL){
1146 fprintf(stderr, "===SARG: (removetmp) %s: %s\n",text[45],warea);
1147 exit(1);
1148 }
1149 while(fgets(buf,sizeof(buf),fp_in)!=NULL) {
1150 if(strncmp(buf,"TOTAL",5) == 0)
1151 break;
1152 }
1153 fclose(fp_in);
1154 if((fp_in=fopen(warea,"w"))==NULL){
1155 fprintf(stderr, "SARG: (removetmp) %s: %s\n",text[45],warea);
1156 exit(1);
1157 }
1158 fputs(buf,fp_in);
1159 fclose(fp_in);
1160 if (snprintf(warea,sizeof(warea),"%s/sarg-period",outdir)>=sizeof(warea)) {
1161 fprintf(stderr, "SARG: (removetmp) directory too long to remove: %s/sarg-period\n",outdir);
1162 exit(1);
1163 }
1164 unlink(warea);
1165
1166 return;
1167 }
1168
1169 void load_excludecodes(void)
1170 {
1171
1172 FILE *fp_in;
1173 char data[80];
1174
1175 if((fp_in=fopen(ExcludeCodes,"r"))==NULL) {
1176 fprintf(stderr, "SARG: (util) Cannot open file: %s (exclude_codes)\n",ExcludeCodes);
1177 exit(1);
1178 }
1179
1180 while(fgets(data,sizeof(data),fp_in)!=NULL) {
1181 data[strlen(data)-1]='\0';
1182 strcat(excludecode,data);
1183 strcat(excludecode,";");
1184 excode++;
1185 }
1186
1187 fclose(fp_in);
1188 return;
1189
1190 }
1191
1192 int vercode(const char *code)
1193 {
1194 char warea[1024];
1195 char cod[80];
1196 int z;
1197
1198 strcpy(warea,excludecode);
1199 for(z=0; z<=excode-1; z++) {
1200 if (getword_multisep(cod,sizeof(cod),warea,';')<0) {
1201 printf("SARG: Maybe you have a broken record or garbage in a version code.\n");
1202 exit(1);
1203 }
1204 if(strcmp(code,cod) == 0)
1205 return 1;
1206 }
1207 return 0;
1208 }
1209
1210 void fixnone(char *str)
1211 {
1212 char *eol;
1213
1214 eol=strchr(str,'\n');
1215 if (eol) *eol=0;
1216 if(strcmp(str,"none") == 0)
1217 str[0]='\0';
1218
1219 return;
1220 }
1221
1222 #ifdef LEGACY_TESTVALIDUSERCHAR
1223 int testvaliduserchar(const char *user)
1224 {
1225
1226 int x=0;
1227 int y=0;
1228
1229 for (y=0; y<strlen(UserInvalidChar); y++) {
1230 for (x=0; x<strlen(user); x++) {
1231 if(user[x] == UserInvalidChar[y])
1232 return 1;
1233 }
1234 }
1235 return 0;
1236 }
1237 #else
1238 int testvaliduserchar(const char *user)
1239 {
1240
1241 char * p_UserInvalidChar = UserInvalidChar ;
1242 const char * p_user ;
1243
1244 while( *p_UserInvalidChar ) {
1245 p_user = user ;
1246 while ( *p_user ) {
1247 if( *p_UserInvalidChar == *p_user )
1248 return 1;
1249 p_user++ ;
1250 }
1251 p_UserInvalidChar++ ;
1252 }
1253 return 0;
1254 }
1255 #endif
1256
1257 int compar( const void *a, const void *b )
1258 { if( *(int *)a > *(int *)b ) return 1;
1259 if( *(int *)a < *(int *)b ) return -1;
1260 return 0;
1261 }
1262
1263 int getnumlist( char *buf, numlist *list, const int len, const int maxvalue )
1264 { int i, j, d, flag, r1, r2;
1265 char *pbuf, **bp, *strbufs[ 24 ];
1266
1267 bp = strbufs;
1268 strtok( buf, " \t" );
1269 for( *bp = strtok( NULL, "," ), list->len = 0; *bp; *bp = strtok( NULL, "," ) )
1270 { if( ++bp >= &strbufs[ 24 ] )
1271 break;
1272 list->len++;
1273 }
1274 if( ! list->len )
1275 return -1;
1276 d = 0;
1277 for( i = 0; i < list->len; i++ )
1278 { if( strstr( strbufs[ i ], "-" ) != 0 )
1279 { pbuf = strbufs[ i ];
1280 strtok( pbuf, "-" );
1281 pbuf = strtok( NULL, "\0" );
1282 r1 = atoi( strbufs[ i ] );
1283 if( ( r2 = atoi( pbuf ) ) >= maxvalue || r1 >= r2 )
1284 return -1;
1285 if( i + d + ( r2 - r1 ) + 1 <= len )
1286 { for( j = r1; j <= r2; j++ )
1287 list->list[ i + d++ ] = j;
1288 d--;
1289 }
1290 }
1291 else
1292 if( ( list->list[ i + d ] = atoi( strbufs[ i ] ) ) >= maxvalue )
1293 return 1;
1294 }
1295 list->len += d;
1296 qsort( list->list, list->len, sizeof( int ), compar );
1297 do
1298 { flag = 0;
1299 for( i = 0; i < list->len - 1; i++ )
1300 if( list->list[ i ] == list->list[ i + 1 ] )
1301 { for( j = i + 1; j < list->len; j++ )
1302 list->list[ j - 1 ] = list->list[ j ];
1303 list->len--;
1304 flag = 1;
1305 break;
1306 }
1307 } while( flag );
1308 return 0;
1309 }
1310
1311
1312 void show_info(FILE *fp_ou)
1313 {
1314 if(strcmp(ShowSargInfo,"yes") != 0) return;
1315 zdate(ftime, DateFormat);
1316 fprintf(fp_ou,"<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></center>\n",text[108],URL,PGM,VERSION,text[109],ftime);
1317 }
1318
1319 void show_sarg(FILE *fp_ou, const char *ind)
1320 {
1321 if(strcmp(ShowSargLogo,"yes") == 0) fprintf(fp_ou,"<center><table cellpadding=0 cellspacing=0>\n<tr><th class=\"logo\"><a href=\"http://sarg.sourceforge.net\"><img src=\"%s/images/sarg.png\" border=\"0\" align=\"absmiddle\" title=\"SARG, Squid Analysis Report Generator. Logo by Osamu Matsuzaki\"></a>&nbsp;<font class=\"logo\">Squid Analysis Report Generator</font></th></tr>\n<tr><th class=\"title\">&nbsp</th></tr>\n<table>\n",ind);
1322 }
1323
1324 char *get_size(const char *path, const char *file)
1325 {
1326 FILE *fp;
1327 char response[255];
1328 char cmd[255];
1329
1330 if (snprintf(cmd,sizeof(cmd),"du -skh %s%s",path,file)>=sizeof(cmd)) {
1331 printf("SARG: Cannot get disk space because the path %s%s is too long.\n",path,file);
1332 exit(1);
1333 }
1334 fp = popen(cmd, "r");
1335 fgets(response, sizeof(response), fp);
1336 if (getword_multisep(val5,sizeof(val5),response,'\t')<0) {
1337 printf("SARG: Maybe the command %s failed.\n",cmd);
1338 exit(1);
1339 }
1340 pclose(fp);
1341
1342 return (val5);
1343 }
1344
1345
1346 void write_html_header(FILE *fp_ou, const char * ind)
1347 {
1348 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</head>\n",CharSet);
1349 css(fp_ou);
1350 fprintf(fp_ou,"<body style=\"font-family:%s;font-size:%s;background-color:%s;background-image:url(%s)\">\n",FontFace,TitleFontSize,BgColor,BgImage);
1351 if(strlen(LogoImage) > 0) fprintf(fp_ou, "<center><table cellpadding=\"0\" cellspacing=\"0\">\n<tr><th class=\"logo\"><img src='%s' border=0 align=absmiddle width=%s height=%s>&nbsp;%s</th></tr>\n<tr><td height=\"5\"></td></tr>\n</table>\n",LogoImage,Width,Height,LogoText);
1352 show_sarg(fp_ou, ind);
1353 fprintf(fp_ou,"<center><table cellpadding=\"0\" cellspacing=\"0\">\n<tr><th class=\"title\">%s</th></tr>\n</table></center>\n<center><table cellpadding=\"1\" cellspacing=\"2\">\n<tr><td></td><td></td></tr>\n",Title);
1354 }
1355
1356 void baddata(void)
1357 {
1358 printf("SARG: ------------------------------------------------------------------------------\n");
1359 printf("SARG: MALICIUS CODE DETECTED.\n");
1360 printf("SARG: I think someone is trying to execute arbitrary code in your system using sarg.\n");
1361 printf("SARG: please review your access.log and/or your useragent.log file.\n");
1362 printf("SARG: process stoped. No actions taken.\n");
1363 printf("SARG: ------------------------------------------------------------------------------\n");
1364
1365 system("rm -rf /tmp/sarg");
1366 sprintf(tmp4,"rm -rf %s",dirname);
1367 system(tmp4);
1368 system("rm -rf /tmp/sarg");
1369
1370 exit(1);
1371 }
1372
1373
1374 void url_module(char *url, char *w2)
1375 {
1376 int x, y;
1377 char w[255];
1378
1379 bzero(w, 255);
1380 bzero(w2, 255);
1381 y=0;
1382 for(x=strlen(url)-1; x>=0; x--) {
1383 if(url[x] == '/' || y>255) break;
1384 w[y]=url[x];
1385 y++;
1386 }
1387
1388 y=0;
1389 for(x=strlen(w)-1; x>=0; x--) {
1390 w2[y]=w[x];
1391 y++;
1392 }
1393 }
1394
1395
1396 void write_html_trailer(FILE *fp_ou)
1397 {
1398 fputs("</table></center>\n",fp_ou);
1399 zdate(ftime, DateFormat);
1400 show_info(fp_ou);
1401 fputs("</body>\n</html>\n",fp_ou);
1402 }
1403
1404 void version(void)
1405 {
1406 printf("SARG Version: %s\n",VERSION);
1407 exit(0);
1408 }
1409
1410 char *get_param_value(const char *param,char *line)
1411 {
1412 int plen;
1413
1414 while (*line==' ' || *line=='\t') line++;
1415 plen=strlen(param);
1416 if (strncasecmp(line,param,plen)) return(NULL);
1417 if (line[plen]!=' ' && line[plen]!='\t') return(NULL);
1418 line+=plen;
1419 while (*line==' ' || *line=='\t') line++;
1420 return(line);
1421 }