]> git.ipfire.org Git - thirdparty/sarg.git/blobdiff - userinfo.c
Merge messages about IP addresses.
[thirdparty/sarg.git] / userinfo.c
index 8cdabc071976e20ab96c5c822ce35782f224af37..54859c1b14d40ece38ff8c05517f4efd8093b343 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * SARG Squid Analysis Report Generator      http://sarg.sourceforge.net
- *                                                            1998, 2011
+ *                                                            1998, 2015
  *
  * SARG donations:
  *      please look at http://sarg.sourceforge.net/donations.php
@@ -26,6 +26,8 @@
 
 #include "include/conf.h"
 #include "include/defs.h"
+#include "include/stringbuffer.h"
+#include "include/alias.h"
 
 //! The number of users to group in one unit.
 #define USERS_PER_GROUP 50
@@ -58,8 +60,12 @@ struct userscanstruct
 static struct usergroupstruct *first_user_group=NULL;
 //! The counter to generate unique user number when ::AnonymousOutputFiles is set.
 static int AnonymousCounter=0;
+//! String buffer to store the user's related constants.
+static StringBufferObject UserStrings=NULL;
+//! User aliases.
+static AliasObject UserAliases=NULL;
 
-struct userinfostruct *userinfo_create(const char *userid)
+struct userinfostruct *userinfo_create(const char *userid,const char *ip)
 {
        struct usergroupstruct *group, *last;
        struct userinfostruct *user;
@@ -68,6 +74,15 @@ struct userinfostruct *userinfo_create(const char *userid)
        int flen;
        int count, clen;
        char cstr[9];
+       char filename[MAX_USER_FNAME_LEN];
+
+       if (!UserStrings) {
+               UserStrings=StringBuffer_Create();
+               if (!UserStrings) {
+                       debuga(_("Not enough memory to store the user's strings\n"));
+                       exit(EXIT_FAILURE);
+               }
+       }
 
        last=NULL;
        for (group=first_user_group ; group ; group=group->next) {
@@ -78,7 +93,7 @@ struct userinfostruct *userinfo_create(const char *userid)
        if (!group) {
                group=malloc(sizeof(*group));
                if (!group) {
-                       debuga(_("Not enough memory to store the user\n"));
+                       debuga(_("Not enough memory to store user \"%s\"\n"),userid);
                        exit(EXIT_FAILURE);
                }
                memset(group,0,sizeof(*group));
@@ -89,41 +104,67 @@ struct userinfostruct *userinfo_create(const char *userid)
        }
        user=group->list+group->nusers++;
 
-       safe_strcpy(user->id,userid,sizeof(user->id));
+       user->id=StringBuffer_Store(UserStrings,userid);
+       if (!user->id) {
+               debuga(_("Not enough memory to store user ID \"%s\"\n"),userid);
+               exit(EXIT_FAILURE);
+       }
+       user->label=user->id; //assign a label to avoid a NULL pointer in case none is provided
+       if (ip) {
+               /*
+                * IP address is not the same as the user's ID. A separate buffer
+                * must be allocated.
+                */
+               user->id_is_ip=false;
+               user->ip=StringBuffer_Store(UserStrings,ip);
+       } else {
+               /*
+                * User's IP address share the same buffer as the user's ID.
+                */
+               user->id_is_ip=true;
+               user->ip=user->id;
+       }
 
        if (AnonymousOutputFiles) {
-               snprintf(user->filename,sizeof(user->filename),"%d",AnonymousCounter++);
+               snprintf(filename,sizeof(filename),"%d",AnonymousCounter++);
        } else {
                skip=0;
                j=0;
                for (i=0 ; userid[i] && j<MAX_USER_FNAME_LEN-1 ; i++) {
                        if (isalnum(userid[i]) || userid[i]=='-' || userid[i]=='_') {
-                               user->filename[j++]=userid[i];
+                               filename[j++]=userid[i];
                                skip=0;
                        } else {
                                if (!skip) {
-                                       user->filename[j++]='_';
+                                       filename[j++]='_';
                                        skip=1;
                                }
                        }
                }
-               user->filename[j]='\0';
-               flen=i-1;
+               if (j==0) filename[j++]='_'; //don't leave a file name empty
+               flen=j;
+               filename[j]='\0';
 
                count=0;
                for (group=first_user_group ; group ; group=group->next) {
                        lastuser=(group->next) ? group->nusers : group->nusers-1;
                        for (i=0 ; i<lastuser ; i++) {
-                               if (strcasecmp(user->filename,group->list[i].filename)==0) {
-                                       clen=sprintf(cstr,"-%04X",count++);
+                               if (strcasecmp(filename,group->list[i].filename)==0) {
+                                       clen=sprintf(cstr,"+%X",count++);
                                        if (flen+clen<MAX_USER_FNAME_LEN)
-                                               strcpy(user->filename+flen,cstr);
+                                               strcpy(filename+flen,cstr);
                                        else
-                                               strcpy(user->filename+MAX_USER_FNAME_LEN-clen,cstr);
+                                               strcpy(filename+MAX_USER_FNAME_LEN-clen,cstr);
                                }
                        }
                }
        }
+       user->filename=StringBuffer_Store(UserStrings,filename);
+       if (!user->filename)
+       {
+               debuga(_("Not enough memory to store the file name for user \"%s\"\n"),user->id);
+               exit(EXIT_FAILURE);
+       }
 
        return(user);
 }
@@ -137,6 +178,23 @@ void userinfo_free(void)
                free(group);
        }
        first_user_group=NULL;
+       StringBuffer_Destroy(&UserStrings);
+}
+
+/*!
+ * Store the user's label.
+ * \param uinfo The user info structure created by userinfo_create().
+ * \param label The string label to store.
+ */
+void userinfo_label(struct userinfostruct *uinfo,const char *label)
+{
+       if (!uinfo) return;
+       if (!UserStrings) return;
+       uinfo->label=StringBuffer_Store(UserStrings,label);
+       if (!uinfo->label) {
+               debuga(_("Not enough memory to store label \"%s\" of user \"%s\"\n"),label,uinfo->id);
+               exit(EXIT_FAILURE);
+       }
 }
 
 struct userinfostruct *userinfo_find_from_file(const char *filename)
