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