summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2017-12-13 15:13:59 +0000
committerRichard Hughes <richard@hughsie.com>2017-12-14 12:15:26 +0000
commitb5a370a05da6d5ef2d7969c7ce0bd850b46388b4 (patch)
tree09b69d45da450f037188659f26217705932a3e56
parentb4e44c181619e58f16881aa6fbf9d906872bed85 (diff)
downloadgcab-b5a370a05da6d5ef2d7969c7ce0bd850b46388b4.tar.gz
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.
-rw-r--r--docs/reference/gcab-sections.txt1
-rw-r--r--libgcab/gcab-file.c62
-rw-r--r--libgcab/gcab-file.h3
-rw-r--r--libgcab/libgcab.syms1
-rw-r--r--src/gcab.c2
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);