home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / System / XADmaster / xad_dev / Sources / clients / Tar.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-04-01  |  6.3 KB  |  240 lines

  1. #ifndef XADMASTER_TAR_C
  2. #define XADMASTER_TAR_C
  3.  
  4. /* Programmheader
  5.  
  6.     Name:        Tar.c
  7.     Main:        xadmaster
  8.     Versionstring:    $VER: Tar.c 1.7 (25.03.2001)
  9.     Author:        SDI
  10.     Distribution:    Freeware
  11.     Description:    Tar file archiver client
  12.  
  13.  1.0   07.09.98 : first version
  14.  1.1   29.06.99 : now uses master free stuff
  15.  1.2   29.08.99 : now uses xfi_DataPos
  16.  1.3   15.09.99 : also strips / from TF_DIR entries
  17.  1.4   11.08.00 : cleaner design
  18.  1.5   20.11.00 : octtonum read one byte less than specified
  19.  1.6   17.12.00 : octtonum now accepts spaces at end also
  20.  1.7   25.03.01 : now uses xadAddFileEntry()
  21. */
  22.  
  23. #include <proto/xadmaster.h>
  24. #include <dos/dos.h>
  25. #include "SDI_compiler.h"
  26. #define SDI_TO_ANSI
  27. #include "SDI_ASM_STD_protos.h"
  28.  
  29. #ifndef XADMASTERFILE
  30. #define Tar_Client        FirstClient
  31. #define NEXTCLIENT        0
  32. #define XADMASTERVERSION    10
  33. UBYTE version[] = "$VER: Tar 1.7 (25.03.2001)";
  34. #endif
  35. #define TAR_VERSION        1
  36. #define TAR_REVISION        7
  37.  
  38. struct TarHeader
  39. {                /* byte offset */
  40.   UBYTE th_Name[100];        /*   0 */
  41.   UBYTE th_Mode[8];        /* 100 */
  42.   UBYTE th_UserID[8];        /* 108 */
  43.   UBYTE th_GroupID[8];        /* 116 */
  44.   UBYTE th_Size[12];        /* 124 */
  45.   UBYTE th_MTime[12];        /* 136 */
  46.   UBYTE th_Checksum[8];     /* 148 */
  47.   UBYTE th_Typeflag;        /* 156 */
  48.   UBYTE th_LinkName[100];    /* 157 */
  49.   UBYTE th_Magic[6];        /* 257 */
  50.   UBYTE th_Version[2];        /* 263 */
  51.   UBYTE th_UserName[32];    /* 265 */
  52.   UBYTE th_GroupName[32];    /* 297 */
  53.   UBYTE th_DevMajor[8];     /* 329 */
  54.   UBYTE th_DevMinor[8];     /* 337 */
  55.   UBYTE th_Prefix[155];     /* 345 */
  56.   UBYTE th_Pad[12];        /* 500 */
  57. };
  58.  
  59. /* Values used in Typeflag field.  */
  60. #define TF_FILE     '0'  /* Regular file */
  61. #define TF_AFILE    '\0' /* Regular file */
  62. #define TF_LINK     '1'  /* Link */
  63. #define TF_SYM        '2'  /* Reserved - but GNU tar uses this for links... */
  64. #define TF_CHAR     '3'  /* Character special */
  65. #define TF_BLOCK    '4'  /* Block special */
  66. #define TF_DIR        '5'  /* Drawer */
  67. #define TF_FIFO     '6'  /* FIFO special */
  68. #define TF_CONT     '7'  /* Reserved */
  69.  
  70. static ULONG octtonum(STRPTR oct, LONG width, LONG *ok)
  71. {
  72.   ULONG i = 0;
  73.  
  74.   while(*oct == ' ' && width--)
  75.     ++oct;
  76.  
  77.   if(!*oct)
  78.     *ok = 0;
  79.   else
  80.   {
  81.     while(width-- && *oct >= '0' && *oct <= '7')
  82.      i = (i*8)+*(oct++)-'0';
  83.  
  84.     while(*oct == ' ' && width--)
  85.       ++oct;
  86.  
  87.     if(width > 0 && *oct)    /* an error, set error flag */
  88.       *ok = 0;
  89.   }
  90.  
  91.   return i;
  92. }
  93.  
  94. static BOOL checktarsum(struct TarHeader *th)
  95. {
  96.   LONG sc, i;
  97.   ULONG uc, checks;
  98.   
  99.   i = 1;
  100.   checks = octtonum(th->th_Checksum, 8, &i);
  101.   if(!i)
  102.     return 0;
  103.  
  104.   for(i = sc = uc = 0; i < 512; ++i)
  105.   {
  106.     sc += ((BYTE *) th)[i];
  107.     uc += ((UBYTE *) th)[i];
  108.   }
  109.   
  110.   for(i = 148; i < 156; ++i)
  111.   {
  112.     sc -= ((BYTE *) th)[i];
  113.     uc -= ((UBYTE *) th)[i];
  114.   }
  115.   sc += 8 * ' ';
  116.   uc += 8 * ' ';
  117.  
  118.   if(checks != uc && checks != (ULONG) sc)
  119.     return 0;
  120.   return 1;
  121. }
  122.  
  123. ASM(BOOL) Tar_RecogData(REG(d0, ULONG size), REG(a0, STRPTR data),
  124. REG(a6, struct xadMasterBase *xadMasterBase))
  125. {
  126.   if(data[0] > 0x1F && checktarsum((struct TarHeader *) data))
  127.     return 1;
  128.   else
  129.     return 0;
  130. }
  131.  
  132. ASM(LONG) Tar_GetInfo(REG(a0, struct xadArchiveInfo *ai),
  133. REG(a6, struct xadMasterBase *xadMasterBase))
  134. {
  135.   struct TarHeader th;
  136.   struct xadFileInfo *fi;
  137.   LONG err = 0, size, ok, a, b, d, i, pos;
  138.  
  139.   while(!err && ai->xai_InPos < ai->xai_InSize && !(err = xadHookAccess(XADAC_READ, sizeof(struct TarHeader), &th, ai)))
  140.   {
  141.     if(!th.th_Name[0])
  142.       break;
  143.     ok = checktarsum(&th); /* check checksum and init ok */
  144.     size = octtonum(th.th_Size, 12, &ok);
  145.  
  146.     pos = ai->xai_InPos;
  147.     if(ok && (th.th_Typeflag == TF_FILE || th.th_Typeflag == TF_AFILE ||
  148.     th.th_Typeflag == TF_DIR || th.th_Typeflag == TF_SYM ||
  149.     th.th_Typeflag == TF_LINK))
  150.     {
  151.       a = strlen(th.th_Name) + 1;
  152.       if(th.th_Name[a-2] == '/')
  153.       {
  154.     if(th.th_Typeflag == TF_AFILE || th.th_Typeflag == TF_FILE || th.th_Typeflag == TF_DIR)
  155.     {
  156.       th.th_Name[--a-1] == 0;
  157.           th.th_Typeflag = TF_DIR;
  158.         }
  159.       }
  160.       
  161.       b = th.th_LinkName[0] ? 1 + strlen(th.th_LinkName) : 0;
  162.       i = th.th_UserName[0] ? 1 + strlen(th.th_UserName) : 0;
  163.       d = th.th_GroupName[0] ? 1 + strlen(th.th_GroupName) : 0;
  164.  
  165.       if(!(fi = (struct xadFileInfo *) xadAllocObject(XADOBJ_FILEINFO,
  166.       XAD_OBJNAMESIZE, a+b+i+d, TAG_DONE)))
  167.         err = XADERR_NOMEMORY;
  168.       else
  169.       {
  170.         fi->xfi_DataPos = pos;
  171.         fi->xfi_Flags = XADFIF_SEEKDATAPOS;
  172.     if(th.th_Typeflag == TF_LINK || th.th_Typeflag == TF_SYM)
  173.       fi->xfi_Flags |= XADFIF_LINK;
  174.     else if(th.th_Typeflag == TF_DIR)
  175.     {
  176.       fi->xfi_Flags |= XADFIF_DIRECTORY;
  177.       size = 0;
  178.     }
  179.     else
  180.       fi->xfi_Flags |= XADFIF_EXTRACTONBUILD;
  181.  
  182.         fi->xfi_CrunchSize = fi->xfi_Size = size;
  183.         xadCopyMem(th.th_Name, fi->xfi_FileName, a-1);
  184.         if(b)
  185.         {
  186.           fi->xfi_LinkName = fi->xfi_FileName + a;
  187.           xadCopyMem(th.th_LinkName, fi->xfi_LinkName, b-1);
  188.         }
  189.         if(i)
  190.         {
  191.           fi->xfi_UserName = fi->xfi_FileName + a + b;
  192.           xadCopyMem(th.th_UserName, fi->xfi_UserName, i-1);
  193.         }
  194.         if(d)
  195.         {
  196.           fi->xfi_GroupName = fi->xfi_FileName + a + b + i;
  197.           xadCopyMem(th.th_GroupName, fi->xfi_GroupName, d-1);
  198.         }
  199.         fi->xfi_OwnerUID = octtonum(th.th_UserID, 8, &ok);
  200.         fi->xfi_OwnerGID = octtonum(th.th_GroupID, 8, &ok);
  201.  
  202.         xadConvertProtection(XAD_PROTUNIX, octtonum(th.th_Mode, 8, &ok), XAD_GETPROTAMIGA,
  203.         &fi->xfi_Protection, TAG_DONE);
  204.  
  205.         xadConvertDates(XAD_DATEUNIX, octtonum(th.th_MTime, 12, &ok),
  206.         XAD_MAKELOCALDATE, 1, XAD_GETDATEXADDATE, &fi->xfi_Date, TAG_DONE);
  207.  
  208.         if(th.th_Typeflag == TF_FILE || th.th_Typeflag == TF_AFILE)
  209.           size = (size+511)&~511;
  210.         else
  211.           size = 0;
  212.  
  213.         err = xadAddFileEntry(fi, ai, XAD_SETINPOS, ai->xai_InPos+size, TAG_DONE);
  214.       }
  215.     }
  216.   }
  217.  
  218.   if(err)
  219.   {
  220.     ai->xai_Flags |= XADAIF_FILECORRUPT;
  221.     ai->xai_LastError = err;
  222.   }
  223.  
  224.   return (ai->xai_FileInfo ? 0 : err);
  225. }
  226.  
  227. ASM(LONG) Tar_UnArchive(REG(a0, struct xadArchiveInfo *ai),
  228. REG(a6, struct xadMasterBase *xadMasterBase))
  229. {
  230.   return xadHookAccess(XADAC_COPY, ai->xai_CurFile->xfi_Size, 0, ai);
  231. }
  232.  
  233. const struct xadClient Tar_Client = {
  234. NEXTCLIENT, XADCLIENT_VERSION, XADMASTERVERSION, TAR_VERSION, TAR_REVISION,
  235. 512, XADCF_FILEARCHIVER|XADCF_FREEFILEINFO, XADCID_TAR, "Tar",
  236. (BOOL (*)()) Tar_RecogData, (LONG (*)()) Tar_GetInfo,
  237. (LONG (*)()) Tar_UnArchive, 0};
  238.  
  239. #endif /* XADMASTER_TAR_C */
  240.