If supported, store the etag values from downloaded tiles in extended
attributes on the local files, instead of cluttering our maps directory
with .etag files.

Signed-off-by: Sven Wegener <sven.wege...@stealer.net>
---
 src/download.c |  107 +++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 86 insertions(+), 21 deletions(-)

diff --git a/src/download.c b/src/download.c
index dd129d2..6476f3b 100644
--- a/src/download.c
+++ b/src/download.c
@@ -142,6 +142,88 @@ static void unlock_file(const char *fn)
        g_mutex_unlock(file_list_mutex);
 }
 
+static gboolean get_etag_xattr(const char *fn, DownloadFileOptions 
*file_options)
+{
+  GFile *file;
+  GFileInfo *fileinfo;
+  gboolean result = FALSE;
+
+  file = g_file_new_for_path(fn);
+  fileinfo = g_file_query_info(file, "xattr::viking.etag", 
G_FILE_QUERY_INFO_NONE, NULL, NULL);
+  if (fileinfo) {
+    const char *etag = g_file_info_get_attribute_string(fileinfo, 
"xattr::viking.etag");
+    if (etag) {
+      g_debug("%s: Get etag (xattr) from %s: %s", __FUNCTION__, fn, etag);
+      file_options->etag = g_strdup(etag);
+      result = TRUE;
+    }
+    g_object_unref(fileinfo);
+  }
+  g_object_unref(file);
+
+  return result;
+}
+
+static gboolean get_etag_file(const char *fn, DownloadFileOptions 
*file_options)
+{
+  gchar *etag_filename = g_strdup_printf("%s.etag", fn);
+  gboolean result = g_file_get_contents (etag_filename, &(file_options->etag), 
NULL, NULL);
+  g_free (etag_filename);
+  if (result)
+    g_debug("%s: Get etag (file) from %s: %s", __FUNCTION__, fn, 
file_options->etag);
+  return result;
+}
+
+static void get_etag(const char *fn, DownloadFileOptions *file_options)
+{
+  /* first try to get etag from xattr, then fall back to plain file  */
+  if (!get_etag_xattr(fn, file_options) && !get_etag_file(fn, file_options)) {
+    g_debug("%s: Failed to get etag from %s", __FUNCTION__, fn);
+    return;
+  }
+
+  /* check if etag is short enough */
+  if (strlen(file_options->etag) > 100) {
+    g_free(file_options->etag);
+    file_options->etag = NULL;
+  }
+
+  /* TODO: should check that etag is a valid string */
+}
+
+static gboolean set_etag_xattr(const char *fn, DownloadFileOptions 
*file_options)
+{
+  GFile *file;
+  gboolean result = FALSE;
+
+  file = g_file_new_for_path(fn);
+  if (g_file_set_attribute_string(file, "xattr::viking.etag", 
file_options->new_etag, G_FILE_QUERY_INFO_NONE, NULL, NULL)) {
+    g_debug("%s: Set etag (xattr) on %s: %s", __FUNCTION__, fn, 
file_options->new_etag);
+    result = TRUE;
+  }
+  g_object_unref(file);
+
+  return result;
+}
+
+static gboolean set_etag_file(const char *fn, DownloadFileOptions 
*file_options)
+{
+  gchar *etag_filename = g_strdup_printf("%s.etag", fn);
+  gboolean result = g_file_set_contents (etag_filename, 
file_options->new_etag, -1, NULL);
+  g_free (etag_filename);
+  if (result)
+    g_debug("%s: Set etag (file) on %s: %s", __FUNCTION__, fn, 
file_options->new_etag);
+  return result;
+}
+
+static void set_etag(const char *fn, const char *fntmp, DownloadFileOptions 
*file_options)
+{
+  /* first try to store etag in extended attribute, then fall back to plain 
file */
+  if (!set_etag_xattr(fntmp, file_options) && !set_etag_file(fn, 
file_options)) {
+    g_debug("%s: Failed to set etag on %s", __FUNCTION__, fn);
+  }
+}
+
 static int download( const char *hostname, const char *uri, const char *fn, 
DownloadMapOptions *options, gboolean ftp, void *handle)
 {
   FILE *f;
@@ -173,19 +255,7 @@ static int download( const char *hostname, const char 
*uri, const char *fn, Down
       file_options.time_condition = file_time;
     }
     if (options->use_etag) {
-      gchar *etag_filename = g_strdup_printf("%s.etag", fn);
-      gsize etag_length = 0;
-      g_file_get_contents (etag_filename, &(file_options.etag), &etag_length, 
NULL);
-      g_free (etag_filename);
-      etag_filename = NULL;
-
-      /* check if etag is short enough */
-      if (etag_length > 100) {
-        g_free(file_options.etag);
-        file_options.etag = NULL;
-      }
-
-      /* TODO: should check that etag is a valid string */
+      get_etag(fn, &file_options);
     }
 
   } else {
@@ -242,14 +312,9 @@ static int download( const char *hostname, const char 
*uri, const char *fn, Down
     return -1;
   }
 
-  if (options->use_etag) {
-    if (file_options.new_etag) {
-      /* server returned an etag value */
-      gchar *etag_filename = g_strdup_printf("%s.etag", fn);
-      g_file_set_contents (etag_filename, file_options.new_etag, -1, NULL);
-      g_free (etag_filename);
-      etag_filename = NULL;
-    }
+  if (options->use_etag && file_options.new_etag) {
+    /* server returned an etag value */
+    set_etag(fn, tmpfilename, &file_options);
   }
 
   if (ret == DOWNLOAD_NO_NEWER_FILE)  {
-- 
1.7.4.5


------------------------------------------------------------------------------
What Every C/C++ and Fortran developer Should Know!
Read this article and learn how Intel has extended the reach of its 
next-generation tools to help Windows* and Linux* C/C++ and Fortran 
developers boost performance applications - including clusters. 
http://p.sf.net/sfu/intel-dev2devmay
_______________________________________________
Viking-devel mailing list
Viking-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/viking-devel
Viking home page: http://viking.sf.net/

Reply via email to