Mercurial > noffle
view src/fetchlist.c @ 288:c02c4eb95f95 noffle
[svn] * src/configfile.h,src/configfile.c,docs/noffle.conf.5: Add noffle-user
and noffle-group configs.
* src/configfile.c,src/fetch.c,src/fetchlist.c,src/protocol.c,
src/server.c: Replace strcpy() with Utl_cpyStr() where appropriate.
See Debian bug 168128.
* src/control.c,src/configfile.c,src/noffle.c: Replace [s]scanf("%s")
with [s]scanf(MAXCHAR_FMT).
* src/noffle.c: Log warning if noffle.conf is world readable.
* src/noffle.c: Restrict most options to news admins; i.e. those who
are root or news on running Noffle.
* Makefile.in,acconfig.h,aclocal.m4,config.h.in,configure,configure.in,
docs/Makefile.in,docs/noffle.conf.5,packages/Makefile.in,
packages/redhat/Makefile.in,src/Makefile.am,src/Makefile.in,
src/authenticate.c,src/authenticate.h,src/noffle.c,src/server.c:
Add basic authentication using either Noffle-specific user file
or authenticating via PAM (service 'noffle'). PAM authentication
needs to run as root, so a Noffle server that needs PAM
must be started by root. Helpful (?) error messages will be logged
if not. Noffle will switch ruid and euid to 'news' (or whatever
is configured) ASAP.
* src/noffle.c: Add uid checking.
author | bears |
---|---|
date | Fri, 10 Jan 2003 23:25:45 +0000 |
parents | 01755687c565 |
children |
line wrap: on
line source
/* fetchlist.c $Id: fetchlist.c 419 2003-01-10 23:11:43Z bears $ */ #if HAVE_CONFIG_H #include <config.h> #endif #include <stdio.h> #include <errno.h> #include <unistd.h> #include "fetchlist.h" #include "configfile.h" #include "log.h" #include "util.h" #include "portable.h" struct Elem { Str name; FetchMode mode; }; static struct Fetchlist { struct Elem *elem; int size; int max; Bool dirty; } fetchlist = { NULL, 0, 0, FALSE }; static void clearList( void ) { fetchlist.size = 0; fetchlist.dirty = FALSE; } static int compareElem( const void *elem1, const void *elem2 ) { const struct Elem* e1 = (const struct Elem*)elem1; const struct Elem* e2 = (const struct Elem*)elem2; return strcmp( e1->name, e2->name ); } static struct Elem * searchElem( const char *name ) { int i; for ( i = 0; i < fetchlist.size; ++i ) if ( strcmp( name, fetchlist.elem[ i ].name ) == 0 ) return &fetchlist.elem[ i ]; return NULL; } static void appGrp( const char *name, FetchMode mode ) { struct Elem elem; if ( fetchlist.max < fetchlist.size + 1 ) { if ( ! ( fetchlist.elem = realloc( fetchlist.elem, ( fetchlist.max + 50 ) * sizeof( fetchlist.elem[ 0 ] ) ) ) ) Log_fatal( "Could not realloc fetchlist" ); fetchlist.max += 50; } Utl_cpyStr( elem.name, name ); elem.mode = mode; fetchlist.elem[ fetchlist.size++ ] = elem; } void Fetchlist_read( void ) { FILE *f; Str file; char *p; FetchMode mode = OVER; Bool valid; int ret; Str line, grp, modeStr; Log_dbg( LOG_DBG_FETCH, "Reading %s", file ); snprintf( file, MAXCHAR, "%s/fetchlist", Cfg_spoolDir() ); clearList(); if ( ! ( f = fopen( file, "r" ) ) ) { Log_inf( "No file %s", file ); return; } while ( fgets( line, MAXCHAR, f ) ) { p = Utl_stripWhiteSpace( line ); if ( *p == '#' || *p == '\0' ) continue; ret = sscanf( p, MAXCHAR_FMT " " MAXCHAR_FMT, grp, modeStr ); valid = TRUE; if ( ret < 1 || ret > 2 ) valid = FALSE; else if ( ret >= 2 ) { if ( strcmp( modeStr, "full" ) == 0 ) mode = FULL; else if ( strcmp( modeStr, "thread" ) == 0 ) mode = THREAD; else if ( strcmp( modeStr, "over" ) == 0 ) mode = OVER; else valid = FALSE; } if ( ! valid ) { Log_err( "Invalid entry in %s: %s", file, line ); continue; } appGrp( grp, mode ); } if ( ferror( f ) ) Log_err( "Error reading %s: %s", file, strerror( errno ) ); if ( fclose( f ) != 0 ) Log_err( "Error closing %s; %s", file, strerror( errno ) ); } Bool Fetchlist_write( void ) { int i; FILE *f; Str file, tmpfname; const char *modeStr = ""; Bool res; /* Any changes? */ if ( ! fetchlist.dirty ) return TRUE; qsort( fetchlist.elem, (size_t)fetchlist.size, sizeof( fetchlist.elem[ 0 ] ), compareElem ); snprintf( file, MAXCHAR, "%s/fetchlist", Cfg_spoolDir() ); snprintf( tmpfname, MAXCHAR, "%s/.#%d.fetchlist", Cfg_spoolDir(), (int) getpid() ); if ( ! ( f = fopen( tmpfname, "w" ) ) ) { Log_err( "Could not open %s for writing", file ); return FALSE; } res = TRUE; for ( i = 0; i < fetchlist.size; ++i ) { switch ( fetchlist.elem[ i ].mode ) { case FULL: modeStr = "full"; break; case THREAD: modeStr = "thread"; break; case OVER: modeStr = "over"; break; } fprintf( f, "%s %s\n", fetchlist.elem[ i ].name, modeStr ); if ( ferror( f ) ) { Log_err( "Error writing %s: %s", tmpfname, strerror( errno ) ); clearerr( f ); res = FALSE; } } if ( fclose( f ) != 0 ) { Log_err( "Error closing %s: %s", tmpfname, strerror( errno ) ); res = FALSE; } if ( res ) { if ( rename( tmpfname, file ) < 0 ) { Log_err( "Rename of %s to %s failed: %s", tmpfname, file, strerror( errno ) ); res = FALSE; } } return res; } int Fetchlist_size( void ) { return fetchlist.size; } Bool Fetchlist_contains( const char *name, FetchMode *mode ) { struct Elem *elem = searchElem( name ); if ( elem == NULL ) return FALSE; if ( mode != NULL ) *mode = elem->mode; return TRUE; } Bool Fetchlist_element( const char **name, FetchMode *mode, int idx ) { if ( idx < 0 || idx >= fetchlist.size ) return FALSE; *name = fetchlist.elem[ idx ].name; *mode = fetchlist.elem[ idx ].mode; return TRUE; } Bool Fetchlist_add( const char *name, FetchMode mode ) { struct Elem *elem = searchElem( name ); fetchlist.dirty = TRUE; if ( elem == NULL ) { appGrp( name, mode ); return TRUE; } Utl_cpyStr( elem->name, name ); elem->mode = mode; return FALSE; } Bool Fetchlist_remove( const char *name ) { struct Elem *elem = searchElem( name ); if ( elem == NULL ) return FALSE; fetchlist.dirty = TRUE; *elem = fetchlist.elem[ fetchlist.size - 1 ]; --fetchlist.size; return TRUE; }