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 (&ltime);
+}
+
 /* 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

Reply via email to