`This is not LINUX! This is Plan 9. There are rules.' -boyd/walter See also `cat -v Considered Harmful' Reference: /n/sources/patch/sorry/tard Date: Fri Apr 22 21:31:15 CES 2005 --- /rc/bin/tard Thu Jan 1 00:00:00 1970 +++ /rc/bin/tard Fri Apr 22 21:27:19 2005 @@ -0,0 +1,22 @@ +#!/bin/rc + +opts=$1;shift +f=$1;shift + +switch ($f) { +case (~ $f '(\.tar\.gz|\.tgz)$') + c='gzip' + uc='gunzip' +case (~ $f '(\.tar\.bz|\.tbz|\.tar\.bz2|\.tbz2)$') + c='bzip2' + uc='bunzip2' +case (~ $f '(\.tar\.Z|\.tz)$') + c='compress' + uc='uncompress' +} + +if(~ $opts 'x') + cat $f | $uc | tar $opts +if not { + tar $opts $* | $c > $f +} --- /sys/man/1/tard Thu Jan 1 00:00:00 1970 +++ /sys/man/1/tard Fri Apr 22 21:27:36 2005 @@ -0,0 +1,18 @@ +.TH TARD 1 +.SH NAME +tard \- tar with file compression detection +.SH SYNOPSIS +.B tard +.I opts +.I file +[ +.I files ... +] +.SH DESCRIPTION +.I Tard +Calls tar and does (de)compression depending on the extension of the third parameter. + +.SH SOURCE +.B /rc/bin/tard +.SH "SEE ALSO" +.IR tar (1) --- /sys/man/1/tar Fri Apr 22 21:27:55 2005 +++ /sys/man/1/tar Fri Apr 22 21:27:52 2005 @@ -108,40 +108,7 @@ .BR t , give more details about the archive entries. -.TP -.B z -Operate on compressed tar archives. -The type of compression is inferred from the file name extension: -.IR gzip (1) -for -.B .tar.gz -and -.BR .tgz ; -.I bzip2 -(see -.IR gzip (1)) -for -.BR .tar.bz , -.BR .tbz , -.BR .tar.bz2 , -and -.BR .tbz2 ; -.I compress -(not distributed) -for -.B .tar.Z -and -.BR .tz . -If no extension matches, -.I gzip -is used. -The -.B z -flag is unnecessary (but allowed) when using the -.B t -and -.B x -verbs on archives with recognized extensions. + .SH EXAMPLES .I Tar can be used to copy hierarchies thus: @@ -155,6 +122,7 @@ .IR ar (1), .IR bundle (1), .IR tapefs (1) +.IR tard (1) .SH BUGS There is no way to ask for any but the last occurrence of a file. --- /sys/src/cmd/tar.c Fri Apr 22 21:28:24 2005 +++ /sys/src/cmd/tar.c Fri Apr 22 21:28:16 2005 @@ -93,18 +93,6 @@ }; } Hdr; -typedef struct { - char *comp; - char *decomp; - char *sfx[4]; -} Compress; - -static Compress comps[] = { - "gzip", "gunzip", { ".tar.gz", ".tgz" }, /* default */ - "compress", "uncompress", { ".tar.Z", ".tz" }, - "bzip2", "bunzip2", { ".tar.bz", ".tbz", - ".tar.bz2",".tbz2" }, -}; typedef struct { int kid; @@ -125,7 +113,6 @@ static int relative = 1; static int settime; static int verbose; -static int docompress; static int keepexisting; static Off nexthdr; @@ -143,80 +130,6 @@ exits("usage"); } -/* compression */ - -static Compress * -compmethod(char *name) -{ - int i, nmlen = strlen(name), sfxlen; - Compress *cp; - - for (cp = comps; cp < comps + nelem(comps); cp++) - for (i = 0; i < nelem(cp->sfx) && cp->sfx[i]; i++) { - sfxlen = strlen(cp->sfx[i]); - if (nmlen > sfxlen && - strcmp(cp->sfx[i], name + nmlen - sfxlen) == 0) - return cp; - } - return docompress? comps: nil; -} - -/* - * push a filter, cmd, onto fd. if input, it's an input descriptor. - * returns a descriptor to replace fd, or -1 on error. - */ -static int -push(int fd, char *cmd, int input, Pushstate *ps) -{ - int nfd, pifds[2]; - String *s; - - ps->open = 0; - ps->fd = fd; - ps->input = input; - if (fd < 0 || pipe(pifds) < 0) - return -1; - ps->kid = fork(); - switch (ps->kid) { - case -1: - return -1; - case 0: - if (input) - dup(pifds[Wr], Stdout); - else - dup(pifds[Rd], Stdin); - close(pifds[input? Rd: Wr]); - dup(fd, (input? Stdin: Stdout)); - s = s_new(); - if (cmd[0] != '/') - s_append(s, "/bin/"); - s_append(s, cmd); - execl(s_to_c(s), cmd, nil); - sysfatal("can't exec %s: %r", cmd); - default: - nfd = pifds[input? Rd: Wr]; - close(pifds[input? Wr: Rd]); - break; - } - ps->rfd = nfd; - ps->open = 1; - return nfd; -} - -static char * -pushclose(Pushstate *ps) -{ - Waitmsg *wm; - - if (ps->fd < 0 || ps->rfd < 0 || !ps->open) - return "not open"; - close(ps->rfd); - ps->rfd = -1; - ps->open = 0; - while ((wm = wait()) != nil && wm->pid != ps->kid) - continue; - return wm? wm->msg: nil; -} /* * block-buffer management @@ -674,19 +587,13 @@ ulong blksleft, blksread; Off bytes; Hdr *hp; - Compress *comp = nil; - Pushstate ps; if (usefile && docreate) { ar = create(usefile, OWRITE, 0666); - if (docompress) - comp = compmethod(usefile); } else if (usefile) ar = open(usefile, ORDWR); else ar = Stdout; - if (comp) - ar = push(ar, comp->comp, Output, &ps); if (ar < 0) sysfatal("can't open archive %s: %r", usefile); @@ -720,8 +627,6 @@ getblkz(ar); putlastblk(ar); - if (comp) - return pushclose(&ps); if (ar > Stderr) close(ar); return nil; @@ -913,16 +818,11 @@ int ar; char *longname; Hdr *hp; - Compress *comp = nil; - Pushstate ps; if (usefile) { ar = open(usefile, OREAD); - comp = compmethod(usefile); } else ar = Stdin; - if (comp) - ar = push(ar, comp->decomp, Input, &ps); if (ar < 0) sysfatal("can't open archive %s: %r", usefile); @@ -934,8 +834,6 @@ skip(ar, hp, longname); } - if (comp) - return pushclose(&ps); if (ar > Stderr) close(ar); return nil; @@ -993,9 +891,6 @@ break; case 'x': verb = Xtract; - break; - case 'z': - docompress++; break; case '-': break;