diff src/client.c @ 180:09ca6eb5c7ff noffle

[svn] * TODO,src/client.c,src/client.h,src/fetch.c,src/fetch.h,src/noffle.c: Improve error checking during fetches. A fetch is now aborted immediately if the connection times out or if an unexpected response arrives. This should fix problems with articles appearing in the wrong group, and possibly other mysterious happenings.
author bears
date Wed, 09 May 2001 12:33:43 +0100
parents 0ce333d046b9
children a43a528cfbe7
line wrap: on
line diff
--- a/src/client.c	Wed May 09 12:15:31 2001 +0100
+++ b/src/client.c	Wed May 09 12:33:43 2001 +0100
@@ -1,7 +1,7 @@
 /*
   client.c
 
-  $Id: client.c 269 2001-03-13 11:46:03Z enz $
+  $Id: client.c 279 2001-05-09 11:33:43Z bears $
 */
 
 #if HAVE_CONFIG_H
@@ -166,7 +166,7 @@
 
 static int getStat( void );
 
-static Bool
+static int
 performAuth( void )
 {
     int stat;
@@ -176,30 +176,27 @@
     if ( strcmp( user, "" ) == 0 )
     {
         Log_err( "No username for authentication set" );
-        return FALSE;
+        return STAT_AUTH_REQUIRED;
     }    
     putCmd( "AUTHINFO USER %s", user );
     stat = getStat();
     if ( stat == STAT_AUTH_ACCEPTED )
-        return TRUE;
+        return stat;
     else if ( stat != STAT_MORE_AUTH_REQUIRED )
     {
         Log_err( "Username rejected. Server stat: %s", client.lastStat );
-        return FALSE;
+        return stat;
     }    
     if ( strcmp( pass, "" ) == 0 )
     {
         Log_err( "No password for authentication set" );
-        return FALSE;
+        return STAT_AUTH_REQUIRED;
     }
     putCmd( "AUTHINFO PASS %s", pass );
     stat = getStat();
     if ( stat != STAT_AUTH_ACCEPTED )
-    {
         Log_err( "Password rejected. Server status: %s", client.lastStat );
-        return FALSE;
-    }    
-    return TRUE;    
+    return stat;    
 }
 
 static int
@@ -219,7 +216,8 @@
     {
         client.auth = TRUE;
         strcpy( lastCmd, client.lastCmd );
-        if ( performAuth() )
+	result = performAuth();
+        if ( result == STAT_AUTH_ACCEPTED )
         {
             putCmd( lastCmd );
             return getStat();
@@ -533,6 +531,13 @@
     if ( ! putCmd( cmd ) )
         return FALSE;
     stat = getStat();
+    if ( stat == STAT_PROGRAM_FAULT )
+	return FALSE;
+
+    /*
+     * Try LIST instead of LIST ACTIVE in case server doesn't
+     * support LIST ACTIVE.
+     */
     if ( pattern[ 0 ] != '\0' && stat != STAT_GRPS_FOLLOW )
     {
 	*noServerPattern = TRUE;
@@ -589,6 +594,7 @@
     int stat;
     DynStr *response;
     const char *lines;
+    Bool result;
 
     ASSERT( ! Lock_gotLock() );
     Utl_cpyStr( cmd, "LIST NEWSGROUPS" );
@@ -602,6 +608,10 @@
     if ( ! putCmd( cmd ) )
         return FALSE;
     stat = getStat();
+    if ( stat == STAT_PROGRAM_FAULT )
+	return FALSE;
+
+    /* Try without pattern in case server doesn't support patterns. */
     if ( pattern[ 0 ] != '\0' && stat != STAT_GRPS_FOLLOW )
     {
 	*noServerPattern = TRUE;
@@ -623,12 +633,14 @@
 	return FALSE;
     
     lines = DynStr_str( response );
+    result = TRUE;
     while ( ( lines = Utl_getLn( line, lines) ) != NULL )
     {
         if ( sscanf( line, "%s", name ) != 1 )
         {
             Log_err( "Unknown reply to LIST NEWSGROUPS: %s", line );
-            continue;
+	    result = FALSE;
+	    break;
         }
 	if ( *noServerPattern && ! isGetGroup( name ) )
 	    continue;
@@ -641,7 +653,7 @@
     }
     Lock_closeDatabases();
     del_DynStr( response );
-    return TRUE;
+    return result;
 }
 
 Bool
@@ -664,7 +676,7 @@
 	    break;
     }
 
-    if ( ! doneOne )
+    if ( res && ! doneOne )
 	res = doGetDsc( "", &noServerPattern );
 
     del_GrEn( ge );
@@ -909,6 +921,9 @@
 		 rmtFirst, rmtLast );
 
 	newsgroups = collectTxt();
+	if ( newsgroups == NULL )
+	    return FALSE;
+	
 	groupLines = DynStr_str( newsgroups );
     }
     else
