-fixed-time <timestamp> set mkfs-timestamp and file-mtime to this timestamp.
Reproducible builds requires the removal of all timestamp or setting all to a 
specific one.

Signed-off-by: Alexander Couzens <lyn...@fe80.eu>
---
 .../patches/120-add-fixed-timestamp-support.patch  | 130 +++++++++++++
 .../patches/200-add-fixed-timestamp-option.patch   | 210 +++++++++++++++++++++
 2 files changed, 340 insertions(+)
 create mode 100644 tools/squashfs/patches/120-add-fixed-timestamp-support.patch
 create mode 100644 tools/squashfs4/patches/200-add-fixed-timestamp-option.patch

diff --git a/tools/squashfs/patches/120-add-fixed-timestamp-support.patch 
b/tools/squashfs/patches/120-add-fixed-timestamp-support.patch
new file mode 100644
index 0000000..a88623f
--- /dev/null
+++ b/tools/squashfs/patches/120-add-fixed-timestamp-support.patch
@@ -0,0 +1,130 @@
+Index: squashfs3.0/squashfs-tools/mksquashfs.c
+===================================================================
+--- squashfs3.0.orig/squashfs-tools/mksquashfs.c
++++ squashfs3.0/squashfs-tools/mksquashfs.c
+@@ -253,7 +253,7 @@ int get_sorted_inode(squashfs_inode *ino
+ int read_sort_file(char *filename, int source, char *source_path[]);
+ void sort_files_and_write(struct dir_info *dir);
+ struct file_info *duplicate(char *(get_next_file_block)(struct 
duplicate_buffer_handle *, unsigned int), struct duplicate_buffer_handle 
*file_start, long long bytes, unsigned int **block_list, long long *start, int 
blocks, struct fragment **fragment, char *frag_data, int frag_bytes);
+-struct dir_info *dir_scan1(char *, int (_readdir)(char *, char *, struct 
dir_info *));
++struct dir_info *dir_scan1(char *, int (_readdir)(char *, char *, struct 
dir_info *), time_t fixed_time);
+ 
+ #define MKINODE(A)    ((squashfs_inode)(((squashfs_inode) inode_bytes << 16) 
+ (((char *)A) - data_cache)))
+ 
+@@ -1518,12 +1518,13 @@ void scan2_freedir(struct directory *dir
+ }
+ 
+ 
+-void dir_scan(squashfs_inode *inode, char *pathname, int (_readdir)(char *, 
char *, struct dir_info *))
++void dir_scan(squashfs_inode *inode, char *pathname, int (_readdir)(char *, 
char *, struct dir_info *),
++            time_t fixed_time)
+ {
+-      struct dir_info *dir_info = dir_scan1(pathname, _readdir);
++      struct dir_info *dir_info = dir_scan1(pathname, _readdir, fixed_time);
+       struct dir_ent *dir_ent;
+       struct inode_info *inode_info;
+       
+       if(dir_info == NULL)
+               return;
+ 
+@@ -1547,20 +1548,25 @@ void dir_scan(squashfs_inode *inode, cha
+               inode_info->buf.st_mode = S_IRWXU | S_IRWXG | S_IRWXO;
+               inode_info->buf.st_uid = getuid();
+               inode_info->buf.st_gid = getgid();
+-              inode_info->buf.st_mtime = time(NULL);
++              inode_info->buf.st_mtime = fixed_time != -1 ? fixed_time : 
time(NULL);
+       } else if(lstat(pathname, &inode_info->buf) == -1) {
+               char buffer[8192];
+               sprintf(buffer, "Cannot stat dir/file %s, ignoring", pathname);
+               perror(buffer);
+               return;
+       }
++
++      /* override timestamp of lstat if fixed_time is given */
++      if(fixed_time != -1)
++              inode_info->buf.st_mtime= fixed_time;
+       if(sorted)
+               sort_files_and_write(dir_info);
+       dir_scan2(inode, dir_info);
+ }
+ 
+ 
+-struct dir_info *dir_scan1(char *pathname, int (_readdir)(char *, char *, 
struct dir_info *))
++struct dir_info *dir_scan1(char *pathname, int (_readdir)(char *, char *, 
struct dir_info *),
++                         time_t fixed_time)
+ {
+       struct dir_info *dir, *sub_dir;
+       struct stat buf;
+@@ -1582,11 +1590,14 @@ struct dir_info *dir_scan1(char *pathnam
+                       perror(buffer);
+                       continue;
+               }
++
++              if(fixed_time != -1)
++                      buf.st_mtime = fixed_time;
+               if(excluded(filename, &buf))
+                       continue;
+ 
+               if((buf.st_mode & S_IFMT) == S_IFDIR) {
+-                      if((sub_dir = dir_scan1(filename, scan1_readdir)) == 
NULL)
++                      if((sub_dir = dir_scan1(filename, scan1_readdir, 
fixed_time)) == NULL)
+                               continue;
+                       dir->directory_count ++;
+               } else
+@@ -1809,6 +1822,7 @@ int main(int argc, char *argv[])
+       char *b, *root_name = NULL;
+       int be, nopad = FALSE, keep_as_directory = FALSE, orig_be;
+       squashfs_inode inode;
++      time_t fixed_time = -1;
+ 
+ #if __BYTE_ORDER == __BIG_ENDIAN
+       be = TRUE;
+@@ -1898,6 +1912,16 @@ int main(int argc, char *argv[])
+                                       exit(1);
+                               }
+                       }
++              } else if(strcmp(argv[i], "-fixed-time") == 0) {
++                      if(++i == argc) {
++                              ERROR("%s: -fixed-time missing a timestamp\n", 
argv[0]);
++                              exit(1);
++                      }
++                      fixed_time = strtoll(argv[i], &b, 10);
++                      if(*b != '\0') {
++                              ERROR("%s: -fixed-time has an invalid 
number\n", argv[0]);
++                              exit(1);
++                      }
+               } else if(strcmp(argv[i], "-noI") == 0 ||
+                               strcmp(argv[i], "-noInodeCompression") == 0)
+                       noI = TRUE;
+@@ -1967,6 +1991,7 @@ printOptions:
+                       ERROR("-all-root\t\tmake all files owned by root\n");
+                       ERROR("-force-uid uid\t\tset all file uids to uid\n");
+                       ERROR("-force-gid gid\t\tset all file gids to gid\n");
++                      ERROR("-fixed-time timestamp\tSet all timestamps to 
timestamp\n");
+                       ERROR("-le\t\t\tcreate a little endian filesystem\n");
+                       ERROR("-be\t\t\tcreate a big endian filesystem\n");
+                       ERROR("-nopad\t\t\tdo not pad filesystem to a multiple 
of 4K\n");
+@@ -2177,11 +2202,11 @@ printOptions:
+       block_offset = check_data ? 3 : 2;
+ 
+       if(delete && !keep_as_directory && source == 1 && 
S_ISDIR(source_buf.st_mode))
+-              dir_scan(&inode, source_path[0], scan1_readdir);
++              dir_scan(&inode, source_path[0], scan1_readdir, fixed_time);
+       else if(!keep_as_directory && source == 1 && 
S_ISDIR(source_buf.st_mode))
+-              dir_scan(&inode, source_path[0], scan1_single_readdir);
++              dir_scan(&inode, source_path[0], scan1_single_readdir, 
fixed_time);
+       else
+-              dir_scan(&inode, "", scan1_encomp_readdir);
++              dir_scan(&inode, "", scan1_encomp_readdir, fixed_time);
+       sBlk.root_inode = inode;
+       sBlk.inodes = inode_count;
+       sBlk.s_magic = SQUASHFS_MAGIC;
+@@ -2190,7 +2215,7 @@ printOptions:
+       sBlk.block_size = block_size;
+       sBlk.block_log = block_log;
+       sBlk.flags = SQUASHFS_MKFLAGS(noI, noD, check_data, noF, no_fragments, 
always_use_fragments, duplicate_checking);
+-      sBlk.mkfs_time = time(NULL);
++      sBlk.mkfs_time = fixed_time != -1 ? fixed_time : time(NULL);
+ 
+ restore_filesystem:
+       write_fragment();
diff --git a/tools/squashfs4/patches/200-add-fixed-timestamp-option.patch 
b/tools/squashfs4/patches/200-add-fixed-timestamp-option.patch
new file mode 100644
index 0000000..5bc243f
--- /dev/null
+++ b/tools/squashfs4/patches/200-add-fixed-timestamp-option.patch
@@ -0,0 +1,210 @@
+Index: squashfs4.2/squashfs-tools/mksquashfs.c
+===================================================================
+--- squashfs4.2.orig/squashfs-tools/mksquashfs.c
++++ squashfs4.2/squashfs-tools/mksquashfs.c
+@@ -429,9 +429,10 @@ struct file_info *duplicate(long long fi
+       struct file_buffer *file_buffer, int blocks, unsigned short checksum,
+       unsigned short fragment_checksum, int checksum_flag);
+ struct dir_info *dir_scan1(char *, struct pathnames *, int (_readdir)(char *,
+-      char *, struct dir_info *));
+-struct dir_info *dir_scan2(struct dir_info *dir, struct pseudo *pseudo);
+-void dir_scan3(squashfs_inode *inode, struct dir_info *dir_info);
++      char *, struct dir_info *), time_t fixed_time);
++struct dir_info *dir_scan2(struct dir_info *dir, struct pseudo *pseudo,
++                         time_t timestamp);
++void dir_scan3(squashfs_inode *inode, struct dir_info *dir_info, time_t 
fixed_time);
+ struct file_info *add_non_dup(long long file_size, long long bytes,
+       unsigned int *block_list, long long start, struct fragment *fragment,
+       unsigned short checksum, unsigned short fragment_checksum,
+@@ -3588,16 +3589,17 @@ void scan3_freedir(struct directory *dir
+ 
+ 
+ void dir_scan(squashfs_inode *inode, char *pathname,
+-      int (_readdir)(char *, char *, struct dir_info *))
++      int (_readdir)(char *, char *, struct dir_info *),
++            time_t fixed_time)
+ {
+       struct stat buf;
+-      struct dir_info *dir_info = dir_scan1(pathname, paths, _readdir);
++      struct dir_info *dir_info = dir_scan1(pathname, paths, _readdir, 
fixed_time);
+       struct dir_ent *dir_ent;
+       
+       if(dir_info == NULL)
+               return;
+ 
+-      dir_scan2(dir_info, pseudo);
++      dir_scan2(dir_info, pseudo, fixed_time);
+ 
+       dir_ent = malloc(sizeof(struct dir_ent));
+       if(dir_ent == NULL)
+@@ -3612,7 +3614,7 @@ void dir_scan(squashfs_inode *inode, cha
+               buf.st_mode = S_IRWXU | S_IRWXG | S_IRWXO | S_IFDIR;
+               buf.st_uid = getuid();
+               buf.st_gid = getgid();
+-              buf.st_mtime = time(NULL);
++              buf.st_mtime = fixed_time != -1 ? fixed_time : time(NULL);
+               buf.st_dev = 0;
+               buf.st_ino = 0;
+               dir_ent->inode = lookup_inode(&buf);
+@@ -3623,6 +3625,9 @@ void dir_scan(squashfs_inode *inode, cha
+                               pathname, strerror(errno));
+                       return;
+               }
++              if (fixed_time != -1)
++                      buf.st_mtime = fixed_time;
++
+               dir_ent->inode = lookup_inode(&buf);
+       }
+ 
+@@ -3647,14 +3652,15 @@ void dir_scan(squashfs_inode *inode, cha
+               sort_files_and_write(dir_info);
+       if(progress)
+               enable_progress_bar();
+-      dir_scan3(inode, dir_info);
++      dir_scan3(inode, dir_info, fixed_time);
+       dir_ent->inode->inode = *inode;
+       dir_ent->inode->type = SQUASHFS_DIR_TYPE;
+ }
+ 
+ 
+ struct dir_info *dir_scan1(char *pathname, struct pathnames *paths,
+-      int (_readdir)(char *, char *, struct dir_info *))
++      int (_readdir)(char *, char *, struct dir_info *),
++                         time_t fixed_time)
+ {
+       char filename[8192], dir_name[8192];
+       struct dir_info *dir = scan1_opendir(pathname);
+@@ -3699,7 +3705,7 @@ struct dir_info *dir_scan1(char *pathnam
+               }
+ 
+               if((buf.st_mode & S_IFMT) == S_IFDIR) {
+-                      sub_dir = dir_scan1(filename, new, scan1_readdir);
++                      sub_dir = dir_scan1(filename, new, scan1_readdir, 
fixed_time);
+                       if(sub_dir == NULL)
+                               continue;
+                       dir->directory_count ++;
+@@ -3717,7 +3723,8 @@ error:
+ }
+ 
+ 
+-struct dir_info *dir_scan2(struct dir_info *dir, struct pseudo *pseudo)
++struct dir_info *dir_scan2(struct dir_info *dir, struct pseudo *pseudo,
++                         time_t fixed_time)
+ {
+       struct dir_info *sub_dir;
+       struct dir_ent *dir_ent;
+@@ -3734,7 +3741,8 @@ struct dir_info *dir_scan2(struct dir_in
+               char *name = dir_ent->name;
+ 
+               if((buf->st_mode & S_IFMT) == S_IFDIR)
+-                      dir_scan2(dir_ent->dir, pseudo_subdir(name, pseudo));
++                      dir_scan2(dir_ent->dir, pseudo_subdir(name, pseudo),
++                                fixed_time);
+       }
+ 
+       while((pseudo_ent = pseudo_readdir(pseudo)) != NULL) {
+@@ -3778,7 +3786,7 @@ struct dir_info *dir_scan2(struct dir_in
+               }
+ 
+               if(pseudo_ent->dev->type == 'd') {
+-                      sub_dir = dir_scan2(NULL, pseudo_ent->pseudo);
++                      sub_dir = dir_scan2(NULL, pseudo_ent->pseudo, 
fixed_time);
+                       if(sub_dir == NULL) {
+                               ERROR("Could not create pseudo directory \"%s\""
+                                       ", skipping...\n",
+@@ -3795,7 +3803,7 @@ struct dir_info *dir_scan2(struct dir_in
+               buf.st_gid = pseudo_ent->dev->gid;
+               buf.st_rdev = makedev(pseudo_ent->dev->major,
+                       pseudo_ent->dev->minor);
+-              buf.st_mtime = time(NULL);
++              buf.st_mtime = fixed_time != -1 ? fixed_time : time(NULL);
+               buf.st_ino = pseudo_ino ++;
+ 
+               if(pseudo_ent->dev->type == 'f') {
+@@ -3836,7 +3844,7 @@ struct dir_info *dir_scan2(struct dir_in
+ }
+ 
+ 
+-void dir_scan3(squashfs_inode *inode, struct dir_info *dir_info)
++void dir_scan3(squashfs_inode *inode, struct dir_info *dir_info, time_t 
fixed_time)
+ {
+       int squashfs_type;
+       int duplicate_file;
+@@ -3855,6 +3863,9 @@ void dir_scan3(squashfs_inode *inode, st
+                       ?  dir_ent->inode->inode_number :
+                       dir_ent->inode->inode_number + dir_inode_no;
+ 
++              if(fixed_time != -1)
++                      buf->st_mtime = fixed_time;
++
+               if(dir_ent->inode->inode == SQUASHFS_INVALID_BLK) {
+                       switch(buf->st_mode & S_IFMT) {
+                               case S_IFREG:
+@@ -3870,7 +3881,7 @@ void dir_scan3(squashfs_inode *inode, st
+ 
+                               case S_IFDIR:
+                                       squashfs_type = SQUASHFS_DIR_TYPE;
+-                                      dir_scan3(inode, dir_ent->dir);
++                                      dir_scan3(inode, dir_ent->dir, 
fixed_time);
+                                       break;
+ 
+                               case S_IFLNK:
+@@ -4578,6 +4589,7 @@ int main(int argc, char *argv[])
+       struct squashfs_super_block sBlk;
+       char *b, *root_name = NULL;
+       int nopad = FALSE, keep_as_directory = FALSE;
++      time_t fixed_time = -1;
+       squashfs_inode inode;
+       int readb_mbytes = READER_BUFFER_DEFAULT,
+               writeb_mbytes = WRITER_BUFFER_DEFAULT,
+@@ -4674,6 +4686,15 @@ int main(int argc, char *argv[])
+                       progress = FALSE;
+               else if(strcmp(argv[i], "-no-exports") == 0)
+                       exportable = FALSE;
++              else if(strcmp(argv[i], "-fixed-time") == 0) {
++                      if((++i == argc) || (fixed_time =
++                                      strtoll(argv[i], &b, 10), *b != '\0')) {
++                              ERROR("%s: -fixed-time missing or invalid "
++                                      "timestamp\n", argv[0]);
++
++                              exit(1);
++                      }
++              }
+               else if(strcmp(argv[i], "-processors") == 0) {
+                       if((++i == argc) || (processors =
+                                       strtol(argv[i], &b, 10), *b != '\0')) {
+@@ -4936,8 +4957,9 @@ printOptions:
+                       ERROR("-info\t\t\tprint files written to filesystem\n");
+                       ERROR("-no-progress\t\tdon't display the progress "
+                               "bar\n");
++                      ERROR("-fixed-time <timestamp>\tSet all timestamps to 
<timestamp>\n");
+                       ERROR("-processors <number>\tUse <number> processors."
+                               "  By default will use number of\n");
+                       ERROR("\t\t\tprocessors available\n");
+                       ERROR("-read-queue <size>\tSet input queue to <size> "
+                               "Mbytes.  Default %d Mbytes\n",
+@@ -5298,12 +5318,12 @@ printOptions:
+ 
+       if(delete && !keep_as_directory && source == 1 &&
+                       S_ISDIR(source_buf.st_mode))
+-              dir_scan(&inode, source_path[0], scan1_readdir);
++              dir_scan(&inode, source_path[0], scan1_readdir, fixed_time);
+       else if(!keep_as_directory && source == 1 &&
+                       S_ISDIR(source_buf.st_mode))
+-              dir_scan(&inode, source_path[0], scan1_single_readdir);
++              dir_scan(&inode, source_path[0], scan1_single_readdir, 
fixed_time);
+       else
+-              dir_scan(&inode, "", scan1_encomp_readdir);
++              dir_scan(&inode, "", scan1_encomp_readdir, fixed_time);
+       sBlk.root_inode = inode;
+       sBlk.inodes = inode_count;
+       sBlk.s_magic = SQUASHFS_MAGIC;
+@@ -5314,7 +5334,7 @@ printOptions:
+       sBlk.flags = SQUASHFS_MKFLAGS(noI, noD, noF, noX, no_fragments,
+               always_use_fragments, duplicate_checking, exportable,
+               no_xattrs, comp_opts);
+-      sBlk.mkfs_time = time(NULL);
++      sBlk.mkfs_time = fixed_time != -1 ? fixed_time : time(NULL);
+ 
+ restore_filesystem:
+       if(progress && estimated_uncompressed) {
-- 
2.6.3
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to