Skip to content

Commit 0f54b25

Browse files
author
Jon Daniel
committed
POSIX GNU tar read support
- supporting tared csm.bin of Chasm: The Rift Remastered at https://store.steampowered.com/app/2061230/Chasm_The_Rift/ - Thanks to @sezero for OS/2 and Windows fixes
1 parent 0cd18b8 commit 0f54b25

6 files changed

Lines changed: 352 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ set(PHYSFS_SRCS
9292
src/physfs_archiver_qpak.c
9393
src/physfs_archiver_wad.c
9494
src/physfs_archiver_csm.c
95+
src/physfs_archiver_tar.c
9596
src/physfs_archiver_zip.c
9697
src/physfs_archiver_slb.c
9798
src/physfs_archiver_iso9660.c
@@ -130,6 +131,11 @@ if(NOT PHYSFS_ARCHIVE_CSM)
130131
add_definitions(-DPHYSFS_SUPPORTS_CSM=0)
131132
endif()
132133

134+
option(PHYSFS_ARCHIVE_TAR "Enable POSIX TAR / Chasm: The Rift [Demo] Remastered csm.bin support" TRUE)
135+
if(NOT PHYSFS_ARCHIVE_TAR)
136+
add_definitions(-DPHYSFS_SUPPORTS_TAR=0)
137+
endif()
138+
133139
option(PHYSFS_ARCHIVE_HOG "Enable Descent I/II HOG support" TRUE)
134140
if(NOT PHYSFS_ARCHIVE_HOG)
135141
add_definitions(-DPHYSFS_SUPPORTS_HOG=0)
@@ -325,6 +331,7 @@ message_bool_option("7zip support" PHYSFS_ARCHIVE_7Z)
325331
message_bool_option("GRP support" PHYSFS_ARCHIVE_GRP)
326332
message_bool_option("WAD support" PHYSFS_ARCHIVE_WAD)
327333
message_bool_option("CSM support" PHYSFS_ARCHIVE_CSM)
334+
message_bool_option("TAR support" PHYSFS_ARCHIVE_TAR)
328335
message_bool_option("HOG support" PHYSFS_ARCHIVE_HOG)
329336
message_bool_option("MVL support" PHYSFS_ARCHIVE_MVL)
330337
message_bool_option("QPAK support" PHYSFS_ARCHIVE_QPAK)

src/Makefile.os2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ SRCS = physfs.c &
2626
physfs_archiver_slb.c &
2727
physfs_archiver_iso9660.c &
2828
physfs_archiver_csm.c &
29+
physfs_archiver_tar.c &
2930
physfs_archiver_vdf.c
3031

3132

src/physfs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,6 +1191,9 @@ static int initStaticArchivers(void)
11911191
#if PHYSFS_SUPPORTS_CSM
11921192
REGISTER_STATIC_ARCHIVER(CSM);
11931193
#endif
1194+
#if PHYSFS_SUPPORTS_TAR
1195+
REGISTER_STATIC_ARCHIVER(TAR);
1196+
#endif
11941197
#if PHYSFS_SUPPORTS_SLB
11951198
REGISTER_STATIC_ARCHIVER(SLB);
11961199
#endif

src/physfs_archiver_tar.c

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* tar support routines for PhysicsFS.
3+
*
4+
* Please see the file LICENSE.txt in the source's root directory.
5+
*
6+
* based on code by Uli Köhler: https://techoverflow.net/2013/03/29/reading-tar-files-in-c/
7+
*/
8+
9+
#define __PHYSICSFS_INTERNAL__
10+
#include "physfs_internal.h"
11+
12+
#if PHYSFS_SUPPORTS_TAR
13+
#include "physfs_tar.h"
14+
15+
static bool TAR_loadEntries(PHYSFS_Io *io, void *arc)
16+
{
17+
union block zero_block;
18+
union block current_block;
19+
PHYSFS_uint64 count = 0;
20+
bool long_name = false;
21+
22+
memset(zero_block.buffer, 0, sizeof(BLOCKSIZE));
23+
memset(current_block.buffer, 0, sizeof(BLOCKSIZE));
24+
25+
/* read header block until zero-only terminated block */
26+
for(; __PHYSFS_readAll(io, current_block.buffer, BLOCKSIZE); count++)
27+
{
28+
if( memcmp(current_block.buffer, zero_block.buffer, BLOCKSIZE) == 0 )
29+
return true;
30+
31+
/* verify magic */
32+
switch(TAR_magic(&current_block))
33+
{
34+
case POSIX_FORMAT:
35+
TAR_posix_block(io, arc, &current_block, &count, &long_name);
36+
break;
37+
case OLDGNU_FORMAT:
38+
break;
39+
case GNU_FORMAT:
40+
break;
41+
case V7_FORMAT:
42+
break;
43+
case USTAR_FORMAT:
44+
break;
45+
case STAR_FORMAT:
46+
break;
47+
default:
48+
break;
49+
}
50+
}
51+
52+
return false;
53+
}
54+
55+
static void *TAR_openArchive(PHYSFS_Io *io, const char *name,
56+
int forWriting, int *claimed)
57+
{
58+
void *unpkarc = NULL;
59+
union block first;
60+
enum archive_format format;
61+
62+
assert(io != NULL); /* shouldn't ever happen. */
63+
64+
BAIL_IF(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
65+
66+
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, first.buffer, BLOCKSIZE), NULL);
67+
format = TAR_magic(&first);
68+
io->seek(io, 0);
69+
*claimed = format == DEFAULT_FORMAT ? 0 : 1;
70+
71+
unpkarc = UNPK_openArchive(io, 0, 1);
72+
BAIL_IF_ERRPASS(!unpkarc, NULL);
73+
74+
if (!TAR_loadEntries(io, unpkarc))
75+
{
76+
UNPK_abandonArchive(unpkarc);
77+
return NULL;
78+
} /* if */
79+
80+
81+
return unpkarc;
82+
} /* TAR_openArchive */
83+
84+
85+
const PHYSFS_Archiver __PHYSFS_Archiver_TAR =
86+
{
87+
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
88+
{
89+
"TAR",
90+
"POSIX tar archives / Chasm: the Rift Remastered",
91+
"Jon Daniel <jondaniel879@gmail.com>",
92+
"http://www.gnu.org/software/tar/",
93+
0,
94+
},
95+
TAR_openArchive,
96+
UNPK_enumerate,
97+
UNPK_openRead,
98+
UNPK_openWrite,
99+
UNPK_openAppend,
100+
UNPK_remove,
101+
UNPK_mkdir,
102+
UNPK_stat,
103+
UNPK_closeArchive
104+
};
105+
106+
#endif /* defined PHYSFS_SUPPORTS_TAR */
107+
108+
/* end of physfs_archiver_tar.c ... */
109+

