view src/outgoing.c @ 191:28488e0e3630 noffle

[svn] * src/group.h,src/group.c,src/noffle.c,src/server.c: Grp_setLastAccess is only ever called with last param as time(NULL), so remove it and call time() inside the implementation of Grp_setLastAccess. * src/client.c,src/group.h,src/group.c,src/noffle.c,src/post.c: Groups are automatically unsubscribed when the last access to the group is older than a particular threshold. However, for very low traffic groups, the last access may exceed the threshold simply because there has been no new article posted. In this case, rather than unsubscribe, update the group last access time. This means that groups are now only unsubscribed if the last access exceeds the threshold AND articles have arrived in the group since. Add Grp_setLastPostTime() to track the last time an article arrived in the group.
author bears
date Sat, 20 Oct 2001 14:23:46 +0100
parents fed1334d766b
children 24d4cd032da5
line wrap: on
line source

/*
  outgoing.c

  $Id: outgoing.c 300 2001-08-05 08:24:22Z bears $
*/

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

#include "outgoing.h"

#include <stdio.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

#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 <unistd.h>
#include "configfile.h"
#include "log.h"
#include "util.h"
#include "portable.h"

struct Outgoing
{
    DIR *dir;
    Str serv;
} outgoing = { NULL, "" };

static void
fileOutgoing( Str file, const char *serv, const char *msgId )
{
    snprintf( file, MAXCHAR, "%s/outgoing/%s/%s",
              Cfg_spoolDir(), serv, msgId );
}

static void
createDir( const char *serv )
{
    Str dir;
    int r;

    snprintf( dir, MAXCHAR, "%s/outgoing/%s", Cfg_spoolDir(), serv );
    r = mkdir( dir, 0755 );
    if ( r != 0 )
        Log_dbg( LOG_DBG_NEWSBASE, "mkdir: %s", strerror( errno ) );
}

Bool
Out_add( const char *serv, const char *msgId, const DynStr *artTxt )
{
    Str file;
    FILE *f;

    fileOutgoing( file, serv, msgId );
    if ( ! ( f = fopen( file, "w" ) ) )
    {
        createDir( serv );
        if ( ! ( f = fopen( file, "w" ) ) )
        {
            Log_err( "Cannot open %s", file );
            return FALSE;
        }
    }
    fprintf( f, "%s", DynStr_str( artTxt ) );
    fclose( f );
    return TRUE;
}

Bool
Out_first( const char *serv, Str msgId, DynStr *artTxt )
{
    Str file;
    
    snprintf( file, MAXCHAR, "%s/outgoing/%s", Cfg_spoolDir(), serv );
    if ( ! ( outgoing.dir = opendir( file ) ) )
    {
        Log_dbg( LOG_DBG_NEWSBASE, "Cannot open %s", file );
        return FALSE;
    }
    Utl_cpyStr( outgoing.serv, serv );
    Out_next( NULL, NULL ); /* "."  */
    Out_next( NULL, NULL ); /* ".." */
    return Out_next( msgId, artTxt );
}

Bool
Out_next( Str msgId, DynStr *artTxt )
{
    struct dirent *d;
    FILE *f;
    Str file, line;

    ASSERT( outgoing.dir );
    if ( ! ( d = readdir( outgoing.dir ) ) )
    {
        closedir( outgoing.dir );
        outgoing.dir = NULL;
        return FALSE;
    }
    if ( artTxt == NULL )
        return ( d->d_name != NULL );
    fileOutgoing( file, outgoing.serv, d->d_name );
    if ( ! ( f = fopen( file, "r" ) ) )
    {
        Log_err( "Cannot open %s for read", file );
        return FALSE;
    }
    DynStr_clear( artTxt );
    while ( fgets( line, MAXCHAR, f ) )
        DynStr_app( artTxt, line );
    Utl_cpyStr( msgId, d->d_name );
    fclose( f );
    return TRUE;
}

void
Out_remove( const char *serv, const char *msgId )
{
    Str file;

    fileOutgoing( file, serv, msgId );
    if ( unlink( file ) != 0 )
        Log_err( "Cannot remove %s", file );
}

Bool
Out_find( const char *msgId, Str server )
{
    Str servdir;
    DIR *d;
    struct dirent *entry;
    Bool res;
    
    
    snprintf( servdir, MAXCHAR, "%s/outgoing", Cfg_spoolDir() );
    if ( ! ( d = opendir( servdir ) ) )
    {
        Log_dbg( LOG_DBG_NEWSBASE, "Cannot open %s", servdir );
        return FALSE;
    }

    readdir( d );	/* '.' */
    readdir( d );	/* '..' */

    res = FALSE;
    while ( ! res && ( entry = readdir( d ) ) != NULL )
    {
	Str file;
	struct stat s;

	fileOutgoing( file, entry->d_name, msgId );
	if ( stat( file, &s ) == 0 )
	{
	    res = TRUE;
	    Utl_cpyStr( server, entry->d_name );
	}
    }

    closedir( d );
    return res;
}