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