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.
This commit is contained in:
parent
aab2e273bd
commit
ce4a10abe7
48
tar.c
48
tar.c
|
@ -55,6 +55,31 @@ static dev_t tardev;
|
||||||
static int mflag;
|
static int mflag;
|
||||||
static char filtermode = '\0';
|
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 *
|
static FILE *
|
||||||
decomp(FILE *fp)
|
decomp(FILE *fp)
|
||||||
{
|
{
|
||||||
|
@ -170,7 +195,6 @@ static int
|
||||||
unarchive(char *fname, ssize_t l, char b[BLKSIZ])
|
unarchive(char *fname, ssize_t l, char b[BLKSIZ])
|
||||||
{
|
{
|
||||||
FILE *f = NULL;
|
FILE *f = NULL;
|
||||||
struct timeval times[2];
|
|
||||||
struct header *h = (struct header *)b;
|
struct header *h = (struct header *)b;
|
||||||
long mode, major, minor, type, mtime, uid, gid;
|
long mode, major, minor, type, mtime, uid, gid;
|
||||||
char lname[101], *tmp, *p;
|
char lname[101], *tmp, *p;
|
||||||
|
@ -247,13 +271,7 @@ unarchive(char *fname, ssize_t l, char b[BLKSIZ])
|
||||||
if (f)
|
if (f)
|
||||||
fshut(f, fname);
|
fshut(f, fname);
|
||||||
|
|
||||||
if (!mflag) {
|
pushent(fname, mtime);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +333,9 @@ static void
|
||||||
xt(int argc, char *argv[], int (*fn)(char *, ssize_t, char[BLKSIZ]))
|
xt(int argc, char *argv[], int (*fn)(char *, ssize_t, char[BLKSIZ]))
|
||||||
{
|
{
|
||||||
char b[BLKSIZ], fname[256 + 1], *p;
|
char b[BLKSIZ], fname[256 + 1], *p;
|
||||||
|
struct timeval times[2];
|
||||||
struct header *h = (struct header *)b;
|
struct header *h = (struct header *)b;
|
||||||
|
struct ent *ent;
|
||||||
long size;
|
long size;
|
||||||
int i, n;
|
int i, n;
|
||||||
|
|
||||||
|
@ -353,6 +373,18 @@ xt(int argc, char *argv[], int (*fn)(char *, ssize_t, char[BLKSIZ]))
|
||||||
}
|
}
|
||||||
if (ferror(tarfile))
|
if (ferror(tarfile))
|
||||||
eprintf("fread %s:", tarfilename);
|
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
|
static void
|
||||||
|
|
Loading…
Reference in New Issue
Block a user