diff src/client.c @ 127:3c71e28c8eef noffle

[svn] Release-1-0 mergedocs/NOTES
author bears
date Tue, 25 Jul 2000 13:14:54 +0100
parents ec190bad201b
children d6c006a27ffe
line wrap: on
line diff
--- a/src/client.c	Tue Jul 25 13:12:50 2000 +0100
+++ b/src/client.c	Tue Jul 25 13:14:54 2000 +0100
@@ -1,7 +1,7 @@
 /*
   client.c
 
-  $Id: client.c 177 2000-07-22 06:21:11Z enz $
+  $Id: client.c 183 2000-07-25 12:14:54Z bears $
 */
 
 #if HAVE_CONFIG_H
@@ -25,6 +25,7 @@
 #include "dynamicstring.h"
 #include "group.h"
 #include "itemlist.h"
+#include "lock.h"
 #include "log.h"
 #include "over.h"
 #include "protocol.h"
@@ -269,6 +270,29 @@
     return ( r >= 0 );
 }
 
+static DynStr *
+collectTxt( void )
+{
+    DynStr *res;
+    Str line;
+    Bool err;
+
+    res = new_DynStr(2048);
+    if ( res == NULL )
+	return NULL;
+
+    while ( getTxtLn( line, &err ) && ! err )
+	DynStr_appLn( res, line );
+
+    if ( err )
+    {
+	del_DynStr( res );
+	return NULL;
+    }
+    else
+	return res;
+}
+
 Bool
 Client_connect( const char *serv )
 {
@@ -280,6 +304,7 @@
     Str host, s;
     struct sockaddr_in sIn;
 
+    ASSERT( client.in == NULL && client.out == NULL );
     client.auth = FALSE;
     Utl_cpyStr( s, serv );
     pStart = Utl_stripWhiteSpace( s );
@@ -328,6 +353,7 @@
 		if ( client.out != NULL )
 		    fclose( client.out );
                 close( sock );
+		client.in = client.out = NULL;
                 break;
             }
             stat = getStat();
@@ -352,6 +378,7 @@
 	    fclose( client.in );
 	    fclose( client.out );
 	    close( sock );
+	    client.in = client.out = NULL;
         }
     }
     return FALSE;
@@ -418,14 +445,19 @@
 }
 
 static void
-processGrps( Bool noServerPattern )
+processGrps( const char *lines, Bool noServerPattern )
 {
     char postAllow;
-    Bool err;
     int first, last;
     Str grp, line, file;
-    
-    while ( getTxtLn( line, &err ) && ! err )
+    Bool groupupdate;
+
+    ASSERT( ! Lock_gotLock() );
+    if ( ! Lock_openDatabases() )
+	return;
+
+    groupupdate = FALSE;
+    while ( ( lines = Utl_getLn( line, lines) ) != NULL )
     {
         if ( sscanf( line, "%s %d %d %c",
                      grp, &last, &first, &postAllow ) != 4 )
@@ -454,6 +486,7 @@
                 Grp_setFirstLast( grp, 1, 0 );
             Grp_setServ( grp, client.serv );
 	    Grp_setPostAllow( grp, postAllow );
+	    groupupdate = TRUE;
         }
         else
         {
@@ -464,18 +497,24 @@
                 Grp_setServ( grp, client.serv );
                 Grp_setRmtNext( grp, first );
 		Grp_setPostAllow( grp, postAllow );
+		groupupdate = TRUE;
             }
             else
                 Log_dbg( "Group %s is already fetched from %s",
-                           grp, Grp_server( grp ) );
-            
+			 grp, Grp_server( grp ) );            
         }
     }
-    if ( ! err )
+
+    snprintf( file, MAXCHAR, "%s/lastupdate.%s",
+	      Cfg_spoolDir(), client.serv );
+    Utl_stamp( file );
+    if ( groupupdate )
     {
-        snprintf( file, MAXCHAR, "%s/groupinfo.lastupdate", Cfg_spoolDir() );
-        Utl_stamp( file );
+	snprintf( file, MAXCHAR, "%s/groupinfo.lastupdate",
+		  Cfg_spoolDir() );
+	Utl_stamp( file );
     }
