On Tue, 5 May 2009, Allin Cottrell wrote:
> Now that I have a somewhat better understanding of how libgsf
> works, here's a suggestion for a patch (attached).
Sorry, the patch contained a breakage, trying again.
Allin Cottrell
diff -ub libgsf-1.14.12.orig/gsf/gsf-infile-zip.c
libgsf-1.14.12.new/gsf/gsf-infile-zip.c
--- libgsf-1.14.12.orig/gsf/gsf-infile-zip.c 2009-04-17 18:27:14.000000000
-0400
+++ libgsf-1.14.12.new/gsf/gsf-infile-zip.c 2009-05-05 14:13:19.000000000
-0400
@@ -38,6 +38,7 @@
PROP_0,
PROP_SOURCE,
PROP_COMPRESSION_LEVEL,
+ PROP_MODTIME,
PROP_INTERNAL_PARENT,
};
@@ -192,7 +193,7 @@
GsfZipDirent *dirent;
guint8 const *data;
guint16 name_len, extras_len, comment_len, compr_method;
- guint32 crc32, csize, usize, off;
+ guint32 dostime, crc32, csize, usize, off;
gchar *name;
/* Read data and check the header */
@@ -207,6 +208,8 @@
comment_len = GSF_LE_GET_GUINT16 (data + ZIP_DIRENT_COMMENT_SIZE);
compr_method = GSF_LE_GET_GUINT16 (data + ZIP_DIRENT_COMPR_METHOD);
+
+ dostime = GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_DOSTIME);
crc32 = GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_CRC32);
csize = GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_CSIZE);
usize = GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_USIZE);
@@ -223,6 +226,7 @@
dirent->name = name;
dirent->compr_method = compr_method;
+ dirent->dostime = dostime;
dirent->crc32 = crc32;
dirent->csize = csize;
dirent->usize = usize;
@@ -589,6 +593,28 @@
return FALSE;
}
+static gint32
+zip_time_translate (guint32 dostime)
+{
+ struct tm ltime;
+ time_t now = time (NULL);
+
+ ltime = *localtime (&now);
+
+ ltime.tm_year = (dostime >> 25) + 80;
+ ltime.tm_mon = ((dostime >> 21) & 0x0f) - 1;
+ ltime.tm_mday = (dostime >> 16) & 0x1f;
+ ltime.tm_hour = (dostime >> 11) & 0x0f;
+ ltime.tm_min = (dostime >> 5) & 0x3f;
+ ltime.tm_sec = (dostime & 0x1f) << 1;
+
+ ltime.tm_wday = -1;
+ ltime.tm_yday = -1;
+ ltime.tm_isdst = -1;
+
+ return (gint32) mktime (<ime);
+}
+
/* GsfInfile class functions */
/*****************************************************************************/
@@ -752,6 +778,12 @@
? zip->vdir->dirent->compr_method
: 0);
break;
+ case PROP_MODTIME:
+ g_value_set_int (value,
+ zip->vdir->dirent
+ ?
zip_time_translate(zip->vdir->dirent->dostime)
+ : 0);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -833,6 +865,16 @@
G_PARAM_READABLE));
g_object_class_install_property
(gobject_class,
+ PROP_MODTIME,
+ g_param_spec_int ("modification-time",
+ "Last modification time",
+ "The last modification time of the file.",
+ G_MININT, G_MAXINT,
+ 0,
+ GSF_PARAM_STATIC |
+ G_PARAM_READABLE));
+ g_object_class_install_property
+ (gobject_class,
PROP_INTERNAL_PARENT,
g_param_spec_object ("internal-parent",
"",
diff -ub libgsf-1.14.12.orig/gsf/gsf-outfile-zip.c
libgsf-1.14.12.new/gsf/gsf-outfile-zip.c
--- libgsf-1.14.12.orig/gsf/gsf-outfile-zip.c 2009-04-17 18:27:14.000000000
-0400
+++ libgsf-1.14.12.new/gsf/gsf-outfile-zip.c 2009-05-05 16:44:34.000000000
-0400
@@ -37,7 +37,8 @@
PROP_0,
PROP_SINK,
PROP_ENTRY_NAME,
- PROP_COMPRESSION_LEVEL
+ PROP_COMPRESSION_LEVEL,
+ PROP_MODTIME,
};
static GObjectClass *parent_class;
@@ -56,6 +57,8 @@
z_stream *stream;
GsfZipCompressionMethod compression_method;
+ time_t modtime;
+
gboolean writing;
guint8 *buf;
@@ -281,7 +284,7 @@
GsfZipDirent *dirent = gsf_zip_dirent_new ();
dirent->name = stream_name_build (zip);
dirent->compr_method = zip->compression_method;
- dirent->dostime = zip_time_make (time (NULL));
+ dirent->dostime = zip_time_make (zip->modtime);
return dirent;
}
@@ -611,6 +614,7 @@
zip->root_order = NULL;
zip->stream = NULL;
zip->compression_method = GSF_ZIP_DEFLATED;
+ zip->modtime = time (NULL);
zip->writing = FALSE;
zip->buf = NULL;
zip->buf_size = 0;
@@ -658,6 +662,9 @@
case PROP_ENTRY_NAME:
zip->entry_name = g_strdup (g_value_get_string (value));
break;
+ case PROP_MODTIME:
+ zip->modtime = (time_t) g_value_get_int (value);
+ break;
case PROP_COMPRESSION_LEVEL: {
int level = g_value_get_int (value);
switch (level) {
@@ -723,6 +730,17 @@
GSF_PARAM_STATIC |
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property
+ (gobject_class,
+ PROP_MODTIME,
+ g_param_spec_int ("modification-time",
+ "Last modification time",
+ "The last modification time of the file.",
+ G_MININT, G_MAXINT,
+ 0,
+ GSF_PARAM_STATIC |
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
}
GSF_CLASS (GsfOutfileZip, gsf_outfile_zip,
diff -ub libgsf-1.14.12.orig/gsf/gsf-output-stdio.c
libgsf-1.14.12.new/gsf/gsf-output-stdio.c
--- libgsf-1.14.12.orig/gsf/gsf-output-stdio.c 2009-04-17 18:27:14.000000000
-0400
+++ libgsf-1.14.12.new/gsf/gsf-output-stdio.c 2009-05-05 15:56:12.000000000
-0400
@@ -34,6 +34,7 @@
#endif
#include <sys/types.h>
#include <sys/stat.h>
+#include <utime.h>
#ifdef HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
@@ -51,6 +52,11 @@
#define W_OK 2
#endif
+enum {
+ PROP_0,
+ PROP_MODTIME,
+};
+
static GObjectClass *parent_class;
struct _GsfOutputStdio {
@@ -60,6 +66,7 @@
char *real_filename, *temp_filename;
gboolean create_backup_copy, keep_open;
struct stat st;
+ time_t modtime;
};
typedef struct {
@@ -121,6 +128,17 @@
#endif
}
+static void
+set_filetime (char const *filename, time_t modtime)
+{
+ struct utimbuf ut;
+
+ ut.actime = time (NULL);
+ ut.modtime = modtime;
+
+ utime (filename, &ut);
+}
+
#define GSF_MAX_LINK_LEVEL 256
/* Calls g_file_read_link() until we find a real filename. */
@@ -279,6 +297,10 @@
}
chmod_wrapper (stdio->real_filename, stdio->st.st_mode);
#endif
+
+ /* Set the file modification time, if wanted */
+ if (stdio->modtime)
+ set_filetime(stdio->real_filename, stdio->modtime);
}
g_free (backup_filename);
@@ -387,6 +409,43 @@
stdio->file = NULL;
stdio->create_backup_copy = FALSE;
stdio->keep_open = FALSE;
+ stdio->modtime = (time_t) 0;
+}
+
+static void
+gsf_output_stdio_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GsfOutputStdio *stdio = (GsfOutputStdio *)object;
+
+ switch (property_id) {
+ case PROP_MODTIME:
+ g_value_set_int (value, stdio->modtime);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gsf_output_stdio_set_property (GObject *object,
+ guint property_id,
+ GValue const *value,
+ GParamSpec *pspec)
+{
+ GsfOutputStdio *stdio = (GsfOutputStdio *)object;
+
+ switch (property_id) {
+ case PROP_MODTIME:
+ stdio->modtime = (time_t) g_value_get_int (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
}
static void
@@ -395,11 +454,24 @@
GsfOutputClass *output_class = GSF_OUTPUT_CLASS (gobject_class);
gobject_class->finalize = gsf_output_stdio_finalize;
+ gobject_class->get_property = gsf_output_stdio_get_property;
+ gobject_class->set_property = gsf_output_stdio_set_property;
output_class->Close = gsf_output_stdio_close;
output_class->Seek = gsf_output_stdio_seek;
output_class->Write = gsf_output_stdio_write;
output_class->Vprintf = gsf_output_stdio_vprintf;
+ g_object_class_install_property
+ (gobject_class,
+ PROP_MODTIME,
+ g_param_spec_int ("modification-time",
+ "Last modification time",
+ "The last modification time of the file.",
+ G_MININT, G_MAXINT,
+ 0,
+ GSF_PARAM_STATIC |
+ G_PARAM_READWRITE));
+
parent_class = g_type_class_peek_parent (gobject_class);
}
_______________________________________________
gnumeric-list mailing list
gnumeric-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gnumeric-list