[libgsf] gsf: create archives with proper modtime.



commit 9136cc8745e805386d20282e65a0097b29beea9d
Author: Morten Welinder <terra gnome org>
Date:   Thu Mar 7 16:16:07 2013 -0500

    gsf: create archives with proper modtime.

 ChangeLog             |   10 +++++
 NEWS                  |    2 +-
 gsf/gsf-outfile-zip.c |   32 ++++++++++-----
 gsf/gsf-utils.c       |   14 ++++++
 gsf/gsf-utils.h       |    3 +
 tools/gsf.c           |  109 ++++++++++++++++++++-----------------------------
 6 files changed, 95 insertions(+), 75 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 9084173..ffac7dd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2013-03-07  Morten Welinder  <terra gnome org>
+
+       * gsf/gsf-utils.c (gsf_property_settings_find): New function.
+
+       * gsf/gsf-outfile-zip.c (gsf_outfile_zip_new_child): Don't add
+       modtime is caller did.
+
+       * tools/gsf.c (load_recursively): Simlify using, of all things,
+       gsf.  Avoid crazy memory usage.  Take care of modtime.
+
 2013-03-04  Morten Welinder  <terra gnome org>
 
        * gsf/gsf-infile-tar.c (tar_init_info): Also read mtime from
diff --git a/NEWS b/NEWS
index 35575f3..0051763 100644
--- a/NEWS
+++ b/NEWS
@@ -8,7 +8,7 @@ Morten:
        * Add modtime support for GsfInput, GsfInputStdio, GsfInputGzip.
        * Add modtime support for GsfInfileZip, GsfInfileTar.
        * Add modtime support for GsfOutput, GsfOutputStdio, GsfOutputGzip.
-       * Enhance gsf tool to print modtime.
+       * Enhance gsf tool to print modtime and create archives with modtime.
 
 --------------------------------------------------------------------------
 libgsf 1.14.26
diff --git a/gsf/gsf-outfile-zip.c b/gsf/gsf-outfile-zip.c
index 1067676..0892ffd 100644
--- a/gsf/gsf-outfile-zip.c
+++ b/gsf/gsf-outfile-zip.c
@@ -268,21 +268,28 @@ zip_time_make (GDateTime *modtime)
        gint year, month, day, hour, minute, second;
        guint32 ztime;
 
-       g_return_val_if_fail (modtime != NULL, 0);
+       if (!modtime)
+               modtime = g_date_time_new_now_utc ();
+       else
+               g_date_time_ref (modtime);
 
        g_date_time_get_ymd (modtime, &year, &month, &day);
-       if (year < 1980 || year > 1980 + 0x7f)
-               return 0;
        hour = g_date_time_get_hour (modtime);
        minute = g_date_time_get_minute (modtime);
        second = g_date_time_get_second (modtime);
 
-       ztime = (year - 1980) & 0x7f;
-       ztime = (ztime << 4) | (month  & 0x0f);
-       ztime = (ztime << 5) | (day & 0x1f);
-       ztime = (ztime << 5) | (hour & 0x1f);
-       ztime = (ztime << 6) | (minute & 0x3f);
-       ztime = (ztime << 5) | ((second / 2) & 0x1f);
+       if (year < 1980 || year > 1980 + 0x7f)
+               ztime = 0;
+       else {
+               ztime = (year - 1980) & 0x7f;
+               ztime = (ztime << 4) | (month  & 0x0f);
+               ztime = (ztime << 5) | (day & 0x1f);
+               ztime = (ztime << 5) | (hour & 0x1f);
+               ztime = (ztime << 6) | (minute & 0x3f);
+               ztime = (ztime << 5) | ((second / 2) & 0x1f);
+       }
+
+       g_date_time_unref (modtime);
 
        return ztime;
 }
@@ -594,12 +601,17 @@ gsf_outfile_zip_new_child (GsfOutfile *parent,
                                       &params, &n_params,
                                       "sink", zip_parent->sink,
                                       "entry-name", name,
-                                      "modtime", gsf_output_get_modtime (GSF_OUTPUT (parent)),
                                       NULL);
        gsf_property_settings_collect_valist (GSF_OUTFILE_ZIP_TYPE,
                                              &params, &n_params,
                                              first_property_name,
                                              args);
+       if (!gsf_property_settings_find ("modtime", params, n_params))
+               gsf_property_settings_collect (GSF_OUTFILE_ZIP_TYPE,
+                                              &params, &n_params,
+                                              "modtime", gsf_output_get_modtime (GSF_OUTPUT (parent)),
+                                              NULL);
+
        child = (GsfOutfileZip *)g_object_newv (GSF_OUTFILE_ZIP_TYPE,
                                                n_params,
                                                params);
diff --git a/gsf/gsf-utils.c b/gsf/gsf-utils.c
index 6f721c8..3cc0b8d 100644
--- a/gsf/gsf-utils.c
+++ b/gsf/gsf-utils.c
@@ -797,6 +797,20 @@ gsf_property_settings_collect (GType object_type,
   va_end (var_args);
 }
 
+const GParameter *
+gsf_property_settings_find (const char *name,
+                           const GParameter *params,
+                           size_t n_params)
+{
+       size_t i;
+
+       for (i = 0; i < n_params; i++)
+               if (g_str_equal (name, params[i].name))
+                       return params + i;
+
+       return NULL;
+}
+
 void
 gsf_property_settings_free (GParameter *params,
                            size_t n_params)
