aboutsummaryrefslogtreecommitdiffstats
path: root/tools/zip/patches/011-add-option-for-reproducible-archives.patch
blob: 45b9d67e159327798535db55cd264ab9eeec6c38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
From 6d659fc87451c02c8777dc33f750b16834e4c715 Mon Sep 17 00:00:00 2001
From: Mathias Kresin <dev@kresin.me>
Date: Sat, 12 Jan 2019 19:33:33 +0100
Subject: [PATCH] add option for reproducible archives

Add the option -mt/--mtime to pass a timestamp which is used as filedate
for the containing files.

So far, it isn't used for anything written to the extra fields,
therefore requires the -X (eXclude eXtra file attributes) parameter to
be effective.

Signed-off-by: Mathias Kresin <dev@kresin.me>
---
 globals.c |  1 +
 util.c    | 22 ++++++++++++++++++++++
 zip.c     |  6 ++++++
 zip.h     |  1 +
 zipup.c   |  4 +++-
 5 files changed, 33 insertions(+), 1 deletion(-)

--- a/globals.c
+++ b/globals.c
@@ -205,6 +205,7 @@ uzoff_t bytes_this_split = 0;     /* byt
 int read_split_archive = 0;       /* 1=scanzipf_reg detected spanning signature */
 int split_method = 0;             /* 0=no splits, 1=seekable, 2=data desc, -1=no */
 uzoff_t split_size = 0;           /* how big each split should be */
+time_t timestamp = -1;             /* fixed timestamp for archive content filedate */
 int split_bell = 0;               /* when pause for next split ring bell */
 uzoff_t bytes_prev_splits = 0;    /* total bytes written to all splits before this */
 uzoff_t bytes_this_entry = 0;     /* bytes written for this entry across all splits */
--- a/util.c
+++ b/util.c
@@ -1217,6 +1217,7 @@ int DisplayNumString(file, i)
   return 0;
 }
 
+
 /* Read numbers with trailing size multiplier (like 10M) and return number.
    10/30/04 EG */
 
@@ -1279,6 +1280,29 @@ uzoff_t ReadNumString( numstring )
 }
 
 
+uzoff_t ReadNumStringUL( numstring )
+  char *numstring;
+{
+  zoff_t num = 0;
+
+  /* check if valid number (currently no negatives) */
+  if (numstring == NULL) {
+    zipwarn("Unable to read empty number in ReadNumString", "");
+    return (uzoff_t)-1;
+  }
+  if (numstring[0] < '0' || numstring[0] > '9') {
+    zipwarn("Unable to read number (must start with digit): ", numstring);
+    return (uzoff_t)-1;
+  }
+  if (strlen(numstring) > 10) {
+    zipwarn("Number too long to read (10 characters max): ", numstring);
+    return (uzoff_t)-1;
+  }
+
+  return (uzoff_t)atoll(numstring);
+}
+
+
 /* Write the number as a string with a multiplier (like 10M) to outstring.
    Always writes no more than 3 digits followed maybe by a multiplier and
    returns the characters written or -1 if error.
--- a/zip.c
+++ b/zip.c
@@ -1942,6 +1942,7 @@ int set_filetype(out_path)
 #ifdef UNICODE_TEST
 #define o_sC            0x146
 #endif
+#define o_mt            0x255
 
 
 /* the below is mainly from the old main command line
@@ -2036,6 +2037,7 @@ struct option_struct far options[] = {
     {"m",  "move",        o_NO_VALUE,       o_NOT_NEGATABLE, 'm',  "add files to archive then delete files"},
     {"mm", "",            o_NO_VALUE,       o_NOT_NEGATABLE, o_mm, "not used"},
     {"MM", "must-match",  o_NO_VALUE,       o_NOT_NEGATABLE, o_MM, "error if in file not matched/not readable"},
+    {"mt", "mtime",       o_REQUIRED_VALUE, o_NOT_NEGATABLE, o_mt, "use fixed timestamp for archive content filedate"},
     {"n",  "suffixes",    o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'n',  "suffixes to not compress: .gz:.zip"},
     {"nw", "no-wild",     o_NO_VALUE,       o_NOT_NEGATABLE, o_nw, "no wildcards during add or update"},
 #if defined(AMIGA) || defined(MACOS)
@@ -2440,6 +2442,7 @@ char **argv;            /* command line
   split_method = 0;           /* 0=no splits, 1=update LHs, 2=data descriptors */
   split_size = 0;             /* how big each split should be */
   split_bell = 0;             /* when pause for next split ring bell */
+  timestamp = -1;             /* fixed timestamp for archive content filedate */
   bytes_prev_splits = 0;      /* total bytes written to all splits before this */
   bytes_this_entry = 0;       /* bytes written for this entry across all splits */
   noisy_splits = 0;           /* be verbose about creating splits */
@@ -2897,6 +2900,9 @@ char **argv;            /* command line
           dispose = 1;  break;
         case o_MM:  /* Exit with error if input file can't be read */
           bad_open_is_error = 1; break;
+        case o_mt:  /* fixed timestamp for archive content filedate */
+          timestamp = ReadNumStringUL(value);
+          break;
         case 'n':   /* Don't compress files with a special suffix */
           special = value;
           /* special = NULL; */ /* will be set at next argument */
--- a/zip.h
+++ b/zip.h
@@ -502,6 +502,7 @@ extern uzoff_t bytes_this_split; /* byte
 extern int read_split_archive;   /* 1=scanzipf_reg detected spanning signature */
 extern int split_method;         /* 0=no splits, 1=seekable, 2=data descs, -1=no */
 extern uzoff_t split_size;       /* how big each split should be */
+extern time_t timestamp;         /* fixed timestamp for archive content filedate */
 extern int split_bell;           /* when pause for next split ring bell */
 extern uzoff_t bytes_prev_splits; /* total bytes written to all splits before this */
 extern uzoff_t bytes_this_entry; /* bytes written for this entry across all splits */
@@ -789,6 +790,7 @@ char *zip_fzofft       OF((zoff_t, char
 int DisplayNumString OF ((FILE *file, uzoff_t i));
 int WriteNumString OF((uzoff_t num, char *outstring));
 uzoff_t ReadNumString OF((char *numstring));
+uzoff_t ReadNumStringUL OF((char *numstring));
 
 /* returns true if abbrev is abbreviation for string */
 int abbrevmatch OF((char *, char *, int, int));
--- a/zipup.c
+++ b/zipup.c
@@ -415,7 +415,6 @@ struct zlist far *z;    /* zip entry to
   char *tempextra = NULL;
   char *tempcextra = NULL;
 
-
 #ifdef WINDLL
 # ifdef ZIP64_SUPPORT
   extern _int64 filesize64;
@@ -441,6 +440,9 @@ struct zlist far *z;    /* zip entry to
   if (tim == 0 || q == (zoff_t) -3)
     return ZE_OPEN;
 
+  if (timestamp > 0)
+    tim = unix2dostime(&timestamp);
+
   /* q is set to -1 if the input file is a device, -2 for a volume label */
   if (q == (zoff_t) -2) {
      isdir = 1;