+    Lock_closeDatabases();
 }
 
 void
@@ -493,6 +532,7 @@
 {
     Str cmd;
     int stat;
+    DynStr *response;
 
     Utl_cpyStr( cmd, "LIST ACTIVE" );
     if ( pattern[ 0 ] != '\0' )
@@ -517,7 +557,13 @@
 	Log_err( "%s failed: %s", cmd, client.lastStat );
 	return FALSE;
     }
-    processGrps( *noServerPattern );
+
+    response = collectTxt();
+    if ( response == NULL )
+	return FALSE;
+    
+    processGrps( DynStr_str( response ), *noServerPattern );
+    del_DynStr( response );
     return TRUE;
 }
 
@@ -551,10 +597,12 @@
 static Bool
 doGetDsc( const char *pattern, Bool *noServerPattern )
 {
-    Bool err;
     Str name, line, dsc, cmd;
     int stat;
+    DynStr *response;
+    const char *lines;
 
+    ASSERT( ! Lock_gotLock() );
     Utl_cpyStr( cmd, "LIST NEWSGROUPS" );
     if ( pattern[ 0 ] != '\0' )
     {
@@ -578,7 +626,16 @@
         Log_err( "%s failed: %s", cmd, client.lastStat );
         return FALSE;
     }
-    while ( getTxtLn( line, &err ) && ! err )
+
+    response = collectTxt();
+    if ( response == NULL )
+	return FALSE;
+    
+    if ( ! Lock_openDatabases() )
+	return FALSE;
+    
+    lines = DynStr_str( response );
+    while ( ( lines = Utl_getLn( line, lines) ) != NULL )
     {
         if ( sscanf( line, "%s", name ) != 1 )
         {
@@ -594,6 +651,8 @@
             Grp_setDsc( name, dsc );
         }
     }
+    Lock_closeDatabases();
+    del_DynStr( response );
     return TRUE;
 }
 
@@ -624,87 +683,12 @@
     return res;
 }
 
-static Bool
-doGetCreationTimes( const char *pattern, Bool *noServerPattern )
-{
-    Bool err;
-    Str name, line, cmd;
-    time_t t;
-    int stat;
-
-    Utl_cpyStr( cmd, "LIST ACTIVE.TIMES" );
-    if ( pattern[ 0 ] != '\0' )
-    {
-	Utl_catStr( cmd, " " );
-	Utl_catStr( cmd, pattern );
-    }
-
-    *noServerPattern = FALSE;
-    if ( ! putCmd( cmd ) )
-        return FALSE;
-    stat = getStat();
-    if ( pattern[ 0 ] != '\0' && stat != STAT_GRPS_FOLLOW )
-    {
-	*noServerPattern= TRUE;
-	if ( ! putCmd( "LIST ACTIVE.TIMES" ) )
-	    return FALSE;
-	stat = getStat();
-    }    
-    if ( stat != STAT_GRPS_FOLLOW )
-    {
-        Log_err( "%s failed: %s", cmd, client.lastStat );
-        return FALSE;
-    }
-    while ( getTxtLn( line, &err ) && ! err )
-    {
-        if ( sscanf( line, "%s %ld", name, &t ) != 2 )
-        {
-            Log_err( "Unknown reply to LIST ACTIVE.TIMES: %s", line );
-            continue;
-        }
-	if ( *noServerPattern && ! isGetGroup( name ) )
-	    continue;
-        if ( Grp_exists( name ) )
-        {
-            Log_inf( "Creation time of %s: %ld", name, t );
-            Grp_setCreated( name, t );
-        }
-    }
-    return TRUE;
-}
-
-Bool
-Client_getCreationTimes( void )
-{
-    GroupEnum *ge;
-    const char *pattern;
-    Bool doneOne, noServerPattern, res;
-
-    Log_inf( "Querying group creation times" );
-
-    doneOne = FALSE;
-    res = TRUE;
-    ge = new_GetGrEn( client.serv );
-    while ( res && ( pattern = GrEn_next( ge ) ) != NULL )
-    {
-	res = doGetCreationTimes( pattern, &noServerPattern );
-	doneOne = TRUE;
-	if ( noServerPattern )
-	    break;
-    }
-
-    if ( ! doneOne )
-	res = doGetCreationTimes( "", &noServerPattern );
-
-    del_GrEn( ge );
-    return res;
-}
-
 Bool
 Client_getNewgrps( const time_t *lastTime )
 {
     Str s;
     const char *p;
+    DynStr *response;
 
     ASSERT( *lastTime > 0 );
     strftime( s, MAXCHAR, "%Y%m%d %H%M00", gmtime( lastTime ) );
@@ -721,7 +705,13 @@
         Log_err( "NEWGROUPS command failed: %s", client.lastStat );
         return FALSE;
     }
