diff src/noffle.c @ 255:52f467c7213b noffle

[svn] * docs/noffle.1,src/Makefile.am,src/Makefile.in,src/content.c, src/content.h,src/database.c,src/database.h,src/expire.c, src/expire.h,src/noffle.c: Split out expire code from database.c, change to remove articles in place (rather than rebuild article database) and add separate command to rebuild article database from articles listed in overviews. This may help if the article database gets corrupted.
author bears
date Wed, 26 Jun 2002 14:15:44 +0100
parents 93d5d8b098da
children d6fedc09b052
line wrap: on
line diff
--- a/src/noffle.c	Wed Jun 26 14:14:56 2002 +0100
+++ b/src/noffle.c	Wed Jun 26 14:15:44 2002 +0100
@@ -10,7 +10,7 @@
   received for some seconds (to allow multiple clients connect at the same
   time).
 
-  $Id: noffle.c 382 2002-06-05 22:03:44Z mirkol $
+  $Id: noffle.c 387 2002-06-26 13:15:44Z bears $
 */
 
 #if HAVE_CONFIG_H
@@ -30,6 +30,7 @@
 #include "control.h"
 #include "configfile.h"
 #include "database.h"
+#include "expire.h"
 #include "fetch.h"
 #include "fetchlist.h"
 #include "filter.h"
@@ -236,84 +237,17 @@
             }
 }
 
-/* Expire all overviews not in database */
 static void
-expireContents( void )
+doExpire( void )
 {
-    const Over *ov;
-    int i;
-    int cntDel, cntLeft;
-    Str grp;
-    Bool autoUnsubscribe;
-    int autoUnsubscribeDays;
-    time_t maxAge = 0;
-    const char *msgId;
-
-    autoUnsubscribe = Cfg_autoUnsubscribe();
-    autoUnsubscribeDays = Cfg_autoUnsubscribeDays();
-    maxAge = Cfg_autoUnsubscribeDays() * 24 * 3600;
-    if ( ! Cont_firstGrp( grp ) )
-        return;
-    Log_inf( "Expiring overviews not in database" );
-    Fetchlist_read();
-    do
-    {
-	if ( ! Grp_exists( grp ) )
-            Log_err( "Overview file for unknown group %s exists", grp );
-        else
-        {
-            cntDel = cntLeft = 0;
-            Cont_read( grp );
-            for ( i = Cont_first(); i <= Cont_last(); ++i )
-                if ( ( ov = Cont_get( i ) ) )
-                {
-                    msgId = Ov_msgId( ov );
-                    if ( ! Db_contains( msgId ) )
-                    {
-                        Cont_delete( i );
-                        ++cntDel;
-                    }
-                    else
-                        ++cntLeft;
-                }
-
-	    /*
-	     * Auto unsubscribe where applicable if last article arrival
-	     * time is maxAge newer than the last access time. This ensures
-	     * the low traffic groups don't get expired simply because
-	     * there's been nothing to read.
-	     */
-            if ( ! Grp_local( grp )
-                 && Fetchlist_contains( grp, NULL )
-                 && autoUnsubscribe
-                 && difftime( Grp_lastPostTime(grp),
-			      Grp_lastAccess( grp ) ) > maxAge )
-            {
-		Log_ntc( "Auto-unsubscribing from %s after %d "
-			 "days without access",
-			 grp, autoUnsubscribeDays );
-		Pseudo_autoUnsubscribed( grp, autoUnsubscribeDays );
-		Fetchlist_remove( grp );
-		Grp_setRmtNext( grp, GRP_RMT_NEXT_NOT_SUBSCRIBED );
-            }
-            if ( Cont_write() )
-                Grp_setFirstLast( grp, Cont_first(), Cont_last() );
-            Log_inf( "%ld overviews deleted from group %s, %ld left (%ld-%ld)",
-                     cntDel, grp, cntLeft, Grp_first( grp ), Grp_last( grp ) );
-        }
-    }
-    while ( Cont_nextGrp( grp ) );
-    Fetchlist_write();
+    Exp_expire();
 }
 
 static void
-doExpire( void )
+doRebuild( void )
 {
-    Db_close();
-    Db_expire();
-    if ( ! Db_open() )
-        return;
-    expireContents();
+    if ( ! Db_rebuild() )
+	fprintf( stderr, "Rebuild failed.\n" );
 }
 
 static void
@@ -374,8 +308,9 @@
         Log_inf( "Deleting group '%s'", name );
 
 	/*
-	  Delete all articles that are only in the group. Check the
-	  article Xref for more than one group.
+	  Delete all articles that are only in the group or are
+	  crossposted only to groups that do not exist on this
+	  server.
 	 */
 	Cont_read( name );
 	for ( i = Cont_first(); i <= Cont_last(); i++ )
@@ -384,17 +319,42 @@
 	    Bool toDelete;
 	    Str msgId;
 
+	    if ( ! Cont_validNumb( i ) )
+		continue;
+
 	    over = Cont_get( i );
 	    toDelete = TRUE;
 	    if ( over != NULL )
 	    {
-		ItemList * xref;
+		ItemList *xrefs;
+		const char *xref;
+		int localXrefs = 0;
 
 		Utl_cpyStr( msgId, Ov_msgId( over ) );
-		xref = new_Itl( Db_xref( msgId ), " " );
-		if ( Itl_count( xref ) > 1 )
+		xrefs = new_Itl( Db_xref( msgId ), " " );
+		for ( xref = Itl_first( xrefs );
+		      xref != NULL;
+		      xref = Itl_next( xrefs) )
+		{
+		    Str xgrp;
+		    int no;
+
+		    if ( sscanf( xref, "%s:%d", xgrp, &no ) != 2 )
+		    {
+			/* Malformed xref - leave article just in case */
+			Log_err( "Malformed Xref: entry in %s: %s",
+				 msgId, xref);
+			toDelete = FALSE;
+			break;
+		    }
+		    
+		    if ( Cont_exists( xgrp ) )
+			++localXrefs;
+		}
+		
+		if ( localXrefs > 1 )
 		    toDelete = FALSE;
-		del_Itl( xref );
+		del_Itl( xrefs );
 	    }
 	    Cont_delete( i );
 	    if ( toDelete )
@@ -565,6 +525,7 @@
       "Usage: noffle <option>\n"
       "Option is one of the following:\n"
       " -a | --article <msg id>|all      Show article(s) in database\n"
+      " -B | --rebuild                   Rebuild article database\n"
       " -c | --cancel <msg id>           Remove article from database\n"
       " -C | --create <grp>              Create a local group\n"
       " -d | --database                  Show content of article database\n"
@@ -797,6 +758,7 @@
 	{ "--online", 		"-n" },
 	{ "--post", 		"-p" },
 	{ "--query", 		"-q" },
+	{ "--rebuild", 		"-B" },
 	{ "--server",		"-r" },
 	{ "--requested",	"-R" },
 	{ "--subscribe-over",	"-s" },
@@ -870,6 +832,9 @@
         else
             doArt( *argv );
         break;
+    case 'B':
+	doRebuild();
+	break;
     case 'c':
         if ( *argv == NULL )
         {