Fix tar(1) handling of archives with improper internal order
Not all archives are packed in such way to be generated without having to recursively generate the output path. For now, reuse the function from mkdir.c and later move it to libutil.
This commit is contained in:
parent
3ef6d4e4c9
commit
97905f6991
30
tar.c
30
tar.c
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
|
#include <libgen.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -172,6 +173,29 @@ archive(const char *path)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mkdirp(char *path)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
for (p = path; *p; p++) {
|
||||||
|
if (*p != '/')
|
||||||
|
continue;
|
||||||
|
*p = '\0';
|
||||||
|
if (mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST) {
|
||||||
|
weprintf("mkdir %s:", path);
|
||||||
|
*p = '/';
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*p = '/';
|
||||||
|
}
|
||||||
|
if (mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST) {
|
||||||
|
weprintf("mkdir %s:", path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
unarchive(char *fname, ssize_t l, char b[BLKSIZ])
|
unarchive(char *fname, ssize_t l, char b[BLKSIZ])
|
||||||
{
|
{
|
||||||
|
@ -179,13 +203,17 @@ unarchive(char *fname, ssize_t l, char b[BLKSIZ])
|
||||||
struct timeval times[2];
|
struct timeval times[2];
|
||||||
struct header *h = (void *)b;
|
struct header *h = (void *)b;
|
||||||
long mode, major, minor, type, mtime, uid, gid;
|
long mode, major, minor, type, mtime, uid, gid;
|
||||||
char lname[101], *p;
|
char lname[101], *tmp, *p;
|
||||||
|
|
||||||
if (!mflag && ((mtime = strtoul(h->mtime, &p, 8)) < 0 || *p != '\0'))
|
if (!mflag && ((mtime = strtoul(h->mtime, &p, 8)) < 0 || *p != '\0'))
|
||||||
eprintf("strtoul %s: invalid number\n", h->mtime);
|
eprintf("strtoul %s: invalid number\n", h->mtime);
|
||||||
if (unlink(fname) < 0 && errno != ENOENT && errno != EISDIR)
|
if (unlink(fname) < 0 && errno != ENOENT && errno != EISDIR)
|
||||||
eprintf("unlink %s:", fname);
|
eprintf("unlink %s:", fname);
|
||||||
|
|
||||||
|
tmp = strdup(fname);
|
||||||
|
mkdirp(dirname(tmp));
|
||||||
|
free(tmp);
|
||||||
|
|
||||||
switch (h->type) {
|
switch (h->type) {
|
||||||
case REG:
|
case REG:
|
||||||
case AREG:
|
case AREG:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user