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 }