[comp.bugs.4bsd] Tar and absolute pathnames

gnu@hoptoad.uucp (John Gilmore) (02/02/88)

In article <2561@encore.UUCP> adamm@encore.UUCP (Adam S. Moskowitz) writes:
>Some time back, ted@braggvax posted a query about 4.3BSD tar & absolute path
>names.  Did this issue ever get resolved (other than by telling Ted he was a
>fool for using absolute pathnames)?

I never saw the query, but can maybe provide some info.  Absolute pathnames
worked OK on the 4.2 tar we used at Sun.  The bad part was that I would
occasionally receive tapes written by amateurs, which had absolute path
names.  This made it hard to extract them into, say, my home directory.

My PD tar (in the comp.sources.unix archives) automatically strips off
a leading "/", both when creating a tape and when extracting one.  In both
cases it warns you about it.  Recently I got a request from David Vezie
at r2d2, mentioning that to move things from machine to machine he often
does:

	tar cf - /path/path/dir | rsh machine tar xvpf -

but if "rsh" won't put him in the root directory, with pdtar he has to:

	tar cf - /path/path/dir | rsh machine 'cd / ; tar xvpf -'

This is the only half-reasonable use of absolute pathnames in tar that
I've ever seen.  I advised him to make a shell script that just does
the second form, since it works with both tars.
-- 
{pyramid,ptsfa,amdahl,sun,ihnp4}!hoptoad!gnu			  gnu@toad.com
		"Watch me change my world..." -- Liquid Theatre

phil@sequent.UUCP (Phil Hochstetler) (02/04/88)

I once ran into a tape written this way and devised a quick filter that
gets around this problem.  Basically, you can process the tar header
blocks moving the pathname up to get rid of the leading '/' but have to
be sure the header checksum is correct.  My quick solution is to move
the '/' to the end of the pathname array, after the terminating null
character.  This means you can then do:

	tarfix < absolute.archive.tar | tar -xpvBf -

to extract the archive correctly.  Code follows:

---- tarfix.c
main()
{
	char fixbuf[512];

	while (read(0, fixbuf, sizeof (fixbuf)) == sizeof (fixbuf)) {
		if (fixbuf[0] == '/' && fixbuf[99] == 0) {
			strcpy(fixbuf, &fixbuf[1]);
			fixbuf[99] = '/';
		}
		write(1, fixbuf, sizeof (fixbuf));
	}
}
----
Phil Hochstetler
Sequent Computer Systems
Beaverton, Oregon