]> git.ipfire.org Git - thirdparty/sarg.git/blame - userinfo.c
Change version number to 2.3.4
[thirdparty/sarg.git] / userinfo.c
CommitLineData
f2ec8c75
FM
1/*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
61d965f3 3 * 1998, 2012
f2ec8c75
FM
4 *
5 * SARG donations:
6 * please look at http://sarg.sourceforge.net/donations.php
7 * Support:
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
9 * ---------------------------------------------------------------------
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
24 *
25 */
26
27#include "include/conf.h"
28#include "include/defs.h"
29
30//! The number of users to group in one unit.
31#define USERS_PER_GROUP 50
32
33/*! \brief Group the users in one allocation unit.
34Structure to store a group of users and reduce the number of memory
35allocations.
36*/
37struct usergroupstruct
38{
9bd92830
FM
39 //! The next group of users.
40 struct usergroupstruct *next;
41 //! A group of users.
42 struct userinfostruct list[USERS_PER_GROUP];
43 //! The number of users stored in the list.
44 int nusers;
f2ec8c75
FM
45};
46
93551487
FM
47/*! \brief Hold pointer to scan through the user list.
48*/
49struct userscanstruct
50{
51 //! The group containing the user.
52 struct usergroupstruct *group;
53 //! The index of the user in the group.
54 int index;
55};
56
f2ec8c75
FM
57//! The first group of users.
58static struct usergroupstruct *first_user_group=NULL;
829a53c2
FM
59//! The counter to generate unique user number when ::AnonymousOutputFiles is set.
60static int AnonymousCounter=0;
f2ec8c75
FM
61
62struct userinfostruct *userinfo_create(const char *userid)
63{
9bd92830
FM
64 struct usergroupstruct *group, *last;
65 struct userinfostruct *user;
d09d93c6 66 int i, j, lastuser;
9bd92830
FM
67 int skip;
68 int flen;
69 int count, clen;
70 char cstr[9];
71
72 last=NULL;
73 for (group=first_user_group ; group ; group=group->next) {
74 if (group->nusers<USERS_PER_GROUP) break;
75 last=group;
76 }
77
78 if (!group) {
79 group=malloc(sizeof(*group));
80 if (!group) {
81 debuga(_("Not enough memory to store the user\n"));
82 exit(EXIT_FAILURE);
83 }
84 memset(group,0,sizeof(*group));
85 if (last)
86 last->next=group;
87 else
88 first_user_group=group;
89 }
90 user=group->list+group->nusers++;
91
a87d4d11 92 safe_strcpy(user->id,userid,sizeof(user->id));
9bd92830 93
829a53c2
FM
94 if (AnonymousOutputFiles) {
95 snprintf(user->filename,sizeof(user->filename),"%d",AnonymousCounter++);
96 } else {
97 skip=0;
98 j=0;
99 for (i=0 ; userid[i] && j<MAX_USER_FNAME_LEN-1 ; i++) {
100 if (isalnum(userid[i]) || userid[i]=='-' || userid[i]=='_') {
101 user->filename[j++]=userid[i];
102 skip=0;
103 } else {
104 if (!skip) {
105 user->filename[j++]='_';
106 skip=1;
107 }
9bd92830
FM
108 }
109 }
439d83cc 110 if (j==0) user->filename[j++]='_'; //don't leave a file name empty
8217e6e5 111 flen=j;
829a53c2 112 user->filename[j]='\0';
829a53c2
FM
113
114 count=0;
115 for (group=first_user_group ; group ; group=group->next) {
116 lastuser=(group->next) ? group->nusers : group->nusers-1;
117 for (i=0 ; i<lastuser ; i++) {
118 if (strcasecmp(user->filename,group->list[i].filename)==0) {
8217e6e5 119 clen=sprintf(cstr,"+%X",count++);
829a53c2
FM
120 if (flen+clen<MAX_USER_FNAME_LEN)
121 strcpy(user->filename+flen,cstr);
122 else
123 strcpy(user->filename+MAX_USER_FNAME_LEN-clen,cstr);
124 }
9bd92830
FM
125 }
126 }
127 }
128
129 return(user);
f2ec8c75
FM
130}
131
132void userinfo_free(void)
133{
9bd92830 134 struct usergroupstruct *group, *next;
f2ec8c75 135
9bd92830
FM
136 for (group=first_user_group ; group ; group=next) {
137 next=group->next;
138 free(group);
139 }
140 first_user_group=NULL;
f2ec8c75
FM
141}
142
143struct userinfostruct *userinfo_find_from_file(const char *filename)
144{
9bd92830
FM
145 struct usergroupstruct *group;
146 int i;
147
148 for (group=first_user_group ; group ; group=group->next) {
149 for (i=0 ; i<group->nusers ; i++)
150 if (strcmp(filename,group->list[i].filename)==0)
151 return(group->list+i);
152 }
153 return(NULL);
f2ec8c75
FM
154}
155
156struct userinfostruct *userinfo_find_from_id(const char *id)
157{
9bd92830
FM
158 struct usergroupstruct *group;
159 int i;
160
161 for (group=first_user_group ; group ; group=group->next) {
162 for (i=0 ; i<group->nusers ; i++)
163 if (strcmp(id,group->list[i].id)==0)
164 return(group->list+i);
165 }
166 return(NULL);
f2ec8c75 167}
93551487
FM
168
169/*!
170Start the scanning of the user list.
171
172\return The object to pass to subsequent scanning functions or NULL
173if it failed. The object must be freed with a call to userinfo_stop().
174*/
175userscan userinfo_startscan(void)
176{
177 userscan uscan;
178
179 uscan=malloc(sizeof(*uscan));
180 if (!uscan) return(NULL);
181 uscan->group=first_user_group;
182 uscan->index=0;
183 return(uscan);
184}
185
186/*!
187Free the memory allocated by userinfo_start().
188
189\param uscan The object created by userinfo_start().
190*/
191void userinfo_stopscan(userscan uscan)
192{
193 free(uscan);
194}
195
196/*!
197Get the user pointed to by the object and advance the object
198to the next user.
199
200\param uscan The object created by userinfo_start().
201
202\return The user in the list or NULL if the end of the list
203is reached.
204*/
205struct userinfostruct *userinfo_advancescan(userscan uscan)
206{
207 struct userinfostruct *uinfo;
208
209 if (!uscan) return(NULL);
210 if (!uscan->group) return(NULL);
211 if (uscan->index<0 || uscan->index>=uscan->group->nusers) return(NULL);
212
213 uinfo=uscan->group->list+uscan->index;
214
215 ++uscan->index;
216 if (uscan->index>=uscan->group->nusers) {
217 uscan->group=uscan->group->next;
218 uscan->index=0;
219 }
220 return(uinfo);
221}
a58e6d54
FM
222
223/*!
224Clear the general purpose flag from all the user's info.
225*/
226void userinfo_clearflag(void)
227{
228 struct usergroupstruct *group;
229 int i;
230
231 for (group=first_user_group ; group ; group=group->next) {
232 for (i=0 ; i<group->nusers ; i++)
233 group->list[i].flag=0;
234 }
235}
236