[libgsf] gsf: create archives with proper modtime.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgsf] gsf: create archives with proper modtime.
- Date: Thu, 7 Mar 2013 21:16:27 +0000 (UTC)
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,
¶ms, &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,
¶ms, &n_params,
first_property_name,
args);
+ if (!gsf_property_settings_find ("modtime", params, n_params))
+ gsf_property_settings_collect (GSF_OUTFILE_ZIP_TYPE,
+ ¶ms, &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]