Support gnu long filename extensions by default for tar on create, list, and
extract. We now generate GNU tar archives by default ("ustar ^@" instead of "ustar^@00"). GNU extensions can be disabled with --strict. XXX: long symlinks untested.
This commit is contained in:
parent
2da742de79
commit
f70dfaaf73
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ar_io.c,v 1.26 2002/10/13 17:19:33 christos Exp $ */
|
||||
/* $NetBSD: ar_io.c,v 1.27 2002/10/16 03:46:07 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)ar_io.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: ar_io.c,v 1.26 2002/10/13 17:19:33 christos Exp $");
|
||||
__RCSID("$NetBSD: ar_io.c,v 1.27 2002/10/16 03:46:07 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -776,7 +776,7 @@ ar_read(char *buf, int cnt)
|
|||
lstrval = res;
|
||||
if (res < 0)
|
||||
syswarn(1, errno, "Failed read on archive volume %d", arvol);
|
||||
else if (!is_oldgnutar)
|
||||
else if (!is_gnutar)
|
||||
tty_warn(0, "End of archive volume %d reached", arvol);
|
||||
return(res);
|
||||
}
|
||||
|
@ -1395,7 +1395,7 @@ ar_next(void)
|
|||
if (sigprocmask(SIG_SETMASK, &o_mask, (sigset_t *)NULL) < 0)
|
||||
syswarn(0, errno, "Unable to restore signal mask");
|
||||
|
||||
if (done || !wr_trail || is_oldgnutar || force_one_volume)
|
||||
if (done || !wr_trail || is_gnutar || force_one_volume)
|
||||
return(-1);
|
||||
|
||||
tty_prnt("\nATTENTION! %s archive volume change required.\n", argv0);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ar_subs.c,v 1.17 2002/10/12 15:39:29 christos Exp $ */
|
||||
/* $NetBSD: ar_subs.c,v 1.18 2002/10/16 03:46:08 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.17 2002/10/12 15:39:29 christos Exp $");
|
||||
__RCSID("$NetBSD: ar_subs.c,v 1.18 2002/10/16 03:46:08 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -107,6 +107,16 @@ list(void)
|
|||
* step through the archive until the format says it is done
|
||||
*/
|
||||
while (next_head(arcn) == 0) {
|
||||
if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) {
|
||||
/*
|
||||
* we need to read, to get the real filename
|
||||
*/
|
||||
off_t cnt;
|
||||
if (!(*frmt->rd_data)(arcn, -1, &cnt));
|
||||
(void)rd_skip(cnt + arcn->pad);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arcn->name[0] == '/' && !check_Aflag()) {
|
||||
memmove(arcn->name, arcn->name + 1, strlen(arcn->name));
|
||||
}
|
||||
|
@ -133,7 +143,6 @@ list(void)
|
|||
if (res == 0)
|
||||
ls_list(arcn, now, stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
* skip to next archive format header using values calculated
|
||||
* by the format header read routine
|
||||
|
@ -192,8 +201,14 @@ extract(void)
|
|||
* says it is done
|
||||
*/
|
||||
while (next_head(arcn) == 0) {
|
||||
int gnu_longlink_hack =
|
||||
(arcn->type == PAX_GLL || arcn->type == PAX_GLF);
|
||||
if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) {
|
||||
/*
|
||||
* we need to read, to get the real filename
|
||||
*/
|
||||
if (!(*frmt->rd_data)(arcn, -1, &cnt));
|
||||
(void)rd_skip(cnt + arcn->pad);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arcn->name[0] == '/' && !check_Aflag()) {
|
||||
memmove(arcn->name, arcn->name + 1, strlen(arcn->name));
|
||||
|
@ -202,19 +217,17 @@ extract(void)
|
|||
* check for pattern, and user specified options match. When
|
||||
* all the patterns are matched we are done
|
||||
*/
|
||||
if (!gnu_longlink_hack) {
|
||||
if ((res = pat_match(arcn)) < 0)
|
||||
break;
|
||||
if ((res = pat_match(arcn)) < 0)
|
||||
break;
|
||||
|
||||
if ((res > 0) || (sel_chk(arcn) != 0)) {
|
||||
/*
|
||||
* file is not selected. skip past any file
|
||||
* data and padding and go back for the next
|
||||
* archive member
|
||||
*/
|
||||
(void)rd_skip(arcn->skip + arcn->pad);
|
||||
continue;
|
||||
}
|
||||
if ((res > 0) || (sel_chk(arcn) != 0)) {
|
||||
/*
|
||||
* file is not selected. skip past any file
|
||||
* data and padding and go back for the next
|
||||
* archive member
|
||||
*/
|
||||
(void)rd_skip(arcn->skip + arcn->pad);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -227,8 +240,7 @@ extract(void)
|
|||
* file AFTER the name mod. In honesty the pax spec is probably
|
||||
* flawed in this respect. ignore this for GNU long links.
|
||||
*/
|
||||
if ((uflag || Dflag) && ((lstat(arcn->name, &sb) == 0)) &&
|
||||
!gnu_longlink_hack) {
|
||||
if ((uflag || Dflag) && ((lstat(arcn->name, &sb) == 0))) {
|
||||
if (uflag && Dflag) {
|
||||
if ((arcn->sb.st_mtime <= sb.st_mtime) &&
|
||||
(arcn->sb.st_ctime <= sb.st_ctime)) {
|
||||
|
@ -264,8 +276,7 @@ extract(void)
|
|||
* Non standard -Y and -Z flag. When the existing file is
|
||||
* same age or newer skip; ignore this for GNU long links.
|
||||
*/
|
||||
if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0)) &&
|
||||
!gnu_longlink_hack) {
|
||||
if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) {
|
||||
if (Yflag && Zflag) {
|
||||
if ((arcn->sb.st_mtime <= sb.st_mtime) &&
|
||||
(arcn->sb.st_ctime <= sb.st_ctime)) {
|
||||
|
@ -302,8 +313,7 @@ extract(void)
|
|||
/*
|
||||
* all ok, extract this member based on type
|
||||
*/
|
||||
if ((arcn->type != PAX_REG) && (arcn->type != PAX_CTG) &&
|
||||
!gnu_longlink_hack) {
|
||||
if ((arcn->type != PAX_REG) && (arcn->type != PAX_CTG)) {
|
||||
/*
|
||||
* process archive members that are not regular files.
|
||||
* throw out padding and any data that might follow the
|
||||
|
@ -328,9 +338,7 @@ extract(void)
|
|||
* we have a file with data here. If we can not create it, skip
|
||||
* over the data and purge the name from hard link table
|
||||
*/
|
||||
if (gnu_longlink_hack)
|
||||
fd = -1; /* this tells the pax internals to DTRT */
|
||||
else if ((fd = file_creat(arcn)) < 0) {
|
||||
if ((fd = file_creat(arcn)) < 0) {
|
||||
(void)rd_skip(arcn->skip + arcn->pad);
|
||||
purg_lnk(arcn);
|
||||
continue;
|
||||
|
@ -340,8 +348,7 @@ extract(void)
|
|||
* any unprocessed data
|
||||
*/
|
||||
res = (*frmt->rd_data)(arcn, fd, &cnt);
|
||||
if (!gnu_longlink_hack)
|
||||
file_close(arcn, fd);
|
||||
file_close(arcn, fd);
|
||||
if (vflag && vfpart) {
|
||||
(void)putc('\n', listf);
|
||||
vfpart = 0;
|
||||
|
@ -1032,7 +1039,7 @@ next_head(ARCHD *arcn)
|
|||
* storage device, better give the user the bad news.
|
||||
*/
|
||||
if ((ret == 0) || (rd_sync() < 0)) {
|
||||
if (!is_oldgnutar)
|
||||
if (!is_gnutar)
|
||||
tty_warn(1,
|
||||
"Premature end of file on archive read");
|
||||
return(-1);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: extern.h,v 1.33 2002/10/15 16:16:29 christos Exp $ */
|
||||
/* $NetBSD: extern.h,v 1.34 2002/10/16 03:46:08 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -295,7 +295,7 @@ u_int st_hash(char *, int, int);
|
|||
/*
|
||||
* tar.c
|
||||
*/
|
||||
extern int is_oldgnutar;
|
||||
extern int is_gnutar;
|
||||
int tar_endwr(void);
|
||||
off_t tar_endrd(void);
|
||||
int tar_trail(char *, int, int *);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: options.c,v 1.47 2002/10/15 16:16:29 christos Exp $ */
|
||||
/* $NetBSD: options.c,v 1.48 2002/10/16 03:46:08 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992 Keith Muller.
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: options.c,v 1.47 2002/10/15 16:16:29 christos Exp $");
|
||||
__RCSID("$NetBSD: options.c,v 1.48 2002/10/16 03:46:08 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -116,6 +116,7 @@ static int getline_error;
|
|||
#define OPT_NORECURSE 12
|
||||
#define OPT_FORCE_LOCAL 13
|
||||
#define OPT_INSECURE 14
|
||||
#define OPT_STRICT 15
|
||||
|
||||
/*
|
||||
* Format specific routine table - MUST BE IN SORTED ORDER BY NAME
|
||||
|
@ -698,6 +699,8 @@ struct option tar_longopts[] = {
|
|||
{ "exclude-from", required_argument, 0, 'X' },
|
||||
{ "compress", no_argument, 0, 'Z' },
|
||||
{ "uncompress", no_argument, 0, 'Z' },
|
||||
{ "strict", no_argument, 0,
|
||||
OPT_STRICT },
|
||||
{ "atime-preserve", no_argument, 0,
|
||||
OPT_ATIME_PRESERVE },
|
||||
{ "unlink", no_argument, 0,
|
||||
|
@ -843,12 +846,12 @@ tar_options(int argc, char **argv)
|
|||
* this is a create or extract operation.
|
||||
*/
|
||||
if (act == ARCHIVE) {
|
||||
/* GNU tar: write V7 format archives. */
|
||||
Oflag = 1;
|
||||
/* 4.2BSD: don't add directory entries. */
|
||||
if (opt_add("write_opt=nodir") < 0)
|
||||
tar_usage();
|
||||
|
||||
/* GNU tar: write V7 format archives. */
|
||||
frmt = &(fsub[F_TAR]);
|
||||
} else {
|
||||
/* SUS: don't preserve owner/group. */
|
||||
pids = 0;
|
||||
|
@ -1014,6 +1017,10 @@ tar_options(int argc, char **argv)
|
|||
case OPT_INSECURE:
|
||||
secure = 0;
|
||||
break;
|
||||
case OPT_STRICT:
|
||||
/* disable gnu extensions */
|
||||
is_gnutar = 0;
|
||||
break;
|
||||
default:
|
||||
tar_usage();
|
||||
break;
|
||||
|
@ -1685,10 +1692,16 @@ bad_opt(void)
|
|||
/*
|
||||
* print all we were given
|
||||
*/
|
||||
tty_warn(1,"These format options are not supported");
|
||||
tty_warn(1," These format options are not supported for %s",
|
||||
frmt->name);
|
||||
while ((opt = opt_next()) != NULL)
|
||||
(void)fprintf(stderr, "\t%s = %s\n", opt->name, opt->value);
|
||||
pax_usage();
|
||||
if (strcmp(NM_TAR, argv0) == 0)
|
||||
tar_usage();
|
||||
else if (strcmp(NM_CPIO, argv0) == 0)
|
||||
cpio_usage();
|
||||
else
|
||||
pax_usage();
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -1873,7 +1886,7 @@ void
|
|||
pax_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: pax [-cdnvzO] [-E limit] [-f archive] [-N dbdir] [-s replstr] ...\n"
|
||||
"Usage: pax [-cdnvzO] [-E limit] [-f archive] [-N dbdir] [-s replstr] ...\n"
|
||||
" [-U user] ... [-G group] ... [-T [from_date][,to_date]] ...\n"
|
||||
" [pattern ...]\n");
|
||||
fprintf(stderr,
|
||||
|
@ -1901,7 +1914,7 @@ pax_usage(void)
|
|||
void
|
||||
tar_usage(void)
|
||||
{
|
||||
(void)fputs("usage: tar -{crtux}[-befhmopqvwzHLOPXZ014578] [archive] "
|
||||
(void)fputs("Usage: tar -{crtux}[-befhmopqvwzHLOPXZ014578] [archive] "
|
||||
"[blocksize]\n"
|
||||
" [-C directory] [-T file] [-s replstr] "
|
||||
"[file ...]\n", stderr);
|
||||
|
@ -1920,23 +1933,23 @@ cpio_usage(void)
|
|||
|
||||
#if 1
|
||||
(void)fputs(
|
||||
"usage: cpio -i [-BcdfmrStuv] [ -C blksize ] [ -H header ]\n",
|
||||
"Usage: cpio -i [-BcdfmrStuv] [ -C blksize ] [ -H header ]\n",
|
||||
stderr);
|
||||
(void)fputs(" [ -I file ] [ pattern ... ]\n", stderr);
|
||||
(void)fputs("usage: cpio -o [-aABcLv] [ -C bufsize ] [ -H header ]\n",
|
||||
(void)fputs("Usage: cpio -o [-aABcLv] [ -C bufsize ] [ -H header ]\n",
|
||||
stderr);
|
||||
(void)fputs(" [ -O file ]\n", stderr);
|
||||
(void)fputs("usage: cpio -p [ adlLmuv ] directory\n", stderr);
|
||||
(void)fputs("Usage: cpio -p [ adlLmuv ] directory\n", stderr);
|
||||
#else
|
||||
/* no E, M, R, V, b, k or s */
|
||||
(void)fputs("usage: cpio -i [-bBcdfkmrsStuvV] [ -C bufsize ]\n", stderr);
|
||||
(void)fputs("Usage: cpio -i [-bBcdfkmrsStuvV] [ -C bufsize ]\n", stderr);
|
||||
(void)fputs(" [ -E file ] [ -H header ] [ -I file [ -M message ] ]\n",
|
||||
stderr);
|
||||
(void)fputs(" [ -R id ] [ pattern ... ]\n", stderr);
|
||||
(void)fputs("usage: cpio -o [-aABcLvV] [ -C bufsize ] [ -H header ]\n",
|
||||
(void)fputs("Usage: cpio -o [-aABcLvV] [ -C bufsize ] [ -H header ]\n",
|
||||
stderr);
|
||||
(void)fputs(" [ -O file [ -M message ] ]\n", stderr);
|
||||
(void)fputs("usage: cpio -p [ adlLmuvV ] [ -R id ] directory\n", stderr);
|
||||
(void)fputs("Usage: cpio -p [ adlLmuvV ] [ -R id ] directory\n", stderr);
|
||||
#endif
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
|
|
151
bin/pax/tar.c
151
bin/pax/tar.c
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tar.c,v 1.25 2002/10/13 17:21:50 christos Exp $ */
|
||||
/* $NetBSD: tar.c,v 1.26 2002/10/16 03:46:09 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.25 2002/10/13 17:21:50 christos Exp $");
|
||||
__RCSID("$NetBSD: tar.c,v 1.26 2002/10/16 03:46:09 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -68,6 +68,7 @@ __RCSID("$NetBSD: tar.c,v 1.25 2002/10/13 17:21:50 christos Exp $");
|
|||
* Routines for reading, writing and header identify of various versions of tar
|
||||
*/
|
||||
|
||||
static void longlink(ARCHD *);
|
||||
static u_long tar_chksm(char *, int);
|
||||
static char *name_split(char *, int);
|
||||
static int ul_oct(u_long, char *, int, int);
|
||||
|
@ -80,8 +81,12 @@ static int ull_oct(unsigned long long, char *, int, int);
|
|||
*/
|
||||
|
||||
static int tar_nodir; /* do not write dirs under old tar */
|
||||
int is_oldgnutar; /* skip end-ofvolume checks */
|
||||
int is_gnutar = 1; /* 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 */
|
||||
|
||||
/*
|
||||
* tar_endwr()
|
||||
|
@ -729,8 +734,9 @@ ustar_id(char *blk, int size)
|
|||
return(-1);
|
||||
if (strncmp(hd->magic, TMAGIC, TMAGLEN - 1) != 0)
|
||||
return(-1);
|
||||
if (!strncmp(hd->magic, "ustar ", 8))
|
||||
is_oldgnutar = 1;
|
||||
/* This is GNU tar */
|
||||
if (strncmp(hd->magic, "ustar ", 8) != 0)
|
||||
is_gnutar = 0;
|
||||
if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT))
|
||||
return(-1);
|
||||
return(0);
|
||||
|
@ -775,7 +781,14 @@ ustar_rd(ARCHD *arcn, char *buf)
|
|||
*dest++ = '/';
|
||||
cnt++;
|
||||
}
|
||||
arcn->nlen = strlcpy(dest, hd->name, sizeof(arcn->name) - cnt);
|
||||
if (gnu_hack_string) {
|
||||
arcn->nlen = strlcpy(dest, gnu_hack_string,
|
||||
sizeof(arcn->name) - cnt);
|
||||
free(gnu_hack_string);
|
||||
gnu_hack_string = NULL;
|
||||
} else {
|
||||
arcn->nlen = strlcpy(dest, hd->name, sizeof(arcn->name) - cnt);
|
||||
}
|
||||
|
||||
/*
|
||||
* follow the spec to the letter. we should only have mode bits, strip
|
||||
|
@ -865,6 +878,27 @@ ustar_rd(ARCHD *arcn, char *buf)
|
|||
arcn->ln_nlen = strlcpy(arcn->ln_name, hd->linkname,
|
||||
sizeof(arcn->ln_name));
|
||||
break;
|
||||
case LONGLINKTYPE:
|
||||
if (is_gnutar)
|
||||
arcn->type = PAX_GLL;
|
||||
/* FALLTHROUGH */
|
||||
case LONGNAMETYPE:
|
||||
if (is_gnutar) {
|
||||
/*
|
||||
* GNU long link/file; we tag these here and let the
|
||||
* pax internals deal with it -- too ugly otherwise.
|
||||
*/
|
||||
if (hd->typeflag != LONGLINKTYPE)
|
||||
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");
|
||||
}
|
||||
break;
|
||||
case CONTTYPE:
|
||||
case AREGTYPE:
|
||||
case REGTYPE:
|
||||
|
@ -882,6 +916,37 @@ ustar_rd(ARCHD *arcn, char *buf)
|
|||
return(0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
longlink(ARCHD *arcn)
|
||||
{
|
||||
ARCHD larc;
|
||||
|
||||
memset(&larc, 0, sizeof(larc));
|
||||
|
||||
switch (arcn->type) {
|
||||
case PAX_SLK:
|
||||
case PAX_HRG:
|
||||
case PAX_HLK:
|
||||
larc.type = PAX_GLL;
|
||||
larc.ln_nlen = strlcpy(larc.ln_name, "././@LongLink",
|
||||
sizeof(larc.ln_name));
|
||||
gnu_hack_string = arcn->ln_name;
|
||||
gnu_hack_len = arcn->ln_nlen + 1;
|
||||
break;
|
||||
default:
|
||||
larc.nlen = strlcpy(larc.name, "././@LongLink",
|
||||
sizeof(larc.name));
|
||||
gnu_hack_string = arcn->name;
|
||||
gnu_hack_len = arcn->nlen + 1;
|
||||
larc.type = PAX_GLF;
|
||||
}
|
||||
/*
|
||||
* We need a longlink now.
|
||||
*/
|
||||
ustar_wr(&larc);
|
||||
}
|
||||
|
||||
/*
|
||||
* ustar_wr()
|
||||
* write a ustar header for the file specified in the ARCHD to the archive
|
||||
|
@ -914,9 +979,15 @@ ustar_wr(ARCHD *arcn)
|
|||
* check the length of the linkname
|
||||
*/
|
||||
if (((arcn->type == PAX_SLK) || (arcn->type == PAX_HLK) ||
|
||||
(arcn->type == PAX_HRG)) && (arcn->ln_nlen >= sizeof(hd->linkname))){
|
||||
tty_warn(1, "Link name too long for ustar %s", arcn->ln_name);
|
||||
return(1);
|
||||
(arcn->type == PAX_HRG)) &&
|
||||
(arcn->ln_nlen >= sizeof(hd->linkname))){
|
||||
if (is_gnutar) {
|
||||
longlink(arcn);
|
||||
} else {
|
||||
tty_warn(1, "Link name too long for ustar %s",
|
||||
arcn->ln_name);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -924,8 +995,14 @@ ustar_wr(ARCHD *arcn)
|
|||
* pt != arcn->name, the name has to be split
|
||||
*/
|
||||
if ((pt = name_split(arcn->name, arcn->nlen)) == NULL) {
|
||||
tty_warn(1, "File name too long for ustar %s", arcn->name);
|
||||
return(1);
|
||||
if (is_gnutar) {
|
||||
longlink(arcn);
|
||||
pt = arcn->name;
|
||||
} else {
|
||||
tty_warn(1, "File name too long for ustar %s",
|
||||
arcn->name);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -981,38 +1058,58 @@ ustar_wr(ARCHD *arcn)
|
|||
if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
|
||||
goto out;
|
||||
break;
|
||||
case PAX_GLL:
|
||||
case PAX_SLK:
|
||||
case PAX_HLK:
|
||||
case PAX_HRG:
|
||||
if (arcn->type == PAX_SLK)
|
||||
hd->typeflag = SYMTYPE;
|
||||
else if (arcn->type == PAX_GLL)
|
||||
hd->typeflag = LONGLINKTYPE;
|
||||
else
|
||||
hd->typeflag = LNKTYPE;
|
||||
strlcpy(hd->linkname, arcn->ln_name, sizeof(hd->linkname));
|
||||
if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
|
||||
if (ul_oct((u_long)gnu_hack_len, hd->size,
|
||||
sizeof(hd->size), 3))
|
||||
goto out;
|
||||
break;
|
||||
case PAX_GLF:
|
||||
case PAX_REG:
|
||||
case PAX_CTG:
|
||||
default:
|
||||
/*
|
||||
* file data with this type, set the padding
|
||||
*/
|
||||
if (arcn->type == PAX_CTG)
|
||||
hd->typeflag = CONTTYPE;
|
||||
else
|
||||
hd->typeflag = REGTYPE;
|
||||
arcn->pad = TAR_PAD(arcn->sb.st_size);
|
||||
if (OFFT_OCT(arcn->sb.st_size, hd->size, sizeof(hd->size), 3)) {
|
||||
tty_warn(1,"File is too long for ustar %s",
|
||||
arcn->org_name);
|
||||
return(1);
|
||||
if (arcn->type == PAX_GLF) {
|
||||
hd->typeflag = LONGNAMETYPE;
|
||||
arcn->pad = TAR_PAD(gnu_hack_len);
|
||||
if (OFFT_OCT((u_long)gnu_hack_len, hd->size,
|
||||
sizeof(hd->size), 3)) {
|
||||
tty_warn(1,"File is too long for ustar %s",
|
||||
arcn->org_name);
|
||||
return(1);
|
||||
}
|
||||
} else {
|
||||
if (arcn->type == PAX_CTG)
|
||||
hd->typeflag = CONTTYPE;
|
||||
else
|
||||
hd->typeflag = REGTYPE;
|
||||
arcn->pad = TAR_PAD(arcn->sb.st_size);
|
||||
if (OFFT_OCT(arcn->sb.st_size, hd->size,
|
||||
sizeof(hd->size), 3)) {
|
||||
tty_warn(1,"File is too long for ustar %s",
|
||||
arcn->org_name);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
strncpy(hd->magic, TMAGIC, TMAGLEN);
|
||||
strncpy(hd->version, TVERSION, TVERSLEN);
|
||||
if (is_gnutar)
|
||||
hd->magic[TMAGLEN - 1] = hd->magic[TMAGLEN] = ' ';
|
||||
else
|
||||
strncpy(hd->version, TVERSION, TVERSLEN);
|
||||
|
||||
/*
|
||||
* set the remaining fields. Some versions want all 16 bits of mode
|
||||
|
@ -1040,6 +1137,16 @@ ustar_wr(ARCHD *arcn)
|
|||
return(-1);
|
||||
if (wr_skip((off_t)(BLKMULT - sizeof(HD_USTAR))) < 0)
|
||||
return(-1);
|
||||
if (gnu_hack_string) {
|
||||
int res = wr_rdbuf(gnu_hack_string, gnu_hack_len);
|
||||
int pad = gnu_hack_len;
|
||||
gnu_hack_string = NULL;
|
||||
gnu_hack_len = 0;
|
||||
if (res < 0)
|
||||
return(-1);
|
||||
if (wr_skip((off_t)(BLKMULT - (pad % BLKMULT))) < 0)
|
||||
return(-1);
|
||||
}
|
||||
if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG))
|
||||
return(0);
|
||||
return(1);
|
||||
|
|
Loading…
Reference in New Issue