[hackers] [sbase] tar: Apply mtime at the end otherwise it gets reverted || sin

From: <git_AT_suckless.org>
Date: Thu, 23 Apr 2015 13:37:44 +0200 (CEST)

commit ce4a10abe7e64d6d869ffa0ff06319af500a4e48
Author: sin <sin_AT_2f30.org>
Date: Thu Apr 23 12:34:37 2015 +0100

    tar: Apply mtime at the end otherwise it gets reverted
    
    Consider the following scenario:
    
    1) create a/
    2) apply mtime to a/
    3) create a/b # reverts mtime on a
    
    TODO: utimes() does not work on symlinks.

diff --git a/tar.c b/tar.c
index c08ea47..6277cc4 100644
--- a/tar.c
+++ b/tar.c
_AT_@ -55,6 +55,31 @@ static dev_t tardev;
 static int mflag;
 static char filtermode = '\0';
 
+struct ent {
+ char *name;
+ time_t mtime;
+} *ents;
+static size_t entlen;
+
+static void
+pushent(char *name, time_t mtime)
+{
+ ents = reallocarray(ents, entlen + 1, sizeof(*ents));
+ ents[entlen].name = strdup(name);
+ ents[entlen].mtime = mtime;
+ entlen++;
+}
+
+struct ent *
+popent(void)
+{
+ if (entlen) {
+ entlen--;
+ return &ents[entlen];
+ }
+ return NULL;
+}
+
 static FILE *
 decomp(FILE *fp)
 {
_AT_@ -170,7 +195,6 @@ static int
 unarchive(char *fname, ssize_t l, char b[BLKSIZ])
 {
         FILE *f = NULL;
- struct timeval times[2];
         struct header *h = (struct header *)b;
         long mode, major, minor, type, mtime, uid, gid;
         char lname[101], *tmp, *p;
_AT_@ -247,13 +271,7 @@ unarchive(char *fname, ssize_t l, char b[BLKSIZ])
         if (f)
                 fshut(f, fname);
 
- if (!mflag) {
- times[0].tv_sec = times[1].tv_sec = mtime;
- times[0].tv_usec = times[1].tv_usec = 0;
- if (utimes(fname, times) < 0)
- eprintf("utimes %s:", fname);
- }
-
+ pushent(fname, mtime);
         return 0;
 }
 
_AT_@ -315,7 +333,9 @@ static void
 xt(int argc, char *argv[], int (*fn)(char *, ssize_t, char[BLKSIZ]))
 {
         char b[BLKSIZ], fname[256 + 1], *p;
+ struct timeval times[2];
         struct header *h = (struct header *)b;
+ struct ent *ent;
         long size;
         int i, n;
 
_AT_@ -353,6 +373,18 @@ xt(int argc, char *argv[], int (*fn)(char *, ssize_t, char[BLKSIZ]))
         }
         if (ferror(tarfile))
                 eprintf("fread %s:", tarfilename);
+
+ if (!mflag) {
+ while ((ent = popent())) {
+ times[0].tv_sec = times[1].tv_sec = ent->mtime;
+ times[0].tv_usec = times[1].tv_usec = 0;
+ if (utimes(ent->name, times) < 0)
+ weprintf("utimes %s:", ent->name);
+ free(ent->name);
+ }
+ free(ents);
+ ents = NULL;
+ }
 }
 
 static void
Received on Thu Apr 23 2015 - 13:37:44 CEST

This archive was generated by hypermail 2.3.0 : Thu Apr 23 2015 - 13:48:15 CEST