# HG changeset patch
# User bears
# Date 1013187961 0
# Node ID 6767c6f3218fd4b4b832339a5d322707dd4dd8cf
# Parent  e7ee1bb9887bdc196ccd93bdfb3624a58c607443
[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.

diff -r e7ee1bb9887b -r 6767c6f3218f src/fetchlist.c
--- 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;