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 } |
