home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume4 / fixtar < prev    next >
Text File  |  1989-02-03  |  5KB  |  172 lines

  1. Path: xanth!mcnc!rutgers!ucsd!ames!mailrus!tut.cis.ohio-state.edu!cwjcc!hal!ncoast!allbery
  2. From: sahayman@watmath.UUCP (Steve Hayman)
  3. Newsgroups: comp.sources.misc
  4. Subject: v04i032: fixtar - A filter for converting absolute tar pathnames to relative
  5. Message-ID: <8808190250.AA12792@watmath>
  6. Date: 19 Aug 88 02:50:33 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: sahayman@watmath.UUCP (Steve Hayman)
  9. Lines: 160
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. Posting-number: Volume 4, Issue 32
  13. Submitted-by: "Steve Hayman" <sahayman@watmath.UUCP>
  14. Archive-name: fixtar
  15.  
  16. # This is a shell archive.  Remove anything before this line,
  17. # then unpack it by saving it in a file and typing "sh file".
  18. #
  19. # Wrapped by sahayman@math.waterloo.edu on Thu Aug 18 22:49:24 EDT 1988
  20. # Contents:  README fixtar.c
  21.  
  22. echo x - README
  23. sed 's/^@//' > "README" <<'@//E*O*F README//'
  24. "fixtar" is a filter that knows what tar-format looks like, and removes
  25. leading '/' from any absolute pathnames in the tar file.  This can
  26. be handy if you have a tar tape with absolute paths and want to
  27. extract the files into other locations.  You can do something like
  28.  
  29.     dd if=$TAPE ibs=10k | fixtar | tar xf -
  30.  
  31. and all the /path/names will be extracted as "path/names".
  32.  
  33. I hope this is of use to somebody.  On the whole you're probably
  34. better off getting John Gilmore's public-domain "tar", which
  35. also handles this problem and has many other nice features.  This
  36. is just a quick hack solution... I've used it on 4.3 BSD, it
  37. ought to work elsewhere but unfortunately I can't be sure.
  38.  
  39. @..Steve Hayman, U. of Waterloo
  40.   sahayman@math.waterloo.edu
  41.  
  42. P.S. No makefile (just "cc -o fixtar fixtar.c" should do it), no man page,
  43.   no apologies :-)
  44. @//E*O*F README//
  45. chmod u=rw,g=r,o=r README
  46.  
  47. echo x - fixtar.c
  48. sed 's/^@//' > "fixtar.c" <<'@//E*O*F fixtar.c//'
  49. #include <stdio.h>
  50. /*
  51.  * fixtar - a filter to convert absolute pathnames
  52.  * in tar to relative, by shifting them left one byte..
  53.  * this filter changes "/path/name" to "path/name"
  54.  *
  55.  * Usage: something like
  56.  * dd if=$TAPE | fixtar | tar xf -
  57.  *
  58.  * If the tar tape has "/path/name" in it, fixtar will
  59.  * convert that to "path/name" and tar will extract it
  60.  * relative to the current directory.
  61.  *
  62.  * You might want something like "dd if=$TAPE ibs=10k" to read
  63.  * the tape properly.
  64.  * I have used this on 4.3 BSD only.  It ought to work on
  65.  * other versions of Unix but unfortunately I have no way of knowing.
  66.  *
  67.  * This program knows about tar format and is careful to diddle
  68.  * only the header blocks, not the data blocks.
  69.  *
  70.  * You're probably better off using John Gilmore's public-domain "tar",
  71.  * which always extracts with relative pathnames.  (And which has
  72.  * many other nice features.)
  73.  *
  74.  * .. Steve Hayman, U. of Waterloo
  75.  *    sahayman@math.waterloo.edu
  76.  */
  77.  
  78. /*
  79.  * these definitions are straight out of "man 5 tar"
  80.  */
  81. #define TBLOCK    512
  82. #define NAMSIZ    100
  83.  
  84. union hblock {
  85.     char dummy[TBLOCK];
  86.     struct header {
  87.         char name[NAMSIZ];
  88.         char mode[8];
  89.         char uid[8];
  90.         char gid[8];
  91.         char size[12];
  92.         char mtime[12];
  93.         char chksum[8];
  94.         char linkflag;
  95.         char linkname[NAMSIZ];
  96.     } dbuf;
  97. };
  98.  
  99. union hblock hb;
  100.  
  101. main()
  102. {
  103.     register int i;
  104.     char *p;
  105.     int size;
  106.     int chksum;
  107.     int zerob = 0;
  108.  
  109.     while ( ( i = read(0, hb.dummy, (int)sizeof(hb.dummy))) > 0   ) {
  110.         if ( hb.dbuf.name[0] == '\0' ) {
  111.             zerob++;
  112.             write(1, hb.dummy, i);
  113.             /*
  114.              * two zero blocks in a row means end-of-archive
  115.              */
  116.             if ( zerob == 2 ) {
  117.                 /*
  118.                  * read and write anything that's left,
  119.                  * what the heck.
  120.                  */
  121.                 while ( (i = read(0, hb.dummy,
  122.                         (int)sizeof(hb.dummy))) > 0 ) {
  123.                     write(1, hb.dummy, i);
  124.                 }
  125.                 exit(0);
  126.             }
  127.             continue;
  128.         }
  129.         zerob = 0;
  130.         p = hb.dbuf.name;
  131.         if ( *p == '/' ) {
  132.             /*
  133.              * Shift the name left one char, which
  134.              * removes the leading '/'
  135.              */
  136.             p++;
  137.             do {
  138.                 *(p-1) = *p;
  139.             } while ( *p++ );    /* up to and including '\0' */
  140.  
  141.             fprintf(stderr, "Adjusted: /%s\n", hb.dbuf.name );
  142.  
  143.             /*
  144.              * Fix the checksum - we have one less '/' in the
  145.              * header (and one more '\0' that doesn't change
  146.              * the checksum)
  147.              */
  148.             sscanf(hb.dbuf.chksum, " %o", &chksum );
  149.             chksum -= '/';
  150.             /*
  151.              * "each field of width w has w-2 digits,
  152.              *  a space and a null, except chksum which
  153.              *  has a null followed by a space"
  154.              */
  155.             sprintf( hb.dbuf.chksum, "%6o", chksum);
  156.             
  157.         }
  158.         write( 1, hb.dummy, i);
  159.         sscanf(hb.dbuf.size, " %o", &size);
  160.         while ( size > 0 ) {
  161.             i = read(0, hb.dummy, (int)sizeof(hb.dummy) );
  162.             write( 1, hb.dummy, i);
  163.             size -= sizeof(hb.dummy);
  164.         }
  165.     }
  166.     exit(0);
  167. }
  168. @//E*O*F fixtar.c//
  169. chmod u=rw,g=r,o=r fixtar.c
  170.  
  171. exit 0
  172.