diff src/fetchlist.c @ 232:6767c6f3218f noffle

[svn] * src/fetchlist.c: Write fetchlist to new file and update if written correctly. Stops fetchlist being trashed on disc full. Also add fetchlist dirty flag to save unnecessary rewrites.
author bears
date Fri, 08 Feb 2002 17:06:01 +0000
parents fed1334d766b
children f8a91e2b4060
line wrap: on
line diff
--- a/src/fetchlist.c	Wed Dec 19 16:07:06 2001 +0000
+++ b/src/fetchlist.c	Fri Feb 08 17:06:01 2002 +0000
@@ -1,7 +1,7 @@
 /*
   fetchlist.c
 
-  $Id: fetchlist.c 300 2001-08-05 08:24:22Z bears $
+  $Id: fetchlist.c 363 2002-02-08 17:06:01Z bears $
 */
 
 #if HAVE_CONFIG_H
@@ -9,6 +9,8 @@
 #endif
 
 #include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
 #include "fetchlist.h"
 #include "configfile.h"
 #include "log.h"
@@ -26,20 +28,14 @@
     struct Elem *elem;
     int size;
     int max;
-} fetchlist = { NULL, 0, 0 };
-
-static const char *
-getFile( void )
-{
-    static Str file;
-    snprintf( file, MAXCHAR, "%s/fetchlist", Cfg_spoolDir() );
-    return file;
-}
+    Bool dirty;
+} fetchlist = { NULL, 0, 0, FALSE };
 
 static void
 clearList( void )
 {
     fetchlist.size = 0;
+    fetchlist.dirty = FALSE;
 }
 
 static int
@@ -87,7 +83,7 @@
 Fetchlist_read( void )
 {
     FILE *f;
-    const char *file = getFile();
+    Str file;
     char *p;
     FetchMode mode = OVER;
     Bool valid;
@@ -95,6 +91,7 @@
     Str line, grp, modeStr;
 
     Log_dbg( LOG_DBG_FETCH, "Reading %s", file );
+    snprintf( file, MAXCHAR, "%s/fetchlist", Cfg_spoolDir() );
     clearList();
     if ( ! ( f = fopen( file, "r" ) ) )
     {
@@ -128,7 +125,10 @@
         }
         appGrp( grp, mode );
     }
-    fclose( f );
+    if ( ferror( f ) )
+        Log_err( "Error reading %s: %s", file, strerror( errno ) );
+    if ( fclose( f ) != 0 )
+        Log_err( "Error closing %s; %s", file, strerror( errno ) );
 }
 
 Bool
@@ -136,16 +136,27 @@
 {
     int i;
     FILE *f;
-    const char *file = getFile();
+    Str file, tmpfname;
     const char *modeStr = "";
+    Bool res;
 
+    /* Any changes? */
+    if ( ! fetchlist.dirty )
+        return TRUE;
+    
     qsort( fetchlist.elem, (size_t)fetchlist.size,
            sizeof( fetchlist.elem[ 0 ] ), compareElem );
-    if ( ! ( f = fopen( file, "w" ) ) )
+    
+    snprintf( file, MAXCHAR, "%s/fetchlist", Cfg_spoolDir() );
+    snprintf( tmpfname, MAXCHAR, "%s/.#%d.fetchlist",
+              Cfg_spoolDir(), (int) getpid() );
+    
+    if ( ! ( f = fopen( tmpfname, "w" ) ) )
     {
         Log_err( "Could not open %s for writing", file );
         return FALSE;
     }
+    res = TRUE;
     for ( i = 0; i < fetchlist.size; ++i )
     {
         switch ( fetchlist.elem[ i ].mode )
@@ -158,9 +169,30 @@
             modeStr = "over"; break;
         }
         fprintf( f, "%s %s\n", fetchlist.elem[ i ].name, modeStr );
+        if ( ferror( f ) )
+        {
+            Log_err( "Error writing %s: %s", tmpfname, strerror( errno ) );
+            clearerr( f );
+            res = FALSE;
+        }
     }
-    fclose( f );
-    return TRUE;
+    if ( fclose( f ) != 0 )
+    {
+        Log_err( "Error closing %s: %s", tmpfname, strerror( errno ) );
+        res = FALSE;
+    }
+
+    if ( res )
+    {
+        if ( rename( tmpfname, file ) < 0 )
+        {
+            Log_err( "Rename of %s to %s failed: %s", tmpfname, file,
+                     strerror( errno ) );
+            res = FALSE;
+        }
+    }
+        
+    return res;
 }
 
 int
@@ -189,6 +221,7 @@
 Fetchlist_add( const char *name, FetchMode mode )
 {
     struct Elem *elem = searchElem( name );
+    fetchlist.dirty = TRUE;
     if ( elem == NULL )
     {
         appGrp( name, mode );
@@ -205,6 +238,7 @@
     struct Elem *elem = searchElem( name );
     if ( elem == NULL )
         return FALSE;
+    fetchlist.dirty = TRUE;
     *elem = fetchlist.elem[ fetchlist.size - 1 ];
     --fetchlist.size;
     return TRUE;