@@ -165,6 +223,19 @@ struct userinfostruct *userinfo_find_from_id(const char *id)
        return(NULL);
 }
 
+struct userinfostruct *userinfo_find_from_ip(const char *ip)
+{
+       struct usergroupstruct *group;
+       int i;
+
+       for (group=first_user_group ; group ; group=group->next) {
+               for (i=0 ; i<group->nusers ; i++)
+                       if (strcmp(ip,group->list[i].ip)==0)
+                               return(group->list+i);
+       }
+       return(NULL);
+}
+
 /*!
 Start the scanning of the user list.
 
@@ -233,3 +304,70 @@ void userinfo_clearflag(void)
        }
 }
 
+/*!
+Read the file containing the user names to alias in the report.
+
+\param Filename The name of the file.
+*/
+void read_useralias(const char *Filename)
+{
+       FILE *fi;
+       longline line;
+       char *buf;
+
+       if (debug) debuga(_("Reading user alias file \"%s\"\n"),Filename);
+
+       UserAliases=Alias_Create();
+       if (!UserAliases) {
+               debuga(_("Cannot store user's aliases\n"));
+               exit(EXIT_FAILURE);
+       }
+
+       fi=fopen(Filename,"rt");
+       if (!fi) {
+               debuga(_("Cannot read user name alias file \"%s\": %s\n"),Filename,strerror(errno));
+               exit(EXIT_FAILURE);
+       }
+
+       if ((line=longline_create())==NULL) {
+               debuga(_("Not enough memory to read the user name aliases\n"));
+               exit(EXIT_FAILURE);
+       }
+
+       while ((buf=longline_read(fi,line)) != NULL) {
+               if (Alias_Store(UserAliases,buf)<0) {
+                       debuga(_("While reading \"%s\"\n"),Filename);
+                       exit(EXIT_FAILURE);
+               }
+       }
+
+       longline_destroy(&line);
+       if (fclose(fi)==EOF) {
+               debuga(_("Read error in \"%s\": %s\n"),Filename,strerror(errno));
+               exit(EXIT_FAILURE);
+       }
+
+       if (debug) {
+               debuga(_("List of user names to alias:\n"));
+               Alias_PrintList(UserAliases);
+       }
+}
+
+/*!
+Free the memory allocated by read_useralias().
+*/
+void free_useralias(void)
+{
+       Alias_Destroy(&UserAliases);
+}
+
+/*!
+Replace the user's name or ID by an alias if one is defined.
+
+\param user The user's name or ID as extracted from the report.
+*/
+const char *process_user(const char *user)
+{
+       user=Alias_Replace(UserAliases,user);
+       return(user);
+}