#ifndef _HASHTAB_H
#define _HASHTAB_H

typedef struct hnode  *HNODEPTR;           /* site node (host) pointer     */
typedef struct unode  *UNODEPTR;           /* url node pointer             */
typedef struct rnode  *RNODEPTR;           /* referrer node                */
typedef struct anode  *ANODEPTR;           /* user agent node pointer      */
typedef struct inode  *INODEPTR;           /* user (ident) node pointer    */
#ifdef USE_DNS
typedef struct dnode  *DNODEPTR;           /* DNS hash table node struct   */
#endif
typedef struct opnode *OPNODEPTR;          /* currently opened path struct */
typedef struct pnode  *PNODEPTR;           /* achieved path -
                                              no more new entries          */

/* Object flags */
#define OBJ_REG  0                         /* Regular object               */
#define OBJ_HIDE 1                         /* Hidden object                */
#define OBJ_GRP  2                         /* Grouped object               */

#ifdef USE_DNS
struct dnode {  char *string;              /* DNS node hash table struct   */
              #ifdef USE_IPV6
              struct sockaddr_storage  addr;
              #else
              struct in_addr  addr;
              #endif
              struct dnode    *llist;
              struct dnode    *next; };
#endif

struct hnode {  char *string;              /* host hash table structure    */
                 int flag;
              u_long count;
              u_long files;
              u_long visit;                /* visit information            */
              u_long tstamp;
                char *lasturl;
              double xfer;
              struct hnode *next; };

struct unode {  char *string;              /* url hash table structure     */
                 int flag;                 /* Object type (REG, HIDE, GRP) */
              u_long count;                /* requests counter             */
              u_long files;                /* files counter ?? - unused    */
              u_long entry;                /* entry page counter           */
              u_long exit;                 /* exit page counter            */
              double xfer;                 /* xfer size in bytes           */
                 int urlindex;             /* used by TopPath & UserFlow   */
              struct unode *next; };       /* pointer to next node         */

struct rnode {  char *string;              /* referrer hash table struct   */
                 int flag;
              u_long count;
              struct rnode *next; };

struct anode {  char *string;              /* user agent struct            */
                 int flag;
              u_long count;
              struct anode *next; };

struct inode {  char *string;              /* host hash table struct       */
                 int flag;
              u_long count;
              u_long files;
              u_long visit;
              u_long tstamp;
              double xfer;
              struct inode *next; };

struct opnode {
       struct opnode *next;
         struct list *path;               /* LISTPTR path                 */
              u_long hash;
              u_long tstamp;
                char *hostname;
                char *search_string;
                char *user;
                char *referrer; };

struct pnode {
        struct pnode *next;
         struct list *path;               /* LISTPTR path                */
              u_long hash;
                 int count;                /* n. of times it was found     */
                  /* The key can be whatever string we want.
                     With this we will be able to build generic htables
                     containing hostname, search_string, user or referrers */
                char *key;
            };

                                           /* hash tables for:             */
extern HNODEPTR sm_htab[MAXHASH];          /* sites (monthly)              */
extern HNODEPTR sd_htab[MAXHASH];          /* sites (daily)                */
extern UNODEPTR um_htab[MAXHASH];          /* urls                         */
extern RNODEPTR rm_htab[MAXHASH];          /* referrers and agents...      */
extern ANODEPTR am_htab[MAXHASH];          /* user agents                  */
extern INODEPTR im_htab[MAXHASH];          /* ident table (username)       */
#ifdef USE_DNS
extern DNODEPTR host_table[MAXHASH];       /* DNS resolver table           */
#endif
extern OPNODEPTR op_htab[MAXHASH];         /* currently opened path        */
extern PNODEPTR  gp_htab[MAXHASH];         /* all path (not sorted)        */
extern PNODEPTR  fm_htab[MAXHASH];         /* users flow (monthly)         */

extern int    put_hnode(char *, int, u_long, u_long, double, u_long *,
                        u_long, u_long, char *, HNODEPTR *);
extern int    put_unode(char *, int, u_long, double, u_long *,
                        u_long, u_long, UNODEPTR *);
extern int    put_inode(char *, int, u_long, u_long, double, u_long *,
                        u_long, u_long, INODEPTR *);
extern int    put_rnode(char *, int, u_long, u_long *, RNODEPTR *);
extern int    put_anode(char *, int, u_long, u_long *, ANODEPTR *);

extern int    add_opitem(char *, char *, char *, char *, char *, u_long, OPNODEPTR *);
extern int    flush_opnode(u_long, char *);
extern void   flush_ophtab(u_long);

extern int    put_pnode(struct list *, char *, int, u_long, PNODEPTR *htab);

#ifdef USE_DNS
  #ifdef USE_IPV6
  extern int    put_dnode(char *, struct sockaddr_storage *, DNODEPTR *);
  #else
  extern int    put_dnode(char *, struct in_addr *, DNODEPTR *);
  #endif
  extern void   del_dlist(DNODEPTR *);
#endif

extern void   del_hlist(HNODEPTR *);          /* delete host htab          */
extern void   del_ulist(UNODEPTR *);          /* delete url htab           */
extern void   del_rlist(RNODEPTR *);          /* delete referrer htab      */
extern void   del_alist(ANODEPTR *);          /* delete user agent htab    */
extern void   del_ilist(INODEPTR *);          /* delete user htab          */
extern void   del_plist(PNODEPTR *, int);     /* delete path list          */
extern void   del_oplist(OPNODEPTR *, int);   /* delete opened path list   */

extern void   month_update_exit(u_long);
extern u_long tot_visit(HNODEPTR *);

extern UNODEPTR find_url_node(char *str);     /* finds unode given url str */

extern char   *find_url(char *);              /* finds pointer in url htab */
extern char   *find_hostname(char *);         /* finds pointer in sm_htab  */
extern char   *find_user(char *);             /* finds pointer in am_htab  */
extern char   *find_referrer(char *);         /* finds pointer in rm_htab  */

#endif  /* _HASHTAB_H */
