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;