summaryrefslogtreecommitdiffstats
path: root/bin/pax/ar_subs.c
diff options
context:
space:
mode:
authorkris <kris@FreeBSD.org>2001-05-08 06:19:06 +0000
committerkris <kris@FreeBSD.org>2001-05-08 06:19:06 +0000
commit6f2ea93cf4d39dc17b5fff4bc84a55d6562c8cd4 (patch)
tree63ec355a438835dcc12c39eb54e9e286c4f71426 /bin/pax/ar_subs.c
parent7ecc59e45de1a67ed22b32856a18f28bb30d36e6 (diff)
downloadFreeBSD-src-6f2ea93cf4d39dc17b5fff4bc84a55d6562c8cd4.zip
FreeBSD-src-6f2ea93cf4d39dc17b5fff4bc84a55d6562c8cd4.tar.gz
Sync up with OpenBSD. Too many changes to note, but the major features
are: * Implement cpio compatibility mode when pax is invoked as cpio * Extend tar compatibility mode to cover many of the GNU tar single-letter options (bzip2 mode, aka -y/-j is not present in OpenBSD). When invoked as tar, pax is now full-featured enough for use by the ports collection to extract distfiles and create packages. * Many bug fixes to the operation of pax and the tar compatibility modes * Code fixes for things like correct string buffer termination. I tried to preserve existing FreeBSD fixes to this utility; please let me know if I have inadvertently spammed something.
Diffstat (limited to 'bin/pax/ar_subs.c')
-rw-r--r--bin/pax/ar_subs.c72
1 files changed, 57 insertions, 15 deletions
diff --git a/bin/pax/ar_subs.c b/bin/pax/ar_subs.c
index 4f15ffd..f783489 100644
--- a/bin/pax/ar_subs.c
+++ b/bin/pax/ar_subs.c
@@ -130,7 +130,7 @@ list()
if ((res = mod_name(arcn)) < 0)
break;
if (res == 0)
- ls_list(arcn, now);
+ ls_list(arcn, now, stdout);
}
/*
@@ -171,6 +171,7 @@ extract()
ARCHD archd;
struct stat sb;
int fd;
+ time_t now;
arcn = &archd;
/*
@@ -189,6 +190,8 @@ extract()
if (iflag && (name_start() < 0))
return;
+ now = time(NULL);
+
/*
* step through each entry on the archive until the format read routine
* says it is done
@@ -276,11 +279,23 @@ extract()
}
if (vflag) {
- (void)fputs(arcn->name, stderr);
- vfpart = 1;
+ if (vflag > 1)
+ ls_list(arcn, now, listf);
+ else {
+ (void)fputs(arcn->name, listf);
+ vfpart = 1;
+ }
}
/*
+ * if required, chdir around.
+ */
+ if ((arcn->pat != NULL) && (arcn->pat->chdname != NULL))
+ if (chdir(arcn->pat->chdname) != 0)
+ syswarn(1, errno, "Cannot chdir to %s",
+ arcn->pat->chdname);
+
+ /*
* all ok, extract this member based on type
*/
if ((arcn->type != PAX_REG) && (arcn->type != PAX_CTG)) {
@@ -299,7 +314,7 @@ extract()
purg_lnk(arcn);
if (vflag && vfpart) {
- (void)putc('\n', stderr);
+ (void)putc('\n', listf);
vfpart = 0;
}
continue;
@@ -320,11 +335,19 @@ extract()
res = (*frmt->rd_data)(arcn, fd, &cnt);
file_close(arcn, fd);
if (vflag && vfpart) {
- (void)putc('\n', stderr);
+ (void)putc('\n', listf);
vfpart = 0;
}
if (!res)
(void)rd_skip(cnt + arcn->pad);
+
+ /*
+ * if required, chdir around.
+ */
+ if ((arcn->pat != NULL) && (arcn->pat->chdname != NULL))
+ if (fchdir(cwdfd) != 0)
+ syswarn(1, errno,
+ "Can't fchdir to starting directory");
}
/*
@@ -361,6 +384,7 @@ wr_archive(arcn, is_app)
off_t cnt;
int (*wrf)();
int fd = -1;
+ time_t now;
/*
* if this format supports hard link storage, start up the database
@@ -388,6 +412,8 @@ wr_archive(arcn, is_app)
*/
wr_one = is_app;
+ now = time(NULL);
+
/*
* while there are files to archive, process them one at at time
*/
@@ -457,8 +483,12 @@ wr_archive(arcn, is_app)
}
if (vflag) {
- (void)fputs(arcn->name, stderr);
- vfpart = 1;
+ if (vflag > 1)
+ ls_list(arcn, now, listf);
+ else {
+ (void)fputs(arcn->name, listf);
+ vfpart = 1;
+ }
}
++flcnt;
@@ -477,7 +507,7 @@ wr_archive(arcn, is_app)
* so we are done messing with this file
*/
if (vflag && vfpart) {
- (void)putc('\n', stderr);
+ (void)putc('\n', listf);
vfpart = 0;
}
rdfile_close(arcn, &fd);
@@ -495,7 +525,7 @@ wr_archive(arcn, is_app)
res = (*frmt->wr_data)(arcn, fd, &cnt);
rdfile_close(arcn, &fd);
if (vflag && vfpart) {
- (void)putc('\n', stderr);
+ (void)putc('\n', listf);
vfpart = 0;
}
if (res < 0)
@@ -612,7 +642,7 @@ append()
* reading the archive may take a long time. If verbose tell the user
*/
if (vflag) {
- (void)fprintf(stderr,
+ (void)fprintf(listf,
"%s: Reading archive to position at the end...", argv0);
vfpart = 1;
}
@@ -674,7 +704,7 @@ append()
* tell the user we are done reading.
*/
if (vflag && vfpart) {
- (void)fputs("done.\n", stderr);
+ (void)fputs("done.\n", listf);
vfpart = 0;
}
@@ -872,7 +902,7 @@ copy()
}
if (vflag) {
- (void)fputs(arcn->name, stderr);
+ (void)fputs(arcn->name, listf);
vfpart = 1;
}
++flcnt;
@@ -887,7 +917,7 @@ copy()
res = chk_same(arcn);
if (res <= 0) {
if (vflag && vfpart) {
- (void)putc('\n', stderr);
+ (void)putc('\n', listf);
vfpart = 0;
}
continue;
@@ -907,7 +937,7 @@ copy()
if (res < 0)
purg_lnk(arcn);
if (vflag && vfpart) {
- (void)putc('\n', stderr);
+ (void)putc('\n', listf);
vfpart = 0;
}
continue;
@@ -937,7 +967,7 @@ copy()
rdfile_close(arcn, &fdsrc);
if (vflag && vfpart) {
- (void)putc('\n', stderr);
+ (void)putc('\n', listf);
vfpart = 0;
}
}
@@ -988,6 +1018,7 @@ next_head(arcn)
register int hsz;
register int in_resync = 0; /* set when we are in resync mode */
int cnt = 0; /* counter for trailer function */
+ int first = 1; /* on 1st read, EOF isn't premature. */
/*
* set up initial conditions, we want a whole frmt->hsz block as we
@@ -1006,6 +1037,17 @@ next_head(arcn)
break;
/*
+ * If we read 0 bytes (EOF) from an archive when we
+ * expect to find a header, we have stepped upon
+ * an archive without the customary block of zeroes
+ * end marker. It's just stupid to error out on
+ * them, so exit gracefully.
+ */
+ if (first && ret == 0)
+ return(-1);
+ first = 0;
+
+ /*
* some kind of archive read problem, try to resync the
* storage device, better give the user the bad news.
*/
OpenPOWER on IntegriCloud