view content.c @ 32:45ddd5e72164 noffle

[svn] Added comment about seemingly unnessecary code.
author enz
date Sun, 30 Apr 2000 20:07:54 +0100
parents 912123d43a87
children 8e972daaeab9
line wrap: on
line source

/*
  content.c

  $Id: content.c 6 2000-01-04 13:49:50Z enz $
*/

#include <dirent.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "common.h"
#include "config.h"
#include "log.h"
#include "over.h"
#include "pseudo.h"
#include "util.h"

struct
{
    DIR *dir;           /* Directory for browsing through all
                           groups */
    int first;
    int last;
    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, 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;
    }
    if ( cont.first == 0 )
        cont.first = 1;
    if ( ov )
        Ov_setNumb( ov, cont.first + cont.size );
    cont.elem[ cont.size++ ] = ov;
    cont.last = cont.first + cont.size - 1;
}

Bool
Cont_validNumb( int n )
{
    return ( n != 0 && n >= cont.first && n <= cont.last
             && cont.elem[ n - cont.first ] );
}

void
Cont_delete( int n )
{
    Over **ov;

    if ( ! Cont_validNumb( n ) )
        return;
    ov = &cont.elem[ n - cont.first ];
    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;
}

/* 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.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 );
        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 = numb;
        cont.last = numb;
        extendCont( numb - cont.first + 1 );
        cont.elem[ numb - cont.first ] = ov;
    }
    fclose( f );
}

void
Cont_write( void )
{
    Bool anythingWritten;
    int i, first;
    FILE *f;
    const Over *ov;

    first = cont.first;
    while ( ! Cont_validNumb( first ) && first <= cont.last )
        ++first;
    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 ( ! anythingWritten )
        unlink( cont.file );
}

const Over *
Cont_get( int numb )
{
    if ( ! Cont_validNumb( numb ) )
        return NULL;
    return cont.elem[ numb - cont.first ];
}

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