mirror of
https://github.com/MacPaw/XADMaster.git
synced 2025-08-29 03:23:48 +02:00
374 lines
10 KiB
C
Executable file
374 lines
10 KiB
C
Executable file
#ifndef XADMASTER_INFO_C
|
|
#define XADMASTER_INFO_C
|
|
|
|
/* $Id: info.c,v 1.13 2005/06/23 14:54:37 stoecker Exp $
|
|
information handling 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"
|
|
|
|
FUNCxadGetSystemInfo /* no args */
|
|
{
|
|
return &xadMasterBase->xmb_System;
|
|
}
|
|
ENDFUNC
|
|
|
|
FUNCxadRecogFile /* xadSize size, const void *mem, xadTAGPTR tags */
|
|
{
|
|
#ifdef AMIGA
|
|
struct xadClient *xc = xadGetClientInfo();
|
|
#else
|
|
struct xadClient *xc = xadGetClientInfo(xadMasterBase);
|
|
#endif
|
|
|
|
xadINT32 noext = 0;
|
|
xadUINT32 onlyflags = 0, ignoreflags = 0;
|
|
xadTAGPTR ti, ti2 = tags;
|
|
|
|
#ifdef DEBUG
|
|
xadUINT32 crc, crc2;
|
|
|
|
crc = xadCalcCRC32(XADM_PRIV XADCRC32_ID1, ~0, size, mem);
|
|
#endif
|
|
|
|
while((ti = NextTagItem(&ti2)))
|
|
{
|
|
switch(ti->ti_Tag)
|
|
{
|
|
case XAD_NOEXTERN: noext = (xadINT32)ti->ti_Data; break;
|
|
case XAD_IGNOREFLAGS: ignoreflags = (xadUINT32)ti->ti_Data; break;
|
|
case XAD_ONLYFLAGS: onlyflags = (xadUINT32)ti->ti_Data; break;
|
|
}
|
|
}
|
|
|
|
if(noext)
|
|
ignoreflags |= XADCF_EXTERN;
|
|
|
|
#ifdef DEBUG
|
|
DebugRunTime("xadRecogFileA: %s (%08lx, %ld)", noext ? "NOEXTERN" : "EXTERN", mem, size);
|
|
#endif
|
|
|
|
while(xc)
|
|
{
|
|
if((xc->xc_Flags & (XADCF_FILEARCHIVER|XADCF_DISKARCHIVER)) && xc->xc_RecogData &&
|
|
!(xc->xc_Flags & ignoreflags) && ((xc->xc_Flags & onlyflags) == onlyflags))
|
|
{
|
|
if((size >= xc->xc_RecogSize) || (xc->xc_Flags & XADCF_NOCHECKSIZE))
|
|
{
|
|
#ifdef DEBUG
|
|
crc2 = xadCalcCRC32(XADM XADCRC32_ID1, ~0, size, mem);
|
|
#endif
|
|
if(Callback_RecogData(xc, MinVal(size, xc->xc_RecogSize), mem,
|
|
xadMasterBase))
|
|
{
|
|
#ifdef DEBUG
|
|
DebugRunTime("xadRecogFileA: found %s", xc->xc_ArchiverName);
|
|
if(crc2 != xadCalcCRC32(XADM XADCRC32_ID1, ~0, size, mem))
|
|
DebugError("xadRecogFileA: The input buffer was modified by this client.");
|
|
#endif
|
|
return xc;
|
|
}
|
|
#ifdef DEBUG
|
|
if(crc2 != xadCalcCRC32(XADM XADCRC32_ID1, ~0, size, mem))
|
|
DebugError("xadRecogFileA: The input buffer was modified by %s.",
|
|
xc->xc_ArchiverName);
|
|
#endif
|
|
}
|
|
}
|
|
xc = xc->xc_Next;
|
|
}
|
|
#ifdef DEBUG
|
|
if(crc != xadCalcCRC32(XADM XADCRC32_ID1, ~0, size, mem))
|
|
DebugError("xadRecogFileA: The input buffer was modified.");
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
ENDFUNC
|
|
|
|
FUNCxadGetInfo /* struct xadArchiveInfoP *ai, xadTAGPTR tags */
|
|
{
|
|
xadERROR err;
|
|
|
|
#ifdef DEBUG
|
|
DebugTagList("xadGetInfoA", tags);
|
|
#endif
|
|
|
|
/* Validate tag arguments, fill out some ArchiveInfo fields from tags,
|
|
* and initialise hook if required. Only "input" tags are allowed, tags
|
|
* that would generate output are not allowed. */
|
|
ai->xaip_ArchiveInfo.xai_Flags |= XADAIF_ONLYIN;
|
|
err = xadGetHookAccessA(XADM_PRIV XADM_AI(ai), tags);
|
|
ai->xaip_ArchiveInfo.xai_Flags &= ~XADAIF_ONLYIN;
|
|
|
|
/* if a full file path has been provided, extract the filename part */
|
|
if(ai->xaip_InFileName)
|
|
{
|
|
/* FIXME: use an appropriate ConvertName function, as this code is
|
|
* hacky, only working for Amiga and UNIX */
|
|
xadSTRPTR pos, f;
|
|
|
|
for(f = pos = ai->xaip_InFileName; *pos; ++pos)
|
|
{
|
|
#ifdef AMIGA
|
|
if(*pos == ':' || *pos == '/')
|
|
#else
|
|
if(*pos == '/')
|
|
#endif
|
|
f = pos+1;
|
|
}
|
|
if(*f)
|
|
ai->xaip_ArchiveInfo.xai_InName = f;
|
|
}
|
|
if(!err)
|
|
{
|
|
// GOA -->
|
|
struct xadClient *xc = 0;
|
|
xadUINT32 client_id = GetTagData(XAD_CLIENT, 0, tags);
|
|
|
|
if(!client_id)
|
|
{
|
|
xadPTR buf;
|
|
xadSignSize size;
|
|
|
|
size = MinVal(xadMasterBase->xmb_RecogSize,
|
|
ai->xaip_ArchiveInfo.xai_InSize);
|
|
|
|
if((buf = xadAllocVec(XADM size, XADMEMF_ANY|XADMEMF_PUBLIC)))
|
|
{
|
|
if(!(err = xadHookAccess(XADM XADAC_READ, size, buf, XADM_AI(ai))))
|
|
{
|
|
if(!(err = xadHookAccess(XADM XADAC_INPUTSEEK, -size, 0,
|
|
XADM_AI(ai))))
|
|
{
|
|
if(!(xc = xadRecogFileA(XADM size, buf, tags)))
|
|
err = XADERR_FILETYPE;
|
|
}
|
|
}
|
|
xadFreeObjectA(XADM buf, 0);
|
|
}
|
|
else
|
|
err = XADERR_NOMEMORY;
|
|
}
|
|
else
|
|
{
|
|
#ifdef AMIGA
|
|
xc = xadGetClientInfo();
|
|
#else
|
|
xc = xadGetClientInfo(xadMasterBase);
|
|
#endif
|
|
while(xc)
|
|
{
|
|
if(xc->xc_Identifier == client_id) break;
|
|
xc = xc->xc_Next;
|
|
}
|
|
}
|
|
// <-- GOA
|
|
|
|
if(xc)
|
|
{
|
|
ai->xaip_ArchiveInfo.xai_Client = xc;
|
|
err = Callback_GetInfo(xc, ai, xadMasterBase);
|
|
}
|
|
}
|
|
|
|
callprogress(ai, err, err ? XADPMODE_ERROR : XADPMODE_GETINFOEND,
|
|
xadMasterBase);
|
|
ai->xaip_ArchiveInfo.xai_InName = 0;
|
|
/* it is no longer valid after leaving that function */
|
|
|
|
if(err)
|
|
{
|
|
xadFreeInfo(XADM XADM_AI(ai));
|
|
#ifdef DEBUG
|
|
DebugError("xadGetInfo returns \"%s\" (%ld)", xadGetErrorText(XADM err),
|
|
err);
|
|
#endif
|
|
}
|
|
|
|
return err;
|
|
}
|
|
ENDFUNC
|
|
|
|
FUNCxadFreeInfo /* struct xadArchiveInfoP *ai */
|
|
{
|
|
const struct xadClient *xc;
|
|
|
|
#ifdef DEBUG
|
|
DebugRunTime("xadFreeInfo");
|
|
#endif
|
|
|
|
if((xc = ai->xaip_ArchiveInfo.xai_Client))
|
|
{
|
|
if(xc->xc_Free)
|
|
Callback_Free(xc, ai, xadMasterBase);
|
|
|
|
if(ai->xaip_ArchiveInfo.xai_SkipInfo
|
|
&& (xc->xc_Flags & XADCF_FREESKIPINFO))
|
|
{
|
|
struct xadSkipInfo *si, *si2;
|
|
|
|
for(si = ai->xaip_ArchiveInfo.xai_SkipInfo; si; si = si2)
|
|
{
|
|
si2 = si->xsi_Next;
|
|
xadFreeObjectA(XADM si, 0);
|
|
}
|
|
#ifdef DEBUG
|
|
/* not needed in non DEBUG state, because of memset */
|
|
ai->xaip_ArchiveInfo.xai_SkipInfo = 0;
|
|
#endif
|
|
}
|
|
|
|
if(ai->xaip_ArchiveInfo.xai_FileInfo && (xc->xc_Flags &
|
|
(XADCF_FREEFILEINFO|XADCF_FREESPECIALINFO|XADCF_FREEXADSTRINGS)))
|
|
{
|
|
struct xadFileInfo *fi, *fi2;
|
|
struct xadSpecial *s, *s2;
|
|
|
|
for(fi = ai->xaip_ArchiveInfo.xai_FileInfo; fi; fi = fi2)
|
|
{
|
|
if(xc->xc_Flags & XADCF_FREESPECIALINFO)
|
|
{
|
|
for(s = fi->xfi_Special; s; s = s2)
|
|
{
|
|
s2 = s->xfis_Next;
|
|
xadFreeObjectA(XADM s, 0);
|
|
}
|
|
#ifdef DEBUG
|
|
/* not needed in non DEBUG state, because of memset */
|
|
fi->xfi_Special = 0;
|
|
#endif
|
|
}
|
|
if(xc->xc_Flags & XADCF_FREEXADSTRINGS)
|
|
{
|
|
if(fi->xfi_Flags & XADFIF_XADSTRFILENAME)
|
|
{
|
|
xadFreeObjectA(XADM fi->xfi_FileName, 0);
|
|
#ifdef DEBUG
|
|
fi->xfi_FileName = 0;
|
|
#endif
|
|
}
|
|
if(fi->xfi_Flags & XADFIF_XADSTRLINKNAME)
|
|
{
|
|
xadFreeObjectA(XADM fi->xfi_LinkName, 0);
|
|
#ifdef DEBUG
|
|
fi->xfi_FileName = 0;
|
|
#endif
|
|
}
|
|
if(fi->xfi_Flags & XADFIF_XADSTRCOMMENT)
|
|
{
|
|
xadFreeObjectA(XADM fi->xfi_Comment, 0);
|
|
#ifdef DEBUG
|
|
fi->xfi_FileName = 0;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
if(fi->xfi_Special)
|
|
DebugMemError("xadFreeInfo: still some Special entries in list for "
|
|
"entry %ld", fi->xfi_EntryNumber);
|
|
if(fi->xfi_FileName && (fi->xfi_Flags & XADFIF_XADSTRFILENAME))
|
|
DebugMemError("xadFreeInfo: FileName string not released for "
|
|
"entry %ld", fi->xfi_EntryNumber);
|
|
if(fi->xfi_LinkName && (fi->xfi_Flags & XADFIF_XADSTRLINKNAME))
|
|
DebugMemError("xadFreeInfo: LinkName string not released for "
|
|
"entry %ld", fi->xfi_EntryNumber);
|
|
if(fi->xfi_Comment && (fi->xfi_Flags & XADFIF_XADSTRCOMMENT))
|
|
DebugMemError("xadFreeInfo: Comment string not released for "
|
|
"entry %ld", fi->xfi_EntryNumber);
|
|
#endif
|
|
fi2 = fi->xfi_Next;
|
|
if(xc->xc_Flags & XADCF_FREEFILEINFO)
|
|
xadFreeObjectA(XADM fi, 0);
|
|
}
|
|
#ifdef DEBUG
|
|
/* not needed in non DEBUG state, because of memset */
|
|
if(xc->xc_Flags & XADCF_FREEFILEINFO)
|
|
ai->xaip_ArchiveInfo.xai_FileInfo = 0;
|
|
#endif
|
|
}
|
|
|
|
if(ai->xaip_ArchiveInfo.xai_DiskInfo && (xc->xc_Flags
|
|
& (XADCF_FREEDISKINFO|XADCF_FREETEXTINFO|XADCF_FREETEXTINFOTEXT)))
|
|
{
|
|
struct xadDiskInfo *di, *di2;
|
|
struct xadTextInfo *ti, *ti2;
|
|
|
|
for(di = ai->xaip_ArchiveInfo.xai_DiskInfo; di; di = di2)
|
|
{
|
|
di2 = di->xdi_Next;
|
|
|
|
for(ti = di->xdi_TextInfo; ti; ti = ti2)
|
|
{
|
|
ti2 = ti->xti_Next;
|
|
if(ti->xti_Text && (xc->xc_Flags & XADCF_FREETEXTINFOTEXT))
|
|
{
|
|
xadFreeObjectA(XADM ti->xti_Text, 0);
|
|
ti->xti_Text = 0;
|
|
}
|
|
#ifdef DEBUG
|
|
if(ti->xti_Text)
|
|
DebugMemError("xadFreeInfo: still some Texts for entry %ld", di->xdi_EntryNumber);
|
|
#endif
|
|
if(xc->xc_Flags & XADCF_FREETEXTINFO)
|
|
xadFreeObjectA(XADM ti, 0);
|
|
}
|
|
if(xc->xc_Flags & XADCF_FREETEXTINFO)
|
|
di->xdi_TextInfo = 0;
|
|
|
|
#ifdef DEBUG
|
|
if(di->xdi_TextInfo)
|
|
DebugMemError("xadFreeInfo: still some xadTextInfo for entry %ld", di->xdi_EntryNumber);
|
|
#endif
|
|
if(xc->xc_Flags & XADCF_FREEDISKINFO)
|
|
xadFreeObjectA(XADM di, 0);
|
|
}
|
|
#ifdef DEBUG
|
|
/* not needed in non DEBUG state, because of memset */
|
|
if(xc->xc_Flags & XADCF_FREEDISKINFO)
|
|
ai->xaip_ArchiveInfo.xai_DiskInfo = 0;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if(ai->xaip_ArchiveInfo.xai_ImageInfo)
|
|
xadFreeObjectA(XADM ai->xaip_ArchiveInfo.xai_ImageInfo, 0);
|
|
|
|
#ifdef DEBUG
|
|
if(ai->xaip_ArchiveInfo.xai_DiskInfo)
|
|
DebugMemError("xadFreeInfo: xai_DiskInfo entry not cleared");
|
|
if(ai->xaip_ArchiveInfo.xai_FileInfo)
|
|
DebugMemError("xadFreeInfo: xai_FileInfo entry not cleared");
|
|
if(ai->xaip_ArchiveInfo.xai_SkipInfo)
|
|
DebugMemError("xadFreeInfo: xai_SkipInfo entry not cleared");
|
|
if(ai->xaip_ArchiveInfo.xai_PrivateClient)
|
|
DebugMemError("xadFreeInfo: xai_PrivateClient entry not cleared");
|
|
#endif
|
|
|
|
ai->xaip_ArchiveInfo.xai_Flags |= XADAIF_ONLYIN; /* cleared afterwards by memset */
|
|
xadFreeHookAccessA(XADM_PRIV XADM_AI(ai), 0);
|
|
|
|
/* clear the structure to allow reuse */
|
|
memset(ai, 0, sizeof(struct xadArchiveInfoP));
|
|
}
|
|
ENDFUNC
|
|
|
|
#endif /* XADMASTER_INFO_C */
|