[gcab] Add gcab_file_set_date()



commit b5a370a05da6d5ef2d7969c7ce0bd850b46388b4
Author: Richard Hughes <richard hughsie com>
Date:   Wed Dec 13 15:13:59 2017 +0000

    Add gcab_file_set_date()
    
    This allows us to override the modification time from the GFile and allows us
    to create reproducable archives without manually setting the mtime on the
    source files.

 docs/reference/gcab-sections.txt |    1 +
 libgcab/gcab-file.c              |   62 +++++++++++++++++++++++--------------
 libgcab/gcab-file.h              |    3 +-
 libgcab/libgcab.syms             |    1 +
 src/gcab.c                       |    2 +-
 5 files changed, 43 insertions(+), 26 deletions(-)
---
diff --git a/docs/reference/gcab-sections.txt b/docs/reference/gcab-sections.txt
index ebfc90e..35e1871 100644
--- a/docs/reference/gcab-sections.txt
+++ b/docs/reference/gcab-sections.txt
@@ -32,6 +32,7 @@ GCabFileCallback
 GCabFile
 gcab_file_get_attributes
 gcab_file_get_date
+gcab_file_set_date
 gcab_file_get_extract_name
 gcab_file_get_file
 gcab_file_get_name
diff --git a/libgcab/gcab-file.c b/libgcab/gcab-file.c
index 11e2368..96b8b2a 100644
--- a/libgcab/gcab-file.c
+++ b/libgcab/gcab-file.c
@@ -154,25 +154,40 @@ gcab_file_class_init (GCabFileClass *klass)
                              G_PARAM_STATIC_STRINGS));
 }
 
+/**
+ * gcab_file_set_date:
+ * @file: a #GCabFile
+ * @tv: a #GTimeVal
+ *
+ * Sets the file modification date, instead of the value provided by the GFile.
+ *
+ * Since: 1.0
+ **/
+void
+gcab_file_set_date (GCabFile *self, const GTimeVal *tv)
+{
+    g_autoptr(GDateTime) dt = g_date_time_new_from_timeval_utc (tv);
+    self->cfile->date = ((g_date_time_get_year (dt) - 1980 ) << 9 ) +
+        ((g_date_time_get_month (dt)) << 5) +
+         (g_date_time_get_day_of_month (dt));
+    self->cfile->time = ((g_date_time_get_hour (dt)) << 11) +
+        (g_date_time_get_minute (dt) << 5) +
+        (g_date_time_get_second (dt) / 2);
+}
+
 G_GNUC_INTERNAL gboolean
 gcab_file_update_info (GCabFile *self, GFileInfo *info)
 {
     GTimeVal tv;
-    time_t time;
-    struct tm *m; // Use GDateTime when 2.26 in RHEL6
 
     g_return_val_if_fail (GCAB_IS_FILE (self), FALSE);
     g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
 
     g_file_info_get_modification_time (info, &tv);
-    time = tv.tv_sec;
-    m = gmtime (&time);
-
+    if (self->cfile->date == 0)
+        gcab_file_set_date (self, &tv);
     self->cfile->usize = g_file_info_get_size (info);
     self->cfile->fattr = GCAB_FILE_ATTRIBUTE_ARCH;
-    self->cfile->date = ((m->tm_year + 1900 - 1980 ) << 9 ) +
-        ((m->tm_mon+1) << 5 ) + (m->tm_mday);
-    self->cfile->time = (m->tm_hour << 11) + (m->tm_min << 5) + (m->tm_sec / 2);
 
     return TRUE;
 }
@@ -247,30 +262,29 @@ gcab_file_get_size (GCabFile *self)
  * Get the file date, in @result.
  *
  * Since: 0.6
+ *
+ * Returns: %TRUE if @tv was set
  **/
-void
+gboolean
 gcab_file_get_date (GCabFile *self, GTimeVal *tv)
 {
-    struct tm tm;
     guint16 date, time;
+    g_autoptr(GDateTime) dt = NULL;
 
-    g_return_if_fail (GCAB_IS_FILE (self));
-    g_return_if_fail (tv != NULL);
+    g_return_val_if_fail (GCAB_IS_FILE (self), FALSE);
+    g_return_val_if_fail (tv != NULL, FALSE);
 
     date = self->cfile->date;
     time = self->cfile->time;
-
-    tm.tm_isdst = -1;
-    tm.tm_year  = ((date >> 9) + 1980) - 1900;
-    tm.tm_mon   = ((date >> 5) & 0xf) - 1;
-    tm.tm_mday  = (date & 0x1f) - 1;
-
-    tm.tm_hour  = (time >> 11);
-    tm.tm_min   = ((time >> 5) & 0x3f);
-    tm.tm_sec   = (time & 0x1f) * 2;
-
-    tv->tv_sec  = mktime(&tm);
-    tv->tv_usec = 0;
+    dt = g_date_time_new_utc ((date >> 9) + 1980,
+                              (date >> 5) & 0xf,
+                              (date & 0x1f),
+                              (time >> 11),
+                              (time >> 5) & 0x3f,
+                              (time & 0x1f) * 2);
+    if (dt == NULL)
+        return FALSE;
+    return g_date_time_to_timeval (dt, tv);
 }
 
 /**
diff --git a/libgcab/gcab-file.h b/libgcab/gcab-file.h
index 60e59d1..9a3a134 100644
--- a/libgcab/gcab-file.h
+++ b/libgcab/gcab-file.h
@@ -70,9 +70,10 @@ GFile *         gcab_file_get_file                  (GCabFile *file);
 const gchar *   gcab_file_get_name                  (GCabFile *file);
 guint32         gcab_file_get_size                  (GCabFile *file);
 guint32         gcab_file_get_attributes            (GCabFile *file);
-void            gcab_file_get_date                  (GCabFile *file, GTimeVal *result);
+gboolean        gcab_file_get_date                  (GCabFile *file, GTimeVal *result);
 const gchar *   gcab_file_get_extract_name          (GCabFile *file);
 void            gcab_file_set_extract_name          (GCabFile *file, const gchar *name);
+void            gcab_file_set_date                  (GCabFile *file, const GTimeVal *tv);
 
 G_END_DECLS
 
diff --git a/libgcab/libgcab.syms b/libgcab/libgcab.syms
index e65f06c..76bda2b 100644
--- a/libgcab/libgcab.syms
+++ b/libgcab/libgcab.syms
@@ -43,5 +43,6 @@ LIBGCAB1_0.6 {
 } LIBGCAB1_0.5;
 
 LIBGCAB1_1.0 {
+        gcab_file_set_date;
         gcab_folder_get_comptype;
 } LIBGCAB1_0.6;
diff --git a/src/gcab.c b/src/gcab.c
index 4d04ae3..e94fa97 100644
--- a/src/gcab.c
+++ b/src/gcab.c
@@ -195,7 +195,7 @@ individual files from the archive.\
                     if (list_details) {
                         gchar date[32];
                         struct tm *tm;
-                        GTimeVal tv;
+                        GTimeVal tv = {0};
 
                         gcab_file_get_date (GCAB_FILE (l->data), &tv);
                         tm = localtime (&tv.tv_sec);


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