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