mirror of
https://github.com/MacPaw/XADMaster.git
synced 2025-08-29 03:23:48 +02:00
614 lines
18 KiB
C
Executable file
614 lines
18 KiB
C
Executable file
#ifndef XADMASTER_CLIENTFUNC_C
|
|
#define XADMASTER_CLIENTFUNC_C
|
|
|
|
/* $Id: clientfunc.c,v 1.19 2005/06/23 14:54:36 stoecker Exp $
|
|
the client support functions
|
|
|
|
XAD library system for archive handling
|
|
Copyright (C) 1998 and later by Dirk Stöcker <soft@dstoecker.de>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "include/functions.h"
|
|
#include "include/version.h"
|
|
#include <ctype.h> /* needed for isprint() */
|
|
|
|
FUNCxadGetClientInfo /* no args */
|
|
{
|
|
return xadMasterBase->xmb_FirstClient;
|
|
}
|
|
ENDFUNC
|
|
|
|
FUNCxadAddDiskEntry /* struct xadDiskInfo *di, struct xadArchiveInfoP *ai,
|
|
xadTAGPTR tags */
|
|
{
|
|
struct xadDiskInfo *ldi;
|
|
xadTAGPTR ti;
|
|
xadUINT32 i;
|
|
xadERROR ret = 0;
|
|
|
|
#ifdef DEBUG
|
|
DebugHookTagList("xadAddDiskEntry()", tags);
|
|
#endif
|
|
|
|
di->xdi_EntryNumber = ++ai->xaip_LastEntryNumber;
|
|
if((ldi = ai->xaip_LastDiskEntry))
|
|
ldi->xdi_Next = di;
|
|
else
|
|
ai->xaip_ArchiveInfo.xai_DiskInfo = di;
|
|
ai->xaip_LastDiskEntry = di;
|
|
di->xdi_Next = 0;
|
|
/* never return errors before this point! */
|
|
|
|
ldi = ai->xaip_ArchiveInfo.xai_CurDisk;
|
|
ai->xaip_ArchiveInfo.xai_CurDisk = di;
|
|
if(!((i = callprogress(ai, 0, XADPMODE_NEWENTRY, xadMasterBase)) & XADPIF_OK))
|
|
ret = XADERR_BREAK;
|
|
ai->xaip_ArchiveInfo.xai_CurDisk = ldi; /* reset */
|
|
if(!ret && (ti = FindTagItem(XAD_SETINPOS, tags)) &&
|
|
(ai->xaip_ArchiveInfo.xai_InPos != ti->ti_Data
|
|
|| FindTagItem(XAD_USESKIPINFO, tags)))
|
|
{
|
|
ret = xadHookTagAccessA(XADM_PRIV XADAC_INPUTSEEK,
|
|
ti->ti_Data-ai->xaip_ArchiveInfo.xai_InPos, 0, XADM_AI(ai), tags);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
ENDFUNC
|
|
|
|
FUNCxadAddFileEntry /* struct xadFileInfo *fi, struct xadArchiveInfoP *ai,
|
|
xadTAGPTR tags */
|
|
{
|
|
struct xadFileInfo *lfi;
|
|
xadTAGPTR ti;
|
|
xadUINT32 i;
|
|
xadERROR ret = 0;
|
|
|
|
#ifdef DEBUG
|
|
DebugHookTagList("xadAddFileEntry()", tags);
|
|
if(fi->xfi_Special)
|
|
DebugRunTime("LIBxadAddFileEntry: entry '%s' has special info",
|
|
fi->xfi_FileName);
|
|
#endif
|
|
|
|
lfi = ai->xaip_LastFileEntry;
|
|
fi->xfi_EntryNumber = ++ai->xaip_LastEntryNumber;
|
|
if(lfi && (fi->xfi_Flags & XADFIF_DIRECTORY)
|
|
&& GetTagData(XAD_INSERTDIRSFIRST, 0, tags))
|
|
{
|
|
struct xadFileInfo *lfi2 = 0;
|
|
|
|
lfi = ai->xaip_ArchiveInfo.xai_FileInfo;
|
|
|
|
while(lfi && (lfi->xfi_Flags & XADFIF_DIRECTORY) &&
|
|
stricmp(lfi->xfi_FileName, fi->xfi_FileName) <= 0)
|
|
{
|
|
lfi2 = lfi; lfi = lfi->xfi_Next;
|
|
}
|
|
if(lfi2)
|
|
lfi2->xfi_Next = fi;
|
|
else
|
|
ai->xaip_ArchiveInfo.xai_FileInfo = fi;
|
|
if(!(fi->xfi_Next = lfi))
|
|
ai->xaip_LastFileEntry = fi;
|
|
}
|
|
else
|
|
{
|
|
if(lfi)
|
|
lfi->xfi_Next = fi;
|
|
else
|
|
ai->xaip_ArchiveInfo.xai_FileInfo = fi;
|
|
fi->xfi_Next = 0;
|
|
ai->xaip_LastFileEntry = fi;
|
|
}
|
|
/* never return errors before this point! */
|
|
|
|
lfi = ai->xaip_ArchiveInfo.xai_CurFile;
|
|
ai->xaip_ArchiveInfo.xai_CurFile = fi;
|
|
if(!((i = callprogress(ai, 0, XADPMODE_NEWENTRY, xadMasterBase))
|
|
& XADPIF_OK))
|
|
ret = XADERR_BREAK;
|
|
ai->xaip_ArchiveInfo.xai_CurFile = lfi; /* reset */
|
|
if(!ret && (ti = FindTagItem(XAD_SETINPOS, tags)) &&
|
|
(ai->xaip_ArchiveInfo.xai_InPos != ti->ti_Data
|
|
|| FindTagItem(XAD_USESKIPINFO, tags)))
|
|
ret = xadHookTagAccessA(XADM XADAC_INPUTSEEK,
|
|
ti->ti_Data-ai->xaip_ArchiveInfo.xai_InPos, 0,
|
|
XADM_AI(ai), tags);
|
|
|
|
return ret;
|
|
}
|
|
ENDFUNC
|
|
|
|
FUNCxadHookAccess /* xadUINT32 command, xadSignSize data, xadPTR buffer,
|
|
struct xadArchiveInfoP *ai */
|
|
{
|
|
return xadHookTagAccessA(XADM_PRIV command, data, buffer, XADM_AI(ai), 0);
|
|
}
|
|
ENDFUNC
|
|
|
|
static xadERROR skipread(xadUINT8 *buf, xadSize size,
|
|
struct xadArchiveInfoP *ai, xadUINT32 skip)
|
|
{
|
|
#ifdef AMIGA
|
|
struct xadMasterBaseP *xadMasterBase = (struct xadMasterBaseP *) ai->xaip_MasterBase;
|
|
struct UtilityBase *UtilityBase = xadMasterBase->xmb_UtilityBase;
|
|
#endif
|
|
struct xadHookParam *ihp;
|
|
struct Hook *ih;
|
|
const struct xadSkipInfo *si, *si2;
|
|
xadERROR ret = 0;
|
|
xadSize s;
|
|
|
|
ihp = &(ai->xaip_InHookParam);
|
|
ih = ai->xaip_InHook;
|
|
|
|
if(ai->xaip_ArchiveInfo.xai_SkipInfo && skip)
|
|
{
|
|
while(!ret && size)
|
|
{
|
|
si2 = 0;
|
|
for(si = ai->xaip_ArchiveInfo.xai_SkipInfo; si; si = si->xsi_Next)
|
|
{
|
|
/* skip buffer at start */
|
|
if(si->xsi_Position <= ai->xaip_ArchiveInfo.xai_InPos &&
|
|
si->xsi_Position+si->xsi_SkipSize > ai->xaip_ArchiveInfo.xai_InPos)
|
|
{
|
|
ihp->xhp_Command = XADHC_SEEK;
|
|
ihp->xhp_CommandData = si->xsi_Position+si->xsi_SkipSize
|
|
- ai->xaip_ArchiveInfo.xai_InPos;
|
|
ret = CallHookPkt(ih, ai, ihp);
|
|
ai->xaip_ArchiveInfo.xai_InPos = ihp->xhp_DataPos;
|
|
}
|
|
else if(si->xsi_Position > ai->xaip_ArchiveInfo.xai_InPos &&
|
|
(!si2 || si2->xsi_Position > si->xsi_Position))
|
|
si2 = si;
|
|
}
|
|
|
|
if(!ret)
|
|
{
|
|
if(!si2 || (s = si2->xsi_Position - ai->xaip_ArchiveInfo.xai_InPos)
|
|
> size)
|
|
s = size;
|
|
|
|
ihp->xhp_Command = XADHC_READ;
|
|
ihp->xhp_BufferPtr = buf;
|
|
ihp->xhp_BufferSize = s;
|
|
ret = CallHookPkt(ih, ai, ihp);
|
|
buf += s;
|
|
ai->xaip_ArchiveInfo.xai_InPos = ihp->xhp_DataPos;
|
|
size -= s;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ihp->xhp_Command = XADHC_READ;
|
|
ihp->xhp_BufferPtr = buf;
|
|
ihp->xhp_BufferSize = size;
|
|
ret = CallHookPkt(ih, ai, ihp);
|
|
ai->xaip_ArchiveInfo.xai_InPos = ihp->xhp_DataPos;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
xadSignSize getskipsize(xadSignSize data, const struct xadArchiveInfoP *ai)
|
|
{
|
|
const struct xadSkipInfo *si, *silo, *sihi, *sit;
|
|
|
|
#ifdef DEBUG
|
|
xadSignSize sdata;
|
|
sdata = data;
|
|
#endif
|
|
|
|
for(si = silo = sihi = ai->xaip_ArchiveInfo.xai_SkipInfo; si;
|
|
si = si->xsi_Next)
|
|
{
|
|
if(si->xsi_Position > sihi->xsi_Position)
|
|
sihi = si;
|
|
if(si->xsi_Position < silo->xsi_Position)
|
|
silo = si;
|
|
}
|
|
if(data < 0) /* skip when entries are at buffer start or in buffer */
|
|
{
|
|
for(;;)
|
|
{
|
|
if(sihi->xsi_Position < ai->xaip_ArchiveInfo.xai_InPos)
|
|
{
|
|
if(sihi->xsi_Position + sihi->xsi_SkipSize
|
|
> ai->xaip_ArchiveInfo.xai_InPos)
|
|
data -= ai->xaip_ArchiveInfo.xai_InPos - sihi->xsi_Position;
|
|
else if(sihi->xsi_Position + sihi->xsi_SkipSize
|
|
> ai->xaip_ArchiveInfo.xai_InPos+data)
|
|
data -= sihi->xsi_SkipSize;
|
|
}
|
|
if(silo == sihi)
|
|
break;
|
|
else
|
|
{
|
|
sit = silo;
|
|
for(si = ai->xaip_ArchiveInfo.xai_SkipInfo; si; si = si->xsi_Next)
|
|
{
|
|
if(si->xsi_Position > sit->xsi_Position && si->xsi_Position
|
|
< sihi->xsi_Position)
|
|
sit = si;
|
|
}
|
|
sihi = sit;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(;;)
|
|
{
|
|
if(silo->xsi_Position >= ai->xaip_ArchiveInfo.xai_InPos) /* in buffer */
|
|
{
|
|
if(silo->xsi_Position <= ai->xaip_ArchiveInfo.xai_InPos+data)
|
|
data += silo->xsi_SkipSize;
|
|
}
|
|
else if(silo->xsi_Position+silo->xsi_SkipSize
|
|
> ai->xaip_ArchiveInfo.xai_InPos) /* first border partial */
|
|
data += silo->xsi_Position+silo->xsi_SkipSize
|
|
-ai->xaip_ArchiveInfo.xai_InPos;
|
|
if(silo == sihi)
|
|
break;
|
|
else
|
|
{
|
|
sit = sihi;
|
|
for(si = ai->xaip_ArchiveInfo.xai_SkipInfo; si; si = si->xsi_Next)
|
|
{
|
|
if(si->xsi_Position < sit->xsi_Position && si->xsi_Position
|
|
> silo->xsi_Position)
|
|
sit = si;
|
|
}
|
|
silo = sit;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
if(sdata != data)
|
|
DebugRunTime("getskipsize: changed seeksize from %ld to %ld", sdata, data);
|
|
#endif
|
|
return data;
|
|
}
|
|
|
|
FUNCxadHookTagAccess /* xadUINT32 command, xadSignSize data, xadPTR buffer,
|
|
struct xadArchiveInfo *ai, xadTAGPTR tags */
|
|
{
|
|
xadERROR ret = 0;
|
|
xadUINT32 skip = 0;
|
|
struct xadHookParam *ihp, *ohp;
|
|
struct Hook *ih, *oh;
|
|
xadTAGPTR ti;
|
|
struct TagItem tis[2];
|
|
xadUINT32 *crc32 = 0, crc32ID = XADCRC32_ID1;
|
|
xadUINT16 *crc16 = 0, crc16ID = XADCRC16_ID1;
|
|
|
|
#ifdef DEBUG
|
|
static const xadSTRPTR comname[] = {"XADAC_READ", "XADAC_WRITE",
|
|
"XADAC_COPY", "XADAC_INPUTSEEK", "XADAC_OUTPUTSEEK"};
|
|
DebugHookTagList("xadHookAccess(%-16s, %7lld, %08lx, .) pos(%6lld|%6lld)", tags,
|
|
comname[command-XADAC_READ], data, buffer, ai->xaip_ArchiveInfo.xai_InPos,
|
|
ai->xaip_ArchiveInfo.xai_OutPos);
|
|
#endif
|
|
|
|
tis[0].ti_Tag = XAD_SECTORLABELS;
|
|
tis[0].ti_Data = 0;
|
|
tis[1].ti_Tag = TAG_DONE;
|
|
|
|
ihp = &(ai->xaip_InHookParam);
|
|
ohp = &(ai->xaip_OutHookParam);
|
|
ih = ai->xaip_InHook;
|
|
oh = ai->xaip_OutHook;
|
|
|
|
if((!ih && (command == XADAC_READ || command == XADAC_INPUTSEEK
|
|
|| command == XADAC_COPY)) || (!oh && (command == XADAC_WRITE
|
|
|| command == XADAC_OUTPUTSEEK || command == XADAC_COPY)))
|
|
return XADERR_BADPARAMS;
|
|
|
|
ti = tags;
|
|
while((tags = NextTagItem(&ti)))
|
|
{
|
|
switch(tags->ti_Tag)
|
|
{
|
|
case XAD_USESKIPINFO: skip = (xadUINT32) tags->ti_Data; break;
|
|
case XAD_SECTORLABELS: tis[0].ti_Data = tags->ti_Data; break;
|
|
case XAD_GETCRC32: crc32 = (xadUINT32 *)(uintptr_t) tags->ti_Data; break;
|
|
case XAD_GETCRC16: crc16 = (xadUINT16 *)(uintptr_t) tags->ti_Data; break;
|
|
case XAD_CRC32ID: crc32ID = (xadUINT32) tags->ti_Data; break;
|
|
case XAD_CRC16ID: crc16ID = (xadUINT16) tags->ti_Data; break;
|
|
}
|
|
}
|
|
|
|
if(tis[0].ti_Data && (data&(512-1)))
|
|
return XADERR_BADPARAMS;
|
|
|
|
switch(command)
|
|
{
|
|
case XADAC_READ:
|
|
ret = skipread(buffer, data, ai, skip);
|
|
if(crc32)
|
|
*crc32 = xadCalcCRC32(XADM_PRIV crc32ID, *crc32, data, buffer);
|
|
if(crc16)
|
|
*crc16 = xadCalcCRC16(XADM_PRIV crc16ID, *crc16, data, buffer);
|
|
break;
|
|
case XADAC_WRITE:
|
|
ohp->xhp_Command = XADHC_WRITE;
|
|
ohp->xhp_BufferPtr = buffer;
|
|
ohp->xhp_BufferSize = data;
|
|
if(tis[0].ti_Data)
|
|
{
|
|
#ifdef DEBUG
|
|
xadINT32 i, j;
|
|
xadUINT8 r[16*2+1+16+1], *s;
|
|
|
|
s = (xadUINT8 *) tis[0].ti_Data;
|
|
for(i = 0; i < data; i += 512)
|
|
{
|
|
for(j = 0; j < 16; ++j)
|
|
{
|
|
r[j*2] = (*s/16 >= 10) ? (*s/16+'A'-10) : (*s/16+'0');
|
|
r[j*2+1] = (*s%16 >= 10) ? (*s%16+'A'-10) : (*s%16+'0');
|
|
r[32] = ' ';
|
|
r[33+j] = isprint(*s) ? *s : '.';
|
|
++s;
|
|
r[33+16] = 0;
|
|
}
|
|
DebugOther("SectorLabel: %s", r);
|
|
}
|
|
#endif
|
|
ohp->xhp_TagList = tis;
|
|
}
|
|
ret = CallHookPkt(oh, ai, ohp);
|
|
ai->xaip_ArchiveInfo.xai_OutPos = ohp->xhp_DataPos;
|
|
if(ohp->xhp_DataPos > ai->xaip_ArchiveInfo.xai_OutSize)
|
|
{
|
|
ai->xaip_ArchiveInfo.xai_OutSize = ohp->xhp_DataPos;
|
|
if(!ret)
|
|
{
|
|
xadUINT32 i;
|
|
if(!((i = callprogress(ai, 0, XADPMODE_PROGRESS, xadMasterBase))
|
|
& XADPIF_OK))
|
|
ret = XADERR_BREAK;
|
|
else if(i & XADPIF_SKIP)
|
|
ret = XADERR_SKIP;
|
|
}
|
|
}
|
|
if(crc32)
|
|
*crc32 = xadCalcCRC32(XADM crc32ID, *crc32, data, buffer);
|
|
if(crc16)
|
|
*crc16 = xadCalcCRC16(XADM crc16ID, *crc16, data, buffer);
|
|
break;
|
|
case XADAC_COPY:
|
|
{
|
|
xadSize bufsize;
|
|
xadPTR buf;
|
|
|
|
if((bufsize = data) > 51200)
|
|
bufsize = 51200;
|
|
if((buf = xadAllocVec(XADM bufsize, XADMEMF_PUBLIC)))
|
|
{
|
|
ohp->xhp_Command = XADHC_WRITE;
|
|
ohp->xhp_BufferPtr = buf;
|
|
while(data > 0 && !ret)
|
|
{
|
|
ohp->xhp_BufferSize = data > bufsize ? bufsize : data;
|
|
if(!(ret = skipread(buf, ohp->xhp_BufferSize, ai, skip)))
|
|
ret = CallHookPkt(oh, ai, ohp);
|
|
|
|
if(crc32)
|
|
*crc32 = xadCalcCRC32(XADM crc32ID, *crc32, ohp->xhp_BufferSize,
|
|
ohp->xhp_BufferPtr);
|
|
if(crc16)
|
|
*crc16 = xadCalcCRC16(XADM crc16ID, *crc16, ohp->xhp_BufferSize,
|
|
ohp->xhp_BufferPtr);
|
|
|
|
ai->xaip_ArchiveInfo.xai_OutPos = ohp->xhp_DataPos;
|
|
if(ohp->xhp_DataPos > ai->xaip_ArchiveInfo.xai_OutSize)
|
|
{
|
|
ai->xaip_ArchiveInfo.xai_OutSize = ohp->xhp_DataPos;
|
|
if(!ret)
|
|
{
|
|
xadUINT32 i;
|
|
if(!((i = callprogress(ai, 0, XADPMODE_PROGRESS,
|
|
xadMasterBase)) & XADPIF_OK))
|
|
ret = XADERR_BREAK;
|
|
else if(i & XADPIF_SKIP)
|
|
ret = XADERR_SKIP;
|
|
}
|
|
}
|
|
data -= ohp->xhp_BufferSize;
|
|
}
|
|
xadFreeObjectA(XADM buf, 0);
|
|
}
|
|
else
|
|
ret = XADERR_NOMEMORY;
|
|
}
|
|
break;
|
|
case XADAC_INPUTSEEK:
|
|
if(skip)
|
|
data = getskipsize(data, ai);
|
|
|
|
ihp->xhp_Command = XADHC_SEEK;
|
|
ihp->xhp_CommandData = data;
|
|
ret = CallHookPkt(ih, ai, ihp);
|
|
ai->xaip_ArchiveInfo.xai_InPos = ihp->xhp_DataPos;
|
|
break;
|
|
case XADAC_OUTPUTSEEK:
|
|
ohp->xhp_Command = XADHC_SEEK;
|
|
ohp->xhp_CommandData = data;
|
|
ret = CallHookPkt(oh, ai, ohp);
|
|
ai->xaip_ArchiveInfo.xai_OutPos = ohp->xhp_DataPos;
|
|
break;
|
|
default: ret = XADERR_NOTSUPPORTED; break;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
if(ret)
|
|
DebugError("xadHookAccess returns \"%s\" (%ld)", xadGetErrorText(XADM ret), ret);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
ENDFUNC
|
|
|
|
xadUINT32 callprogress(const struct xadArchiveInfoP *ai, xadUINT32 stat,
|
|
xadUINT32 mode, struct xadMasterBaseP * xadMasterBase)
|
|
{
|
|
xadUINT32 ret = XADPIF_OK;
|
|
struct xadProgressInfo *pi;
|
|
#ifdef AMIGA
|
|
struct UtilityBase *UtilityBase = xadMasterBase->xmb_UtilityBase;
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
DebugRunTime("callprogress: hook = $%08lx", ai->xaip_ProgressHook);
|
|
#endif
|
|
|
|
if(ai->xaip_ProgressHook)
|
|
{
|
|
if((pi = (struct xadProgressInfo *) xadAllocObjectA(XADM
|
|
XADOBJ_PROGRESSINFO, 0)))
|
|
{
|
|
pi->xpi_Mode = mode;
|
|
pi->xpi_Client = ai->xaip_ArchiveInfo.xai_Client;
|
|
pi->xpi_DiskInfo = ai->xaip_ArchiveInfo.xai_CurDisk;
|
|
pi->xpi_FileInfo = ai->xaip_ArchiveInfo.xai_CurFile;
|
|
pi->xpi_CurrentSize = ai->xaip_ArchiveInfo.xai_OutSize;
|
|
pi->xpi_LowCyl = ai->xaip_ArchiveInfo.xai_LowCyl;
|
|
pi->xpi_HighCyl = ai->xaip_ArchiveInfo.xai_HighCyl;
|
|
if(mode == XADPMODE_ERROR)
|
|
{
|
|
pi->xpi_Error = stat; stat = 0;
|
|
}
|
|
pi->xpi_Status = stat;
|
|
ret = CallHookPkt(ai->xaip_ProgressHook, 0, pi);
|
|
xadFreeObjectA(XADM pi, 0);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
xadUINT32 callprogressFN(const struct xadArchiveInfoP *ai, xadUINT32 stat,
|
|
xadUINT32 mode, xadSTRPTR *filename, struct xadMasterBaseP * xadMasterBase)
|
|
{
|
|
xadUINT32 ret = XADPIF_OK;
|
|
struct xadProgressInfo *pi;
|
|
#ifdef AMIGA
|
|
struct UtilityBase *UtilityBase = xadMasterBase->xmb_UtilityBase;
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
DebugRunTime("callprogressFN: hook = $%08lx", ai->xaip_ProgressHook);
|
|
#endif
|
|
|
|
if(ai->xaip_ProgressHook)
|
|
{
|
|
if((pi = (struct xadProgressInfo *) xadAllocObjectA(XADM
|
|
XADOBJ_PROGRESSINFO, 0)))
|
|
{
|
|
pi->xpi_FileName = *filename;
|
|
pi->xpi_Mode = mode;
|
|
pi->xpi_Client = ai->xaip_ArchiveInfo.xai_Client;
|
|
pi->xpi_DiskInfo = ai->xaip_ArchiveInfo.xai_CurDisk;
|
|
pi->xpi_FileInfo = ai->xaip_ArchiveInfo.xai_CurFile;
|
|
pi->xpi_CurrentSize = ai->xaip_ArchiveInfo.xai_OutSize;
|
|
pi->xpi_LowCyl = ai->xaip_ArchiveInfo.xai_LowCyl;
|
|
pi->xpi_HighCyl = ai->xaip_ArchiveInfo.xai_HighCyl;
|
|
if(mode == XADPMODE_ERROR)
|
|
{
|
|
pi->xpi_Error = stat; stat = 0;
|
|
}
|
|
pi->xpi_Status = stat;
|
|
ret = CallHookPkt(ai->xaip_ProgressHook, 0, pi);
|
|
*filename = pi->xpi_NewName;
|
|
xadFreeObjectA(XADM pi, 0);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/* Copies all clients given to the central list in xadMasterBase. If any
|
|
* entries have xc_Identifier set, searches the list and overwrites the
|
|
* first entry with the same identifier. The xc_Flags and add_flags are
|
|
* ORed in any new entry. Returns XADTRUE if any client could be added,
|
|
* XADFALSE if no client could be added.
|
|
*/
|
|
xadBOOL xadAddClients(struct xadMasterBaseP *xadMasterBase,
|
|
const struct xadClient *clients,
|
|
xadUINT32 add_flags)
|
|
{
|
|
const struct xadClient *xc;
|
|
struct xadClient *xc2, *new_xc, *tail;
|
|
xadBOOL ok = XADFALSE;
|
|
|
|
/* go to tail of client list */
|
|
tail = xadMasterBase->xmb_FirstClient;
|
|
while (tail && tail->xc_Next) tail = tail->xc_Next;
|
|
|
|
/* for all clients */
|
|
for (xc = clients; xc; xc = xc->xc_Next) {
|
|
/* reject client if it is too new to be used */
|
|
if (xc->xc_MasterVersion > XADMASTERVERSION) continue;
|
|
|
|
/* if client has an ID, try and find if a client with that ID already
|
|
* exists in the list, and overwrite it */
|
|
if (xc->xc_Identifier) {
|
|
/* loop through all clients */
|
|
for (xc2 = xadMasterBase->xmb_FirstClient; xc2; xc2 = xc2->xc_Next) {
|
|
/* if a matching ID is found */
|
|
if (xc2->xc_Identifier == xc->xc_Identifier) {
|
|
/* copy over existing client, but don't lose the list link */
|
|
new_xc = xc2->xc_Next;
|
|
xadCopyMem(XADM xc, xc2, sizeof(struct xadClient));
|
|
xc2->xc_Next = new_xc;
|
|
xc2->xc_Flags |= add_flags;
|
|
ok = XADTRUE;
|
|
break;
|
|
}
|
|
}
|
|
/* if we found a match, this client has been added */
|
|
if (xc2) continue;
|
|
}
|
|
|
|
/* there was no identifier or no match, so we have to add this client */
|
|
if ((new_xc = xadAllocVec(XADM sizeof(struct xadClient), XADMEMF_PUBLIC))) {
|
|
xadCopyMem(XADM xc, new_xc, sizeof(struct xadClient));
|
|
new_xc->xc_Next = NULL;
|
|
new_xc->xc_Flags |= add_flags;
|
|
if (tail) tail->xc_Next = new_xc;
|
|
else xadMasterBase->xmb_FirstClient = new_xc;
|
|
tail = new_xc;
|
|
ok = XADTRUE;
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
/* Removes all clients from the central list in xadMasterBase */
|
|
void xadFreeClients(struct xadMasterBaseP *xadMasterBase)
|
|
{
|
|
struct xadClient *xc, *next;
|
|
for (xc = xadMasterBase->xmb_FirstClient; xc; xc = next) {
|
|
next = xc->xc_Next;
|
|
xadFreeObjectA(XADM xc, 0);
|
|
}
|
|
xadMasterBase->xmb_FirstClient = NULL;
|
|
}
|
|
|
|
#endif /* XADMASTER_CLIENTFUNC_C */
|