-    processGrps( TRUE );
+
+    response = collectTxt();
+    if ( response == NULL )
+	return FALSE;
+    
+    processGrps( DynStr_str( response ), TRUE );
+    del_DynStr( response );
     return TRUE;
 }
 
@@ -816,6 +806,7 @@
     double threadFollowTime, secPerDay, maxTime, timeSinceLastAccess;
     ItemList *itl;
 
+    ASSERT( Lock_gotLock() );
     Log_dbg( "Checking references '%s' for thread mode", ref );
     result = FALSE;
     itl = new_Itl( ref, " \t" );
@@ -862,6 +853,7 @@
     const char *msgId, *p, *xref;
     int n;
 
+    ASSERT( Lock_gotLock() );
     msgId = Ov_msgId( ov );
     if ( Pseudo_isGeneralInfo( msgId ) )
         Log_dbg( "Skipping general info '%s'", msgId );
@@ -900,15 +892,17 @@
 }
 
 Bool
-Client_getOver( int rmtFirst, int rmtLast, FetchMode mode )
+Client_getOver( const char *grp, int rmtFirst, int rmtLast, FetchMode mode )
 {
-    Bool err;
-    size_t bytes, lines;
+    size_t nbytes, nlines;
     int rmtNumb, oldLast, cntMarked;
     Over *ov;
     Str line, subj, from, date, msgId, ref;
+    DynStr *response;
+    const char *lines;
 
-    ASSERT( strcmp( client.grp, "" ) != 0 );
+    ASSERT( ! Lock_gotLock() );
+    ASSERT( strcmp( grp, "" ) != 0 );
     if ( ! putCmd( "XOVER %lu-%lu", rmtFirst, rmtLast ) )
         return FALSE;
     if ( getStat() != STAT_OVERS_FOLLOW )
@@ -917,18 +911,27 @@
         return FALSE;
     }
     Log_dbg( "Requesting overview for remote %lu-%lu", rmtFirst, rmtLast );
+
+    response = collectTxt();
+    if ( response == NULL )
+	return FALSE;
+
+    if ( ! Lock_openDatabases() )
+	return FALSE;
+    Cont_read( grp );
     oldLast = Cont_last();
     cntMarked = 0;
-    while ( getTxtLn( line, &err ) && ! err )
+    lines = DynStr_str( response );
+    while ( ( lines = Utl_getLn( line, lines) ) != NULL )
     {
         if ( ! parseOvLn( line, &rmtNumb, subj, from, date, msgId, ref,
-                          &bytes, &lines ) )
+                          &nbytes, &nlines ) )
             Log_err( "Bad overview line: %s", line );
 	else if ( Cont_find( msgId ) >= 0 )
 	    Log_inf( "Already have '%s'", msgId );
         else
         {
-            ov = new_Over( subj, from, date, msgId, ref, bytes, lines );
+            ov = new_Over( subj, from, date, msgId, ref, nbytes, nlines );
             Cont_app( ov );
             prepareEntry( ov );
             if ( mode == FULL || ( mode == THREAD && needsMark( ref ) ) )
@@ -942,7 +945,11 @@
     if ( oldLast != Cont_last() )
         Log_inf( "Added %s %lu-%lu", client.grp, oldLast + 1, Cont_last() );
     Log_inf( "%u articles marked for download in %s", cntMarked, client.grp  );
-    return err;
+    Cont_write();
+    Grp_setFirstLast( grp, Cont_first(), Cont_last() );
+    Lock_closeDatabases();
+    del_DynStr( response );
+    return TRUE;
 }
 
 static void
