Mercurial > noffle
comparison group.c @ 0:04124a4423d4 noffle
[svn] Initial revision
author | enz |
---|---|
date | Tue, 04 Jan 2000 11:35:42 +0000 |
parents | |
children | 526a4c34ee2e |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:04124a4423d4 |
---|---|
1 /* | |
2 group.c | |
3 | |
4 The group database resides in groupinfo.gdbm and stores all we know about | |
5 the groups we know of. One database record is cached in the global struct | |
6 grp. Group information is transfered between the grp and the database by | |
7 loadGrp() and saveGrp(). This is done transparently. Access to the groups | |
8 database is done by group name, by the functions defined in group.h. | |
9 | |
10 $Id: group.c 3 2000-01-04 11:35:42Z enz $ | |
11 */ | |
12 | |
13 #include "group.h" | |
14 #include <gdbm.h> | |
15 #include <errno.h> | |
16 #include <fcntl.h> | |
17 #include <sys/stat.h> | |
18 #include "config.h" | |
19 #include "log.h" | |
20 #include "util.h" | |
21 | |
22 /* currently only used within grp */ | |
23 typedef struct | |
24 { | |
25 int first; /* number of first article within group */ | |
26 int last; /* number of last article within group */ | |
27 int rmtNext; | |
28 time_t created; | |
29 time_t lastAccess; | |
30 } Entry; | |
31 | |
32 struct | |
33 { | |
34 Str name; /* name of the group */ | |
35 Entry entry; /* more information about this group */ | |
36 Str serv; /* server the group resides on */ | |
37 Str dsc; /* description of the group */ | |
38 GDBM_FILE dbf; | |
39 | |
40 } grp = { "(no grp)", { 0, 0, 0, 0, 0 }, "", "", NULL }; | |
41 | |
42 static const char * | |
43 errMsg( void ) | |
44 { | |
45 if ( errno != 0 ) | |
46 return strerror( errno ); | |
47 return gdbm_strerror( gdbm_errno ); | |
48 } | |
49 | |
50 Bool | |
51 Grp_open( void ) | |
52 { | |
53 Str name; | |
54 int flags; | |
55 | |
56 ASSERT( grp.dbf == NULL ); | |
57 snprintf( name, MAXCHAR, "%s/data/groupinfo.gdbm", Cfg_spoolDir() ); | |
58 flags = GDBM_WRCREAT | GDBM_FAST; | |
59 if ( ! ( grp.dbf = gdbm_open( name, 512, flags, 0644, NULL ) ) ) | |
60 { | |
61 Log_err( "Error opening %s for r/w (%s)", errMsg() ); | |
62 return FALSE; | |
63 } | |
64 Log_dbg( "%s opened for r/w", name ); | |
65 return TRUE; | |
66 } | |
67 | |
68 void | |
69 Grp_close( void ) | |
70 { | |
71 ASSERT( grp.dbf ); | |
72 Log_dbg( "Closing groupinfo" ); | |
73 gdbm_close( grp.dbf ); | |
74 grp.dbf = NULL; | |
75 } | |
76 | |
77 /* Load group info from gdbm-database into global struct grp */ | |
78 static Bool | |
79 loadGrp( const char *name ) | |
80 { | |
81 const char *p; | |
82 datum key, val; | |
83 | |
84 ASSERT( grp.dbf ); | |
85 if ( strcmp( grp.name, name ) == 0 ) | |
86 return TRUE; | |
87 key.dptr = (void *)name; | |
88 key.dsize = strlen( name ) + 1; | |
89 val = gdbm_fetch( grp.dbf, key ); | |
90 if ( val.dptr == NULL ) | |
91 return FALSE; | |
92 grp.entry = *( (Entry *)val.dptr ); | |
93 p = val.dptr + sizeof( grp.entry ); | |
94 Utl_cpyStr( grp.serv, p ); | |
95 p += strlen( p ) + 1; | |
96 Utl_cpyStr( grp.dsc, p ); | |
97 Utl_cpyStr( grp.name, name ); | |
98 free( val.dptr ); | |
99 return TRUE; | |
100 } | |
101 | |
102 /* Save group info from global struct grp into gdbm-database */ | |
103 static void | |
104 saveGrp( void ) | |
105 { | |
106 size_t lenServ, lenDsc, bufLen; | |
107 datum key, val; | |
108 void *buf; | |
109 char *p; | |
110 | |
111 ASSERT( grp.dbf ); | |
112 lenServ = strlen( grp.serv ); | |
113 lenDsc = strlen( grp.dsc ); | |
114 bufLen = sizeof( grp.entry ) + lenServ + lenDsc + 2; | |
115 buf = malloc( bufLen ); | |
116 memcpy( buf, (void *)&grp.entry, sizeof( grp.entry ) ); | |
117 p = (char *)buf + sizeof( grp.entry ); | |
118 strcpy( p, grp.serv ); | |
119 p += lenServ + 1; | |
120 strcpy( p, grp.dsc ); | |
121 key.dptr = (void *)grp.name; | |
122 key.dsize = strlen( grp.name ) + 1; | |
123 val.dptr = buf; | |
124 val.dsize = bufLen; | |
125 if ( gdbm_store( grp.dbf, key, val, GDBM_REPLACE ) != 0 ) | |
126 Log_err( "Could not save group %s: %s", errMsg() ); | |
127 free( buf ); | |
128 } | |
129 | |
130 Bool | |
131 Grp_exists( const char *name ) | |
132 { | |
133 datum key; | |
134 | |
135 ASSERT( grp.dbf ); | |
136 key.dptr = (void*)name; | |
137 key.dsize = strlen( name ) + 1; | |
138 return gdbm_exists( grp.dbf, key ); | |
139 } | |
140 | |
141 void | |
142 Grp_create( const char *name ) | |
143 { | |
144 Utl_cpyStr( grp.name, name ); | |
145 Utl_cpyStr( grp.serv, "(unknown)" ); | |
146 grp.dsc[ 0 ] = '\0'; | |
147 grp.entry.first = 0; | |
148 grp.entry.last = 0; | |
149 grp.entry.rmtNext = 0; | |
150 grp.entry.created = 0; | |
151 grp.entry.lastAccess = 0; | |
152 saveGrp(); | |
153 } | |
154 | |
155 const char * | |
156 Grp_dsc( const char *name ) | |
157 { | |
158 if ( ! loadGrp( name ) ) | |
159 return NULL; | |
160 return grp.dsc; | |
161 } | |
162 | |
163 const char * | |
164 Grp_serv( const char *name ) | |
165 { | |
166 static Str serv = ""; | |
167 | |
168 if ( ! loadGrp( name ) ) | |
169 return "[unknown grp]"; | |
170 if ( Cfg_servListContains( grp.serv ) ) | |
171 Utl_cpyStr( serv, grp.serv ); | |
172 else | |
173 snprintf( serv, MAXCHAR, "[%s]", grp.serv ); | |
174 return serv; | |
175 } | |
176 | |
177 int | |
178 Grp_first( const char *name ) | |
179 { | |
180 if ( ! loadGrp( name ) ) | |
181 return 0; | |
182 return grp.entry.first; | |
183 } | |
184 | |
185 int | |
186 Grp_last( const char *name ) | |
187 { | |
188 if ( ! loadGrp( name ) ) | |
189 return 0; | |
190 return grp.entry.last; | |
191 } | |
192 | |
193 int | |
194 Grp_lastAccess( const char *name ) | |
195 { | |
196 if ( ! loadGrp( name ) ) | |
197 return 0; | |
198 return grp.entry.lastAccess; | |
199 } | |
200 | |
201 int | |
202 Grp_rmtNext( const char *name ) | |
203 { | |
204 if ( ! loadGrp( name ) ) | |
205 return 0; | |
206 return grp.entry.rmtNext; | |
207 } | |
208 | |
209 time_t | |
210 Grp_created( const char *name ) | |
211 { | |
212 if ( ! loadGrp( name ) ) | |
213 return 0; | |
214 return grp.entry.created; | |
215 } | |
216 | |
217 /* Replace group's description (only if value != ""). */ | |
218 void | |
219 Grp_setDsc( const char *name, const char *value ) | |
220 { | |
221 if ( loadGrp( name ) ) | |
222 { | |
223 Utl_cpyStr( grp.dsc, value ); | |
224 saveGrp(); | |
225 } | |
226 } | |
227 | |
228 void | |
229 Grp_setServ( const char *name, const char *value ) | |
230 { | |
231 if ( loadGrp( name ) ) | |
232 { | |
233 Utl_cpyStr( grp.serv, value ); | |
234 saveGrp(); | |
235 } | |
236 } | |
237 | |
238 void | |
239 Grp_setCreated( const char *name, time_t value ) | |
240 { | |
241 if ( loadGrp( name ) ) | |
242 { | |
243 grp.entry.created = value; | |
244 saveGrp(); | |
245 } | |
246 } | |
247 | |
248 void | |
249 Grp_setRmtNext( const char *name, int value ) | |
250 { | |
251 if ( loadGrp( name ) ) | |
252 { | |
253 grp.entry.rmtNext = value; | |
254 saveGrp(); | |
255 } | |
256 } | |
257 | |
258 void | |
259 Grp_setLastAccess( const char *name, int value ) | |
260 { | |
261 if ( loadGrp( name ) ) | |
262 { | |
263 grp.entry.lastAccess = value; | |
264 saveGrp(); | |
265 } | |
266 } | |
267 | |
268 void | |
269 Grp_setFirstLast( const char *name, int first, int last ) | |
270 { | |
271 if ( loadGrp( name ) ) | |
272 { | |
273 grp.entry.first = first; | |
274 grp.entry.last = last; | |
275 saveGrp(); | |
276 } | |
277 } | |
278 | |
279 static datum cursor = { NULL, 0 }; | |
280 | |
281 Bool | |
282 Grp_firstGrp( const char **name ) | |
283 { | |
284 ASSERT( grp.dbf ); | |
285 if ( cursor.dptr != NULL ) | |
286 { | |
287 free( cursor.dptr ); | |
288 cursor.dptr = NULL; | |
289 } | |
290 cursor = gdbm_firstkey( grp.dbf ); | |
291 *name = cursor.dptr; | |
292 return ( cursor.dptr != NULL ); | |
293 } | |
294 | |
295 Bool | |
296 Grp_nextGrp( const char **name ) | |
297 { | |
298 void *oldDptr = cursor.dptr; | |
299 | |
300 ASSERT( grp.dbf ); | |
301 if ( cursor.dptr == NULL ) | |
302 return FALSE; | |
303 cursor = gdbm_nextkey( grp.dbf, cursor ); | |
304 free( oldDptr ); | |
305 *name = cursor.dptr; | |
306 return ( cursor.dptr != NULL ); | |
307 } |