Mercurial > noffle
diff src/content.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 | 32ba1198c6fa |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/content.c Fri May 05 22:45:56 2000 +0100 @@ -0,0 +1,266 @@ +/* + content.c + + $Id: content.c 49 2000-05-05 21:45:56Z uh1763 $ +*/ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <dirent.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include "common.h" +#include "configfile.h" +#include "group.h" +#include "log.h" +#include "over.h" +#include "pseudo.h" +#include "util.h" + +struct +{ + DIR *dir; /* Directory for browsing through all + groups */ + int vecFirst; /* First article number in vector */ + int first; /* First live article number */ + int last; /* Last article number */ + unsigned int size; /* Number of overviews. */ + unsigned int max; /* Size of elem. */ + Over **elem; /* Ptr to array with ptrs to overviews. + NULL entries for non-existing article numbers + in group. */ + Str name; + Str file; +} cont = { NULL, 1, 1, 0, 0, 0, NULL, "", "" }; + +void +Cont_app( Over *ov ) +{ + if ( cont.max < cont.size + 1 ) + { + if ( ! ( cont.elem = realloc( cont.elem, + ( cont.max + 500 ) + * sizeof( cont.elem[ 0 ] ) ) ) ) + { + Log_err( "Could not realloc overview list" ); + exit( EXIT_FAILURE ); + } + cont.max += 500; + } + ASSERT( cont.vecFirst > 0 ); + if ( ov ) + Ov_setNumb( ov, cont.vecFirst + cont.size ); + cont.elem[ cont.size++ ] = ov; + cont.last = cont.vecFirst + cont.size - 1; +} + +Bool +Cont_validNumb( int n ) +{ + return ( n != 0 && n >= cont.first && n <= cont.last + && cont.elem[ n - cont.vecFirst ] ); +} + +void +Cont_delete( int n ) +{ + Over **ov; + + if ( ! Cont_validNumb( n ) ) + return; + ov = &cont.elem[ n - cont.vecFirst ]; + free( *ov ); + *ov = NULL; +} + +/* Remove all overviews from content. */ +static void +clearCont() +{ + int i; + + for ( i = 0; i < cont.size; ++i ) + del_Over( cont.elem[ i ] ); + cont.size = 0; +} + +static void +setupEmpty( const char *name ) +{ + cont.last = Grp_last( name ); + cont.first = cont.vecFirst = cont.last + 1; + ASSERT( cont.first > 0 ); +} + +/* Extend content list to size "cnt" and append NULL entries. */ +static void +extendCont( int cnt ) +{ + int i, n; + + if ( cont.size < cnt ) + { + n = cnt - cont.size; + for ( i = 0; i < n; ++i ) + Cont_app( NULL ); + } +} + +/* Discard all cached overviews, and read in the overviews of a new group + from its overviews file. */ +void +Cont_read( const char *name ) +{ + FILE *f; + Over *ov; + int numb; + Str line; + + /* Delete old overviews and make room for new ones. */ + cont.vecFirst = 0; + cont.first = 0; + cont.last = 0; + Utl_cpyStr( cont.name, name ); + clearCont(); + + /* read overviews from overview file and store them in the overviews + list */ + snprintf( cont.file, MAXCHAR, "%s/overview/%s", Cfg_spoolDir(), name ); + f = fopen( cont.file, "r" ); + if ( ! f ) + { + Log_dbg( "No group overview file: %s", cont.file ); + setupEmpty( name ); + return; + } + Log_dbg( "Reading %s", cont.file ); + while ( fgets( line, MAXCHAR, f ) ) + { + if ( ! ( ov = Ov_read( line ) ) ) + { + Log_err( "Overview corrupted in %s: %s", name, line ); + continue; + } + numb = Ov_numb( ov ); + if ( numb < cont.first ) + { + Log_err( "Wrong ordering in %s: %s", name, line ); + continue; + } + if ( cont.first == 0 ) + cont.first = cont.vecFirst = numb; + cont.last = numb; + extendCont( numb - cont.first + 1 ); + cont.elem[ numb - cont.first ] = ov; + } + fclose( f ); + + if ( cont.first == 0 ) + setupEmpty( name ); /* Corrupt overview file recovery */ +} + +void +Cont_write( void ) +{ + Bool anythingWritten; + int i; + FILE *f; + const Over *ov; + + + /* Move the first article no. to the first active article */ + while ( ! Cont_validNumb( cont.first ) && cont.first <= cont.last ) + ++cont.first; + + /* Save the overview */ + if ( ! ( f = fopen( cont.file, "w" ) ) ) + { + Log_err( "Could not open %s for writing", cont.file ); + return; + } + Log_dbg( "Writing %s (%lu)", cont.file, cont.size ); + anythingWritten = FALSE; + for ( i = 0; i < cont.size; ++i ) + { + if ( ( ov = cont.elem[ i ] ) ) + { + if ( ! Pseudo_isGeneralInfo( Ov_msgId( ov ) ) ) + { + if ( ! Ov_write( ov, f ) ) + { + Log_err( "Writing of overview line failed" ); + break; + } + else + anythingWritten = TRUE; + } + } + } + fclose( f ); + + /* + If empty, remove the overview file and set set first to one + beyond last to flag said emptiness. + */ + if ( ! anythingWritten ) + { + unlink( cont.file ); + cont.first = cont.last + 1; + } +} + +const Over * +Cont_get( int numb ) +{ + if ( ! Cont_validNumb( numb ) ) + return NULL; + return cont.elem[ numb - cont.vecFirst ]; +} + +int +Cont_first( void ) { return cont.first; } + +int +Cont_last( void ) { return cont.last; } + +const char * +Cont_grp( void ) { return cont.name; } + +Bool +Cont_nextGrp( Str result ) +{ + struct dirent *d; + + ASSERT( cont.dir ); + if ( ! ( d = readdir( cont.dir ) ) ) + { + cont.dir = NULL; + return FALSE; + } + if ( ! d->d_name ) + return FALSE; + Utl_cpyStr( result, d->d_name ); + result[ MAXCHAR - 1 ] = '\0'; + return TRUE; +} + +Bool +Cont_firstGrp( Str result ) +{ + Str name; + + snprintf( name, MAXCHAR, "%s/overview", Cfg_spoolDir() ); + if ( ! ( cont.dir = opendir( name ) ) ) + { + Log_err( "Cannot open %s", name ); + return FALSE; + } + Cont_nextGrp( result ); /* "." */ + Cont_nextGrp( result ); /* ".." */ + return Cont_nextGrp( result ); +}