home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ANews 1
/
AnewsCD01.iso
/
Indispensables
/
Compression
/
xad
/
Developer
/
Sources
/
clients
/
Tar.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-08-09
|
7KB
|
264 lines
#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 */