/* 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; }
ASM(void) sz_Free(REG(a0, struct xadArchiveInfo *ai), REG(a6, struct xadMasterBase *xadMasterBase)) #endif { /* This function needs to free all the stuff allocated in info or unarchive function. It may be called multiple times, so clear freed entries! */ ISzAlloc allocImp; /* memory functions for main pool */ ISzAlloc allocTempImp; /* memory functions for temporary pool */ allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; struct xad7zprivate *xad7z = ai->xai_PrivateClient; CSzArEx *db = &xad7z->db; UInt32 *blockIndex = &xad7z->blockIndex; Byte **outBuffer = &xad7z->outBuffer; size_t *outBufferSize = &xad7z->outBufferSize; // allocImp.Free(NULL,*outBuffer); SzArEx_Free(db, &allocImp); *outBuffer=0; *blockIndex = 0xfffffff; *outBufferSize = 0; if(g_buffer) { FreeVec(g_buffer); g_buffer = NULL; } // CrcFreeTable(); xadFreeObjectA(ai->xai_PrivateClient,NULL); ai->xai_PrivateClient = NULL; #ifdef __amigaos4__ DropInterface(INewlib); CloseLibrary(newlibbase); INewlib = NULL; newlibbase = NULL; #endif #ifdef __AROS__ CloseLibrary(aroscbase); aroscbase = NULL; #endif }
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; }
ENDFUNC /*************************** write-to-mem hook **************************/ FUNCHOOK(OutHookStream) { xadERROR err = 0; struct xadMasterBaseP *xadMasterBase; struct StreamPrivate *sp; xadMasterBase = ai->xaip_MasterBase; sp = (struct StreamPrivate *) param->xhp_PrivatePtr; switch(param->xhp_Command) { case XADHC_WRITE: err = xadHookTagAccessA(XADM_PRIV XADAC_WRITE, param->xhp_BufferSize, param->xhp_BufferPtr, XADM_AI(sp->ai), sp->ti); param->xhp_DataPos += param->xhp_BufferSize; break; case XADHC_SEEK: if(((xadSignSize)param->xhp_DataPos + param->xhp_CommandData < 0) || (param->xhp_DataPos + param->xhp_CommandData > ai->xaip_OutSize)) return XADERR_OUTPUT; err = xadHookTagAccessA(XADM XADAC_OUTPUTSEEK, param->xhp_CommandData, 0, XADM_AI(sp->ai), sp->ti); param->xhp_DataPos += param->xhp_CommandData; break; case XADHC_INIT: #ifdef DEBUG DebugOther("OutHookStream: XADHC_INIT"); #endif if((sp = xadAllocVec(XADM sizeof(struct StreamPrivate), XADMEMF_PUBLIC|XADMEMF_CLEAR))) { xadTAGPTR ti, ti2; #ifdef AMIGA struct UtilityBase *UtilityBase = xadMasterBase->xmb_UtilityBase; #endif xadINT32 i; param->xhp_PrivatePtr = sp; for(i = 0; i < 5; ++i) sp->ti[i].ti_Tag = TAG_IGNORE; sp->ti[5].ti_Tag = TAG_DONE; ti = ti2 = ai->xaip_InArcInfo; while((ti2 = NextTagItem(&ti))) { switch(ti2->ti_Tag) { case XAD_ARCHIVEINFO: sp->ai = (struct xadArchiveInfo *)(uintptr_t) ti2->ti_Data; break; case XAD_USESKIPINFO: sp->ti[0].ti_Tag = ti2->ti_Tag; sp->ti[0].ti_Data = ti2->ti_Data; break; case XAD_GETCRC32: sp->ti[1].ti_Tag = ti2->ti_Tag; sp->ti[1].ti_Data = ti2->ti_Data; break; case XAD_GETCRC16: sp->ti[2].ti_Tag = ti2->ti_Tag; sp->ti[2].ti_Data = ti2->ti_Data; break; case XAD_CRC32ID: sp->ti[3].ti_Tag = ti2->ti_Tag; sp->ti[3].ti_Data = ti2->ti_Data; break; case XAD_CRC16ID: sp->ti[4].ti_Tag = ti2->ti_Tag; sp->ti[4].ti_Data = ti2->ti_Data; break; } } for(i = 5; i >= 0 && sp->ti[i].ti_Tag == TAG_IGNORE; --i) /* reduce the number of TAG_IGNORE */ sp->ti[i].ti_Tag = TAG_DONE; if(!sp->ai) err = XADERR_BADPARAMS; } else err = XADERR_NOMEMORY; param->xhp_DataPos = 0; break; case XADHC_FREE: if(param->xhp_PrivatePtr) { xadFreeObjectA(XADM_PRIV param->xhp_PrivatePtr, 0); param->xhp_PrivatePtr = 0; } break; case XADHC_ABORT: break; default: return XADERR_NOTSUPPORTED; } return err; }
ENDFUNC static xadINT32 opendestfile(struct xadArchiveInfoP *ai) { xadUINT32 i, j, flags; xadINT32 ret = 0, doloop = 1; xadSTRPTR n, n2 = 0, name = ai->xaip_OutFileName; struct xadMasterBaseP *xadMasterBase; struct stat statBuf; xadMasterBase = ai->xaip_MasterBase; flags = ai->xaip_ArchiveInfo.xai_Flags; while(!ret && doloop) { if(stat((const char *)name, &statBuf) == -1) break; n = name; if((S_ISREG(statBuf.st_mode) && (flags & XADAIF_OVERWRITE))) break; #ifdef DEBUG DebugOther("InHookFH: ask overwrite/isdir: '%s'", name); #endif j = callprogressFN(ai, S_ISREG(statBuf.st_mode) ? XADPIF_OVERWRITE : XADPIF_ISDIRECTORY, XADPMODE_ASK, &n, ai->xaip_MasterBase); #ifdef DEBUG DebugOther("InHookFH: ask overwrite/isdir result: %ld", j); #endif if(n2) xadFreeObjectA(XADM n2, 0); n2 = 0; if(!(j & XADPIF_OK)) ret = XADERR_BREAK; else if(j & XADPIF_SKIP) ret = XADERR_SKIP; else if(j & XADPIF_RENAME) { if(!n) ret = XADERR_BADPARAMS; else name = n2 = n; } else if((j & XADPIF_OVERWRITE) && S_ISREG(statBuf.st_mode)) { flags |= XADAIF_OVERWRITE; break; } else ret = S_ISREG(statBuf.st_mode) ? XADERR_FILEEXISTS : XADERR_FILEDIR; } if(!ret && ((ai->xaip_OutFileHandle = open((const char *)name, O_WRONLY|O_CREAT, S_IRWXU))) == -1) { xadSTRPTR buf; i = strlen((const char *)name)+1; if((buf = (xadSTRPTR) xadAllocVec(XADM i, XADMEMF_PUBLIC))) { i = 0; while(!ret && name[i]) { for(;name[i] && name[i] != '/'; ++i) buf[i] = name[i]; if(name[i] == '/') { buf[i] = 0; if(stat((const char *)buf, &statBuf) != -1) { if(!(flags & XADAIF_MAKEDIRECTORY)) { if(!((j = callprogress(ai, XADPIF_MAKEDIRECTORY, XADPMODE_ASK, ai->xaip_MasterBase)) & XADPIF_OK)) ret = XADERR_BREAK; else if(j & XADPIF_SKIP) ret = XADERR_SKIP; else if(!(j & XADPIF_MAKEDIRECTORY)) ret = XADERR_MAKEDIR; else flags |= XADAIF_MAKEDIRECTORY; } if(!ret) { #ifndef __MINGW32__ if(mkdir((const char *)buf, S_IRWXU) == -1) ret = XADERR_MAKEDIR; #else if(mkdir((const char *)buf) == -1) ret = XADERR_MAKEDIR; #endif } } buf[i] = name[i]; ++i; } } xadFreeObjectA(XADM buf, 0); } else ret = XADERR_NOMEMORY; if(!ret && ((ai->xaip_OutFileHandle = open((const char *)name, O_WRONLY|O_CREAT, S_IRWXU)) == -1)) ret = XADERR_OPENFILE; } if(n2) xadFreeObjectA(XADM n2, 0); return ret; }