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 }