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 );
+}