Subject: bin/3177: add --fastread to tar to read only what's necessary
To: None <gnats-bugs@gnats.netbsd.org>
From: Hubert Feyrer <feyrer@rfhs8012.fh-regensburg.de>
List: netbsd-bugs
Date: 02/01/1997 22:58:58
>Number: 3177
>Category: bin
>Synopsis: add --fastread to tar to read only what's necessary
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sat Feb 1 21:50:01 1997
>Last-Modified:
>Originator: Hubert Feyrer
>Organization:
Hubert Feyrer <hubert.feyrer@rz.uni-regensburg.de>
>Release: 1.2
>Environment:
System: NetBSD miyu 1.2 NetBSD 1.2 (MIYU) #8: Sun Jan 26 20:34:03 MET 1997 feyrer@miyu:/usr/disk1/src12/sys/arch/i386/compile/MIYU i386
>Description:
The patch below is to make NetBSD's tar-command recognize
the --fast-read switch. It can be used to read only as much
of a tar file as needed to extract e.g. the first file without
scanning to the EOF.
This has been borrowed from FreeBSD, it's used in the ports
system there.
>How-To-Repeat:
tar -xf largefile.tar firstfile
-> scans the whole largefile.tar after extracting firstfile,
slow
tar --fast-read -xf -largefile.tar firstfile
-> aborts after extracting firstfile -> fast.
>Fix:
Patch against NetBSD V1.2's tar command to make it recognize
the --fast-read option. Borrowed from FreeBSD.
diff -crNb /usr/src/gnu/usr.bin/tar/tar.1 tar-NetBSD/tar.1
*** /usr/src/gnu/usr.bin/tar/tar.1 Wed Mar 13 14:55:00 1996
--- tar-NetBSD/tar.1 Sat Feb 1 22:03:50 1997
***************
*** 158,163 ****
--- 158,166 ----
.It Fl -new-volume-script Ar file
Run a script at the end of each archive volume (implies
.Fl M ) .
+ .It Fl -fast-read
+ Stop after all non-wildcard extraction targets have been found
+ in the archive.
.It Fl G
.It Fl -incremental
Create/list/extract old GNU-format incremental backup.
diff -crNb /usr/src/gnu/usr.bin/tar/tar.c tar-NetBSD/tar.c
*** /usr/src/gnu/usr.bin/tar/tar.c Thu Mar 21 18:35:51 1996
--- tar-NetBSD/tar.c Sat Feb 1 21:59:29 1997
***************
*** 88,93 ****
--- 88,94 ----
void name_init ();
void options ();
char *un_quote_string ();
+ int nlpsfreed = 0;
#ifndef S_ISLNK
#define lstat stat
***************
*** 187,192 ****
--- 188,194 ----
{"norecurse", 0, &f_norecurse, 1},
{"unlink", 0, &f_unlink, 1},
+ {"fast-read", 0, &f_fast_read, 1},
{0, 0, 0, 0}
};
***************
*** 766,771 ****
--- 768,774 ----
-[0-7][lmh] specify drive and density\n\
--norecurse don't recurse into subdirectories when creating\n\
--unlink unlink files before creating them\n\
+ --fast-read stop after desired names in archive have been found\n\
", stdout);
}
***************
*** 1127,1132 ****
--- 1130,1136 ----
register char *p;
{
register struct name *nlp;
+ struct name *tmpnlp;
register int len;
again:
***************
*** 1135,1141 ****
if (nlp->fake)
{
if (nlp->change_dir && chdir (nlp->change_dir))
! msg_perror ("Can't change to directory %d", nlp->change_dir);
namelist = 0;
return 1;
}
--- 1139,1145 ----
if (nlp->fake)
{
if (nlp->change_dir && chdir (nlp->change_dir))
! msg_perror ("Can't change to directory %s", nlp->change_dir);
namelist = 0;
return 1;
}
***************
*** 1178,1183 ****
--- 1182,1215 ----
}
if (nlp->change_dir && chdir (nlp->change_dir))
msg_perror ("Can't change to directory %s", nlp->change_dir);
+ if (f_fast_read) {
+ if (strcmp(p, nlp->name) == 0) {
+ /* remove the current entry, since we found a match */
+ /* use brute force, this code is a mess anyway */
+ if (namelist->next == NULL) {
+ /* the list contains one element */
+ free(namelist);
+ namelist = NULL;
+ } else {
+ if (nlp == namelist) {
+ /* the first element is the one */
+ tmpnlp = namelist->next;
+ free(namelist);
+ namelist = tmpnlp;
+ } else {
+ tmpnlp = namelist;
+ while (tmpnlp->next != nlp) {
+ tmpnlp = tmpnlp->next;
+ }
+ tmpnlp->next = nlp->next;
+ free(nlp);
+ }
+ }
+ /* set a boolean to decide wether we started with a */
+ /* non-empty namelist, that was emptied */
+ nlpsfreed = 1;
+ }
+ }
return 1; /* We got a match */
}
}
diff -crNb /usr/src/gnu/usr.bin/tar/tar.h tar-NetBSD/tar.h
*** /usr/src/gnu/usr.bin/tar/tar.h Sat Aug 7 07:42:55 1993
--- tar-NetBSD/tar.h Sat Feb 1 22:01:34 1997
***************
*** 236,241 ****
--- 236,242 ----
TAR_EXTERN int f_compress_block; /* --compress-block */
TAR_EXTERN int f_norecurse; /* --norecurse */
TAR_EXTERN int f_unlink; /* --unlink */
+ TAR_EXTERN int f_fast_read; /* --fast-read */
/*
* We default to Unix Standard format rather than 4.2BSD tar format.
***************
*** 278,283 ****
--- 279,288 ----
*/
TAR_EXTERN char read_error_flag;
+ /*
+ * global boolean, see name_match in tar.c
+ */
+ extern int nlpsfreed;
/*
* Declarations of functions available to the world.
>Audit-Trail:
>Unformatted: