home *** CD-ROM | disk | FTP | other *** search
- #ifndef XADMASTER_TAR_C
- #define XADMASTER_TAR_C
-
- /* Programmheader
-
- Name: Tar.c
- Main: xadmaster
- Versionstring: $VER: Tar.c 1.1 (29.06.1999)
- Author: SDI
- Distribution: Freeware
- Description: Tar file archiver client
-
- 1.0 07.09.98 : first version
- 1.1 29.06.99 : now uses master free stuff
- */
-
- #include <proto/xadmaster.h>
- #include <dos/dos.h>
- #include "SDI_compiler.h"
- #define SDI_TO_ANSI
- #include "SDI_ASM_STD_protos.h"
-
- #ifndef XADMASTERFILE
- #define Tar_Client FirstClient
- #define NEXTCLIENT 0
- UBYTE version[] = "$VER: Tar 1.1 (29.06.1999)";
- #endif
- #define TAR_VERSION 1
- #define TAR_REVISION 1
-
- struct TarHeader
- { /* byte offset */
- UBYTE th_Name[100]; /* 0 */
- UBYTE th_Mode[8]; /* 100 */
- UBYTE th_UserID[8]; /* 108 */
- UBYTE th_GroupID[8]; /* 116 */
- UBYTE th_Size[12]; /* 124 */
- UBYTE th_MTime[12]; /* 136 */
- UBYTE th_Checksum[8]; /* 148 */
- UBYTE th_Typeflag; /* 156 */
- UBYTE th_LinkName[100]; /* 157 */
- UBYTE th_Magic[6]; /* 257 */
- UBYTE th_Version[2]; /* 263 */
- UBYTE th_UserName[32]; /* 265 */
- UBYTE th_GroupName[32]; /* 297 */
- UBYTE th_DevMajor[8]; /* 329 */
- UBYTE th_DevMinor[8]; /* 337 */
- UBYTE th_Prefix[155]; /* 345 */
- UBYTE th_Pad[12]; /* 500 */
- };
-
- /* Values used in Typeflag field. */
- #define TF_FILE '0' /* Regular file */
- #define TF_AFILE '\0' /* Regular file */
- #define TF_LINK '1' /* Link */
- #define TF_SYM '2' /* Reserved - but GNU tar uses this for links... */
- #define TF_CHAR '3' /* Character special */
- #define TF_BLOCK '4' /* Block special */
- #define TF_DIR '5' /* Drawer */
- #define TF_FIFO '6' /* FIFO special */
- #define TF_CONT '7' /* Reserved */
-
- #ifndef TM_UREAD
- /* Bits used in the mode field, values in octal. */
- #define TM_SUID 04000 /* Set UID on execution */
- #define TM_SGID 02000 /* Set GID on execution */
- #define TM_SVTX 01000 /* Reserved */
- /* File permissions */
- #define TM_UREAD 00400 /* Read by owner */
- #define TM_UWRITE 00200 /* Write by owner */
- #define TM_UEXEC 00100 /* Execute/search by owner */
- #define TM_GREAD 00040 /* Read by group */
- #define TM_GWRITE 00020 /* Write by group */
- #define TM_GEXEC 00010 /* Execute/search by group */
- #define TM_OREAD 00004 /* Read by other */
- #define TM_OWRITE 00002 /* Write by other */
- #define TM_OEXEC 00001 /* Execute/search by other */
- #endif
-
- static ULONG octtonum(STRPTR oct, LONG width, LONG *ok)
- {
- ULONG i = 0;
-
- while(width-- && *oct == ' ')
- ++oct;
-
- if(!*oct)
- *ok = 0;
- else
- {
- while(width-- && *oct >= '0' && *oct <= '7')
- i = (i*8)+*(oct++)-'0';
-
- if(width > 0 && *oct) /* an error, set error flag */
- *ok = 0;
- }
-
- return i;
- }
-
- BOOL checktarsum(struct TarHeader *th)
- {
- LONG sc, i;
- ULONG uc, checks;
-
- i = 1;
- checks = octtonum(th->th_Checksum, 8, &i);
- if(!i)
- return DOSFALSE;
-
- for(i = sc = uc = 0; i < 512; ++i)
- {
- sc += ((BYTE *) th)[i];
- uc += ((UBYTE *) th)[i];
- }
-
- for(i = 148; i < 156; ++i)
- {
- sc -= ((BYTE *) th)[i];
- uc -= ((UBYTE *) th)[i];
- }
- sc += 8 * ' ';
- uc += 8 * ' ';
-
- if(checks != uc && checks != (ULONG) sc)
- return DOSFALSE;
- return DOSTRUE;
- }
-
- ASM(BOOL) Tar_RecogData(REG(d0, ULONG size), REG(a0, STRPTR data),
- REG(a6, struct xadMasterBase *xadMasterBase))
- {
- if(data[0] > 0x1F && checktarsum((struct TarHeader *) data))
- return 1;
- else
- return 0;
- }
-
- ASM(LONG) Tar_GetInfo(REG(a0, struct xadArchiveInfo *ai),
- REG(a6, struct xadMasterBase *xadMasterBase))
- {
- struct TarHeader th;
- struct xadFileInfo *fi = 0, *fi2;
- LONG err, size, ok, a, b, d, i, pos, num = 1;
-
- while(!(err = xadHookAccess(XADAC_READ, sizeof(struct TarHeader), &th, ai)))
- {
- if(!th.th_Name[0])
- break;
- ok = checktarsum(&th); /* check checksum and init ok */
- size = octtonum(th.th_Size, 12, &ok);
-
- pos = ai->xai_InPos;
- if(ok && (th.th_Typeflag == TF_FILE ||
- th.th_Typeflag == TF_AFILE) &&
- err != xadHookAccess(XADAC_INPUTSEEK, (size+511)&~511, 0, ai))
- ok = 0;
- if(ok && (th.th_Typeflag == TF_FILE || th.th_Typeflag == TF_AFILE ||
- th.th_Typeflag == TF_DIR || th.th_Typeflag == TF_SYM ||
- th.th_Typeflag == TF_LINK))
- {
- a = strlen(th.th_Name) + 1;
- if(th.th_Name[a-2] == '/')
- {
- if(th.th_Typeflag == TF_AFILE || th.th_Typeflag == TF_FILE)
- {
- th.th_Name[--a-1] == 0;
- th.th_Typeflag = TF_DIR;
- }
- }
-
- b = th.th_LinkName[0] ? 1 + strlen(th.th_LinkName) : 0;
- i = th.th_UserName[0] ? 1 + strlen(th.th_UserName) : 0;
- d = th.th_GroupName[0] ? 1 + strlen(th.th_GroupName) : 0;
-
- if(!(fi2 = (struct xadFileInfo *) xadAllocObject(XADOBJ_FILEINFO,
- XAD_OBJNAMESIZE, a+b+i+d, TAG_DONE)))
- {
- err = XADERR_NOMEMORY; break;
- }
- else
- {
- fi2->xfi_PrivateInfo = (APTR) pos;
- if(th.th_Typeflag == TF_LINK || th.th_Typeflag == TF_SYM)
- fi2->xfi_Flags |= XADFIF_LINK;
- else if(th.th_Typeflag == TF_DIR)
- {
- fi2->xfi_Flags |= XADFIF_DIRECTORY;
- size = 0;
- }
- fi2->xfi_CrunchSize = fi2->xfi_Size = size;
- xadCopyMem(th.th_Name, fi2->xfi_FileName, a-1);
- if(b)
- {
- fi2->xfi_LinkName = fi2->xfi_FileName + a;
- xadCopyMem(th.th_LinkName, fi2->xfi_LinkName, b-1);
- }
- if(i)
- {
- fi2->xfi_UserName = fi2->xfi_FileName + a + b;
- xadCopyMem(th.th_UserName, fi2->xfi_UserName, i-1);
- }
- if(d)
- {
- fi2->xfi_GroupName = fi2->xfi_FileName + a + b + i;
- xadCopyMem(th.th_GroupName, fi2->xfi_GroupName, d-1);
- }
- fi2->xfi_OwnerUID = octtonum(th.th_UserID, 8, &ok);
- fi2->xfi_OwnerGID = octtonum(th.th_GroupID, 8, &ok);
-
- i = octtonum(th.th_Mode, 8, &ok);
- if(!(i & TM_UREAD)) fi2->xfi_Protection |= FIBF_READ;
- if(!(i & TM_UWRITE)) fi2->xfi_Protection |= FIBF_WRITE;
- if(!(i & TM_UEXEC)) fi2->xfi_Protection |= FIBF_EXECUTE;
- if(i & TM_GREAD) fi2->xfi_Protection |= FIBF_GRP_READ;
- if(i & TM_GWRITE) fi2->xfi_Protection |= FIBF_GRP_WRITE;
- if(i & TM_GEXEC) fi2->xfi_Protection |= FIBF_GRP_EXECUTE;
- if(i & TM_OREAD) fi2->xfi_Protection |= FIBF_OTR_READ;
- if(i & TM_OWRITE) fi2->xfi_Protection |= FIBF_OTR_WRITE;
- if(i & TM_OEXEC) fi2->xfi_Protection |= FIBF_OTR_EXECUTE;
-
- err = xadConvertDates(XAD_DATEUNIX, octtonum(th.th_MTime, 12, &ok),
- XAD_MAKELOCALDATE, 1, XAD_GETDATEXADDATE, &fi2->xfi_Date, TAG_DONE);
-
- if(ok && !err)
- {
- fi2->xfi_EntryNumber = num++;
- if(fi)
- fi->xfi_Next = fi2;
- else
- ai->xai_FileInfo = fi2;
- fi = fi2;
- }
- else
- xadFreeObjectA(fi2, 0);
- }
- }
- if(!ok)
- ai->xai_Flags |= XADAIF_FILECORRUPT;
- }
-
- return err;
- }
-
- ASM(LONG) Tar_UnArchive(REG(a0, struct xadArchiveInfo *ai),
- REG(a6, struct xadMasterBase *xadMasterBase))
- {
- LONG i;
-
- if((i = ((LONG) (ai->xai_CurFile->xfi_PrivateInfo)) - ai->xai_InPos))
- if((i = xadHookAccess(XADAC_INPUTSEEK, i, 0, ai)))
- return i;
-
- return xadHookAccess(XADAC_COPY, ai->xai_CurFile->xfi_Size, 0, ai);
- }
-
- struct xadClient Tar_Client = {
- NEXTCLIENT, XADCLIENT_VERSION, 2, TAR_VERSION, TAR_REVISION,
- 512, XADCF_FILEARCHIVER|XADCF_FREEFILEINFO, XADCID_TAR, "Tar",
- (BOOL (*)()) Tar_RecogData, (LONG (*)()) Tar_GetInfo,
- (LONG (*)()) Tar_UnArchive, 0};
-
- #endif /* XADASTER_TAR_C */
-