]> git.ipfire.org Git - thirdparty/sarg.git/blob - userinfo.c
Report any error while reading the day summary file
[thirdparty/sarg.git] / userinfo.c
1 /*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
3 * 1998, 2011
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.
34 Structure to store a group of users and reduce the number of memory
35 allocations.
36 */
37 struct usergroupstruct
38 {
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;
45 };
46
47 /*! \brief Hold pointer to scan through the user list.
48 */
49 struct 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
57 //! The first group of users.
58 static struct usergroupstruct *first_user_group=NULL;
59 //! The counter to generate unique user number when ::AnonymousOutputFiles is set.
60 static int AnonymousCounter=0;
61
62 struct userinfostruct *userinfo_create(const char *userid)
63 {
64 struct usergroupstruct *group, *last;
65 struct userinfostruct *user;
66 int i, j, lastuser;
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
92 safe_strcpy(user->id,userid,sizeof(user->id));
93
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 }
108 }
109 }
110 user->filename[j]='\0';
111 flen=i-1;
112
113 count=0;
114 for (group=first_user_group ; group ; group=group->next) {
115 lastuser=(group->next) ? group->nusers : group->nusers-1;
116 for (i=0 ; i<lastuser ; i++) {
117 if (strcasecmp(user->filename,group->list[i].filename)==0) {
118 clen=sprintf(cstr,"-%04X",count++);
119 if (flen+clen<MAX_USER_FNAME_LEN)
120 strcpy(user->filename+flen,cstr);
121 else
122 strcpy(user->filename+MAX_USER_FNAME_LEN-clen,cstr);
123 }
124 }
125 }
126 }
127
128 return(user);
129 }
130
131 void userinfo_free(void)
132 {
133 struct usergroupstruct *group, *next;
134
135 for (group=first_user_group ; group ; group=next) {
136 next=group->next;
137 free(group);
138 }
139 first_user_group=NULL;
140 }
141
142 struct userinfostruct *userinfo_find_from_file(const char *filename)
143 {
144 struct usergroupstruct *group;
145 int i;
146
147 for (group=first_user_group ; group ; group=group->next) {
148 for (i=0 ; i<group->nusers ; i++)
149 if (strcmp(filename,group->list[i].filename)==0)
150 return(group->list+i);
151 }
152 return(NULL);
153 }
154
155 struct userinfostruct *userinfo_find_from_id(const char *id)
156 {
157 struct usergroupstruct *group;
158 int i;
159
160 for (group=first_user_group ; group ; group=group->next) {
161 for (i=0 ; i<group->nusers ; i++)
162 if (strcmp(id,group->list[i].id)==0)
163 return(group->list+i);
164 }
165 return(NULL);
166 }
167
168 /*!
169 Start the scanning of the user list.
170
171 \return The object to pass to subsequent scanning functions or NULL
172 if it failed. The object must be freed with a call to userinfo_stop().
173 */
174 userscan userinfo_startscan(void)
175 {
176 userscan uscan;
177
178 uscan=malloc(sizeof(*uscan));
179 if (!uscan) return(NULL);
180 uscan->group=first_user_group;
181 uscan->index=0;
182 return(uscan);
183 }
184
185 /*!
186 Free the memory allocated by userinfo_start().
187
188 \param uscan The object created by userinfo_start().
189 */
190 void userinfo_stopscan(userscan uscan)
191 {
192 free(uscan);
193 }
194
195 /*!
196 Get the user pointed to by the object and advance the object
197 to the next user.
198
199 \param uscan The object created by userinfo_start().
200
201 \return The user in the list or NULL if the end of the list
202 is reached.
203 */
204 struct userinfostruct *userinfo_advancescan(userscan uscan)
205 {
206 struct userinfostruct *uinfo;
207
208 if (!uscan) return(NULL);
209 if (!uscan->group) return(NULL);
210 if (uscan->index<0 || uscan->index>=uscan->group->nusers) return(NULL);
211
212 uinfo=uscan->group->list+uscan->index;
213
214 ++uscan->index;
215 if (uscan->index>=uscan->group->nusers) {
216 uscan->group=uscan->group->next;
217 uscan->index=0;
218 }
219 return(uinfo);
220 }
221
222 /*!
223 Clear the general purpose flag from all the user's info.
224 */
225 void userinfo_clearflag(void)
226 {
227 struct usergroupstruct *group;
228 int i;
229
230 for (group=first_user_group ; group ; group=group->next) {
231 for (i=0 ; i<group->nusers ; i++)
232 group->list[i].flag=0;
233 }
234 }
235