]> git.ipfire.org Git - thirdparty/sarg.git/blame - userinfo.c
Update the Russian translation.
[thirdparty/sarg.git] / userinfo.c
CommitLineData
f2ec8c75
FM
1/*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
e99bf0c0 3 * 1998, 2013
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 61
cfd16d6e 62struct userinfostruct *userinfo_create(const char *userid,const char *ip)
f2ec8c75 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';
cfd16d6e
FM
113 strncpy(user->ip,ip,sizeof(user->ip)-1);
114 user->ip[sizeof(user->ip)-1]='\0';
829a53c2
FM
115
116 count=0;
117 for (group=first_user_group ; group ; group=group->next) {
118 lastuser=(group->next) ? group->nusers : group->nusers-1;
119 for (i=0 ; i<lastuser ; i++) {
120 if (strcasecmp(user->filename,group->list[i].filename)==0) {
8217e6e5 121 clen=sprintf(cstr,"+%X",count++);
829a53c2
FM
122 if (flen+clen<MAX_USER_FNAME_LEN)
123 strcpy(user->filename+flen,cstr);
124 else
125 strcpy(user->filename+MAX_USER_FNAME_LEN-clen,cstr);
126 }
9bd92830
FM
127 }
128 }
129 }
130
131 return(user);
f2ec8c75
FM
132}
133
134void userinfo_free(void)
135{
9bd92830 136 struct usergroupstruct *group, *next;
f2ec8c75 137
9bd92830
FM
138 for (group=first_user_group ; group ; group=next) {
139 next=group->next;
140 free(group);
141 }
142 first_user_group=NULL;
f2ec8c75
FM
143}
144
145struct userinfostruct *userinfo_find_from_file(const char *filename)
146{
9bd92830
FM
147 struct usergroupstruct *group;
148 int i;
149
150 for (group=first_user_group ; group ; group=group->next) {
151 for (i=0 ; i<group->nusers ; i++)
152 if (strcmp(filename,group->list[i].filename)==0)
153 return(group->list+i);
154 }
155 return(NULL);
f2ec8c75
FM
156}
157
158struct userinfostruct *userinfo_find_from_id(const char *id)
159{
9bd92830
FM
160 struct usergroupstruct *group;
161 int i;
162
163 for (group=first_user_group ; group ; group=group->next) {
164 for (i=0 ; i<group->nusers ; i++)
165 if (strcmp(id,group->list[i].id)==0)
166 return(group->list+i);
167 }
168 return(NULL);
f2ec8c75 169}
93551487
FM
170
171/*!
172Start the scanning of the user list.
173
174\return The object to pass to subsequent scanning functions or NULL
175if it failed. The object must be freed with a call to userinfo_stop().
176*/
177userscan userinfo_startscan(void)
178{
179 userscan uscan;
180
181 uscan=malloc(sizeof(*uscan));
182 if (!uscan) return(NULL);
183 uscan->group=first_user_group;
184 uscan->index=0;
185 return(uscan);
186}
187
188/*!
189Free the memory allocated by userinfo_start().
190
191\param uscan The object created by userinfo_start().
192*/
193void userinfo_stopscan(userscan uscan)
194{
195 free(uscan);
196}
197
198/*!
199Get the user pointed to by the object and advance the object
200to the next user.
201
202\param uscan The object created by userinfo_start().
203
204\return The user in the list or NULL if the end of the list
205is reached.
206*/
207struct userinfostruct *userinfo_advancescan(userscan uscan)
208{
209 struct userinfostruct *uinfo;
210
211 if (!uscan) return(NULL);
212 if (!uscan->group) return(NULL);
213 if (uscan->index<0 || uscan->index>=uscan->group->nusers) return(NULL);
214
215 uinfo=uscan->group->list+uscan->index;
216
217 ++uscan->index;
218 if (uscan->index>=uscan->group->nusers) {
219 uscan->group=uscan->group->next;
220 uscan->index=0;
221 }
222 return(uinfo);
223}
a58e6d54
FM
224
225/*!
226Clear the general purpose flag from all the user's info.
227*/
228void userinfo_clearflag(void)
229{
230 struct usergroupstruct *group;
231 int i;
232
233 for (group=first_user_group ; group ; group=group->next) {
234 for (i=0 ; i<group->nusers ; i++)
235 group->list[i].flag=0;
236 }
237}
238