Add proper longlink support. Previously we handled longname support, and
the longlink support was completely wrong.
This commit is contained in:
parent
5fc1c3b058
commit
4472ef1520
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ar_subs.c,v 1.18 2002/10/16 03:46:08 christos Exp $ */
|
||||
/* $NetBSD: ar_subs.c,v 1.19 2002/10/17 00:32:36 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)ar_subs.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: ar_subs.c,v 1.18 2002/10/16 03:46:08 christos Exp $");
|
||||
__RCSID("$NetBSD: ar_subs.c,v 1.19 2002/10/17 00:32:36 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -112,7 +112,8 @@ list(void)
|
|||
* we need to read, to get the real filename
|
||||
*/
|
||||
off_t cnt;
|
||||
if (!(*frmt->rd_data)(arcn, -1, &cnt));
|
||||
if (!(*frmt->rd_data)(arcn, arcn->type == PAX_GLF
|
||||
? -1 : -2, &cnt));
|
||||
(void)rd_skip(cnt + arcn->pad);
|
||||
continue;
|
||||
}
|
||||
|
@ -205,7 +206,8 @@ extract(void)
|
|||
/*
|
||||
* we need to read, to get the real filename
|
||||
*/
|
||||
if (!(*frmt->rd_data)(arcn, -1, &cnt));
|
||||
if (!(*frmt->rd_data)(arcn, arcn->type == PAX_GLF
|
||||
? -1 : -2, &cnt));
|
||||
(void)rd_skip(cnt + arcn->pad);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: extern.h,v 1.34 2002/10/16 03:46:08 christos Exp $ */
|
||||
/* $NetBSD: extern.h,v 1.35 2002/10/17 00:32:36 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -146,7 +146,7 @@ int bcpio_wr(ARCHD *);
|
|||
/*
|
||||
* file_subs.c
|
||||
*/
|
||||
extern char *gnu_hack_string;
|
||||
extern char *gnu_name_string, *gnu_link_string;
|
||||
int file_creat(ARCHD *);
|
||||
void file_close(ARCHD *, int);
|
||||
int lnk_creat(ARCHD *);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: file_subs.c,v 1.24 2002/10/12 15:39:29 christos Exp $ */
|
||||
/* $NetBSD: file_subs.c,v 1.25 2002/10/17 00:32:36 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)file_subs.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: file_subs.c,v 1.24 2002/10/12 15:39:29 christos Exp $");
|
||||
__RCSID("$NetBSD: file_subs.c,v 1.25 2002/10/17 00:32:36 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -839,6 +839,7 @@ file_write(int fd, char *str, int cnt, int *rem, int *isempt, int sz,
|
|||
char *end;
|
||||
int wcnt;
|
||||
char *st = str;
|
||||
char **strp;
|
||||
|
||||
/*
|
||||
* while we have data to process
|
||||
|
@ -897,17 +898,27 @@ file_write(int fd, char *str, int cnt, int *rem, int *isempt, int sz,
|
|||
/*
|
||||
* have non-zero data in this file system block, have to write
|
||||
*/
|
||||
if (fd == -1) {
|
||||
/* GNU hack */
|
||||
if (gnu_hack_string)
|
||||
switch (fd) {
|
||||
case -1:
|
||||
strp = &gnu_name_string;
|
||||
break;
|
||||
case -2:
|
||||
strp = &gnu_link_string;
|
||||
break;
|
||||
default:
|
||||
strp = NULL;
|
||||
break;
|
||||
}
|
||||
if (strp) {
|
||||
if (*strp)
|
||||
err(1, "WARNING! Major Internal Error! GNU hack Failing!");
|
||||
gnu_hack_string = malloc(wcnt + 1);
|
||||
if (gnu_hack_string == NULL) {
|
||||
*strp = malloc(wcnt + 1);
|
||||
if (*strp == NULL) {
|
||||
tty_warn(1, "Out of memory");
|
||||
return(-1);
|
||||
}
|
||||
strncpy(gnu_hack_string, st, wcnt);
|
||||
gnu_hack_string[wcnt] = 0;
|
||||
strlcpy(*strp, st, wcnt);
|
||||
break;
|
||||
} else if (xwrite(fd, st, wcnt) != wcnt) {
|
||||
syswarn(1, errno, "Failed write to file %s", name);
|
||||
return(-1);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tar.c,v 1.28 2002/10/16 18:53:40 christos Exp $ */
|
||||
/* $NetBSD: tar.c,v 1.29 2002/10/17 00:32:36 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)tar.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: tar.c,v 1.28 2002/10/16 18:53:40 christos Exp $");
|
||||
__RCSID("$NetBSD: tar.c,v 1.29 2002/10/17 00:32:36 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -68,6 +68,7 @@ __RCSID("$NetBSD: tar.c,v 1.28 2002/10/16 18:53:40 christos Exp $");
|
|||
* Routines for reading, writing and header identify of various versions of tar
|
||||
*/
|
||||
|
||||
static void expandname(ARCHD *, const char *, const char *);
|
||||
static void longlink(ARCHD *);
|
||||
static u_long tar_chksm(char *, int);
|
||||
static char *name_split(char *, int);
|
||||
|
@ -85,8 +86,10 @@ int is_gnutar; /* behave like gnu tar; enable gnu
|
|||
* extensions and skip end-ofvolume
|
||||
* checks
|
||||
*/
|
||||
char *gnu_hack_string; /* ././@LongLink hackery */
|
||||
int gnu_hack_len; /* len of gnu_hack_string */
|
||||
static char *gnu_hack_string; /* ././@LongLink hackery */
|
||||
static int gnu_hack_len; /* len of gnu_hack_string */
|
||||
char *gnu_name_string; /* ././@LongLink hackery name */
|
||||
char *gnu_link_string; /* ././@LongLink hackery name */
|
||||
|
||||
/*
|
||||
* tar_endwr()
|
||||
|
@ -402,22 +405,16 @@ tar_rd(ARCHD *arcn, char *buf)
|
|||
*/
|
||||
if (tar_id(buf, BLKMULT) < 0)
|
||||
return(-1);
|
||||
memset(arcn, 0, sizeof(*arcn));
|
||||
arcn->org_name = arcn->name;
|
||||
arcn->sb.st_nlink = 1;
|
||||
arcn->pat = NULL;
|
||||
arcn->sb.st_nlink = 1;
|
||||
|
||||
/*
|
||||
* copy out the name and values in the stat buffer
|
||||
*/
|
||||
hd = (HD_TAR *)buf;
|
||||
if (gnu_hack_string) {
|
||||
arcn->nlen = strlcpy(arcn->name, gnu_hack_string,
|
||||
sizeof(arcn->name));
|
||||
free(gnu_hack_string);
|
||||
gnu_hack_string = NULL;
|
||||
} else {
|
||||
arcn->nlen = strlcpy(arcn->name, hd->name, sizeof(arcn->name));
|
||||
}
|
||||
expandname(arcn, hd->name, hd->linkname);
|
||||
arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode,sizeof(hd->mode),OCT) &
|
||||
0xfff);
|
||||
arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT);
|
||||
|
@ -440,8 +437,6 @@ tar_rd(ARCHD *arcn, char *buf)
|
|||
* the st_mode so -v printing will look correct.
|
||||
*/
|
||||
arcn->type = PAX_SLK;
|
||||
arcn->ln_nlen = strlcpy(arcn->ln_name, hd->linkname,
|
||||
sizeof(arcn->ln_name));
|
||||
arcn->sb.st_mode |= S_IFLNK;
|
||||
break;
|
||||
case LNKTYPE:
|
||||
|
@ -451,8 +446,6 @@ tar_rd(ARCHD *arcn, char *buf)
|
|||
*/
|
||||
arcn->type = PAX_HLK;
|
||||
arcn->sb.st_nlink = 2;
|
||||
arcn->ln_nlen = strlcpy(arcn->ln_name, hd->linkname,
|
||||
sizeof(arcn->ln_name));
|
||||
|
||||
/*
|
||||
* no idea of what type this thing really points at, but
|
||||
|
@ -472,8 +465,6 @@ tar_rd(ARCHD *arcn, char *buf)
|
|||
arcn->type = PAX_GLF;
|
||||
arcn->pad = TAR_PAD(arcn->sb.st_size);
|
||||
arcn->skip = arcn->sb.st_size;
|
||||
arcn->ln_name[0] = '\0';
|
||||
arcn->ln_nlen = 0;
|
||||
break;
|
||||
case AREGTYPE:
|
||||
case REGTYPE:
|
||||
|
@ -484,8 +475,6 @@ tar_rd(ARCHD *arcn, char *buf)
|
|||
* Note: V7 tar doesn't actually have DIRTYPE, but it was
|
||||
* reported that V7 archives using USTAR directories do exist.
|
||||
*/
|
||||
arcn->ln_name[0] = '\0';
|
||||
arcn->ln_nlen = 0;
|
||||
if (*pt == '/' || hd->linkflag == DIRTYPE) {
|
||||
/*
|
||||
* it is a directory, set the mode for -v printing
|
||||
|
@ -765,10 +754,11 @@ ustar_rd(ARCHD *arcn, char *buf)
|
|||
*/
|
||||
if (ustar_id(buf, BLKMULT) < 0)
|
||||
return(-1);
|
||||
|
||||
memset(arcn, 0, sizeof(*arcn));
|
||||
arcn->org_name = arcn->name;
|
||||
arcn->sb.st_nlink = 1;
|
||||
arcn->pat = NULL;
|
||||
arcn->nlen = 0;
|
||||
arcn->sb.st_nlink = 1;
|
||||
hd = (HD_USTAR *)buf;
|
||||
|
||||
/*
|
||||
|
@ -782,11 +772,11 @@ ustar_rd(ARCHD *arcn, char *buf)
|
|||
*dest++ = '/';
|
||||
cnt++;
|
||||
}
|
||||
if (gnu_hack_string) {
|
||||
arcn->nlen = strlcpy(dest, gnu_hack_string,
|
||||
if (gnu_name_string) {
|
||||
arcn->nlen = strlcpy(dest, gnu_name_string,
|
||||
sizeof(arcn->name) - cnt);
|
||||
free(gnu_hack_string);
|
||||
gnu_hack_string = NULL;
|
||||
free(gnu_name_string);
|
||||
gnu_name_string = NULL;
|
||||
} else {
|
||||
arcn->nlen = strlcpy(dest, hd->name, sizeof(arcn->name) - cnt);
|
||||
}
|
||||
|
@ -817,8 +807,6 @@ ustar_rd(ARCHD *arcn, char *buf)
|
|||
/*
|
||||
* set the defaults, these may be changed depending on the file type
|
||||
*/
|
||||
arcn->ln_name[0] = '\0';
|
||||
arcn->ln_nlen = 0;
|
||||
arcn->pad = 0;
|
||||
arcn->skip = 0;
|
||||
arcn->sb.st_rdev = (dev_t)0;
|
||||
|
@ -873,11 +861,6 @@ ustar_rd(ARCHD *arcn, char *buf)
|
|||
arcn->sb.st_mode |= S_IFREG;
|
||||
arcn->sb.st_nlink = 2;
|
||||
}
|
||||
/*
|
||||
* copy the link name
|
||||
*/
|
||||
arcn->ln_nlen = strlcpy(arcn->ln_name, hd->linkname,
|
||||
sizeof(arcn->ln_name));
|
||||
break;
|
||||
case LONGLINKTYPE:
|
||||
if (is_gnutar)
|
||||
|
@ -893,8 +876,6 @@ ustar_rd(ARCHD *arcn, char *buf)
|
|||
arcn->type = PAX_GLF;
|
||||
arcn->pad = TAR_PAD(arcn->sb.st_size);
|
||||
arcn->skip = arcn->sb.st_size;
|
||||
arcn->ln_name[0] = '\0';
|
||||
arcn->ln_nlen = 0;
|
||||
} else {
|
||||
tty_warn(1, "GNU Long %s found in posix ustar archive.",
|
||||
hd->typeflag == LONGLINKTYPE ? "Link" : "File");
|
||||
|
@ -917,6 +898,27 @@ ustar_rd(ARCHD *arcn, char *buf)
|
|||
return(0);
|
||||
}
|
||||
|
||||
static void
|
||||
expandname(ARCHD *arcn, const char *name, const char *linkname)
|
||||
{
|
||||
if (gnu_name_string) {
|
||||
arcn->nlen = strlcpy(arcn->name, gnu_name_string,
|
||||
sizeof(arcn->name));
|
||||
free(gnu_name_string);
|
||||
gnu_name_string = NULL;
|
||||
} else {
|
||||
arcn->nlen = strlcpy(arcn->name, name, sizeof(arcn->name));
|
||||
}
|
||||
if (gnu_link_string) {
|
||||
arcn->ln_nlen = strlcpy(arcn->ln_name, gnu_link_string,
|
||||
sizeof(arcn->ln_name));
|
||||
free(gnu_link_string);
|
||||
gnu_link_string = NULL;
|
||||
} else {
|
||||
arcn->ln_nlen = strlcpy(arcn->ln_name, linkname,
|
||||
sizeof(arcn->ln_name));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
longlink(ARCHD *arcn)
|
||||
|
|
Loading…
Reference in New Issue