diff --git a/gsf/gsf-utils.h b/gsf/gsf-utils.h
index a0b3db9..20edad1 100644
--- a/gsf/gsf-utils.h
+++ b/gsf/gsf-utils.h
@@ -309,6 +309,9 @@ void        gsf_property_settings_collect (GType object_type,
                                           size_t *p_n_params,
                                           const gchar *first_property_name,
                                           ...);
+const GParameter *gsf_property_settings_find (const char *name,
+                                             const GParameter *params,
+                                             size_t n_params);
 void        gsf_property_settings_free (GParameter *params,
                                        size_t n_params);
 
diff --git a/tools/gsf.c b/tools/gsf.c
index 6f75270..553997a 100644
--- a/tools/gsf.c
+++ b/tools/gsf.c
@@ -3,8 +3,10 @@
 #include <gsf-config.h>
 #include <gsf/gsf.h>
 #include <glib/gi18n.h>
+#include <glib/gstdio.h>
 #include <gio/gio.h>
 #include <string.h>
+#include <errno.h>
 
 static gboolean show_version;
 
@@ -351,6 +353,7 @@ gsf_list_props (int argc, char **argv)
 }
 
 /* ------------------------------------------------------------------------- */
+
 static void
 show_error (char const *name, GError *error)
 {
@@ -368,87 +371,65 @@ static void
 load_recursively (GsfOutfile *outfile, char const *path)
 {
        GError *error = NULL;
-       GFile *file;
-       GFileType type;
-       goffset size;
-       gsize bytes_read;
-       char *buffer;
-
-       file = g_file_new_for_path (path);
-       type = g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL);
+       struct stat statbuf;
 
-       switch (type) {
-       case G_FILE_TYPE_DIRECTORY: {
-               char *buffer = g_file_get_basename (file);
-               GFileEnumerator *enumerator;
-               GsfOutfile *dir;
-
-               dir = GSF_OUTFILE (gsf_outfile_new_child (outfile, buffer, TRUE));
-               g_free (buffer);
-               enumerator = g_file_enumerate_children (file, "standard::*", G_FILE_QUERY_INFO_NONE, NULL, 
&error);
-               while (1) {
-                       char *childname;
-                       GFileInfo *info;
-
-                       info = g_file_enumerator_next_file (enumerator, NULL, &error);
-                       if (!info)
-                               break;
-
-                       childname = g_build_filename (path, g_file_info_get_name (info), NULL);
-                       load_recursively (dir, childname);
-                       g_free (childname);
-                       g_object_unref (info);
-               }
-               g_object_unref (enumerator);
-               g_object_unref (dir);
-               break;
+       if (g_stat (path, &statbuf) == -1) {
+               g_printerr ("Failed to stat %s: %s\n",
+                           path, g_strerror (errno));
+               return;
        }
-       case G_FILE_TYPE_SYMBOLIC_LINK:
-               /* do nothing */
-               break;
-       default: {
+
+       if (S_ISDIR (statbuf.st_mode)) {
+               GsfInfile *in = gsf_infile_stdio_new (path, &error);
+               GsfOutfile *out;
+               int i, n;
                char *base;
-               GFileInfo *info;
-               GFileInputStream *stream;
-               GsfOutput *output;
 
-               stream = g_file_read (file, NULL, &error);
-               if (error) {
+               if (!in) {
                        show_error (path, error);
                        return;
                }
-               info = g_file_input_stream_query_info(stream, "standard::*", NULL, &error);
-               if (error) {
-                       show_error (path, error);
-                       return;
+
+               base = g_path_get_basename (path);
+               out = GSF_OUTFILE (gsf_outfile_new_child (outfile, base, TRUE));
+               g_free (base);
+
+               n = gsf_infile_num_children (in);
+               for (i = 0; i < n; i++) {
+                       char const *child = gsf_infile_name_by_index (in, i);
+                       char *name = g_build_filename (path, child, NULL);
+                       load_recursively (out, name);
+                       g_free (name);
                }
-               size = g_file_info_get_size (info);
-               g_object_unref (info);
 
-               g_print ("f %10" GSF_OFF_T_FORMAT " %s\n", size, path);
+               g_object_unref (out);
+               g_object_unref (in);
+       } else if (S_ISREG (statbuf.st_mode)) {
+               char *base;
+               GsfInput *in;
+               GsfOutput *out;
 
-               buffer = g_new (gchar, size);
-               g_input_stream_read_all ((GInputStream *)stream, buffer, size, &bytes_read, NULL, &error);
-               if (error) {
+               in = gsf_input_stdio_new (path, &error);
+               if (!in) {
                        show_error (path, error);
                        return;
                }
 
-               base = g_file_get_basename (file);
-               output = gsf_outfile_new_child (outfile, base, FALSE);
-               gsf_output_write (output, size, buffer);
-               gsf_output_close (output);
-               g_object_unref (output);
+               base = g_path_get_basename (path);
+               out = gsf_outfile_new_child_full
+                       (outfile, base, FALSE,
+                        "modtime", gsf_input_get_modtime (in),
+                        NULL);
+               g_printerr ("Adding %s\n", path);
+               gsf_input_copy (in, out);
+               gsf_output_close (out);
+               g_object_unref (out);
                g_free (base);
 
-               g_free (buffer);
-               g_object_unref (stream);
-               break;
-       }
-
+               g_object_unref (in);
+       } else {
+               g_printerr ("Ignoring %s\n", path);
        }
-
-       g_object_unref (file);
 }
 
 static int


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]