Skip to content

Commit 4633501

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/ - @sezero OS/2 fix
1 parent 0cd18b8 commit 4633501

File tree

6 files changed

+407
-1
lines changed

6 files changed

+407
-1
lines changed

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: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#define __PHYSICSFS_INTERNAL__
1212
#include "physfs_internal.h"
13-
13+
#include <time.h>
1414
#if defined(_MSC_VER)
1515
/* this code came from https://stackoverflow.com/a/8712996 */
1616
int __PHYSFS_msvc_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
@@ -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: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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+
21+
memset(zero_block.buffer, 0, sizeof(BLOCKSIZE));
22+
memset(current_block.buffer, 0, sizeof(BLOCKSIZE));
23+
24+
/* read header block until zero-only terminated block */
25+
for(; __PHYSFS_readAll(io, current_block.buffer, BLOCKSIZE); count++)
26+
{
27+
if( memcmp(current_block.buffer, zero_block.buffer, BLOCKSIZE) == 0 )
28+
return true;
29+
30+
/* verify magic */
31+
switch(TAR_magic(&current_block))
32+
{
33+
case POSIX_FORMAT:
34+
TAR_posix_block(io, arc, &current_block, &count);
35+
break;
36+
case OLDGNU_FORMAT:
37+
break;
38+
case GNU_FORMAT:
39+
break;
40+
case V7_FORMAT:
41+
break;
42+
case USTAR_FORMAT:
43+
break;
44+
case STAR_FORMAT:
45+
break;
46+
default:
47+
break;
48+
}
49+
}
50+
51+
return false;
52+
}
53+
54+
static void *TAR_openArchive(PHYSFS_Io *io, const char *name,
55+
int forWriting, int *claimed)
56+
{
57+
void *unpkarc = NULL;
58+
union block first;
59+
enum archive_format format;
60+
61+
assert(io != NULL); /* shouldn't ever happen. */
62+
63+
BAIL_IF(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
64+
65+
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, first.buffer, BLOCKSIZE), NULL);
66+
format = TAR_magic(&first);
67+
io->seek(io, 0);
68+
*claimed = format == DEFAULT_FORMAT ? 0 : 1;
69+
70+
unpkarc = UNPK_openArchive(io, 0, 1);
71+
BAIL_IF_ERRPASS(!unpkarc, NULL);
72+
73+
if (!TAR_loadEntries(io, unpkarc))
74+
{
75+
UNPK_abandonArchive(unpkarc);
76+
return NULL;
77+
} /* if */
78+
79+
80+
return unpkarc;
81+
} /* TAR_openArchive */
82+
83+
84+
const PHYSFS_Archiver __PHYSFS_Archiver_TAR =
85+
{
86+
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
87+
{
88+
"TAR",
89+
"POSIX tar archives / Chasm: the Rift Remastered",
90+
"Jon Daniel <jondaniel879@gmail.com>",
91+
"http://www.gnu.org/software/tar/",
92+
0,
93+
},
94+
TAR_openArchive,
95+
UNPK_enumerate,
96+
UNPK_openRead,
97+
UNPK_openWrite,
98+
UNPK_openAppend,
99+
UNPK_remove,
100+
UNPK_mkdir,
101+
UNPK_stat,
102+
UNPK_closeArchive
103+
};
104+
105+
#endif /* defined PHYSFS_SUPPORTS_TAR */
106+
107+
/* end of physfs_archiver_tar.c ... */
108+

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)