Mercurial > noffle
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/group.c Fri May 05 22:45:56 2000 +0100 @@ -0,0 +1,375 @@ +/* + group.c + + The group database resides in groupinfo.gdbm and stores all we know about + the groups we know of. One database record is cached in the global struct + grp. Group information is transfered between the grp and the database by + loadGrp() and saveGrp(). This is done transparently. Access to the groups + database is done by group name, by the functions defined in group.h. + + $Id: group.c 49 2000-05-05 21:45:56Z uh1763 $ +*/ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include "group.h" +#include <gdbm.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> +#include "configfile.h" +#include "log.h" +#include "util.h" + +/* currently only used within grp */ +typedef struct +{ + int first; /* number of first article within group */ + int last; /* number of last article within group */ + int rmtNext; + time_t created; + time_t lastAccess; +} Entry; + +struct +{ + Str name; /* name of the group */ + Entry entry; /* more information about this group */ + Str serv; /* server the group resides on */ + Str dsc; /* description of the group */ + char postAllow; /* Posting status */ + GDBM_FILE dbf; +} grp = { "(no grp)", { 0, 0, 0, 0, 0 }, "", "", ' ', NULL }; + +/* + Note: postAllow should really go in Entry. But changing Entry would + make backwards group file format capability tricky, so it goes + where it is, and we test the length of the retrieved record to + determine if it exists. + + Someday if we really change the record format this should be tidied up. + */ + +static const char * +errMsg( void ) +{ + if ( errno != 0 ) + return strerror( errno ); + return gdbm_strerror( gdbm_errno ); +} + +Bool +Grp_open( void ) +{ + Str name; + int flags; + + ASSERT( grp.dbf == NULL ); + snprintf( name, MAXCHAR, "%s/data/groupinfo.gdbm", Cfg_spoolDir() ); + flags = GDBM_WRCREAT | GDBM_FAST; + if ( ! ( grp.dbf = gdbm_open( name, 512, flags, 0644, NULL ) ) ) + { + Log_err( "Error opening %s for r/w (%s)", errMsg() ); + return FALSE; + } + Log_dbg( "%s opened for r/w", name ); + return TRUE; +} + +void +Grp_close( void ) +{ + ASSERT( grp.dbf ); + Log_dbg( "Closing groupinfo" ); + gdbm_close( grp.dbf ); + grp.dbf = NULL; + Utl_cpyStr( grp.name, "" ); +} + +/* Load group info from gdbm-database into global struct grp */ +static Bool +loadGrp( const char *name ) +{ + const char *p; + datum key, val; + + ASSERT( grp.dbf ); + if ( strcmp( grp.name, name ) == 0 ) + return TRUE; + key.dptr = (void *)name; + key.dsize = strlen( name ) + 1; + val = gdbm_fetch( grp.dbf, key ); + if ( val.dptr == NULL ) + return FALSE; + grp.entry = *( (Entry *)val.dptr ); + p = val.dptr + sizeof( grp.entry ); + Utl_cpyStr( grp.serv, p ); + p += strlen( p ) + 1; + Utl_cpyStr( grp.dsc, p ); + p += strlen( p) + 1; + if ( p - val.dptr < val.dsize ) + grp.postAllow = p[ 0 ]; + else + grp.postAllow = 'y'; + Utl_cpyStr( grp.name, name ); + free( val.dptr ); + return TRUE; +} + +/* Save group info from global struct grp into gdbm-database */ +static void +saveGrp( void ) +{ + size_t lenServ, lenDsc, bufLen; + datum key, val; + void *buf; + char *p; + + ASSERT( grp.dbf ); + lenServ = strlen( grp.serv ); + lenDsc = strlen( grp.dsc ); + bufLen = sizeof( grp.entry ) + lenServ + lenDsc + 2 + sizeof( char ); + buf = malloc( bufLen ); + memcpy( buf, (void *)&grp.entry, sizeof( grp.entry ) ); + p = (char *)buf + sizeof( grp.entry ); + strcpy( p, grp.serv ); + p += lenServ + 1; + strcpy( p, grp.dsc ); + p += lenDsc + 1; + p[ 0 ] = grp.postAllow; + key.dptr = (void *)grp.name; + key.dsize = strlen( grp.name ) + 1; + val.dptr = buf; + val.dsize = bufLen; + if ( gdbm_store( grp.dbf, key, val, GDBM_REPLACE ) != 0 ) + Log_err( "Could not save group %s: %s", errMsg() ); + free( buf ); +} + +Bool +Grp_exists( const char *name ) +{ + datum key; + + ASSERT( grp.dbf ); + key.dptr = (void*)name; + key.dsize = strlen( name ) + 1; + return gdbm_exists( grp.dbf, key ); +} + +Bool +Grp_local( const char *name ) +{ + if ( ! loadGrp( name ) ) + return 0; + return ( strcmp( grp.serv, GRP_LOCAL_SERVER_NAME ) == 0 ); +} + +void +Grp_create( const char *name ) +{ + Utl_cpyStr( grp.name, name ); + Utl_cpyStr( grp.serv, "(unknown)" ); + grp.dsc[ 0 ] = '\0'; + grp.entry.first = 1; + grp.entry.last = 0; + grp.entry.rmtNext = 0; + grp.entry.created = 0; + grp.entry.lastAccess = 0; + grp.postAllow = 'y'; + saveGrp(); +} + +void +Grp_delete( const char *name ) +{ + datum key; + + ASSERT( grp.dbf ); + key.dptr = (void*)name; + key.dsize = strlen( name ) + 1; + gdbm_delete( grp.dbf, key ); +} + +const char * +Grp_dsc( const char *name ) +{ + if ( ! loadGrp( name ) ) + return NULL; + return grp.dsc; +} + +const char * +Grp_serv( const char *name ) +{ + static Str serv = ""; + + if ( ! loadGrp( name ) ) + return "[unknown grp]"; + if ( Cfg_servListContains( grp.serv ) + || Grp_local( name ) ) + Utl_cpyStr( serv, grp.serv ); + else + snprintf( serv, MAXCHAR, "[%s]", grp.serv ); + return serv; +} + +int +Grp_first( const char *name ) +{ + if ( ! loadGrp( name ) ) + return 0; + return grp.entry.first; +} + +int +Grp_last( const char *name ) +{ + if ( ! loadGrp( name ) ) + return 0; + return grp.entry.last; +} + +int +Grp_lastAccess( const char *name ) +{ + if ( ! loadGrp( name ) ) + return 0; + return grp.entry.lastAccess; +} + +int +Grp_rmtNext( const char *name ) +{ + if ( ! loadGrp( name ) ) + return 0; + return grp.entry.rmtNext; +} + +time_t +Grp_created( const char *name ) +{ + if ( ! loadGrp( name ) ) + return 0; + return grp.entry.created; +} + +char +Grp_postAllow( const char *name ) +{ + if ( ! loadGrp( name ) ) + return 0; + return grp.postAllow; +} + + +/* Replace group's description (only if value != ""). */ +void +Grp_setDsc( const char *name, const char *value ) +{ + if ( loadGrp( name ) ) + { + Utl_cpyStr( grp.dsc, value ); + saveGrp(); + } +} + +void +Grp_setLocal( const char *name ) +{ + Grp_setServ( name, GRP_LOCAL_SERVER_NAME ); +} + +void +Grp_setServ( const char *name, const char *value ) +{ + if ( loadGrp( name ) ) + { + Utl_cpyStr( grp.serv, value ); + saveGrp(); + } +} + +void +Grp_setCreated( const char *name, time_t value ) +{ + if ( loadGrp( name ) ) + { + grp.entry.created = value; + saveGrp(); + } +} + +void +Grp_setRmtNext( const char *name, int value ) +{ + if ( loadGrp( name ) ) + { + grp.entry.rmtNext = value; + saveGrp(); + } +} + +void +Grp_setLastAccess( const char *name, int value ) +{ + if ( loadGrp( name ) ) + { + grp.entry.lastAccess = value; + saveGrp(); + } +} + +void +Grp_setPostAllow( const char *name, char postAllow ) +{ + if ( loadGrp( name ) ) + { + grp.postAllow = postAllow; + saveGrp(); + } +} + +void +Grp_setFirstLast( const char *name, int first, int last ) +{ + if ( loadGrp( name ) ) + { + grp.entry.first = first; + grp.entry.last = last; + saveGrp(); + } +} + +static datum cursor = { NULL, 0 }; + +Bool +Grp_firstGrp( const char **name ) +{ + ASSERT( grp.dbf ); + if ( cursor.dptr != NULL ) + { + free( cursor.dptr ); + cursor.dptr = NULL; + } + cursor = gdbm_firstkey( grp.dbf ); + *name = cursor.dptr; + return ( cursor.dptr != NULL ); +} + +Bool +Grp_nextGrp( const char **name ) +{ + void *oldDptr = cursor.dptr; + + ASSERT( grp.dbf ); + if ( cursor.dptr == NULL ) + return FALSE; + cursor = gdbm_nextkey( grp.dbf, cursor ); + free( oldDptr ); + *name = cursor.dptr; + return ( cursor.dptr != NULL ); +}