Ejemplo n.º 1
0
/**
 * Load first file from a .ZIP archive into memory, and return the number
 * of bytes loaded.
 */
Uint8 *ZIP_ReadFirstFile(const char *pszFileName, long *pImageSize, const char * const ppszExts[])
{
	unzFile uf=NULL;
	Uint8 *pBuffer;
	char *pszZipPath;
	unz_file_info file_info;

	*pImageSize = 0;

	/* Open the ZIP file */
	uf = unzOpen(pszFileName);
	if (uf == NULL)
	{
		Log_Printf(LOG_ERROR, "Cannot open '%s'\n", pszFileName);
		return NULL;
	}

	/* Locate the first file in the ZIP archive */
	pszZipPath = ZIP_FirstFile(pszFileName, ppszExts);
	if (pszZipPath == NULL)
	{
		Log_Printf(LOG_ERROR, "Failed to locate first file in '%s'\n", pszFileName);
		unzClose(uf);
		return NULL;
	}

	if (unzLocateFile(uf, pszZipPath, 0) != UNZ_OK)
	{
		Log_Printf(LOG_ERROR, "Error: Can not locate '%s' in the archive!\n", pszZipPath);
		free(pszZipPath);
		return NULL;
	}

	/* Get file information (file size!) */
	if (unzGetCurrentFileInfo(uf, &file_info, pszZipPath, ZIP_PATH_MAX, NULL, 0, NULL, 0) != UNZ_OK)
	{
		Log_Printf(LOG_ERROR, "Error with zipfile in unzGetCurrentFileInfo.\n");
		free(pszZipPath);
		return NULL;
	}

	/* Extract to buffer */
	pBuffer = ZIP_ExtractFile(uf, pszZipPath, file_info.uncompressed_size);

	/* And close the file */
	unzCloseCurrentFile(uf);
	unzClose(uf);

	free(pszZipPath);

	if (pBuffer)
		*pImageSize = file_info.uncompressed_size;

	return pBuffer;
}
Ejemplo n.º 2
0
OSErr
InflateFiles(void *hZip, void *hFind, short tgtVRefNum, long tgtDirID)
{
	OSErr		err = noErr;
	Boolean		bFoundAll = false;
	PRInt32		rv = 0;
	char		filename[255] = "\0", *lastslash, *leaf, macfilename[255] = "\0";
	Handle		fullPathH = 0;
	short 		fullPathLen = 0;
	Ptr			fullPathStr = 0;
	StringPtr	extractedFile = 0;
	FSSpec		extractedFSp, outFSp;
	
	
	while (!bFoundAll)
	{
		/* find next item if one exists */
		rv = ZIP_FindNext( hFind, filename, 255 );
		if (rv==ZIP_ERR_FNF)
		{
			bFoundAll = true;
			break;
		}
		else if (rv!=ZIP_OK)
			return rv;	
		
		/* ignore if item is a dir entry */	
		lastslash = strrchr(filename, '/');
		if (lastslash == (&filename[0] + strlen(filename) - 1)) /* dir entry encountered */
			continue;

		/* grab leaf filename only */
		if (lastslash == 0)
			leaf = filename;
		else
			leaf = lastslash + 1;
		
		/* obtain and NULL terminate the full path string */
		err = GetFullPath(tgtVRefNum, tgtDirID, "\p", &fullPathLen, &fullPathH); /* get dirpath */
		if (err!=noErr)
			return err;

        strcpy(macfilename, filename);        
        SLASHES_2_COLONS(macfilename);
		HLock(fullPathH);
		fullPathStr = NewPtrClear(fullPathLen + strlen(macfilename) + 1);
		strncat(fullPathStr, *fullPathH, fullPathLen);
		strcat(fullPathStr, macfilename);	/* tack on filename to dirpath */
		*(fullPathStr+fullPathLen+strlen(macfilename)) = '\0';
		
		/* create directories if file is nested in new subdirs */
		WhackDirectories(fullPathStr);
		err = DirCreateRecursive(fullPathStr);			
		
		if (err!=noErr)
		{
			if (fullPathStr) 
				DisposePtr((Ptr)fullPathStr);
			if (fullPathH)
			{
				HUnlock(fullPathH);				
				DisposeHandle(fullPathH);
			}
			continue; /* XXX do we want to do this? */
		}
		
		/* extract the file to its full path destination */
		rv = ZIP_ExtractFile( hZip, filename, fullPathStr );
		
		HUnlock(fullPathH);
		if (fullPathH)
			DisposeHandle(fullPathH);
		if (rv!=ZIP_OK)
		{
			if (fullPathStr)
				DisposePtr((Ptr)fullPathStr);			
			return rv;
		}
		
		/* AppleSingle decode if need be */
		extractedFile = CToPascal(fullPathStr); 
		if (extractedFile)
		{
			err = FSMakeFSSpec(0, 0, extractedFile, &extractedFSp);
			err = FSMakeFSSpec(0, 0, extractedFile, &outFSp);
			err = AppleSingleDecode(&extractedFSp, &outFSp);
			
			/* delete original file if named different than final file */
			if (!pstrcmp(extractedFSp.name, outFSp.name))
			{
				err = FSpDelete(&extractedFSp);
			}
		}
			
		/* record for cleanup later */
		FSMakeFSSpec(outFSp.vRefNum, outFSp.parID, outFSp.name, &coreFileList[currCoreFile]);
		currCoreFile++;
		
		/* progress bar update (roll the barber poll) */
		if (gWPtr)
			IdleControls(gWPtr);	
			
		if (extractedFile)
			DisposePtr((Ptr)extractedFile);
		if (fullPathStr)
			DisposePtr(fullPathStr);
	}
        
	return err;
}
Ejemplo n.º 3
0
/**
 * Load disk image from a .ZIP archive into memory, set  the number
 * of bytes loaded into pImageSize and return the data or NULL on error.
 */
