view src/over.c @ 235:21f75cc470f4 noffle

[svn] * docs/noffle.conf.5: Correct typo in From: filter description. * src/client.c: Fix memory leak in filter code. * src/fetchlist.c: Write fetchlist to new file and update if written correctly. Stops fetchlist being trashed on disc full. Also add fetchlist dirty flag to save unnecessary rewrites.
author bears
date Mon, 11 Feb 2002 11:20:31 +0000
parents c3478c3c81ce
children 5ebb557435b2
line wrap: on
line source

/*
  over.c

  $Id: over.c 360 2001-12-19 16:06:30Z mirkol $
*/

#if HAVE_CONFIG_H
#include <config.h>
#endif

#if TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#else
#if HAVE_SYS_TIME_H
#include <sys/time.h>
#else
#include <time.h>
#endif
#endif

#include <errno.h>
#include "configfile.h"
#include "content.h"
#include "database.h"
#include "fetchlist.h"
#include "log.h"
#include "over.h"
#include "protocol.h"
#include "pseudo.h"
#include "portable.h"
#include "util.h"

struct Over
{
    int numb;            /* message number of the overviewed article */
    char *subj;
    char *from;
    char *date;
    char *msgId;
    char *ref;
    size_t bytes;
    size_t lines;
    time_t time;
};

static void
replacetabs_Over( const char *header )
/* Replace the tab character in overview data by a space.
   refer to rfc2980 */
{
    while( *header )
        switch ( *header )
        {
            case '\t':
            case '\r':
            case '\n':
                *header = ' ';
            default:
                header++;
        }
    return;
}

Over *
new_Over( const char *subj, const char *from,
          const char *date, const char *msgId, const char *ref,
          size_t bytes, size_t lines )
{
    Over *ov;

    if ( ! ( ov = malloc( sizeof( Over ) ) ) )
    {
        Log_err( "Cannot allocate Over" );
        exit( EXIT_FAILURE );
    }
    ov->numb = 0;
    Utl_allocAndCpy( &ov->subj, subj );
    Utl_allocAndCpy( &ov->from, from );
    Utl_allocAndCpy( &ov->date, date );
    Utl_allocAndCpy( &ov->msgId, msgId );
    Utl_allocAndCpy( &ov->ref, ref );
    ov->bytes = bytes;
    ov->lines = lines;
    return ov;
}

void
del_Over( Over *self )
{
    if ( ! self )
        return;
    free( self->subj );
    self->subj = NULL;
    free( self->from );
    self->from = NULL;
    free( self->date );
    self->date = NULL;
    free( self->msgId );
    self->msgId = NULL;
    free( self->ref );
    self->ref = NULL;
    free( self );
}

int
Ov_numb( const Over *self )
{
    return self->numb;
}

const char *
Ov_subj( const Over *self )
{
    return self->subj;
}

const char *
Ov_from( const Over *self )
{
    return self->from;
}

const char *
Ov_date( const Over *self )
{
    return self->date;
}

const char *
Ov_msgId( const Over *self )
{
    return self->msgId;
}

const char *
Ov_ref( const Over *self )
{
    return self->ref;
}

size_t
Ov_bytes( const Over *self )
{
    return self->bytes;
}

size_t
Ov_lines( const Over *self )
{
    return self->lines;
}

void
Ov_setNumb( Over *self, int numb )
{
    self->numb = numb;
}

Bool
Ov_write( const Over *self, FILE *f )
{
    replacetabs_Over( self->subj );
    replacetabs_Over( self->from );
    replacetabs_Over( self->date );
    replacetabs_Over( self->msgId );
    replacetabs_Over( self->ref );
    return ( fprintf( f, "%i\t%s\t%s\t%s\t%s\t%s\t%d\t%d\n",
                      self->numb, self->subj,
                      self->from, self->date, self->msgId,
                      self->ref, self->bytes,
                      self->lines ) > 0 );
}

static const char *
readField( Str result, const char *p )
{
    size_t len;
    char *r;

    if ( ! p )
        return NULL;
    r = result;
    *r = '\0';
    len = 0;
    while ( *p != '\t' && *p != '\n' )
    {
        if ( ! *p )
            return p;
        *(r++) = *(p++);
        ++len;
        if ( len >= MAXCHAR - 1 )
        {
            *r = '\0';
            Log_err( "Field in overview too long: %s", r );
            return ++p;
        }
    }
    *r = '\0';
    return ++p;
}

/* read Over-struct from line */
Over *
Ov_read( char *line )
{
    size_t bytes, lines;
    const char *p;
    Over *result;
    int numb;
    Str t, subj, from, date, msgId, ref;
    
    p = readField( t, line );
    if ( sscanf( t, "%i", &numb ) != 1 )
        return NULL;
    p = readField( subj, p );
    p = readField( from, p );
    p = readField( date, p );
    p = readField( msgId, p );
    p = readField( ref, p );
    p = readField( t, p );
    if ( sscanf( t, "%d", &bytes ) != 1 )
        return NULL;
    p = readField( t, p );
    if ( sscanf( t, "%d", &lines ) != 1 )
        return NULL;
    result = new_Over( subj, from, date, msgId, ref, bytes, lines );
    Ov_setNumb( result, numb );
    return result;
}