CArchive7Zip::CArchive7Zip(const string& name) : CArchiveBuffered(name), isOpen(false), curSearchHandle(1) { SZ_RESULT res; archiveStream.File = fopen(name.c_str(), "rb"); if (archiveStream.File == 0) return; archiveStream.InStream.Read = SzFileReadImp; archiveStream.InStream.Seek = SzFileSeekImp; allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; InitCrcTable(); SzArDbExInit(&db); res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp); if (res != SZ_OK) return; isOpen = true; // Get contents of archive and store name->int mapping for (int i = 0; i < db.Database.NumFiles; ++i) { CFileItem* fi = db.Database.Files + i; if (fi->Size > 0) { string name = fi->Name; //SetSlashesForwardToBack(name); FileData fd; fd.origName = name; fd.fp = i; fd.size = fi->Size; transform(name.begin(), name.end(), name.begin(), (int (*)(int))tolower); fileData[name] = fd; } } }
int main(int numargs, char *args[]) { CFileInStream archiveStream; CArchiveDatabaseEx db; SZ_RESULT res; ISzAlloc allocImp; ISzAlloc allocTempImp; printf("\n7z ANSI-C Decoder 4.43 Copyright (c) 1999-2006 Igor Pavlov 2006-06-04\n"); if (numargs == 1) { printf( "\nUsage: 7zDec <command> <archive_name>\n\n" "<Commands>\n" " e: Extract files from archive\n" " l: List contents of archive\n" " t: Test integrity of archive\n"); return 0; } if (numargs < 3) { PrintError("incorrect command"); return 1; } archiveStream.File = fopen(args[2], "rb"); if (archiveStream.File == 0) { PrintError("can not open input file"); return 1; } archiveStream.InStream.Read = SzFileReadImp; archiveStream.InStream.Seek = SzFileSeekImp; allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; InitCrcTable(); SzArDbExInit(&db); res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp); if (res == SZ_OK) { char *command = args[1]; int listCommand = 0; int testCommand = 0; int extractCommand = 0; if (strcmp(command, "l") == 0) listCommand = 1; if (strcmp(command, "t") == 0) testCommand = 1; else if (strcmp(command, "e") == 0) extractCommand = 1; if (listCommand) { UInt32 i; for (i = 0; i < db.Database.NumFiles; i++) { CFileItem *f = db.Database.Files + i; printf("%10d %s\n", (int)f->Size, f->Name); } } else if (testCommand || extractCommand) { UInt32 i; /* if you need cache, use these 3 variables. if you use external function, you can make these variable as static. */ UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ printf("\n"); for (i = 0; i < db.Database.NumFiles; i++) { size_t offset; size_t outSizeProcessed; CFileItem *f = db.Database.Files + i; if (f->IsDirectory) printf("Directory "); else printf(testCommand ? "Testing ": "Extracting"); printf(" %s", f->Name); if (f->IsDirectory) { printf("\n"); continue; } res = SzExtract(&archiveStream.InStream, &db, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; if (!testCommand) { FILE *outputHandle; size_t processedSize; char *fileName = f->Name; size_t nameLen = strlen(f->Name); for (; nameLen > 0; nameLen--) if (f->Name[nameLen - 1] == '/') { fileName = f->Name + nameLen; break; } outputHandle = fopen(fileName, "wb+"); if (outputHandle == 0) { PrintError("can not open output file"); res = SZE_FAIL; break; } processedSize = fwrite(outBuffer + offset, 1, outSizeProcessed, outputHandle); if (processedSize != outSizeProcessed) { PrintError("can not write output file"); res = SZE_FAIL; break; } if (fclose(outputHandle)) { PrintError("can not close output file"); res = SZE_FAIL; break; } } printf("\n"); } allocImp.Free(outBuffer); } else { PrintError("incorrect command"); res = SZE_FAIL; } } SzArDbExFree(&db, allocImp.Free); fclose(archiveStream.File); if (res == SZ_OK) { printf("\nEverything is Ok\n"); return 0; } if (res == SZE_OUTOFMEMORY) PrintError("can not allocate memory"); else printf("\nERROR #%d\n", res); return 1; }
int SzParse(char * filepath) { if(!filepath) return 0; int device; if(!FindDevice(browser.dir, &device) || !GetFileSize(browser.selIndex)) return 0; int nbfiles = 0; // save the length/offset of this file unsigned int filelen = browserList[browser.selIndex].length; // setup archive stream SzArchiveStream.offset = 0; SzArchiveStream.len = filelen; SzArchiveStream.pos = 0; // open file file = fopen (filepath, "rb"); if(!file) return 0; // set szMethod to current chosen load device szMethod = device; // set handler functions for reading data from SD/USB/SMB/DVD SzArchiveStream.InStream.Read = SzFileReadImp; SzArchiveStream.InStream.Seek = SzFileSeekImp; // set default 7Zip SDK handlers for allocation and freeing memory SzAllocImp.Alloc = SzAlloc; SzAllocImp.Free = SzFree; SzAllocTempImp.Alloc = SzAllocTemp; SzAllocTempImp.Free = SzFreeTemp; // prepare CRC and 7Zip database structures InitCrcTable(); SzArDbExInit(&SzDb); // open the archive SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp, &SzAllocTempImp); if (SzRes != SZ_OK) { SzDisplayError(SzRes); // free memory used by the 7z SDK SzClose(); } else // archive opened successfully { if(SzDb.Database.NumFiles > 0) { // Parses the 7z into a full file listing HaltParseThread(); // halt parsing ResetBrowser(); // reset browser // add '..' folder in case the user wants exit the 7z AddBrowserEntry(); sprintf(browserList[0].displayname, "Up One Level"); browserList[0].isdir = 1; browserList[0].length = filelen; browserList[0].icon = ICON_FOLDER; // get contents and parse them into file list structure unsigned int SzI, SzJ; SzJ = 1; for (SzI = 0; SzI < SzDb.Database.NumFiles; SzI++) { SzF = SzDb.Database.Files + SzI; // skip directories if (SzF->IsDirectory) continue; if(!AddBrowserEntry()) { ResetBrowser(); ErrorPrompt("Out of memory: too many files!"); SzClose(); SzJ = 0; break; } // parse information about this file to the file list structure snprintf(browserList[SzJ].filename, MAXJOLIET, "%s", SzF->Name); StripExt(browserList[SzJ].displayname, browserList[SzJ].filename); browserList[SzJ].length = SzF->Size; // filesize browserList[SzJ].isdir = 0; // only files will be displayed (-> no flags) browserList[SzJ].filenum = SzI; // the extraction function identifies the file with this number SzJ++; } nbfiles = SzJ; } else { SzClose(); } } CancelAction(); // close file fclose(file); return nbfiles; }
int SzExtractContent(void* ctx, char* archive, char* filename, void** pbuf) { SzContext* archiveStream = (SzContext*)ctx; FILE* fp = 0; SZ_RESULT res; if (!archiveStream->archive || strcmp(archive, archiveStream->archive)) { fp = fopen(archive, "rb"); if (!fp) return -1; } if (archiveStream->File) { if (!archive || fp) { archiveStream->allocImp.Free(archiveStream->outBuffer); SzArDbExFree(&archiveStream->db, archiveStream->allocImp.Free); fclose(archiveStream->File); archiveStream->File = 0; archiveStream->outBuffer = 0; /* it must be 0 before first call for each new archive. */ archiveStream->outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ if (archiveStream->archive) { free(archiveStream->archive); archiveStream->archive = 0; } } } if (!archive) return -1; if (!archiveStream->File) { archiveStream->File = fp; archiveStream->InStream.Read = SzFileReadImp; archiveStream->InStream.Seek = SzFileSeekImp; archiveStream->allocImp.Alloc = SzAlloc; archiveStream->allocImp.Free = SzFree; archiveStream->allocTempImp.Alloc = SzAllocTemp; archiveStream->allocTempImp.Free = SzFreeTemp; InitCrcTable(); SzArDbExInit(&archiveStream->db); res = SzArchiveOpen(&archiveStream->InStream, &archiveStream->db, &archiveStream->allocImp, &archiveStream->allocTempImp); if (res != SZ_OK) { SzArDbExFree(&archiveStream->db, archiveStream->allocImp.Free); fclose(archiveStream->File); archiveStream->File = 0; return -1; } archiveStream->archive = _strdup(archive); } if (filename) { UInt32 i; /* if you need cache, use these 3 variables. if you use external function, you can make these variable as static. */ UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */ for (i = 0; i < archiveStream->db.Database.NumFiles; i++) { size_t offset; size_t outSizeProcessed; CFileItem *f = archiveStream->db.Database.Files + i; if (f->IsDirectory) { // is directory continue; } if (strcmp(f->Name, filename)) { // not matched continue; } res = SzExtract(&archiveStream->InStream, &archiveStream->db, i, &blockIndex, &archiveStream->outBuffer, &archiveStream->outBufferSize, &offset, &outSizeProcessed, &archiveStream->allocImp, &archiveStream->allocTempImp); if (res != SZ_OK) return -1; if (pbuf) *pbuf = (void*)(archiveStream->outBuffer + offset); return (int)outSizeProcessed; } return -1; } else { return archiveStream->db.Database.NumFiles; } }
int SzParse(char * filepath, int method) { int nbfiles = 0; // save the offset and the length of this file inside the archive stream structure SzArchiveStream.offset = filelist[selection].offset; SzArchiveStream.len = filelist[selection].length; SzArchiveStream.pos = 0; // open file switch (method) { case METHOD_SD: case METHOD_USB: fatfile = fopen (filepath, "rb"); if(!fatfile) return 0; break; case METHOD_SMB: smbfile = OpenSMBFile(filepath); if(!smbfile) return 0; break; } // set szMethod to current chosen load method szMethod = method; // set handler functions for reading data from FAT/SMB/DVD SzArchiveStream.InStream.Read = SzFileReadImp; SzArchiveStream.InStream.Seek = SzFileSeekImp; // set default 7Zip SDK handlers for allocation and freeing memory SzAllocImp.Alloc = SzAlloc; SzAllocImp.Free = SzFree; SzAllocTempImp.Alloc = SzAllocTemp; SzAllocTempImp.Free = SzFreeTemp; // prepare CRC and 7Zip database structures InitCrcTable(); SzArDbExInit(&SzDb); // open the archive SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp, &SzAllocTempImp); if (SzRes != SZ_OK) { SzDisplayError(SzRes); // free memory used by the 7z SDK SzClose(); } else // archive opened successfully { if(SzDb.Database.NumFiles > 0) { // Parses the 7z into a full file listing // erase all previous entries memset(&filelist, 0, sizeof(FILEENTRIES) * MAXFILES); // add '..' folder in case the user wants exit the 7z strncpy(filelist[0].displayname, "..", 2); filelist[0].flags = 1; filelist[0].offset = dvddir; filelist[0].length = dvddirlength; // get contents and parse them into file list structure unsigned int SzI, SzJ; SzJ = 1; for (SzI = 0; SzI < SzDb.Database.NumFiles; SzI++) { SzF = SzDb.Database.Files + SzI; // skip directories if (SzF->IsDirectory) continue; // do not exceed MAXFILES to avoid possible buffer overflows if (SzJ == (MAXFILES - 1)) break; // parse information about this file to the dvd file list structure strncpy(filelist[SzJ].filename, SzF->Name, MAXJOLIET); // copy joliet name (useless...) filelist[SzJ].filename[MAXJOLIET] = 0; // terminate string strncpy(filelist[SzJ].displayname, SzF->Name, MAXDISPLAY+1); // crop name for display filelist[SzJ].length = SzF->Size; // filesize filelist[SzJ].offset = SzI; // the extraction function identifies the file with this number filelist[SzJ].flags = 0; // only files will be displayed (-> no flags) SzJ++; } // update maxfiles and select the first entry offset = selection = 0; nbfiles = SzJ; } else { SzArDbExFree(&SzDb, SzAllocImp.Free); } } // close file switch (method) { case METHOD_SD: case METHOD_USB: fclose(fatfile); break; case METHOD_SMB: SMB_CloseFile (smbfile); break; } return nbfiles; }
void CArchiveScanner::Scan(const string& curPath, bool checksum) { InitCrcTable(); isDirty = true; const int flags = (FileSystem::INCLUDE_DIRS | FileSystem::RECURSE); std::vector<std::string> found = filesystem.FindFiles(curPath, "*", flags); for (std::vector<std::string>::iterator it = found.begin(); it != found.end(); ++it) { string fullName = *it; // Strip const char lastFullChar = fullName[fullName.size() - 1]; if ((lastFullChar == '/') || (lastFullChar == '\\')) { fullName = fullName.substr(0, fullName.size() - 1); } const string fn = filesystem.GetFilename(fullName); const string fpath = filesystem.GetDirectory(fullName); const string lcfn = StringToLower(fn); const string lcfpath = StringToLower(fpath); // Exclude archivefiles found inside directory archives (.sdd) if (lcfpath.find(".sdd") != string::npos) { continue; } // Exclude archivefiles found inside hidden directories if ((lcfpath.find("/hidden/") != string::npos) || (lcfpath.find("\\hidden\\") != string::npos)) { continue; } // Is this an archive we should look into? if (CArchiveFactory::IsArchive(fullName)) { struct stat info; stat(fullName.c_str(), &info); // Determine whether to rely on the cached info or not bool cached = false; map<string, ArchiveInfo>::iterator aii = archiveInfo.find(lcfn); if (aii != archiveInfo.end()) { // This archive may have been obsoleted, do not process it if so if (aii->second.replaced.length() > 0) continue; /* For truely correct updating of .sdd archives, this code should be enabled. Unfortunately it has as side effect that all files in all .sdd's always need to be stat()'ed, which really slows down program startup. An update can be forced anyway by removing ArchiveCacheV*.txt or renaming the archive. */ /*if (S_ISDIR(info.st_mode)) { struct stat info2; std::vector<std::string> sddfiles = filesystem.FindFiles(fpath, "*", FileSystem::RECURSE | FileSystem::INCLUDE_DIRS); for (std::vector<std::string>::iterator sddit = found.begin(); sddit != found.end(); ++sddit) { stat(sddit->c_str(), &info2); if (info.st_mtime < info2.st_mtime) { info.st_mtime = info2.st_mtime; } } }*/ if ((unsigned)info.st_mtime == aii->second.modified && fpath == aii->second.path) { cached = true; aii->second.updated = true; } // If we are here, we could have invalid info in the cache // Force a reread if it's a directory archive, as st_mtime only // reflects changes to the directory itself, not the contents. if (!cached) { archiveInfo.erase(aii); } } // Time to parse the info we are interested in if (!cached) { //printf("scanning archive: %s\n", fullName.c_str()); CArchiveBase* ar = CArchiveFactory::OpenArchive(fullName); if (ar) { int cur; string name; int size; ArchiveInfo ai; cur = ar->FindFiles(0, &name, &size); while (cur != 0) { //printf("found %s %d\n", name.c_str(), size); string ext = StringToLower(name.substr(name.find_last_of('.') + 1)); // only accept new format maps if (ext == "smf" || ext == "sm3") { MapData md; if (name.find_last_of('\\') == string::npos && name.find_last_of('/') == string::npos) { md.name = name; md.virtualPath = "/"; } else { if (name.find_last_of('\\') == string::npos) { md.name = name.substr(name.find_last_of('/') + 1); md.virtualPath = name.substr(0, name.find_last_of('/') + 1); // include the backslash } else { md.name = name.substr(name.find_last_of('\\') + 1); md.virtualPath = name.substr(0, name.find_last_of('\\') + 1); // include the backslash } //md.name = md.name.substr(0, md.name.find_last_of('.')); } ai.mapData.push_back(md); } if (name == "modinfo.tdf") { int fh = ar->OpenFile(name); if (fh) { int fsize = ar->FileSize(fh); char* buf = SAFE_NEW char[fsize]; ar->ReadFile(fh, buf, fsize); ar->CloseFile(fh); try { TdfParser p( buf, fsize ); ai.modData = GetModData(&p, "mod"); } catch (const TdfParser::parse_error&) { // Silently ignore mods with parse errors } delete [] buf; } } cur = ar->FindFiles(cur, &name, &size); } ai.path = fpath; ai.modified = info.st_mtime; ai.origName = fn; ai.updated = true; delete ar; // Optionally calculate a checksum for the file // To prevent reading all files in all directory (.sdd) archives every time this function // is called, directory archive checksums are calculated on the fly. if (checksum) { ai.checksum = GetCRC(fullName); } else { ai.checksum = 0; } archiveInfo[lcfn] = ai; } } else { // If cached is true, aii will point to the archive if ((checksum) && (aii->second.checksum == 0)) {
int _7zArchive( STRPTR filename, int mode ) { CFileInStream archiveStream; CArchiveDatabaseEx db; SZ_RESULT res; ISzAlloc allocImp; ISzAlloc allocTempImp; archiveStream.File = Open( filename, MODE_OLDFILE); if (!archiveStream.File) { PrintError("Unable to open archive!"); goto done; } archiveStream.InStream.zRead = SzFileReadImp; archiveStream.InStream.zSeek = SzFileSeekImp; allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; InitCrcTable(); SzArDbExInit(&db); res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp); if (res == SZ_OK) { if( G->CliUsage ) { ShowProgramInfo ( ); Printf("\n%s archive %s\n", (long)((mode == 1) ? "Listing":((mode == 2) ? "Testing":"Extracting")), (long) FilePart( filename )); } if ( mode == 1 ) // LIST mode { UInt32 i; if( G->CliUsage ) { Printf("\n%7s%9s%14s%7s%8s\n",(long)"Date",(long)"Time",(long)"Size",(long)"CRC",(long)"Name"); for( i = 0; i < 60 ; i++ ) PutStr("-"); PutStr("\n"); } for (i = 0; i < db.Database.NumFiles; i++) { CFileItem *f = db.Database.Files + i; if( G->CliUsage ) { UBYTE date[20]; ItemTime( f, date, sizeof(date), FALSE ); Printf("%s%11ld %08lx %s\n", (long)date, (long)f->Size, f->IsFileCRCDefined ? f->FileCRC:0, (long)f->Name); } else NListInsert((APTR) f ); } } else { UInt32 i; // if you need cache, use these 3 variables. // if you use external function, you can make these variable as static. UInt32 blockIndex = 0xFFFFFFFF; // it can have any value before first call (if outBuffer = 0) Byte *outBuffer = 0; // it must be 0 before first call for each new archive. size_t outBufferSize = 0; // it can have any value before first call (if outBuffer = 0) if( G->CliUsage ) PutStr("\n"); for (i = 0; i < db.Database.NumFiles; i++) { size_t offset; size_t outSizeProcessed; CFileItem *f = db.Database.Files + i; if( G->CliUsage ) { #if 0 if (f->IsDirectory) PutStr("Directory"); else Printf("%12s",(long)((mode == 2) ? "Testing":"Extracting")); Printf(" %s", (long)f->Name); #else if (!f->IsDirectory) Printf("%12s %s",(long)((mode == 2) ? "Testing":"Extracting"), (long)f->Name); #endif } else { STATIC UBYTE msg[256]; SNPrintf( msg, sizeof(msg)-1, "%12s %s", (mode == 2) ? "Testing":"Extracting", f->Name ); GaugeUpdate( msg, i*100/db.Database.NumFiles ); } if (f->IsDirectory) { // if( G->CliUsage ) // PutStr("\n"); continue; } res = SzExtract(&archiveStream.InStream, &db, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp); if (res != SZ_OK) break; if ( mode == 3 ) // EXTRACT mode { BPTR outputHandle; UInt32 processedSize; MakeDir( f->Name ); // creates ALL Directories pointing to this file outputHandle = Open( f->Name, MODE_NEWFILE ); if (outputHandle == 0) { PrintError("Unable to open output file!"); res = SZE_FAIL; break; } processedSize = Write(outputHandle, outBuffer + offset, outSizeProcessed); if (processedSize != outSizeProcessed) { PrintError("Cannot write to output file!"); res = SZE_FAIL; break; } Close(outputHandle); SetFileTimeToFile( f ); } if( G->CliUsage ) PutStr("\n"); } allocImp.Free(outBuffer); } } SzArDbExFree(&db, allocImp.Free); Close(archiveStream.File); if (res == SZ_OK) { if( G->CliUsage ) Printf("\n%s\n", (long)"Everything is Ok"); else GaugeUpdate("Everything is Ok", 0 ); return 0; } #if 0 if (res == SZE_OUTOFMEMORY) PrintError("can not allocate memory"); else if( G->CliUsage ) Printf("\nERROR #%ld\n", res); #else PrintError(SzErrorString( res )); #endif if( ! G->CliUsage ) GaugeUpdate("error %ld procesing archive", res ); done: return 1; }
int SzParse(char * filepath, int method) { if(!filepath) return 0; int nbfiles = 0; // save the length/offset of this file unsigned int filelen = browserList[browser.selIndex].length; u64 fileoff = browserList[browser.selIndex].offset; // setup archive stream SzArchiveStream.offset = 0; SzArchiveStream.len = filelen; SzArchiveStream.pos = 0; // open file switch (method) { case METHOD_SD: case METHOD_USB: case METHOD_SMB: file = fopen (filepath, "rb"); if(!file) return 0; break; case METHOD_DVD: SwitchDVDFolder(filepath); break; } // set szMethod to current chosen load method szMethod = method; // set handler functions for reading data from SD/USB/SMB/DVD SzArchiveStream.InStream.Read = SzFileReadImp; SzArchiveStream.InStream.Seek = SzFileSeekImp; // set default 7Zip SDK handlers for allocation and freeing memory SzAllocImp.Alloc = SzAlloc; SzAllocImp.Free = SzFree; SzAllocTempImp.Alloc = SzAllocTemp; SzAllocTempImp.Free = SzFreeTemp; // prepare CRC and 7Zip database structures InitCrcTable(); SzArDbExInit(&SzDb); // open the archive SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp, &SzAllocTempImp); if (SzRes != SZ_OK) { SzDisplayError(SzRes); // free memory used by the 7z SDK SzClose(); } else // archive opened successfully { if(SzDb.Database.NumFiles > 0) { // Parses the 7z into a full file listing // reset browser ResetBrowser(); // add '..' folder in case the user wants exit the 7z strncpy(browserList[0].displayname, "..", 2); browserList[0].isdir = 1; browserList[0].offset = fileoff; browserList[0].length = filelen; // get contents and parse them into file list structure unsigned int SzI, SzJ; SzJ = 1; for (SzI = 0; SzI < SzDb.Database.NumFiles; SzI++) { SzF = SzDb.Database.Files + SzI; // skip directories if (SzF->IsDirectory) continue; BROWSERENTRY * newBrowserList = (BROWSERENTRY *)realloc(browserList, (SzJ+1) * sizeof(BROWSERENTRY)); if(!newBrowserList) // failed to allocate required memory { ResetBrowser(); WaitPrompt("Out of memory: too many files!"); nbfiles = 0; break; } else { browserList = newBrowserList; } memset(&(browserList[SzJ]), 0, sizeof(BROWSERENTRY)); // clear the new entry // parse information about this file to the dvd file list structure strncpy(browserList[SzJ].filename, SzF->Name, MAXJOLIET); // copy joliet name (useless...) strncpy(browserList[SzJ].displayname, SzF->Name, MAXDISPLAY); // crop name for display browserList[SzJ].length = SzF->Size; // filesize browserList[SzJ].offset = SzI; // the extraction function identifies the file with this number browserList[SzJ].isdir = 0; // only files will be displayed (-> no flags) SzJ++; } nbfiles = SzJ; } else { SzArDbExFree(&SzDb, SzAllocImp.Free); } } // close file switch (method) { case METHOD_SD: case METHOD_USB: case METHOD_SMB: fclose(file); break; } return nbfiles; }
value ml_crc32_init (value unit) { CAMLparam1 (unit); InitCrcTable(); CAMLreturn (unit); }