Uint8 *ZIP_ReadDisk(const char *pszFileName, const char *pszZipPath, long *pImageSize)
{
	uLong ImageSize=0;
	unzFile uf=NULL;
	Uint8 *buf;
	char *path;
	int nDiskType = -1;
	Uint8 *pDiskBuffer = NULL;

	*pImageSize = 0;

	uf = unzOpen(pszFileName);
	if (uf == NULL)
	{
		Log_Printf(LOG_ERROR, "Cannot open %s\n", pszFileName);
		return NULL;
	}

	if (pszZipPath == NULL || pszZipPath[0] == 0)
	{
		path = ZIP_FirstFile(pszFileName, pszDiskNameExts);
		if (path == NULL)
		{
			Log_Printf(LOG_ERROR, "Cannot open %s\n", pszFileName);
			unzClose(uf);
			return NULL;
		}
	}
	else
	{
		path = malloc(ZIP_PATH_MAX);
		if (path == NULL)
		{
			perror("ZIP_ReadDisk");
			unzClose(uf);
			return NULL;
		}
		strncpy(path, pszZipPath, ZIP_PATH_MAX);
		path[ZIP_PATH_MAX-1] = '\0';
	}

	ImageSize = ZIP_CheckImageFile(uf, path, ZIP_PATH_MAX, &nDiskType);
	if (ImageSize <= 0)
	{
		unzClose(uf);
		free(path);
		return NULL;
	}

	/* extract to buf */
	buf = ZIP_ExtractFile(uf, path, ImageSize);

	unzCloseCurrentFile(uf);
	unzClose(uf);
	free(path);
	path = NULL;

	if (buf == NULL)
	{
		return NULL;  /* failed extraction, return error */
	}

	switch(nDiskType) {
	case ZIP_FILE_MSA:
		/* uncompress the MSA file */
//		pDiskBuffer = MSA_UnCompress(buf, (long *)&ImageSize);
		free(buf);
		buf = NULL;
		break;
	case ZIP_FILE_DIM:
		/* Skip DIM header */
		ImageSize -= 32;
		memmove(buf, buf+32, ImageSize);
		/* ...and passthrough */
	case ZIP_FILE_ST:
		/* ST image => return buffer directly */
		pDiskBuffer = buf;
		break;
	}
	
	if (pDiskBuffer)
	{
		*pImageSize = ImageSize;
	}
	return pDiskBuffer;
}
Ejemplo n.º 4
0
Archivo: zip.c Proyecto: r-type/hatari
/**
 * Load disk image from a .ZIP archive into memory, set  the number
 * of bytes loaded into pImageSize and return the data or NULL on error.
 */
