]> git.ipfire.org Git - thirdparty/sarg.git/blob - userinfo.c
Change year source files's header
[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
60 struct userinfostruct *userinfo_create(const char *userid)
61 {
62 struct usergroupstruct *group, *last;
63 struct userinfostruct *user;
64 int i, j, lastuser;
65 int skip;
66 int flen;
67 int count, clen;
68 char cstr[9];
69
70 last=NULL;
71 for (group=first_user_group ; group ; group=group->next) {
72 if (group->nusers<USERS_PER_GROUP) break;
73 last=group;
74 }
75
76 if (!group) {
77 group=malloc(sizeof(*group));
78 if (!group) {
79 debuga(_("Not enough memory to store the user\n"));
80 exit(EXIT_FAILURE);
81 }
82 memset(group,0,sizeof(*group));
83 if (last)
84 last->next=group;
85 else
86 first_user_group=group;
87 }
88 user=group->list+group->nusers++;
89
90 strncpy(user->id,userid,MAX_USER_LEN-1);
91 user->id[MAX_USER_LEN-1]='\0';
92
93 skip=0;
94 j=0;
95 for (i=0 ; userid[i] && j<MAX_USER_FNAME_LEN-1 ; i++) {
96 if (isalnum(userid[i]) || userid[i]=='-' || userid[i]=='_') {
97 user->filename[j++]=userid[i];
98 skip=0;
99 } else {
100 if (!skip) {
101 user->filename[j++]='_';
102 skip=1;
103 }
104 }
105 }
106 user->filename[j]='\0';
107 flen=i;
108
109 count=0;
110 for (group=first_user_group ; group ; group=group->next) {
111 lastuser=(group->next) ? group->nusers : group->nusers-1;
112 for (i=0 ; i<lastuser ; i++) {
113 if (strcasecmp(user->filename,group->list[i].filename)==0) {
114 clen=sprintf(cstr,"-%04X",count++);
115 if (flen+clen<MAX_USER_FNAME_LEN)
116 strcpy(user->filename+flen,cstr);
117 else
118 strcpy(user->filename+MAX_USER_FNAME_LEN-clen,cstr);
119 }
120 }
121 }
122
123 return(user);
124 }
125
126 void userinfo_free(void)
127 {
128 struct usergroupstruct *group, *next;
129
130 for (group=first_user_group ; group ; group=next) {
131 next=group->next;
132 free(group);
133 }
134 first_user_group=NULL;
135 }
136
137 struct userinfostruct *userinfo_find_from_file(const char *filename)
138 {
139 struct usergroupstruct *group;
140 int i;
141
142 for (group=first_user_group ; group ; group=group->next) {
143 for (i=0 ; i<group->nusers ; i++)
144 if (strcmp(filename,group->list[i].filename)==0)
145 return(group->list+i);
146 }
147 return(NULL);
148 }
149
150 struct userinfostruct *userinfo_find_from_id(const char *id)
151 {
152 struct usergroupstruct *group;
153 int i;
154
155 for (group=first_user_group ; group ; group=group->next) {
156 for (i=0 ; i<group->nusers ; i++)
157 if (strcmp(id,group->list[i].id)==0)
158 return(group->list+i);
159 }
160 return(NULL);
161 }
162
163 /*!
164 Start the scanning of the user list.
165
166 \return The object to pass to subsequent scanning functions or NULL
167 if it failed. The object must be freed with a call to userinfo_stop().
168 */
169 userscan userinfo_startscan(void)
170 {
171 userscan uscan;
172
173 uscan=malloc(sizeof(*uscan));
174 if (!uscan) return(NULL);
175 uscan->group=first_user_group;
176 uscan->index=0;
177 return(uscan);
178 }
179
180 /*!
181 Free the memory allocated by userinfo_start().
182
183 \param uscan The object created by userinfo_start().
184 */
185 void userinfo_stopscan(userscan uscan)
186 {
187 free(uscan);
188 }
189
190 /*!
191 Get the user pointed to by the object and advance the object
192 to the next user.
193
194 \param uscan The object created by userinfo_start().
195
196 \return The user in the list or NULL if the end of the list
197 is reached.
198 */
199 struct userinfostruct *userinfo_advancescan(userscan uscan)
200 {
201 struct userinfostruct *uinfo;
202
203 if (!uscan) return(NULL);
204 if (!uscan->group) return(NULL);
205 if (uscan->index<0 || uscan->index>=uscan->group->nusers) return(NULL);
206
207 uinfo=uscan->group->list+uscan->index;
208
209 ++uscan->index;
210 if (uscan->index>=uscan->group->nusers) {
211 uscan->group=uscan->group->next;
212 uscan->index=0;
213 }
214 return(uinfo);
215 }