@@ -1063,19 +1078,21 @@
     return ! err;
 }
 
-void
+Bool
 Client_retrieveArt( const char *msgId )
 {
+    Bool res = FALSE;
+    
     ASSERT( Lock_gotLock() );
     if ( ! Db_contains( msgId ) )
     {
         Log_err( "Article '%s' not prepared in database. Skipping.", msgId );
-        return;
+        return TRUE;
     }
     if ( ! ( Db_status( msgId ) & DB_NOT_DOWNLOADED ) )
     {
         Log_inf( "Article '%s' already retrieved. Skipping.", msgId );
-        return;
+        return TRUE;
     }
 
     Lock_closeDatabases();
@@ -1084,16 +1101,18 @@
     else if ( getStat() != STAT_ART_FOLLOWS )
         retrievingFailed( msgId, client.lastStat );
     else
-        retrieveAndStoreArt( msgId, 0, 0 );
+        res = retrieveAndStoreArt( msgId, 0, 0 );
     Lock_openDatabases();
+    return res;
 }
 
-void
+Bool
 Client_retrieveArtList( const char *list, int *artcnt, int artmax )
 {
     Str msgId;
     DynStr *s;
     const char *p;
+    Bool res;
     
     ASSERT( Lock_gotLock() );
     Log_inf( "Retrieving article list" );
@@ -1109,7 +1128,7 @@
         {
             retrievingFailed( msgId, "Connection broke down" );
             del_DynStr( s );
-            return;
+            return FALSE;
         }
         else
             DynStr_appLn( s, msgId );
@@ -1119,15 +1138,20 @@
     Log_dbg( "[S FLUSH]" );
     
     p = DynStr_str( s );
-    while ( ( p = Utl_getLn( msgId, p ) ) )
+    res = TRUE;
+    while ( res && ( p = Utl_getLn( msgId, p ) ) )
     {
         if ( getStat() != STAT_ART_FOLLOWS )
+	{
             retrievingFailed( msgId, client.lastStat );
-        else if ( ! retrieveAndStoreArt( msgId, ++(*artcnt), artmax ) )
-            break;
+	    res = FALSE;
+	}
+        else
+	    res = retrieveAndStoreArt( msgId, ++(*artcnt), artmax );
     }
     del_DynStr( s );
     Lock_openDatabases();
+    return res;
 }
 
 Bool
@@ -1166,24 +1190,33 @@
 }
 
 Bool
-Client_postArt( const char *msgId, const char *artTxt,
-                    Str errStr )
+Client_postArt( const char *msgId, const char *artTxt, Str errStr )
 {
+    int stat;
+    
+    errStr[0] = '\0';
+    
     if ( ! putCmd( "POST" ) )
         return FALSE;
-    if ( getStat() != STAT_SEND_ART )
+    stat = getStat();
+    if ( stat == STAT_PROGRAM_FAULT )
+	return FALSE;
+    else if ( stat != STAT_SEND_ART )
     {
         Log_err( "Posting of %s not allowed: %s", msgId, client.lastStat );
         strcpy( errStr, client.lastStat );
-        return FALSE;
+        return TRUE;
     }
     putTxtBuf( artTxt );
     putEndOfTxt();
-    if ( getStat() != STAT_POST_OK )
+    stat = getStat();
+    if ( stat == STAT_PROGRAM_FAULT )
+	return FALSE;
+    else if ( stat != STAT_POST_OK )
     {
         Log_err( "Posting of %s failed: %s", msgId, client.lastStat );
         strcpy( errStr, client.lastStat );
-        return FALSE;
+        return TRUE;
     }
     Log_inf( "Posted %s (Status: %s)", msgId, client.lastStat );
     return TRUE;