1 /*
2     webalizer - a web server log analysis program
3 
4     Copyright (C) 1997-2013  Bradford L. Barrett
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version, and provided that the above
10     copyright and permission notice is included with all distributed
11     copies of this or derived software.
12 
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17 
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 
22 */
23 
24 /*********************************************/
25 /* STANDARD INCLUDES                         */
26 /*********************************************/
27 
28 #include <time.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>                           /* normal stuff             */
33 #include <ctype.h>
34 #include <sys/utsname.h>
35 
36 /* ensure sys/types */
37 #ifndef _SYS_TYPES_H
38 #include <sys/types.h>
39 #endif
40 
41 /* some need for uint* */
42 #ifdef HAVE_STDINT_H
43 #include <stdint.h>
44 #endif
45 
46 /* need socket header? */
47 #ifdef HAVE_SYS_SOCKET_H
48 #include <sys/socket.h>
49 #endif
50 
51 /* some systems need this */
52 #ifdef HAVE_MATH_H
53 #include <math.h>
54 #endif
55 
56 #include "webalizer.h"                        /* main header              */
57 #include "lang.h"
58 #include "linklist.h"
59 #include "hashtab.h"
60 
61 /* internal function prototypes */
62 
63 HNODEPTR new_hnode(char *);                   /* new host node            */
64 UNODEPTR new_unode(char *);                   /* new url node             */
65 RNODEPTR new_rnode(char *);                   /* new referrer node        */
66 ANODEPTR new_anode(char *);                   /* new user agent node      */
67 SNODEPTR new_snode(char *);                   /* new search string..      */
68 INODEPTR new_inode(char *);                   /* new ident node           */
69 #ifdef USE_DNS
70 DNODEPTR new_dnode(char *);                   /* new DNS node             */
71 #endif  /* USE_DNS */
72 
73 void     update_entry(char *);                /* update entry/exit        */
74 void     update_exit(char *);                 /* page totals              */
75 
76 unsigned int hash(char *);                    /* hash function            */
77 
78 /* local data */
79 
80 HNODEPTR sm_htab[MAXHASH];                    /* hash tables              */
81 HNODEPTR sd_htab[MAXHASH];
82 UNODEPTR um_htab[MAXHASH];                    /* for hits, sites,         */
83 RNODEPTR rm_htab[MAXHASH];                    /* referrers and agents...  */
84 ANODEPTR am_htab[MAXHASH];
85 SNODEPTR sr_htab[MAXHASH];                    /* search string table      */
86 INODEPTR im_htab[MAXHASH];                    /* ident table (username)   */
87 #ifdef USE_DNS
88 DNODEPTR host_table[MAXHASH];                 /* DNS hash table           */
89 #endif  /* USE_DNS */
90 
91 /*********************************************/
92 /* DEL_HTABS - clear out our hash tables     */
93 /*********************************************/
94 
del_htabs()95 void del_htabs()
96 {
97    del_hlist(sd_htab);                        /* Clear out our various    */
98    del_ulist(um_htab);                        /* hash tables here by      */
99    del_hlist(sm_htab);                        /* calling the appropriate  */
100    del_rlist(rm_htab);                        /* del_* fuction for each   */
101    del_alist(am_htab);
102    del_slist(sr_htab);
103    del_ilist(im_htab);
104 #ifdef USE_DNS
105 /* del_dlist(host_table);  */                    /* delete DNS hash table    */
106 #endif  /* USE_DNS */
107 }
108 
109 /*********************************************/
110 /* NEW_HNODE - create host node              */
111 /*********************************************/
112 
new_hnode(char * str)113 HNODEPTR new_hnode(char *str)
114 {
115    HNODEPTR newptr;
116    char     *sptr;
117 
118    if (strlen(str) >= MAXHOST)
119    {
120       if (verbose)
121       {
122          fprintf(stderr,"[new_hnode] %s (%d)",msg_big_one,strlen(str));
123          if (debug_mode)
124             fprintf(stderr,":\n--> %s",str);
125          fprintf(stderr,"\n");
126       }
127       str[MAXHOST-1]=0;
128    }
129 
130    if ( (sptr=malloc(strlen(str)+1))==NULL ) return (HNODEPTR)NULL;
131    strcpy(sptr,str);
132 
133    if (( newptr = malloc(sizeof(struct hnode))) != NULL)
134    {
135       newptr->string    =sptr;
136       newptr->visit     =0;
137       newptr->tstamp    =0;
138       newptr->lasturl   =blank_str;
139    }
140    else free(sptr);
141    return newptr;
142 }
143 
144 /*********************************************/
145 /* PUT_HNODE - insert/update host node       */
146 /*********************************************/
147 
put_hnode(char * str,int type,u_int64_t count,u_int64_t file,double xfer,u_int64_t * ctr,u_int64_t visit,u_int64_t tstamp,char * lasturl,HNODEPTR * htab)148 int put_hnode( char      *str,  /* Hostname  */
149                int       type,  /* obj type  */
150                u_int64_t count, /* hit count */
151                u_int64_t file,  /* File flag */
152                double    xfer,  /* xfer size */
153                u_int64_t *ctr,  /* counter   */
154                u_int64_t visit, /* visits    */
155                u_int64_t tstamp,/* timestamp */
156                char      *lasturl, /* lasturl */
157                HNODEPTR  *htab)  /* ptr>next  */
158 {
159    HNODEPTR cptr,nptr;
160    unsigned int hval;
161 
162    /* check if hashed */
163    hval=hash(str);
164    if ( (cptr = htab[hval]) == NULL)
165    {
166       /* not hashed */
167       if ( (nptr=new_hnode(str)) != NULL)
168       {
169          nptr->flag  = type;
170          nptr->count = count;
171          nptr->files = file;
172          nptr->xfer  = xfer;
173          nptr->next  = NULL;
174          htab[hval] = nptr;
175          if (type!=OBJ_GRP) (*ctr)++;
176 
177          if (visit)
178          {
179             nptr->visit=(visit-1);
180             nptr->lasturl=find_url(lasturl);
181             nptr->tstamp=tstamp;
182             return 0;
183          }
184          else
185          {
186             if (ispage(log_rec.url))
187             {
188                if (htab==sm_htab) update_entry(log_rec.url);
189                nptr->lasturl=find_url(log_rec.url);
190                nptr->tstamp=tstamp;
191                nptr->visit=1;
192             }
193          }
194       }
195    }
196    else
197    {
198       while (cptr != NULL)
199       {
200          if (strcmp(cptr->string,str)==0)
201          {
202             if ((type==cptr->flag)||((type!=OBJ_GRP)&&(cptr->flag!=OBJ_GRP)))
203             {
204                /* found... bump counter */
205                cptr->count+=count;
206                cptr->files+=file;
207                cptr->xfer +=xfer;
208 
209                if (ispage(log_rec.url))
210                {
211                   if ((tstamp-cptr->tstamp)>=visit_timeout)
212                   {
213                      cptr->visit++;
214                      if (htab==sm_htab)
215                      {
216                         update_exit(cptr->lasturl);
217                         update_entry(log_rec.url);
218                      }
219                   }
220                   cptr->lasturl=find_url(log_rec.url);
221                   cptr->tstamp=tstamp;
222                }
223                return 0;
224             }
225          }
226          cptr = cptr->next;
227       }
228       /* not found... */
229       if ( (nptr = new_hnode(str)) != NULL)
230       {
231          nptr->flag  = type;
232          nptr->count = count;
233          nptr->files = file;
234          nptr->xfer  = xfer;
235          nptr->next  = htab[hval];
236          htab[hval]=nptr;
237          if (type!=OBJ_GRP) (*ctr)++;
238 
239          if (visit)
240          {
241             nptr->visit = (visit-1);
242             nptr->lasturl=find_url(lasturl);
243             nptr->tstamp= tstamp;
244             return 0;
245          }
246          else
247          {
248             if (ispage(log_rec.url))
249             {
250                if (htab==sm_htab) update_entry(log_rec.url);
251                nptr->lasturl=find_url(log_rec.url);
252                nptr->tstamp= tstamp;
253                nptr->visit=1;
254             }
255          }
256       }
257    }
258 
259    if (nptr!=NULL)
260    {
261       /* set object type */
262       if (type==OBJ_GRP) nptr->flag=OBJ_GRP;            /* is it a grouping? */
263       else
264       {
265          /* check if it's a hidden object */
266          if ((hide_sites)||(isinlist(hidden_sites,nptr->string)!=NULL))
267            nptr->flag=OBJ_HIDE;
268       }
269    }
270    return nptr==NULL;
271 }
272 
273 /*********************************************/
274 /* DEL_HLIST - delete host hash table        */
275 /*********************************************/
276 
del_hlist(HNODEPTR * htab)277 void	del_hlist(HNODEPTR *htab)
278 {
279    /* free memory used by hash table */
280    HNODEPTR aptr,temp;
281    int i;
282 
283    for (i=0;i<MAXHASH;i++)
284    {
285       if (htab[i] != NULL)
286       {
287          aptr = htab[i];
288          while (aptr != NULL)
289          {
290             temp = aptr->next;
291             free (aptr->string);    /* free hostname string space */
292             free (aptr);            /* free hostname structure    */
293             aptr = temp;
294          }
295          htab[i]=NULL;
296       }
297    }
298 }
299 
300 /*********************************************/
301 /* NEW_UNODE - URL node creation             */
302 /*********************************************/
303 
new_unode(char * str)304 UNODEPTR new_unode(char *str)
305 {
306    UNODEPTR newptr;
307    char     *sptr;
308 
309    if (strlen(str) >= MAXURLH)
310    {
311       if (verbose)
312       {
313          fprintf(stderr,"[new_unode] %s (%d)",msg_big_one,strlen(str));
314          if (debug_mode)
315             fprintf(stderr,":\n--> %s",str);
316          fprintf(stderr,"\n");
317       }
318       str[MAXURLH-1]=0;
319    }
320 
321    if ( (sptr=malloc(strlen(str)+1))==NULL) return (UNODEPTR)NULL;
322    strcpy(sptr,str);
323 
324    if (( newptr = malloc(sizeof(struct unode))) != NULL)
325    {
326       newptr->string=sptr;
327       newptr->count = 0;
328       newptr->flag  = OBJ_REG;
329    }
330    else free(sptr);
331    return newptr;
332 }
333 
334 /*********************************************/
335 /* PUT_UNODE - insert/update URL node        */
336 /*********************************************/
337 
put_unode(char * str,int type,u_int64_t count,double xfer,u_int64_t * ctr,u_int64_t entry,u_int64_t exit,UNODEPTR * htab)338 int put_unode(char *str, int type, u_int64_t count, double xfer,
339               u_int64_t *ctr, u_int64_t entry, u_int64_t exit, UNODEPTR *htab)
340 {
341    UNODEPTR cptr,nptr;
342    unsigned int hval;
343 
344    if (str[0]=='-') return 0;
345 
346    hval = hash(str);
347    /* check if hashed */
348    if ( (cptr = htab[hval]) == NULL)
349    {
350       /* not hashed */
351       if ( (nptr=new_unode(str)) != NULL)
352       {
353          nptr->flag = type;
354          nptr->count= count;
355          nptr->xfer = xfer;
356          nptr->next = NULL;
357          nptr->entry= entry;
358          nptr->exit = exit;
359          htab[hval] = nptr;
360          if (type!=OBJ_GRP) (*ctr)++;
361       }
362    }
363    else
364    {
365       /* hashed */
366       while (cptr != NULL)
367       {
368          if (strcmp(cptr->string,str)==0)
369          {
370             if ((type==cptr->flag)||((type!=OBJ_GRP)&&(cptr->flag!=OBJ_GRP)))
371             {
372                /* found... bump counter */
373                cptr->count+=count;
374                cptr->xfer += xfer;
375                return 0;
376             }
377          }
378          cptr = cptr->next;
379       }
380       /* not found... */
381       if ( (nptr = new_unode(str)) != NULL)
382       {
383          nptr->flag = type;
384          nptr->count= count;
385          nptr->xfer = xfer;
386          nptr->next = htab[hval];
387          nptr->entry= entry;
388          nptr->exit = exit;
389          htab[hval] = nptr;
390          if (type!=OBJ_GRP) (*ctr)++;
391       }
392    }
393    if (nptr!=NULL)
394    {
395       if (type==OBJ_GRP) nptr->flag=OBJ_GRP;
396       else if (isinlist(hidden_urls,nptr->string)!=NULL)
397                          nptr->flag=OBJ_HIDE;
398    }
399    return nptr==NULL;
400 }
401 
402 /*********************************************/
403 /* DEL_ULIST - delete URL hash table         */
404 /*********************************************/
405 
del_ulist(UNODEPTR * htab)406 void	del_ulist(UNODEPTR *htab)
407 {
408    /* free memory used by hash table */
409    UNODEPTR aptr,temp;
410    int i;
411 
412    for (i=0;i<MAXHASH;i++)
413    {
414       if (htab[i] != NULL)
415       {
416          aptr = htab[i];
417          while (aptr != NULL)
418          {
419             temp = aptr->next;
420             free (aptr->string);  /* free up URL string memory */
421             free (aptr);          /* free up URL struct node   */
422             aptr = temp;
423          }
424          htab[i]=NULL;
425       }
426    }
427 }
428 
429 /*********************************************/
430 /* NEW_RNODE - Referrer node creation        */
431 /*********************************************/
432 
new_rnode(char * str)433 RNODEPTR new_rnode(char *str)
434 {
435    RNODEPTR newptr;
436    char     *sptr;
437 
438    if (strlen(str) >= MAXREFH)
439    {
440       if (verbose)
441       {
442          fprintf(stderr,"[new_rnode] %s (%d)",msg_big_one,strlen(str));
443          if (debug_mode)
444             fprintf(stderr,":\n--> %s",str);
445          fprintf(stderr,"\n");
446       }
447       str[MAXREFH-1]=0;
448    }
449 
450    if ( (sptr=malloc(strlen(str)+1))==NULL ) return (RNODEPTR)NULL;
451    strcpy(sptr,str);
452 
453    if (( newptr = malloc(sizeof(struct rnode))) != NULL)
454    {
455       newptr->string= sptr;
456       newptr->count = 1;
457       newptr->flag  = OBJ_REG;
458    }
459    else free(sptr);
460    return newptr;
461 }
462 
463 /*********************************************/
464 /* PUT_RNODE - insert/update referrer node   */
465 /*********************************************/
466 
put_rnode(char * str,int type,u_int64_t count,u_int64_t * ctr,RNODEPTR * htab)467 int put_rnode(char *str, int type, u_int64_t count,
468               u_int64_t *ctr, RNODEPTR *htab)
469 {
470    RNODEPTR cptr,nptr;
471    unsigned int hval;
472 
473    if (str[0]=='-') strcpy(str,"- (Direct Request)");
474 
475    hval = hash(str);
476    /* check if hashed */
477    if ( (cptr = htab[hval]) == NULL)
478    {
479       /* not hashed */
480       if ( (nptr=new_rnode(str)) != NULL)
481       {
482          nptr->flag  = type;
483          nptr->count = count;
484          nptr->next  = NULL;
485          htab[hval]  = nptr;
486          if (type!=OBJ_GRP) (*ctr)++;
487       }
488    }
489    else
490    {
491       while (cptr != NULL)
492       {
493          if (strcmp(cptr->string,str)==0)
494          {
495             if ((type==cptr->flag)||((type!=OBJ_GRP)&&(cptr->flag!=OBJ_GRP)))
496             {
497                /* found... bump counter */
498                cptr->count+=count;
499                return 0;
500             }
501          }
502          cptr = cptr->next;
503       }
504       /* not found... */
505       if ( (nptr = new_rnode(str)) != NULL)
506       {
507          nptr->flag  = type;
508          nptr->count = count;
509          nptr->next  = htab[hval];
510          htab[hval]  = nptr;
511          if (type!=OBJ_GRP) (*ctr)++;
512       }
513    }
514    if (nptr!=NULL)
515    {
516       if (type==OBJ_GRP) nptr->flag=OBJ_GRP;
517       else if (isinlist(hidden_refs,nptr->string)!=NULL)
518                          nptr->flag=OBJ_HIDE;
519    }
520    return nptr==NULL;
521 }
522 
523 /*********************************************/
524 /* DEL_RLIST - delete referrer hash table    */
525 /*********************************************/
526 
del_rlist(RNODEPTR * htab)527 void	del_rlist(RNODEPTR *htab)
528 {
529    /* free memory used by hash table */
530    RNODEPTR aptr,temp;
531    int i;
532 
533    for (i=0;i<MAXHASH;i++)
534    {
535       if (htab[i] != NULL)
536       {
537          aptr = htab[i];
538          while (aptr != NULL)
539          {
540             temp = aptr->next;
541             free (aptr->string);
542             free (aptr);
543             aptr = temp;
544          }
545          htab[i]=NULL;
546       }
547    }
548 }
549 
550 /*********************************************/
551 /* NEW_ANODE - User Agent node creation      */
552 /*********************************************/
553 
new_anode(char * str)554 ANODEPTR new_anode(char *str)
555 {
556    ANODEPTR newptr;
557    char     *sptr;
558 
559    if (strlen(str) >= MAXAGENT)
560    {
561       if (verbose)
562       {
563          fprintf(stderr,"[new_anode] %s (%d)",msg_big_one,strlen(str));
564          if (debug_mode)
565             fprintf(stderr,":\n--> %s",str);
566          fprintf(stderr,"\n");
567       }
568       str[MAXAGENT-1]=0;
569    }
570 
571    if ( (sptr=malloc(strlen(str)+1))==NULL ) return (ANODEPTR)NULL;
572    strcpy(sptr,str);
573 
574    if (( newptr = malloc(sizeof(struct anode))) != NULL)
575    {
576       newptr->string= sptr;
577       newptr->count = 1;
578       newptr->flag  = OBJ_REG;
579    }
580    else free(sptr);
581    return newptr;
582 }
583 
584 /*********************************************/
585 /* PUT_ANODE - insert/update user agent node */
586 /*********************************************/
587 
put_anode(char * str,int type,u_int64_t count,u_int64_t * ctr,ANODEPTR * htab)588 int put_anode(char *str, int type, u_int64_t count,
589               u_int64_t *ctr, ANODEPTR *htab)
590 {
591    ANODEPTR cptr,nptr;
592    unsigned int hval;
593 
594    if (str[0]=='-') return 0;     /* skip bad user agents */
595 
596    hval = hash(str);
597    /* check if hashed */
598    if ( (cptr = htab[hval]) == NULL)
599    {
600       /* not hashed */
601       if ( (nptr=new_anode(str)) != NULL)
602       {
603          nptr->flag = type;
604          nptr->count= count;
605          nptr->next = NULL;
606          htab[hval] = nptr;
607          if (type!=OBJ_GRP) (*ctr)++;
608       }
609    }
610    else
611    {
612       /* hashed */
613       while (cptr != NULL)
614       {
615          if (strcmp(cptr->string,str)==0)
616          {
617             if ((type==cptr->flag)||((type!=OBJ_GRP)&&(cptr->flag!=OBJ_GRP)))
618             {
619                /* found... bump counter */
620                cptr->count+=count;
621                return 0;
622             }
623          }
624          cptr = cptr->next;
625       }
626       /* not found... */
627       if ( (nptr = new_anode(str)) != NULL)
628       {
629          nptr->flag  = type;
630          nptr->count = count;
631          nptr->next  = htab[hval];
632          htab[hval]  = nptr;
633          if (type!=OBJ_GRP) (*ctr)++;
634       }
635    }
636    if (type==OBJ_GRP) nptr->flag=OBJ_GRP;
637    else if (isinlist(hidden_agents,nptr->string)!=NULL)
638                       nptr->flag=OBJ_HIDE;
639    return nptr==NULL;
640 }
641 
642 /*********************************************/
643 /* DEL_ALIST - delete user agent hash table  */
644 /*********************************************/
645 
del_alist(ANODEPTR * htab)646 void	del_alist(ANODEPTR *htab)
647 {
648    /* free memory used by hash table */
649    ANODEPTR aptr,temp;
650    int i;
651 
652    for (i=0;i<MAXHASH;i++)
653    {
654       if (htab[i] != NULL)
655       {
656          aptr = htab[i];
657          while (aptr != NULL)
658          {
659             temp = aptr->next;
660             free (aptr->string);
661             free (aptr);
662             aptr = temp;
663          }
664          htab[i]=NULL;
665       }
666    }
667 }
668 
669 /*********************************************/
670 /* NEW_SNODE - Search str node creation      */
671 /*********************************************/
672 
new_snode(char * str)673 SNODEPTR new_snode(char *str)
674 {
675    SNODEPTR newptr;
676    char     *sptr;
677 
678    if (strlen(str) >= MAXSRCHH)
679    {
680       if (verbose)
681       {
682          fprintf(stderr,"[new_snode] %s (%d)",msg_big_one,strlen(str));
683          if (debug_mode)
684             fprintf(stderr,":\n--> %s",str);
685          fprintf(stderr,"\n");
686       }
687       str[MAXSRCHH-1]=0;
688    }
689 
690    if ( (sptr=malloc(strlen(str)+1))==NULL ) return (SNODEPTR)NULL;
691    strcpy(sptr,str);
692 
693    if (( newptr = malloc(sizeof(struct snode))) != NULL)
694    {
695       newptr->string= sptr;
696       newptr->count = 1;
697    }
698    else free(sptr);
699    return newptr;
700 }
701 
702 /*********************************************/
703 /* PUT_SNODE - insert/update search str node */
704 /*********************************************/
705 
put_snode(char * str,u_int64_t count,SNODEPTR * htab)706 int put_snode(char *str, u_int64_t count, SNODEPTR *htab)
707 {
708    SNODEPTR cptr,nptr;
709    unsigned int hval;
710 
711    if (str[0]==0 || str[0]==' ') return 0;     /* skip bad search strs */
712 
713    hval=hash(str);
714    /* check if hashed */
715    if ( (cptr = htab[hval]) == NULL)
716    {
717       /* not hashed */
718       if ( (nptr=new_snode(str)) != NULL)
719       {
720          nptr->count = count;
721          nptr->next = NULL;
722          htab[hval] = nptr;
723       }
724    }
725    else
726    {
727       /* hashed */
728       while (cptr != NULL)
729       {
730          if (strcmp(cptr->string,str)==0)
731          {
732             /* found... bump counter */
733             cptr->count+=count;
734             return 0;
735          }
736          cptr = cptr->next;
737       }
738       /* not found... */
739       if ( (nptr = new_snode(str)) != NULL)
740       {
741          nptr->count = count;
742          nptr->next  = htab[hval];
743          htab[hval]  = nptr;
744       }
745    }
746    return nptr==NULL;
747 }
748 
749 /*********************************************/
750 /* DEL_SLIST - delete search str hash table  */
751 /*********************************************/
752 
del_slist(SNODEPTR * htab)753 void	del_slist(SNODEPTR *htab)
754 {
755    /* free memory used by hash table */
756    SNODEPTR aptr,temp;
757    int i;
758 
759    for (i=0;i<MAXHASH;i++)
760    {
761       if (htab[i] != NULL)
762       {
763          aptr = htab[i];
764          while (aptr != NULL)
765          {
766             temp = aptr->next;
767             free (aptr->string);
768             free (aptr);
769             aptr = temp;
770          }
771          htab[i]=NULL;
772       }
773    }
774 }
775 
776 /*********************************************/
777 /* NEW_INODE - create ident (username) node  */
778 /*********************************************/
779 
new_inode(char * str)780 INODEPTR new_inode(char *str)
781 {
782    INODEPTR newptr;
783    char     *sptr;
784 
785    if (strlen(str) >= MAXIDENT)
786    {
787       if (verbose)
788       {
789          fprintf(stderr,"[new_inode] %s (%d)",msg_big_one,strlen(str));
790          if (debug_mode)
791             fprintf(stderr,":\n--> %s",str);
792          fprintf(stderr,"\n");
793       }
794       str[MAXIDENT-1]=0;
795    }
796 
797    if ( (sptr=malloc(strlen(str)+1))==NULL ) return (INODEPTR)NULL;
798    strcpy(sptr,str);
799 
800    if (( newptr = malloc(sizeof(struct inode))) != NULL)
801    {
802       newptr->string    =sptr;
803       newptr->visit     =1;
804       newptr->tstamp    =0;
805    }
806    else free(sptr);
807    return newptr;
808 }
809 
810 /*********************************************/
811 /* PUT_INODE - insert/update ident node      */
812 /*********************************************/
813 
put_inode(char * str,int type,u_int64_t count,u_int64_t file,double xfer,u_int64_t * ctr,u_int64_t visit,u_int64_t tstamp,INODEPTR * htab)814 int put_inode( char      *str,  /* ident str */
815                int       type,  /* obj type  */
816                u_int64_t count, /* hit count */
817                u_int64_t file,  /* File flag */
818                double    xfer,  /* xfer size */
819                u_int64_t *ctr,  /* counter   */
820                u_int64_t visit, /* visits    */
821                u_int64_t tstamp,/* timestamp */
822                INODEPTR  *htab) /* hashtable */
823 {
824    INODEPTR cptr,nptr;
825    unsigned int hval;
826 
827    if ((str[0]=='-') || (str[0]==0)) return 0;  /* skip if no username */
828 
829    hval = hash(str);
830    /* check if hashed */
831    if ( (cptr = htab[hval]) == NULL)
832    {
833       /* not hashed */
834       if ( (nptr=new_inode(str)) != NULL)
835       {
836          nptr->flag  = type;
837          nptr->count = count;
838          nptr->files = file;
839          nptr->xfer  = xfer;
840          nptr->next  = NULL;
841          htab[hval] = nptr;
842          if (type!=OBJ_GRP) (*ctr)++;
843 
844          if (visit)
845          {
846             nptr->visit=(visit-1);
847             nptr->tstamp=tstamp;
848             return 0;
849          }
850          else
851          {
852             if (ispage(log_rec.url)) nptr->tstamp=tstamp;
853          }
854       }
855    }
856    else
857    {
858       /* hashed */
859       while (cptr != NULL)
860       {
861          if (strcmp(cptr->string,str)==0)
862          {
863             if ((type==cptr->flag)||((type!=OBJ_GRP)&&(cptr->flag!=OBJ_GRP)))
864             {
865                /* found... bump counter */
866                cptr->count+=count;
867                cptr->files+=file;
868                cptr->xfer +=xfer;
869 
870                if (ispage(log_rec.url))
871                {
872                   if ((tstamp-cptr->tstamp)>=visit_timeout)
873                      cptr->visit++;
874                   cptr->tstamp=tstamp;
875                }
876                return 0;
877             }
878          }
879          cptr = cptr->next;
880       }
881       /* not found... */
882       if ( (nptr = new_inode(str)) != NULL)
883       {
884          nptr->flag  = type;
885          nptr->count = count;
886          nptr->files = file;
887          nptr->xfer  = xfer;
888          nptr->next  = htab[hval];
889          htab[hval]  = nptr;
890          if (type!=OBJ_GRP) (*ctr)++;
891 
892          if (visit)
893          {
894             nptr->visit = (visit-1);
895             nptr->tstamp= tstamp;
896             return 0;
897          }
898          else
899          {
900             if (ispage(log_rec.url)) nptr->tstamp= tstamp;
901          }
902       }
903    }
904 
905    if (nptr!=NULL)
906    {
907       /* set object type */
908       if (type==OBJ_GRP) nptr->flag=OBJ_GRP;            /* is it a grouping? */
909       else
910       {
911          /* check if it's a hidden object */
912          if (isinlist(hidden_users,nptr->string)!=NULL)
913            nptr->flag=OBJ_HIDE;
914       }
915    }
916    return nptr==NULL;
917 }
918 
919 /*********************************************/
920 /* DEL_ILIST - delete ident hash table       */
921 /*********************************************/
922 
del_ilist(INODEPTR * htab)923 void	del_ilist(INODEPTR *htab)
924 {
925    /* free memory used by hash table */
926    INODEPTR aptr,temp;
927    int i;
928 
929    for (i=0;i<MAXHASH;i++)
930    {
931       if (htab[i] != NULL)
932       {
933          aptr = htab[i];
934          while (aptr != NULL)
935          {
936             temp = aptr->next;
937             free (aptr->string);    /* free ident string space */
938             free (aptr);            /* free ident structure    */
939             aptr = temp;
940          }
941          htab[i]=NULL;
942       }
943    }
944 }
945 
946 #ifdef USE_DNS   /* only add these for DNS   */
947 
948 /*********************************************/
949 /* NEW_DNODE - DNS resolver node creation    */
950 /*********************************************/
951 
new_dnode(char * str)952 DNODEPTR new_dnode(char *str)
953 {
954    DNODEPTR newptr;
955    char     *sptr;
956 
957    if (strlen(str) >= MAXHOST)
958    {
959       if (verbose)
960       {
961          fprintf(stderr,"[new_dnode] %s (%d)",msg_big_one,strlen(str));
962          if (debug_mode)
963             fprintf(stderr,":\n--> %s",str);
964          fprintf(stderr,"\n");
965       }
966       str[MAXHOST-1]=0;
967    }
968 
969    if ( (sptr=malloc(strlen(str)+1))==NULL ) return (DNODEPTR)NULL;
970    strcpy(sptr,str);
971 
972    if (( newptr = malloc(sizeof(struct dnode))) != NULL)
973    {
974       newptr->string= sptr;
975    }
976    else free(sptr);
977    return newptr;
978 }
979 
980 /*********************************************/
981 /* PUT_DNODE - insert/update dns host node   */
982 /*********************************************/
983 
put_dnode(char * str,void * addr,int len,DNODEPTR * htab)984 int put_dnode(char *str, void *addr, int len, DNODEPTR *htab)
985 {
986    DNODEPTR cptr,nptr;
987    unsigned int hval;
988 
989    if (str[0]==0 || str[0]==' ') return 0;     /* skip bad hostnames */
990 
991    hval = hash(str);
992    /* check if hashed */
993    if ( (cptr = htab[hval]) == NULL)
994    {
995       /* not hashed */
996       if ( (nptr=new_dnode(str)) != NULL)
997       {
998          if (addr) memcpy(&nptr->addr, addr, len);
999             else   memset(&nptr->addr, 0, sizeof(struct sockaddr_storage));
1000          nptr->addrlen = len;
1001          nptr->next = NULL;
1002          htab[hval] = nptr;
1003       }
1004    }
1005    else
1006    {
1007       /* hashed */
1008       while (cptr != NULL)
1009       {
1010          if (strcmp(cptr->string,str)==0) return 0;
1011          cptr = cptr->next;
1012       }
1013       /* not found... */
1014       if ( (nptr = new_dnode(str)) != NULL)
1015       {
1016          if (addr) memcpy(&nptr->addr, addr, len);
1017             else   memset(&nptr->addr, 0, sizeof(struct sockaddr_storage));
1018          nptr->addrlen = len;
1019          nptr->next  = htab[hval];
1020          htab[hval]  = nptr;
1021       }
1022    }
1023    return nptr==NULL;
1024 }
1025 
1026 /*********************************************/
1027 /* DEL_DLIST - delete dns hash table         */
1028 /*********************************************/
1029 
del_dlist(DNODEPTR * htab)1030 void	del_dlist(DNODEPTR *htab)
1031 {
1032    /* free memory used by hash table */
1033    DNODEPTR dptr,temp;
1034    int i;
1035 
1036    for (i=0;i<MAXHASH;i++)
1037    {
1038       if (htab[i] != NULL)
1039       {
1040          dptr = htab[i];
1041          while (dptr != NULL)
1042          {
1043             temp = dptr->next;
1044             free (dptr->string);
1045             free (dptr);
1046             dptr = temp;
1047          }
1048          htab[i]=NULL;
1049       }
1050    }
1051 }
1052 
1053 #endif /* USE_DNS */
1054 
1055 /*********************************************/
1056 /* FIND_URL - Find URL in hash table         */
1057 /*********************************************/
1058 
find_url(char * str)1059 char *find_url(char *str)
1060 {
1061    UNODEPTR cptr;
1062 
1063    if ( (cptr=um_htab[hash(str)]) != NULL)
1064    {
1065       while (cptr != NULL)
1066       {
1067          if (strcmp(cptr->string,str)==0)
1068             return cptr->string;
1069          cptr = cptr->next;
1070       }
1071    }
1072    return blank_str;   /* shouldn't get here */
1073 }
1074 
1075 /*********************************************/
1076 /* UPDATE_ENTRY - update entry page total    */
1077 /*********************************************/
1078 
update_entry(char * str)1079 void update_entry(char *str)
1080 {
1081    UNODEPTR uptr;
1082 
1083    if (str==NULL) return;
1084    if ( (uptr = um_htab[hash(str)]) == NULL) return;
1085    else
1086    {
1087       while (uptr != NULL)
1088       {
1089          if (strcmp(uptr->string,str)==0)
1090          {
1091             if (uptr->flag!=OBJ_GRP)
1092             {
1093                uptr->entry++;
1094                return;
1095             }
1096          }
1097          uptr=uptr->next;
1098       }
1099    }
1100 }
1101 
1102 /*********************************************/
1103 /* UPDATE_EXIT  - update exit page total     */
1104 /*********************************************/
1105 
update_exit(char * str)1106 void update_exit(char *str)
1107 {
1108    UNODEPTR uptr;
1109 
1110    if (str==NULL) return;
1111    if ( (uptr = um_htab[hash(str)]) == NULL) return;
1112    else
1113    {
1114       while (uptr != NULL)
1115       {
1116          if (strcmp(uptr->string,str)==0)
1117          {
1118             if (uptr->flag!=OBJ_GRP)
1119             {
1120                uptr->exit++;
1121                return;
1122             }
1123          }
1124          uptr=uptr->next;
1125       }
1126    }
1127 }
1128 
1129 /*********************************************/
1130 /* MONTH_UPDATE_EXIT  - eom exit page update */
1131 /*********************************************/
1132 
month_update_exit(u_int64_t tstamp)1133 void month_update_exit(u_int64_t tstamp)
1134 {
1135    HNODEPTR nptr;
1136    int i;
1137 
1138    for (i=0;i<MAXHASH;i++)
1139    {
1140       nptr=sm_htab[i];
1141       while (nptr!=NULL)
1142       {
1143          if (nptr->flag!=OBJ_GRP)
1144          {
1145             if ((tstamp-nptr->tstamp)>=visit_timeout)
1146                update_exit(nptr->lasturl);
1147          }
1148          nptr=nptr->next;
1149       }
1150    }
1151 }
1152 
1153 /*********************************************/
1154 /* TOT_VISIT - calculate total visits        */
1155 /*********************************************/
1156 
tot_visit(HNODEPTR * list)1157 u_int64_t tot_visit(HNODEPTR *list)
1158 {
1159    HNODEPTR   hptr;
1160    u_int64_t  tot=0;
1161    int        i;
1162 
1163    for (i=0;i<MAXHASH;i++)
1164    {
1165       hptr=list[i];
1166       while (hptr!=NULL)
1167       {
1168          if (hptr->flag!=OBJ_GRP) tot+=hptr->visit;
1169          hptr=hptr->next;
1170       }
1171    }
1172    return tot;
1173 }
1174 
1175 #ifdef USE_OLDHASH
1176 /*********************************************/
1177 /* HASH - return hash value for string       */
1178 /*********************************************/
1179 
hash(char * str)1180 unsigned int hash(char *str)
1181 {
1182    uint32_t  hashval=0;
1183 
1184    for (hashval = 0; *str != '\0'; str++)
1185       hashval = *str + (hashval << 5) - hashval;
1186 
1187    return hashval % MAXHASH;
1188 }
1189 
1190 #else /* USE_OLDHASH */
1191 /*********************************************/
1192 /* HASH (SuperFastHash by Paul Hsieh)        */
1193 /*********************************************/
1194 
1195 #undef get16bits
1196 #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
1197   || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
1198 #define get16bits(d) (*((const uint16_t *) (d)))
1199 #endif
1200 
1201 #if !defined (get16bits)
1202 #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
1203                        +(uint32_t)(((const uint8_t *)(d))[0]) )
1204 #endif
1205 
hash(char * str)1206 unsigned int hash(char *str)
1207 {
1208    int len=strlen(str);
1209    uint32_t hash = len, tmp;
1210    int rem;
1211 
1212    if (len <= 0 || str == NULL) return 0;
1213 
1214    rem = len & 3;
1215    len >>= 2;
1216 
1217    /* Main loop */
1218    for (;len > 0; len--)
1219    {
1220       hash  += get16bits (str);
1221       tmp    = (get16bits (str+2) << 11) ^ hash;
1222       hash   = (hash << 16) ^ tmp;
1223       str   += 2*sizeof (uint16_t);
1224       hash  += hash >> 11;
1225    }
1226 
1227    /* Handle end cases */
1228    switch (rem)
1229    {
1230       case 3: hash += get16bits (str);
1231               hash ^= hash << 16;
1232               hash ^= str[sizeof (uint16_t)] << 18;
1233               hash += hash >> 11;
1234               break;
1235       case 2: hash += get16bits (str);
1236               hash ^= hash << 11;
1237               hash += hash >> 17;
1238               break;
1239       case 1: hash += *str;
1240               hash ^= hash << 10;
1241               hash += hash >> 1;
1242    }
1243 
1244    /* Force "avalanching" of final 127 bits */
1245    hash ^= hash << 3;
1246    hash += hash >> 5;
1247    hash ^= hash << 4;
1248    hash += hash >> 17;
1249    hash ^= hash << 25;
1250    hash += hash >> 6;
1251 
1252    return hash % MAXHASH;
1253 }
1254 #endif /* USE_OLDHASH */
1255