home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / telecom / uucp_442 / src / unix / tarsplit.c < prev    next >
C/C++ Source or Header  |  1990-10-08  |  4KB  |  225 lines

  1.  
  2. /*
  3.  *  TARSPLIT.C
  4.  *
  5.  *  $Header: Beta:src/uucp/src/compress/RCS/tarsplit.c,v 1.1 90/02/02 11:48:06 dillon Exp Locker: dillon $
  6.  *
  7.  * TarSplit -- split up tar files (creating directories as needed)
  8.  *
  9.  * usage: TarSplit [pathname]
  10.  *
  11.  * semantics: splits up tar file taken from stdin (or pathname, if
  12.  * specified) and creates the files therein under the working data
  13.  * directory.
  14.  *
  15.  * AmigaDOS Version - no support for stdin.
  16.  */
  17.  
  18. #include <stdio.h>
  19. #include "version.h"
  20. #include "config.h"
  21.  
  22. IDENT(".00");
  23.  
  24. #ifdef    AMIGA
  25. #include <stdlib.h>
  26. #include <exec/types.h>
  27. #ifdef LATTICE
  28. #include <proto/all.h>
  29. #else
  30. #include "protos.h"
  31. #endif
  32. typedef int    bool ;
  33. bool    ChkSumOK() ;
  34. #include <libraries/dosextens.h>
  35. #else
  36. #include <modes.h>
  37. #include <bool.h>
  38. #define DIRMODE     (S_IREAD | S_IWRITE | S_IEXEC | S_IOREAD | S_IOEXEC)
  39. #endif
  40. #define TBLOCK    512
  41. #define NAMSIZ    100
  42.  
  43. union hblock {
  44.     char dummy[TBLOCK];
  45.     struct header {
  46.         char name[NAMSIZ];
  47.         char mode[8];
  48.         char uid[8];
  49.         char gid[8];
  50.         char size[12];
  51.         char mtime[12];
  52.         char chksum[8];
  53.         char linkflag;
  54.         char linkname[NAMSIZ];
  55.     } dbuf;
  56. };
  57.  
  58. #define BLKSIZE     (sizeof (union hblock))
  59. #define HARDLINK    '1'
  60. #define SYMBLINK    '2'
  61. #define NORMAL        '\0'
  62.  
  63. void DoFile();
  64.  
  65. main(argc, argv)
  66. int    argc;
  67. char    *argv[];
  68. {
  69.     FILE        *TarFP;
  70.     union hblock    TarBlock;
  71.  
  72. #ifndef AMIGA
  73.     /* make the compiler happy about formatted I/O for longs... */
  74.     pflinit();
  75. #endif
  76.  
  77.     switch(argc) {
  78. #ifndef AMIGA
  79.     case 1:
  80.         TarFP = stdin;
  81.         break;
  82. #endif
  83.     case 2:
  84.         if ((TarFP = fopen(argv[1], "r")) == NULL) {
  85.             fprintf(stderr, "TarSplit: can't open %s\n", argv[1]);
  86.             exit(1);
  87.         }
  88.         break;
  89.     default:
  90.         fprintf(stderr, "usage: TarSplit [pathname]\n");
  91.         exit(1);
  92.     }
  93.  
  94.     for (;;) {
  95.         if (fread((char *)&TarBlock, BLKSIZE, 1, TarFP) == NULL) {
  96.             fprintf(stderr, "TarSplit: premature EOF\n");
  97.             exit(1);
  98.         } else if (IsZero(&TarBlock)) {
  99.             while (fread((char *)&TarBlock, BLKSIZE, 1, TarFP) != NULL)
  100.                 ;
  101.             break;
  102.         } else
  103.             DoFile(&TarBlock, TarFP);
  104.     }
  105.  
  106. }
  107.  
  108. bool
  109. IsZero(block)
  110. union hblock    *block;
  111. {
  112.     int    i;
  113.     char    *cblock;
  114.  
  115.     cblock = block->dummy;
  116.     for (i = 0; i < TBLOCK; i++)
  117.         if (*cblock++ != '\0')
  118.             return(FALSE);
  119.  
  120.     return (TRUE);
  121.  
  122. }
  123.  
  124. void
  125. DoFile(block, TarFP)
  126. union hblock    *block;
  127. FILE        *TarFP;
  128. {
  129.     long    FSize;
  130.     char    FName[NAMSIZ], *RefName;
  131.     int    i;
  132.     bool    IsDir, OpenOK;
  133.     FILE    *NewFP;
  134.  
  135.     if (!ChkSumOK(block)) {
  136.         fprintf(stderr, "TarSplit: bad checksum, name %s?\n",
  137.             block->dbuf.name);
  138.         exit(1);
  139.     }
  140.  
  141.     switch(block->dbuf.linkflag) {
  142.     case HARDLINK:
  143.     case SYMBLINK:
  144.         fprintf(stderr, "TarSplit: can't handle links\n");
  145.         exit(1);
  146.     case NORMAL:
  147.         break;
  148.     default:
  149.         fprintf(stderr, "TarSplit: unknown linkflag\n");
  150.         exit(1);
  151.     }
  152.  
  153. #ifdef    AMIGA
  154.     if (sscanf(block->dbuf.size, "%12lo", &FSize) != 1) {
  155. #else
  156.     if (sscanf(block->dbuf.size, "%12O", &FSize) != 1) {
  157. #endif
  158.         fprintf(stderr, "TarSplit: bad size\n");
  159.         exit(1);
  160.     }
  161.  
  162.     for (i = 0, RefName = block->dbuf.name; *RefName; i++, RefName++)
  163.         FName[i] = *RefName;
  164.  
  165.     if (IsDir = (*(RefName - 1) == '/')) {
  166.         FName[i - 1] = '\0';
  167.         if (strcmp(FName, ".") == 0)
  168.             OpenOK = TRUE;
  169.         else
  170. #ifdef    AMIGA
  171.             {
  172.                 BPTR Lock;
  173.                 OpenOK = (Lock = CreateDir(FName)) != 0;
  174.                 UnLock(Lock) ;
  175.             }
  176. #else
  177.             OpenOK = mknod(FName, DIRMODE) == 0;
  178. #endif
  179.     } else {
  180.         FName[i] = '\0';
  181.         OpenOK = (NewFP = fopen(FName, "w")) != NULL;
  182.     }
  183.  
  184.     if (!OpenOK) {
  185.         fprintf(stderr, "TarSplit: can't create %s\n", FName);
  186.         exit(1);
  187.     }
  188.  
  189.     for (; FSize > 0; FSize -= TBLOCK) {
  190.         if (fread((char *)block, BLKSIZE, 1, TarFP) == NULL) {
  191.             fprintf(stderr, "TarSplit: premature EOF\n");
  192.             exit(1);
  193.         }
  194.         if (!IsDir)
  195.             fwrite(block->dummy, 1,
  196.                 (FSize > TBLOCK ? TBLOCK : (int) FSize), NewFP);
  197.     }
  198.  
  199.     if (!IsDir)
  200.         fclose(NewFP);
  201. }
  202.  
  203. bool
  204. ChkSumOK(block)
  205. union hblock    *block;
  206. {
  207.     long    Accum, ChkSumVal;
  208.     int    i;
  209.  
  210. #ifdef    AMIGA
  211.     sscanf(block->dbuf.chksum, "%8lo", &ChkSumVal);
  212. #else
  213.     sscanf(block->dbuf.chksum, "%8O", &ChkSumVal);
  214. #endif
  215.     for (i = 0; i < 8; i++)
  216.         block->dbuf.chksum[i] = ' ';
  217.  
  218.     Accum = 0;
  219.     for (i = 0; i < TBLOCK; i++)
  220.         Accum += 0xff & block->dummy[i];
  221.  
  222.     return(Accum == ChkSumVal);
  223.  
  224. }
  225.