home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume4
/
fixtar
< prev
next >
Wrap
Text File
|
1989-02-03
|
5KB
|
172 lines
Path: xanth!mcnc!rutgers!ucsd!ames!mailrus!tut.cis.ohio-state.edu!cwjcc!hal!ncoast!allbery
From: sahayman@watmath.UUCP (Steve Hayman)
Newsgroups: comp.sources.misc
Subject: v04i032: fixtar - A filter for converting absolute tar pathnames to relative
Message-ID: <8808190250.AA12792@watmath>
Date: 19 Aug 88 02:50:33 GMT
Sender: allbery@ncoast.UUCP
Reply-To: sahayman@watmath.UUCP (Steve Hayman)
Lines: 160
Approved: allbery@ncoast.UUCP
Posting-number: Volume 4, Issue 32
Submitted-by: "Steve Hayman" <sahayman@watmath.UUCP>
Archive-name: fixtar
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by sahayman@math.waterloo.edu on Thu Aug 18 22:49:24 EDT 1988
# Contents: README fixtar.c
echo x - README
sed 's/^@//' > "README" <<'@//E*O*F README//'
"fixtar" is a filter that knows what tar-format looks like, and removes
leading '/' from any absolute pathnames in the tar file. This can
be handy if you have a tar tape with absolute paths and want to
extract the files into other locations. You can do something like
dd if=$TAPE ibs=10k | fixtar | tar xf -
and all the /path/names will be extracted as "path/names".
I hope this is of use to somebody. On the whole you're probably
better off getting John Gilmore's public-domain "tar", which
also handles this problem and has many other nice features. This
is just a quick hack solution... I've used it on 4.3 BSD, it
ought to work elsewhere but unfortunately I can't be sure.
@..Steve Hayman, U. of Waterloo
sahayman@math.waterloo.edu
P.S. No makefile (just "cc -o fixtar fixtar.c" should do it), no man page,
no apologies :-)
@//E*O*F README//
chmod u=rw,g=r,o=r README
echo x - fixtar.c
sed 's/^@//' > "fixtar.c" <<'@//E*O*F fixtar.c//'
#include <stdio.h>
/*
* fixtar - a filter to convert absolute pathnames
* in tar to relative, by shifting them left one byte..
* this filter changes "/path/name" to "path/name"
*
* Usage: something like
* dd if=$TAPE | fixtar | tar xf -
*
* If the tar tape has "/path/name" in it, fixtar will
* convert that to "path/name" and tar will extract it
* relative to the current directory.
*
* You might want something like "dd if=$TAPE ibs=10k" to read
* the tape properly.
* I have used this on 4.3 BSD only. It ought to work on
* other versions of Unix but unfortunately I have no way of knowing.
*
* This program knows about tar format and is careful to diddle
* only the header blocks, not the data blocks.
*
* You're probably better off using John Gilmore's public-domain "tar",
* which always extracts with relative pathnames. (And which has
* many other nice features.)
*
* .. Steve Hayman, U. of Waterloo
* sahayman@math.waterloo.edu
*/
/*
* these definitions are straight out of "man 5 tar"
*/
#define TBLOCK 512
#define NAMSIZ 100
union hblock {
char dummy[TBLOCK];
struct header {
char name[NAMSIZ];
char mode[8];
char uid[8];
char gid[8];
char size[12];
char mtime[12];
char chksum[8];
char linkflag;
char linkname[NAMSIZ];
} dbuf;
};
union hblock hb;
main()
{
register int i;
char *p;
int size;
int chksum;
int zerob = 0;
while ( ( i = read(0, hb.dummy, (int)sizeof(hb.dummy))) > 0 ) {
if ( hb.dbuf.name[0] == '\0' ) {
zerob++;
write(1, hb.dummy, i);
/*
* two zero blocks in a row means end-of-archive
*/
if ( zerob == 2 ) {
/*
* read and write anything that's left,
* what the heck.
*/
while ( (i = read(0, hb.dummy,
(int)sizeof(hb.dummy))) > 0 ) {
write(1, hb.dummy, i);
}
exit(0);
}
continue;
}
zerob = 0;
p = hb.dbuf.name;
if ( *p == '/' ) {
/*
* Shift the name left one char, which
* removes the leading '/'
*/
p++;
do {
*(p-1) = *p;
} while ( *p++ ); /* up to and including '\0' */
fprintf(stderr, "Adjusted: /%s\n", hb.dbuf.name );
/*
* Fix the checksum - we have one less '/' in the
* header (and one more '\0' that doesn't change
* the checksum)
*/
sscanf(hb.dbuf.chksum, " %o", &chksum );
chksum -= '/';
/*
* "each field of width w has w-2 digits,
* a space and a null, except chksum which
* has a null followed by a space"
*/
sprintf( hb.dbuf.chksum, "%6o", chksum);
}
write( 1, hb.dummy, i);
sscanf(hb.dbuf.size, " %o", &size);
while ( size > 0 ) {
i = read(0, hb.dummy, (int)sizeof(hb.dummy) );
write( 1, hb.dummy, i);
size -= sizeof(hb.dummy);
}
}
exit(0);
}
@//E*O*F fixtar.c//
chmod u=rw,g=r,o=r fixtar.c
exit 0