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;
        }
    }
}
Exemple #2
0
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;
}
Exemple #4
0
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;
	}
}
Exemple #5
0
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)) {
Exemple #7
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;
}
Exemple #8
0
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;
}
Exemple #9
0
value ml_crc32_init (value unit) 
{
	CAMLparam1 (unit);
	InitCrcTable();
	CAMLreturn (unit);	
}