@@ -950,10 +957,14 @@
 {
     int status;
 
+    ASSERT( ! Lock_gotLock() );
     Log_err( "Retrieving of %s failed: %s", msgId, reason );
+    if ( ! Lock_openDatabases() )
+	return;
     status = Db_status( msgId );
     Pseudo_retrievingFailed( msgId, reason );
     Db_setStatus( msgId, status | DB_RETRIEVING_FAILED );
+    Lock_closeDatabases();
 }
 
 static Bool
@@ -961,17 +972,24 @@
 {
     Bool err;
     DynStr *s = NULL;
-    Str line;
 
+    ASSERT( ! Lock_gotLock() );
     Log_inf( "[%d/%d] Retrieving %s", artcnt, artmax, msgId );
-    s = new_DynStr( 5000 );
-    while ( getTxtLn( line, &err ) && ! err )
-        DynStr_appLn( s, line );
-    if ( ! err )
+    err = TRUE;
+
+    s = collectTxt();
+    if ( s != NULL )
     {
 	const char *txt;
-
+	
 	txt = DynStr_str( s );
+	if ( ! Lock_openDatabases() )
+	{
+	    del_DynStr( s );
+	    retrievingFailed( msgId, "Can't open message base" );
+	    return FALSE;
+	}
+	
         err = ! Db_storeArt( msgId, txt );
 	if ( ! err )
 	{
@@ -990,16 +1008,18 @@
 		del_Itl( ids );
 	    }
 	}
+	Lock_closeDatabases();
+	del_DynStr( s );
     }
     else
         retrievingFailed( msgId, "Connection broke down" );
-    del_DynStr( s );
     return ! err;
 }
 
 void
 Client_retrieveArt( const char *msgId )
 {
+    ASSERT( Lock_gotLock() );
     if ( ! Db_contains( msgId ) )
     {
         Log_err( "Article '%s' not prepared in database. Skipping.", msgId );
@@ -1010,6 +1030,8 @@
         Log_inf( "Article '%s' already retrieved. Skipping.", msgId );
         return;
     }
+
+    Lock_closeDatabases();
     if ( ! putCmd( "ARTICLE %s", msgId ) )
         retrievingFailed( msgId, "Connection broke down" );
     else if ( getStat() != STAT_ART_FOLLOWS )
@@ -1025,6 +1047,7 @@
     DynStr *s;
     const char *p;
     
+    ASSERT( Lock_gotLock() );
     Log_inf( "Retrieving article list" );
     s = new_DynStr( (int)strlen( list ) );
     p = list;
@@ -1042,8 +1065,11 @@
         }
         else
             DynStr_appLn( s, msgId );
+
+    Lock_closeDatabases();
     fflush( client.out );
     Log_dbg( "[S FLUSH]" );
+    
     p = DynStr_str( s );
     while ( ( p = Utl_getLn( msgId, p ) ) )
     {
@@ -1053,6 +1079,7 @@
             break;
     }
     del_DynStr( s );
+    Lock_openDatabases();
 }
 
 Bool
@@ -1061,6 +1088,7 @@
     unsigned int stat;
     int estimatedNumb, first, last;
 
+    ASSERT( Lock_gotLock() );
     if ( ! Grp_exists( name ) )
         return FALSE;
     if ( ! putCmd( "GROUP %s", name ) )
@@ -1082,6 +1110,7 @@
 void
 Client_rmtFirstLast( int *first, int *last )
 {
+    ASSERT( Lock_gotLock() );
     *first = client.rmtFirst;
     *last = client.rmtLast;
 }