src/physfs_internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ extern const PHYSFS_Archiver __PHYSFS_Archiver_HOG;
8989
extern const PHYSFS_Archiver __PHYSFS_Archiver_MVL;
9090
extern const PHYSFS_Archiver __PHYSFS_Archiver_WAD;
9191
extern const PHYSFS_Archiver __PHYSFS_Archiver_CSM;
92+
extern const PHYSFS_Archiver __PHYSFS_Archiver_TAR;
9293
extern const PHYSFS_Archiver __PHYSFS_Archiver_SLB;
9394
extern const PHYSFS_Archiver __PHYSFS_Archiver_ISO9660;
9495
extern const PHYSFS_Archiver __PHYSFS_Archiver_VDF;
@@ -204,6 +205,9 @@ void __PHYSFS_smallFree(void *ptr);
204205
#ifndef PHYSFS_SUPPORTS_CSM
205206
#define PHYSFS_SUPPORTS_CSM PHYSFS_SUPPORTS_DEFAULT
206207
#endif
208+
#ifndef PHYSFS_SUPPORTS_TAR
209+
#define PHYSFS_SUPPORTS_TAR PHYSFS_SUPPORTS_DEFAULT
210+
#endif
207211
#ifndef PHYSFS_SUPPORTS_QPAK
208212
#define PHYSFS_SUPPORTS_QPAK PHYSFS_SUPPORTS_DEFAULT
209213
#endif

0 commit comments

Comments
 (0)