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