]> git.street.me.uk Git - andy/viking.git/blobdiff - src/download.c
Add option to download only maps that are more recent on server
[andy/viking.git] / src / download.c
index 1f10ed124a06dddd0217f70abf21b6b59a55ecfd..e973ab8c148cf4e37d1eb4c4752b8a8c114152b8 100644 (file)
 
 #include <stdio.h>
 #include <ctype.h>
+#include <errno.h>
 #include <string.h>
+#include <sys/types.h>
+#include <utime.h>
 #include <glib.h>
 #include <glib/gstdio.h>
 #include <glib/gi18n.h>
 
+
 #include "download.h"
 
 #include "curl_download.h"
@@ -95,35 +99,39 @@ static int download( const char *hostname, const char *uri, const char *fn, Down
   int ret;
   gchar *tmpfilename;
   gboolean failure = FALSE;
+  time_t time_condition = 0;
 
   /* Check file */
   if ( g_file_test ( fn, G_FILE_TEST_EXISTS ) == TRUE )
   {
-    /* File exists: return */
-    return -3;
+    if (options != NULL && options->check_file_server_time) {
+      /* Get the modified time of this file */
+      struct stat buf;
+      g_stat ( fn, &buf );
+      time_condition = buf.st_mtime;
+    } else {
+      /* Nothing to do as file already exists, so return */
+      return -3;
+    }
   } else {
     gchar *dir = g_path_get_dirname ( fn );
     g_mkdir_with_parents ( dir , 0777 );
     g_free ( dir );
-
-    /* create placeholder file */
-    if ( ! (f = g_fopen ( fn, "w+b" )) ) /* immediately open file so other threads won't -- prevents race condition */
-      return -4;
-    fclose ( f );
-    f = NULL;
   }
 
   tmpfilename = g_strdup_printf("%s.tmp", fn);
-  f = g_fopen ( tmpfilename, "w+b" );
+  f = g_fopen ( tmpfilename, "w+bx" );  /* truncate file and open it in exclusive mode */
   if ( ! f ) {
+    if (errno == EEXIST)
+      g_debug("%s: Couldn't take lock on temporary file \"%s\"\n", __FUNCTION__, tmpfilename);
     g_free ( tmpfilename );
-    g_remove ( fn ); /* couldn't create temporary. delete 0-byte file. */
     return -4;
   }
 
   /* Call the backend function */
-  ret = curl_download_get_url ( hostname, uri, f, options, ftp );
-  if (ret == -1 || ret == 1 || ret == -2) {
+  ret = curl_download_get_url ( hostname, uri, f, options, ftp, time_condition );
+
+  if (ret != DOWNLOAD_NO_ERROR && ret != DOWNLOAD_NO_NEWER_FILE) {
     g_debug("%s: download failed: curl_download_get_url=%d", __FUNCTION__, ret);
     failure = TRUE;
   }
@@ -136,19 +144,22 @@ static int download( const char *hostname, const char *uri, const char *fn, Down
   if (failure)
   {
     g_warning(_("Download error: %s"), fn);
-    fclose ( f );
-    f = NULL;
     g_remove ( tmpfilename );
     g_free ( tmpfilename );
+    fclose ( f );
+    f = NULL;
     g_remove ( fn ); /* couldn't create temporary. delete 0-byte file. */
     return -1;
   }
 
+  if (ret == DOWNLOAD_NO_NEWER_FILE)
+    g_remove ( tmpfilename );
+  else
+    g_rename ( tmpfilename, fn ); /* move completely-downloaded file to permanent location */
+  g_free ( tmpfilename );
   fclose ( f );
   f = NULL;
-  g_rename ( tmpfilename, fn ); /* move completely-downloaded file to permanent location */
-  g_free ( tmpfilename );
-  return ret;
+  return 0;
 }
 
 /* success = 0, -1 = couldn't connect, -2 HTTP error, -3 file exists, -4 couldn't write to file... */