Mercurial > noffle
diff fetch.c @ 0:04124a4423d4 noffle
[svn] Initial revision
author | enz |
---|---|
date | Tue, 04 Jan 2000 11:35:42 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fetch.c Tue Jan 04 11:35:42 2000 +0000 @@ -0,0 +1,247 @@ +/* + fetch.c + + $Id: fetch.c 3 2000-01-04 11:35:42Z enz $ +*/ + +#include "fetch.h" +#include <errno.h> +#include <time.h> +#include <signal.h> +#include "client.h" +#include "config.h" +#include "content.h" +#include "dynamicstring.h" +#include "fetchlist.h" +#include "request.h" +#include "group.h" +#include "log.h" +#include "outgoing.h" +#include "protocol.h" +#include "pseudo.h" +#include "util.h" + +struct Fetch +{ + Bool ready; + Str serv; +} fetch = { FALSE, "" }; + +static Bool +connectToServ( const char *name ) +{ + Log_inf( "Fetch from '%s'", name ); + if ( ! Client_connect( name ) ) + { + Log_err( "Could not connect to %s", name ); + return FALSE; + } + return TRUE; +} + +void +Fetch_getNewGrps( void ) +{ + time_t t; + Str file; + + ASSERT( fetch.ready ); + snprintf( file, MAXCHAR, "%s/groupinfo.lastupdate", Cfg_spoolDir() ); + if ( ! Utl_getStamp( &t, file ) ) + { + Log_err( "Cannot read %s. Please run noffle --query groups", file ); + return; + } + Log_inf( "Updating groupinfo" ); + Client_getNewgrps( &t ); + Utl_stamp( file ); +} + +void +Fetch_getNewArts( const char *name, FetchMode mode ) +{ + int next, first, last, oldLast; + + if ( ! Client_changeToGrp( name ) ) + { + Log_err( "Could not change to group %s", name ); + return; + } + Cont_read( name ); + Client_rmtFirstLast( &first, &last ); + next = Grp_rmtNext( name ); + oldLast = Cont_last(); + if ( next == last + 1 ) + { + Log_inf( "No new articles in %s", name ); + Cont_write(); + Grp_setFirstLast( name, Cont_first(), Cont_last() ); + return; + } + if ( first == 0 && last == 0 ) + { + Log_inf( "No articles in %s", name ); + Cont_write(); + Grp_setFirstLast( name, Cont_first(), Cont_last() ); + return; + } + if ( next > last + 1 ) + { + Log_err( "Article number inconsistent (%s rmt=%lu-%lu, next=%lu)", + name, first, last, next ); + Pseudo_cntInconsistent( name, first, last, next ); + } + else if ( next < first ) + { + Log_inf( "Missing articles (%s first=%lu next=%lu)", + name, first, next ); + Pseudo_missArts( name, first, next ); + } + else + first = next; + if ( last - first > Cfg_maxFetch() ) + { + Log_ntc( "Cutting number of overviews to %lu", Cfg_maxFetch() ); + first = last - Cfg_maxFetch() + 1; + } + Log_inf( "Getting remote overviews %lu-%lu for group %s", + first, last, name ); + Client_getOver( first, last, mode ); + Cont_write(); + Grp_setFirstLast( name, Cont_first(), Cont_last() ); +} + +void +Fetch_updateGrps( void ) +{ + FetchMode mode; + int i, size; + const char* name; + + ASSERT( fetch.ready ); + Fetchlist_read(); + size = Fetchlist_size(); + for ( i = 0; i < size; ++i ) + { + Fetchlist_element( &name, &mode, i ); + if ( strcmp( Grp_serv( name ), fetch.serv ) == 0 ) + Fetch_getNewArts( name, mode ); + } +} + +void +Fetch_getReq_( void ) +{ + Str msgId; + DynStr *list; + const char *p; + int count = 0; + + ASSERT( fetch.ready ); + Log_dbg( "Retrieving articles marked for download" ); + list = new_DynStr( 10000 ); + if ( Req_first( fetch.serv, msgId ) ) + do + { + DynStr_appLn( list, msgId ); + if ( ++count % 20 == 0 ) /* Send max. 20 ARTICLE cmds at once */ + { + p = DynStr_str( list ); + Client_retrieveArtList( p ); + while ( ( p = Utl_getLn( msgId, p ) ) ) + Req_remove( fetch.serv, msgId ); + DynStr_clear( list ); + } + } + while ( Req_next( msgId ) ); + p = DynStr_str( list ); + Client_retrieveArtList( p ); + while ( ( p = Utl_getLn( msgId, p ) ) ) + Req_remove( fetch.serv, msgId ); + del_DynStr( list ); +} + +void +Fetch_postArts( void ) +{ + DynStr *s; + Str msgId, cmd, errStr, sender; + int ret; + const char *txt; + FILE *f; + sig_t lastHandler; + + s = new_DynStr( 10000 ); + if ( Out_first( fetch.serv, msgId, s ) ) + { + Log_inf( "Posting articles" ); + do + { + txt = DynStr_str( s ); + Out_remove( fetch.serv, msgId ); + if ( ! Client_postArt( msgId, txt, errStr ) ) + { + Utl_cpyStr( sender, Cfg_mailTo() ); + if ( strcmp( sender, "" ) == 0 + && ! Prt_searchHeader( txt, "SENDER", sender ) + && ! Prt_searchHeader( txt, "X-NOFFLE-X-SENDER", + sender ) /* see server.c */ + && ! Prt_searchHeader( txt, "FROM", sender ) ) + Log_err( "Article %s has no From/Sender/X-Sender field", + msgId ); + else + { + Log_ntc( "Return article to '%s' by mail", sender ); + snprintf( cmd, MAXCHAR, + "mail -s '[ NOFFLE: Posting failed ]' '%s'", + sender ); + lastHandler = signal( SIGPIPE, SIG_IGN ); + f = popen( cmd, "w" ); + if ( f == NULL ) + Log_err( "Invocation of '%s' failed (%s)", cmd, + strerror( errno ) ); + else + { + fprintf( f, + "\t[ NOFFLE: POSTING OF ARTICLE FAILED ]\n" + "\n" + "\t[ The posting of your article failed. ]\n" + "\t[ Reason of failure at remote server: ]\n" + "\n" + "\t[ %s ]\n" + "\n" + "\t[ Full article text has been appended. ]\n" + "\n" + "%s" + ".\n", + errStr, txt ); + ret = pclose( f ); + if ( ret != EXIT_SUCCESS ) + Log_err( "'%s' exit value %d", cmd, ret ); + signal( SIGPIPE, lastHandler ); + } + } + } + } + while ( Out_next( msgId, s ) ); + } + del_DynStr( s ); +} + +Bool +Fetch_init( const char *serv ) +{ + if ( ! connectToServ( serv ) ) + return FALSE; + Utl_cpyStr( fetch.serv, serv ); + fetch.ready = TRUE; + return TRUE; +} + +void +Fetch_close() +{ + Client_disconnect(); + fetch.ready = FALSE; + Log_inf( "Fetch from '%s' finished", fetch.serv ); +}