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; }