Mercurial > noffle
diff src/fetch.c @ 188:f1bacee93ca6 noffle
[svn] * src/client.c,src/client.h,src/fetch.c,src/noffle.c,src/server.c:
robustness - instead of retruning simple Passed/Failed statuses from
connection functions, return an integer status instead. This allows
Noffle to distinguish between a connection failure, an unrecoverable
protocol error and a recoverable problem. As a concrete instance, Noffle
will no longer abort the connection if a group is removed from the
upstream server. Also beef up error detection a bit.
* src/content.c: instead of overwriting the existing content file(s) when
updating - which leaves a window where Noffle is vulnerable to failure
which will leave the content file corrupted (yes, it happened to me),
write a new content file and rename it over the old file only when it
has been written and closed with no errors reported.
author | bears |
---|---|
date | Wed, 12 Sep 2001 21:33:44 +0100 |
parents | fed1334d766b |
children | 021d145e34e9 |
line wrap: on
line diff
--- a/src/fetch.c Sat Sep 01 16:57:45 2001 +0100 +++ b/src/fetch.c Wed Sep 12 21:33:44 2001 +0100 @@ -1,7 +1,7 @@ /* fetch.c - $Id: fetch.c 300 2001-08-05 08:24:22Z bears $ + $Id: fetch.c 307 2001-09-12 20:33:44Z bears $ */ #if HAVE_CONFIG_H @@ -74,21 +74,32 @@ return FALSE; } Log_inf( "Updating groupinfo" ); - return Client_getNewgrps( &t ); + + /* + * If NEWGROUPS fails, it isn't necessarily fatal. You can do + * a periodic noffle --query groups to refresh your group list. + * So only return failure here if the status indicates the link + * itself failed. + * + * In particular, older versions of NNTPcache have a Y2K bug that + * stops NEWGROUPS working. + */ + return ( ! IS_FATAL( Client_getNewgrps( &t ) ) ); } /* Databases open on entry, closed on exit. */ -static Bool +static int fetchNewArts( const char *name, FetchMode mode ) { - int next, first, last, refetch; + int next, first, last, refetch, stat; - if ( ! Client_changeToGrp( name ) ) + stat = Client_changeToGrp( name ); + if ( stat != STAT_OK ) { Log_err( "Could not change to group %s", name ); if ( Lock_gotLock() ) Lock_closeDatabases(); - return TRUE; + return stat; } Client_rmtFirstLast( &first, &last ); Cont_read( name ); @@ -101,7 +112,7 @@ Cont_write(); Grp_setFirstLast( name, Cont_first(), Cont_last() ); Lock_closeDatabases(); - return TRUE; + return STAT_OK; } if ( first == 0 && last == 0 ) { @@ -109,13 +120,14 @@ Cont_write(); Grp_setFirstLast( name, Cont_first(), Cont_last() ); Lock_closeDatabases(); - return TRUE; + return STAT_OK; } if ( next > last + 1 ) { refetch = last - Cfg_maxFetch() + 1; if ( refetch < 0 ) refetch = 1; - Log_err( "Article number inconsistent (%s rmt=%lu-%lu, next=%lu). Refetching from %lu", + Log_err( "Article number inconsistent (%s rmt=%lu-%lu, next=%lu). " + "Refetching from %lu", name, first, last, next, refetch ); Pseudo_cntInconsistent( name, first, last, next, refetch ); first = refetch; @@ -125,6 +137,16 @@ Log_inf( "Missing articles (%s first=%lu next=%lu)", name, first, next ); Pseudo_missArts( name, first, next ); + + /* + * If we are missing articles but there are none to fetch, + * we must ensure we don't repeatedly generate missing + * article warning on every fetch until there is something + * to fetch. To guard against this, update the group remote + * next now. + */ + Grp_setRmtNext( name, first ); + next = first; } else first = next; @@ -170,7 +192,7 @@ Fetchlist_element( &name, &mode, i ); if ( strcmp( Grp_server( name ), fetch.serv ) == 0 ) { - if ( ! fetchNewArts( name, mode ) ) + if ( IS_FATAL( fetchNewArts( name, mode ) ) ) return FALSE; if ( ! Lock_openDatabases() ) { @@ -183,19 +205,21 @@ return TRUE; } -static Bool +static int fetchMessageList( const char *list, int *artcnt, int artmax ) { const char *p; Str msgId; + int stat; ASSERT( Lock_gotLock() ); - if ( ! Client_retrieveArtList( list, artcnt, artmax ) ) - return FALSE; + stat = Client_retrieveArtList( list, artcnt, artmax ); + if ( stat != STAT_OK ) + return stat; p = list; while ( ( p = Utl_getLn( msgId, p ) ) ) Req_remove( fetch.serv, msgId ); - return TRUE; + return STAT_OK; } Bool @@ -207,6 +231,7 @@ const char *p; int count = 0, artcnt = 0, artmax = 0; Bool res; + int stat; ASSERT( fetch.ready ); Log_dbg( LOG_DBG_FETCH, "Retrieving articles marked for download" ); @@ -250,11 +275,14 @@ DynStr_appLn( fetchList, msgId ); if ( ++count % MAX_ARTICLE_CMDS_QUEUED == 0 ) { - res = fetchMessageList( DynStr_str( fetchList ), &artcnt, artmax ); + stat = fetchMessageList( DynStr_str( fetchList ), &artcnt, + artmax ); + res = ! IS_FATAL( stat ); DynStr_clear( fetchList ); } } - res = res && fetchMessageList( DynStr_str( fetchList ), &artcnt, artmax ); + stat = fetchMessageList( DynStr_str( fetchList ), &artcnt, artmax ); + res = res && ! IS_FATAL( stat ); del_DynStr( fetchList ); del_DynStr( list ); @@ -319,7 +347,7 @@ do { txt = DynStr_str( s ); - if ( ! Client_postArt( msgId, txt, errStr ) ) + if ( Client_postArt( msgId, txt, errStr ) != STAT_OK ) { res = FALSE; break;