Mercurial > noffle
comparison src/group.c @ 43:2842f50feb55 noffle
[svn] * client.c, client.h, common.h, config.c, config.h, content.c, content.h,
control.c, control.h, database.c, database.h, dynamicstring.c,
dynamicstring.h, fetch.c, fetch.h, fetchlist.c, fetchlist.h, group.c,
group.h, itemlist.c, itemlist.h, lock.c, lock.h, log.c, log.h, noffle.c,
online.c, online.h, outgoing.c, outgoing.h, over.c, over.h, post.c, post.h,
protocol.c, protocol.h, pseudo.c, pseudo.h, request.c, request.h, server.c,
server.h, util.c, util.h, wildmat.c, wildmat.h: Moved files to the
subdirectory src/
* Makefile.am, acconfig.h, configure.in, docs/Makefile.am, src/Makefile.am,
Makefile.in, aclocal.m4, config.h.in, configure, install-sh, missing,
mkinstalldirs, stamp-h.in, docs/Makefile.in, src/Makefile.in: Added files.
They are used by aclocal, autoheader, autoconf and automake.
* src/config.c, src/config.h: Renamed to configfile.c and configfile.h,
because configure will generate a config.h file itself.
* src/client.c, src/content.c, src/database.c, src/fetch.c, src/fetchlist.c,
src/group.c, src/lock.c, src/noffle.c, src/online.c, src/outgoing.c,
src/over.c, src/pseudo.c, src/request.c, src/server.c, src/util.c:
Changed '#include "config.h"' to '#include "configfile.h"'.
* src/client.c, src/content.c, src/database.c, src/fetch.c, src/fetchlist.c,
src/group.c, src/lock.c, src/online.c, src/outgoing.c, src/post.c,
src/protocol.c, src/request.c, src/server.c: Files now #include <config.h>.
Added missing <stdio.h>. This removes the warnings about snprintf() not
being declared.
* Makefile: Removed. This is now generated by configure.
author | uh1763 |
---|---|
date | Fri, 05 May 2000 22:45:56 +0100 |
parents | |
children | 125d79c9e586 |
comparison
equal
deleted
inserted
replaced
42:2467ff423c15 | 43:2842f50feb55 |
---|---|
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 49 2000-05-05 21:45:56Z uh1763 $ | |
11 */ | |
12 | |
13 #if HAVE_CONFIG_H | |
14 #include <config.h> | |
15 #endif | |
16 | |
17 #include <stdio.h> | |
18 #include "group.h" | |
19 #include <gdbm.h> | |
20 #include <errno.h> | |
21 #include <fcntl.h> | |
22 #include <sys/stat.h> | |
23 #include "configfile.h" | |
24 #include "log.h" | |
25 #include "util.h" | |
26 | |
27 /* currently only used within grp */ | |
28 typedef struct | |
29 { | |
30 int first; /* number of first article within group */ | |
31 int last; /* number of last article within group */ | |
32 int rmtNext; | |
33 time_t created; | |
34 time_t lastAccess; | |
35 } Entry; | |
36 | |
37 struct | |
38 { | |
39 Str name; /* name of the group */ | |
40 Entry entry; /* more information about this group */ | |
41 Str serv; /* server the group resides on */ | |
42 Str dsc; /* description of the group */ | |
43 char postAllow; /* Posting status */ | |
44 GDBM_FILE dbf; | |
45 } grp = { "(no grp)", { 0, 0, 0, 0, 0 }, "", "", ' ', NULL }; | |
46 | |
47 /* | |
48 Note: postAllow should really go in Entry. But changing Entry would | |
49 make backwards group file format capability tricky, so it goes | |
50 where it is, and we test the length of the retrieved record to | |
51 determine if it exists. | |
52 | |
53 Someday if we really change the record format this should be tidied up. | |
54 */ | |
55 | |
56 static const char * | |
57 errMsg( void ) | |
58 { | |
59 if ( errno != 0 ) | |
60 return strerror( errno ); | |
61 return gdbm_strerror( gdbm_errno ); | |
62 } | |
63 | |
64 Bool | |
65 Grp_open( void ) | |
66 { | |
67 Str name; | |
68 int flags; | |
69 | |
70 ASSERT( grp.dbf == NULL ); | |
71 snprintf( name, MAXCHAR, "%s/data/groupinfo.gdbm", Cfg_spoolDir() ); | |
72 flags = GDBM_WRCREAT | GDBM_FAST; | |
73 if ( ! ( grp.dbf = gdbm_open( name, 512, flags, 0644, NULL ) ) ) | |
74 { | |
75 Log_err( "Error opening %s for r/w (%s)", errMsg() ); | |
76 return FALSE; | |
77 } | |
78 Log_dbg( "%s opened for r/w", name ); | |
79 return TRUE; | |
80 } | |
81 | |
82 void | |
83 Grp_close( void ) | |
84 { | |
85 ASSERT( grp.dbf ); | |
86 Log_dbg( "Closing groupinfo" ); | |
87 gdbm_close( grp.dbf ); | |
88 grp.dbf = NULL; | |
89 Utl_cpyStr( grp.name, "" ); | |
90 } | |
91 | |
92 /* Load group info from gdbm-database into global struct grp */ | |
93 static Bool | |
94 loadGrp( const char *name ) | |
95 { | |
96 const char *p; | |
97 datum key, val; | |
98 | |
99 ASSERT( grp.dbf ); | |
100 if ( strcmp( grp.name, name ) == 0 ) | |
101 return TRUE; | |
102 key.dptr = (void *)name; | |
103 key.dsize = strlen( name ) + 1; | |
104 val = gdbm_fetch( grp.dbf, key ); | |
105 if ( val.dptr == NULL ) | |
106 return FALSE; | |
107 grp.entry = *( (Entry *)val.dptr ); | |
108 p = val.dptr + sizeof( grp.entry ); | |
109 Utl_cpyStr( grp.serv, p ); | |
110 p += strlen( p ) + 1; | |
111 Utl_cpyStr( grp.dsc, p ); | |
112 p += strlen( p) + 1; | |
113 if ( p - val.dptr < val.dsize ) | |
114 grp.postAllow = p[ 0 ]; | |
115 else | |
116 grp.postAllow = 'y'; | |
117 Utl_cpyStr( grp.name, name ); | |
118 free( val.dptr ); | |
119 return TRUE; | |
120 } | |
121 | |
122 /* Save group info from global struct grp into gdbm-database */ | |
123 static void | |
124 saveGrp( void ) | |
125 { | |
126 size_t lenServ, lenDsc, bufLen; | |
127 datum key, val; | |
128 void *buf; | |
129 char *p; | |
130 | |
131 ASSERT( grp.dbf ); | |
132 lenServ = strlen( grp.serv ); | |
133 lenDsc = strlen( grp.dsc ); | |
134 bufLen = sizeof( grp.entry ) + lenServ + lenDsc + 2 + sizeof( char ); | |
135 buf = malloc( bufLen ); | |
136 memcpy( buf, (void *)&grp.entry, sizeof( grp.entry ) ); | |
137 p = (char *)buf + sizeof( grp.entry ); | |
138 strcpy( p, grp.serv ); | |
139 p += lenServ + 1; | |
140 strcpy( p, grp.dsc ); | |
141 p += lenDsc + 1; | |
142 p[ 0 ] = grp.postAllow; | |
143 key.dptr = (void *)grp.name; | |
144 key.dsize = strlen( grp.name ) + 1; | |
145 val.dptr = buf; | |
146 val.dsize = bufLen; | |
147 if ( gdbm_store( grp.dbf, key, val, GDBM_REPLACE ) != 0 ) | |
148 Log_err( "Could not save group %s: %s", errMsg() ); | |
149 free( buf ); | |
150 } | |
151 | |
152 Bool | |
153 Grp_exists( const char *name ) | |
154 { | |
155 datum key; | |
156 | |
157 ASSERT( grp.dbf ); | |
158 key.dptr = (void*)name; | |
159 key.dsize = strlen( name ) + 1; | |
160 return gdbm_exists( grp.dbf, key ); | |
161 } | |
162 | |
163 Bool | |
164 Grp_local( const char *name ) | |
165 { | |
166 if ( ! loadGrp( name ) ) | |
167 return 0; | |
168 return ( strcmp( grp.serv, GRP_LOCAL_SERVER_NAME ) == 0 ); | |
169 } | |
170 | |
171 void | |
172 Grp_create( const char *name ) | |
173 { | |
174 Utl_cpyStr( grp.name, name ); | |
175 Utl_cpyStr( grp.serv, "(unknown)" ); | |
176 grp.dsc[ 0 ] = '\0'; | |
177 grp.entry.first = 1; | |
178 grp.entry.last = 0; | |
179 grp.entry.rmtNext = 0; | |
180 grp.entry.created = 0; | |
181 grp.entry.lastAccess = 0; | |
182 grp.postAllow = 'y'; | |
183 saveGrp(); | |
184 } | |
185 | |
186 void | |
187 Grp_delete( const char *name ) | |
188 { | |
189 datum key; | |
190 | |
191 ASSERT( grp.dbf ); | |
192 key.dptr = (void*)name; | |
193 key.dsize = strlen( name ) + 1; | |
194 gdbm_delete( grp.dbf, key ); | |
195 } | |
196 | |
197 const char * | |
198 Grp_dsc( const char *name ) | |
199 { | |
200 if ( ! loadGrp( name ) ) | |
201 return NULL; | |
202 return grp.dsc; | |
203 } | |
204 | |
205 const char * | |
206 Grp_serv( const char *name ) | |
207 { | |
208 static Str serv = ""; | |
209 | |
210 if ( ! loadGrp( name ) ) | |
211 return "[unknown grp]"; | |
212 if ( Cfg_servListContains( grp.serv ) | |
213 || Grp_local( name ) ) | |
214 Utl_cpyStr( serv, grp.serv ); | |
215 else | |
216 snprintf( serv, MAXCHAR, "[%s]", grp.serv ); | |
217 return serv; | |
218 } | |
219 | |
220 int | |
221 Grp_first( const char *name ) | |
222 { | |
223 if ( ! loadGrp( name ) ) | |
224 return 0; | |
225 return grp.entry.first; | |
226 } | |
227 | |
228 int | |
229 Grp_last( const char *name ) | |
230 { | |
231 if ( ! loadGrp( name ) ) | |
232 return 0; | |
233 return grp.entry.last; | |
234 } | |
235 | |
236 int | |
237 Grp_lastAccess( const char *name ) | |
238 { | |
239 if ( ! loadGrp( name ) ) | |
240 return 0; | |
241 return grp.entry.lastAccess; | |
242 } | |
243 | |
244 int | |
245 Grp_rmtNext( const char *name ) | |
246 { | |
247 if ( ! loadGrp( name ) ) | |
248 return 0; | |
249 return grp.entry.rmtNext; | |
250 } | |
251 | |
252 time_t | |
253 Grp_created( const char *name ) | |
254 { | |
255 if ( ! loadGrp( name ) ) | |
256 return 0; | |
257 return grp.entry.created; | |
258 } | |
259 | |
260 char | |
261 Grp_postAllow( const char *name ) | |
262 { | |
263 if ( ! loadGrp( name ) ) | |
264 return 0; | |
265 return grp.postAllow; | |
266 } | |
267 | |
268 | |
269 /* Replace group's description (only if value != ""). */ | |
270 void | |
271 Grp_setDsc( const char *name, const char *value ) | |
272 { | |
273 if ( loadGrp( name ) ) | |
274 { | |
275 Utl_cpyStr( grp.dsc, value ); | |
276 saveGrp(); | |
277 } | |
278 } | |
279 | |
280 void | |
281 Grp_setLocal( const char *name ) | |
282 { | |
283 Grp_setServ( name, GRP_LOCAL_SERVER_NAME ); | |
284 } | |
285 | |
286 void | |
287 Grp_setServ( const char *name, const char *value ) | |
288 { | |
289 if ( loadGrp( name ) ) | |
290 { | |
291 Utl_cpyStr( grp.serv, value ); | |
292 saveGrp(); | |
293 } | |
294 } | |
295 | |
296 void | |
297 Grp_setCreated( const char *name, time_t value ) | |
298 { | |
299 if ( loadGrp( name ) ) | |
300 { | |
301 grp.entry.created = value; | |
302 saveGrp(); | |
303 } | |
304 } | |
305 | |
306 void | |
307 Grp_setRmtNext( const char *name, int value ) | |
308 { | |
309 if ( loadGrp( name ) ) | |
310 { | |
311 grp.entry.rmtNext = value; | |
312 saveGrp(); | |
313 } | |
314 } | |
315 | |
316 void | |
317 Grp_setLastAccess( const char *name, int value ) | |
318 { | |
319 if ( loadGrp( name ) ) | |
320 { | |
321 grp.entry.lastAccess = value; | |
322 saveGrp(); | |
323 } | |
324 } | |
325 | |
326 void | |
327 Grp_setPostAllow( const char *name, char postAllow ) | |
328 { | |
329 if ( loadGrp( name ) ) | |
330 { | |
331 grp.postAllow = postAllow; | |
332 saveGrp(); | |
333 } | |
334 } | |
335 | |
336 void | |
337 Grp_setFirstLast( const char *name, int first, int last ) | |
338 { | |
339 if ( loadGrp( name ) ) | |
340 { | |
341 grp.entry.first = first; | |
342 grp.entry.last = last; | |
343 saveGrp(); | |
344 } | |
345 } | |
346 | |
347 static datum cursor = { NULL, 0 }; | |
348 | |
349 Bool | |
350 Grp_firstGrp( const char **name ) | |
351 { | |
352 ASSERT( grp.dbf ); | |
353 if ( cursor.dptr != NULL ) | |
354 { | |
355 free( cursor.dptr ); | |
356 cursor.dptr = NULL; | |
357 } | |
358 cursor = gdbm_firstkey( grp.dbf ); | |
359 *name = cursor.dptr; | |
360 return ( cursor.dptr != NULL ); | |
361 } | |
362 | |
363 Bool | |
364 Grp_nextGrp( const char **name ) | |
365 { | |
366 void *oldDptr = cursor.dptr; | |
367 | |
368 ASSERT( grp.dbf ); | |
369 if ( cursor.dptr == NULL ) | |
370 return FALSE; | |
371 cursor = gdbm_nextkey( grp.dbf, cursor ); | |
372 free( oldDptr ); | |
373 *name = cursor.dptr; | |
374 return ( cursor.dptr != NULL ); | |
375 } |