Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POSIX GNU tar read support #64

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ set(PHYSFS_SRCS
src/physfs_archiver_qpak.c
src/physfs_archiver_wad.c
src/physfs_archiver_csm.c
src/physfs_archiver_tar.c
src/physfs_archiver_zip.c
src/physfs_archiver_slb.c
src/physfs_archiver_iso9660.c
Expand Down Expand Up @@ -130,6 +131,11 @@ if(NOT PHYSFS_ARCHIVE_CSM)
add_definitions(-DPHYSFS_SUPPORTS_CSM=0)
endif()

option(PHYSFS_ARCHIVE_TAR "Enable POSIX TAR / Chasm: The Rift [Demo] Remastered csm.bin support" TRUE)
if(NOT PHYSFS_ARCHIVE_TAR)
add_definitions(-DPHYSFS_SUPPORTS_TAR=0)
endif()

option(PHYSFS_ARCHIVE_HOG "Enable Descent I/II HOG support" TRUE)
if(NOT PHYSFS_ARCHIVE_HOG)
add_definitions(-DPHYSFS_SUPPORTS_HOG=0)
Expand Down Expand Up @@ -325,6 +331,7 @@ message_bool_option("7zip support" PHYSFS_ARCHIVE_7Z)
message_bool_option("GRP support" PHYSFS_ARCHIVE_GRP)
message_bool_option("WAD support" PHYSFS_ARCHIVE_WAD)
message_bool_option("CSM support" PHYSFS_ARCHIVE_CSM)
message_bool_option("TAR support" PHYSFS_ARCHIVE_TAR)
message_bool_option("HOG support" PHYSFS_ARCHIVE_HOG)
message_bool_option("MVL support" PHYSFS_ARCHIVE_MVL)
message_bool_option("QPAK support" PHYSFS_ARCHIVE_QPAK)
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.os2
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ SRCS = physfs.c &
physfs_archiver_slb.c &
physfs_archiver_iso9660.c &
physfs_archiver_csm.c &
physfs_archiver_tar.c &
physfs_archiver_vdf.c


Expand Down
3 changes: 3 additions & 0 deletions src/physfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,9 @@ static int initStaticArchivers(void)
#if PHYSFS_SUPPORTS_CSM
REGISTER_STATIC_ARCHIVER(CSM);
#endif
#if PHYSFS_SUPPORTS_TAR
REGISTER_STATIC_ARCHIVER(TAR);
#endif
#if PHYSFS_SUPPORTS_SLB
REGISTER_STATIC_ARCHIVER(SLB);
#endif
Expand Down
109 changes: 109 additions & 0 deletions src/physfs_archiver_tar.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* tar support routines for PhysicsFS.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* based on code by Uli Köhler: https://techoverflow.net/2013/03/29/reading-tar-files-in-c/
*/

#define __PHYSICSFS_INTERNAL__
#include "physfs_internal.h"

#if PHYSFS_SUPPORTS_TAR
#include "physfs_tar.h"

static bool TAR_loadEntries(PHYSFS_Io *io, void *arc)
{
union block zero_block;
union block current_block;
PHYSFS_uint64 count = 0;
bool long_name = false;

memset(zero_block.buffer, 0, sizeof(BLOCKSIZE));
memset(current_block.buffer, 0, sizeof(BLOCKSIZE));

/* read header block until zero-only terminated block */
for(; __PHYSFS_readAll(io, current_block.buffer, BLOCKSIZE); count++)
{
if( memcmp(current_block.buffer, zero_block.buffer, BLOCKSIZE) == 0 )
return true;

/* verify magic */
switch(TAR_magic(&current_block))
{
case POSIX_FORMAT:
TAR_posix_block(io, arc, &current_block, &count, &long_name);
break;
case OLDGNU_FORMAT:
break;
case GNU_FORMAT:
break;
case V7_FORMAT:
break;
case USTAR_FORMAT:
break;
case STAR_FORMAT:
break;
default:
break;
}
}

return false;
}

static void *TAR_openArchive(PHYSFS_Io *io, const char *name,
int forWriting, int *claimed)
{
void *unpkarc = NULL;
union block first;
enum archive_format format;

assert(io != NULL); /* shouldn't ever happen. */

BAIL_IF(forWriting, PHYSFS_ERR_READ_ONLY, NULL);

BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, first.buffer, BLOCKSIZE), NULL);
format = TAR_magic(&first);
io->seek(io, 0);
*claimed = format == DEFAULT_FORMAT ? 0 : 1;

unpkarc = UNPK_openArchive(io, 0, 1);
BAIL_IF_ERRPASS(!unpkarc, NULL);

if (!TAR_loadEntries(io, unpkarc))
{
UNPK_abandonArchive(unpkarc);
return NULL;
} /* if */


return unpkarc;
} /* TAR_openArchive */


const PHYSFS_Archiver __PHYSFS_Archiver_TAR =
{
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
{
"TAR",
"POSIX tar archives / Chasm: the Rift Remastered",
"Jon Daniel <jondaniel879@gmail.com>",
"http://www.gnu.org/software/tar/",
0,
},
TAR_openArchive,
UNPK_enumerate,
UNPK_openRead,
UNPK_openWrite,
UNPK_openAppend,
UNPK_remove,
UNPK_mkdir,
UNPK_stat,
UNPK_closeArchive
};

#endif /* defined PHYSFS_SUPPORTS_TAR */

/* end of physfs_archiver_tar.c ... */

4 changes: 4 additions & 0 deletions src/physfs_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ extern const PHYSFS_Archiver __PHYSFS_Archiver_HOG;
extern const PHYSFS_Archiver __PHYSFS_Archiver_MVL;
extern const PHYSFS_Archiver __PHYSFS_Archiver_WAD;
extern const PHYSFS_Archiver __PHYSFS_Archiver_CSM;
extern const PHYSFS_Archiver __PHYSFS_Archiver_TAR;
extern const PHYSFS_Archiver __PHYSFS_Archiver_SLB;
extern const PHYSFS_Archiver __PHYSFS_Archiver_ISO9660;
extern const PHYSFS_Archiver __PHYSFS_Archiver_VDF;
Expand Down Expand Up @@ -204,6 +205,9 @@ void __PHYSFS_smallFree(void *ptr);
#ifndef PHYSFS_SUPPORTS_CSM
#define PHYSFS_SUPPORTS_CSM PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_TAR
#define PHYSFS_SUPPORTS_TAR PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_QPAK
#define PHYSFS_SUPPORTS_QPAK PHYSFS_SUPPORTS_DEFAULT
#endif
Expand Down