/* 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; }
XADIOFUNCMODE struct xadInOut *xadIOAlloc(xadUINT32 flags, struct xadArchiveInfo *ai, struct xadMasterBase *xadMasterBase) { xadUINT32 size = sizeof(struct xadInOut); struct xadInOut *io; #ifdef DEBUG DebugClient(ai, "xadIOAlloc Flags %lx", flags); #endif if(flags & XADIOF_ALLOCINBUFFER) size += XIDBUFSIZE; if(flags & XADIOF_ALLOCOUTBUFFER) size += XIDBUFSIZE; if((io = (struct xadInOut *) xadAllocVec(XADM size, XADMEMF_CLEAR|XADMEMF_PUBLIC))) { xadSTRPTR b; b = (xadSTRPTR) (io+1); io->xio_Flags = flags; io->xio_PutFunc = xadIOPutFunc; io->xio_GetFunc = xadIOGetFunc; io->xio_ArchiveInfo = ai; io->xio_xadMasterBase = xadMasterBase; if(flags & XADIOF_ALLOCINBUFFER) { io->xio_InBuffer = (xadUINT8 *)b; b += XIDBUFSIZE; io->xio_InBufferSize = io->xio_InBufferPos = XIDBUFSIZE; } if(flags & XADIOF_ALLOCOUTBUFFER) { io->xio_OutBuffer = (xadUINT8 *)b; io->xio_OutBufferSize = XIDBUFSIZE; } } return io; }
ASM(LONG) sz_GetInfo(REG(a0, struct xadArchiveInfo *ai), REG(a6, struct xadMasterBase *xadMasterBase)) #endif { #ifdef __amigaos4__ IExec = (struct ExecIFace *)(*(struct ExecBase **)4)->MainInterface; newlibbase = OpenLibrary("newlib.library", 52); if(newlibbase) INewlib = GetInterface(newlibbase, "main", 1, NULL); #elif defined(__AROS__) if(!(aroscbase = OpenLibrary("arosc.library", 41))) return(XADERR_RESOURCE); #else SysBase = *(struct ExecBase **)4; #endif ai->xai_PrivateClient = xadAllocVec(sizeof(struct xad7zprivate),MEMF_PRIVATE | MEMF_CLEAR); struct xad7zprivate *xad7z = ai->xai_PrivateClient; struct xadFileInfo *fi; long err=XADERR_OK; long res=SZ_OK; size_t namelen; UBYTE *namebuf; // was UWORD CFileXadInStream *archiveStream = &xad7z->archiveStream; CSzArEx *db = &xad7z->db; /* 7z archive database structure */ ISzAlloc allocImp; /* memory functions for main pool */ ISzAlloc allocTempImp; /* memory functions for temporary pool */ CLookToRead *lookStream = &xad7z->lookStream; allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; archiveStream->ai = ai; #ifdef __amigaos4__ archiveStream->IxadMaster = IxadMaster; #else archiveStream->xadMasterBase = xadMasterBase; #endif archiveStream->InStream.Read = SzFileReadImp; archiveStream->InStream.Seek = SzFileSeekImp; if(namebuf = AllocVec(1024, MEMF_PRIVATE)) { LookToRead_CreateVTable(lookStream, False); lookStream->realStream = (ISeekInStream *)&archiveStream->InStream; LookToRead_Init(lookStream); xad7z->blockIndex = 0xfffffff; xad7z->outBuffer = 0; xad7z->outBufferSize = 0; CrcGenerateTable(); SzArEx_Init(db); res = SzArEx_Open(db, &lookStream->s, &allocImp, &allocTempImp); if(res == SZ_OK) { UInt32 i; for (i = 0; i < db->db.NumFiles; i++) { fi = (struct xadFileInfo *) xadAllocObjectA(XADOBJ_FILEINFO, NULL); if (!fi) return(XADERR_NOMEMORY); CSzFileItem *f = db->db.Files + i; fi->xfi_DataPos = 0; //ai->xai_InPos; // i fi->xfi_Size = f->Size; namelen = SzArEx_GetFileNameUtf16(db, i, namebuf); // & if (!(fi->xfi_FileName = xadConvertName(CHARSET_HOST, #if defined(__AROS__) && (AROS_BIG_ENDIAN == 0) XAD_CHARACTERSET, CHARSET_UNICODE_UCS2_LITTLEENDIAN, #else XAD_CHARACTERSET, CHARSET_UNICODE_UCS2_BIGENDIAN, #endif XAD_STRINGSIZE, namelen, XAD_CSTRING, namebuf, // no * TAG_DONE))) return(XADERR_NOMEMORY); xadConvertDates(XAD_DATEAMIGA,ConvertFileTime(&f->MTime), XAD_GETDATEXADDATE,&fi->xfi_Date, TAG_DONE); fi->xfi_CrunchSize = 0; //(long) (db->Database.PackSizes[i] << 32); //fi->xfi_Size; fi->xfi_Flags = 0; if(f->IsDir) { fi->xfi_Flags |= XADFIF_DIRECTORY; } if ((err = xadAddFileEntryA(fi, ai, NULL))) return(XADERR_NOMEMORY); } } FreeVec(namebuf); } return(sztoxaderr(res)); }
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; }