Uint8 *ZIP_ReadDisk(int Drive, const char *pszFileName, const char *pszZipPath, long *pImageSize, int *pImageType)
{
	uLong ImageSize=0;
	unzFile uf=NULL;
	Uint8 *buf;
	char *path;
	Uint8 *pDiskBuffer = NULL;

	*pImageSize = 0;
	*pImageType = FLOPPY_IMAGE_TYPE_NONE;

	uf = unzOpen(pszFileName);
	if (uf == NULL)
	{
		Log_Printf(LOG_ERROR, "Cannot open %s\n", pszFileName);
		return NULL;
	}

	if (pszZipPath == NULL || pszZipPath[0] == 0)
	{
		path = ZIP_FirstFile(pszFileName, pszDiskNameExts);
		if (path == NULL)
		{
			Log_Printf(LOG_ERROR, "Cannot open %s\n", pszFileName);
			unzClose(uf);
			return NULL;
		}
	}
	else
	{
		path = malloc(ZIP_PATH_MAX);
		if (path == NULL)
		{
			perror("ZIP_ReadDisk");
			unzClose(uf);
			return NULL;
		}
		strncpy(path, pszZipPath, ZIP_PATH_MAX);
		path[ZIP_PATH_MAX-1] = '\0';
	}

	ImageSize = ZIP_CheckImageFile(uf, path, ZIP_PATH_MAX, pImageType);
	if (ImageSize <= 0)
	{
		unzClose(uf);
		free(path);
		return NULL;
	}

	/* extract to buf */
	buf = ZIP_ExtractFile(uf, path, ImageSize);

	unzCloseCurrentFile(uf);
	unzClose(uf);
	free(path);
	path = NULL;

	if (buf == NULL)
	{
		return NULL;  /* failed extraction, return error */
	}

	switch(*pImageType) {
	case FLOPPY_IMAGE_TYPE_IPF:
#ifndef HAVE_CAPSIMAGE
		Log_AlertDlg(LOG_ERROR, "This version of Hatari was not built with IPF support, this disk image can't be handled.");
		return NULL;
#else
		/* return buffer */
		pDiskBuffer = buf;
		break;
#endif
	case FLOPPY_IMAGE_TYPE_STX:
		/* return buffer */
		pDiskBuffer = buf;
		break;
	case FLOPPY_IMAGE_TYPE_MSA:
		/* uncompress the MSA file */
		pDiskBuffer = MSA_UnCompress(buf, (long *)&ImageSize, ImageSize);
		free(buf);
		buf = NULL;
		break;
	case FLOPPY_IMAGE_TYPE_DIM:
		/* Skip DIM header */
		ImageSize -= 32;
		memmove(buf, buf+32, ImageSize);
		/* return buffer */
		pDiskBuffer = buf;
		break;
	case FLOPPY_IMAGE_TYPE_ST:
		/* ST image => return buffer directly */
		pDiskBuffer = buf;
		break;
	}
	
	if (pDiskBuffer)
	{
		*pImageSize = ImageSize;
	}
	return pDiskBuffer;
}