Skip to content

Commit 496a5a4

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 5f4b8be commit 496a5a4

2 files changed

Lines changed: 21 additions & 34 deletions

File tree

src/physfs_archiver_tar.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ static bool TAR_loadEntries(PHYSFS_Io *io, void *arc)
1717
union block zero_block;
1818
union block current_block;
1919
PHYSFS_uint64 count = 0;
20+
bool long_name = false;
2021

2122
memset(zero_block.buffer, 0, sizeof(BLOCKSIZE));
2223
memset(current_block.buffer, 0, sizeof(BLOCKSIZE));
@@ -31,7 +32,7 @@ static bool TAR_loadEntries(PHYSFS_Io *io, void *arc)
3132
switch(TAR_magic(&current_block))
3233
{
3334
case POSIX_FORMAT:
34-
TAR_posix_block(io, arc, &current_block, &count);
35+
TAR_posix_block(io, arc, &current_block, &count, &long_name);
3536
break;
3637
case OLDGNU_FORMAT:
3738
break;

src/physfs_tar.h

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
11
#ifndef _INCLUDE_PHYSFS_TAR_H_
22
#define _INCLUDE_PHYSFS_TAR_H_
33

4-
#include <stdio.h>
5-
#include <stdlib.h>
6-
#include <stdint.h>
74
#include <stdbool.h>
8-
#include <string.h>
9-
#include <ctype.h>
10-
#include <sys/stat.h>
11-
#include <fcntl.h>
12-
#include <time.h>
135

146
#ifndef PATH_MAX
157
#define PATH_MAX 1024
@@ -114,43 +106,37 @@ union block
114106
struct posix_header header;
115107
};
116108

117-
static PHYSFS_uint64 TAR_decodeOctal(char* data, size_t size) {
118-
unsigned char* currentPtr = (unsigned char*) data + size;
109+
static PHYSFS_uint64 TAR_decodeOctal(char *data, size_t size) {
110+
unsigned char *currentPtr = (unsigned char*) data + size;
119111
PHYSFS_uint64 sum = 0;
120112
PHYSFS_uint64 currentMultiplier = 1;
121-
unsigned char* checkPtr = currentPtr;
113+
unsigned char *checkPtr = currentPtr;
122114

123-
for (; checkPtr >= (unsigned char*) data; checkPtr--) {
115+
for (; checkPtr >= (unsigned char *) data; checkPtr--) {
124116
if ((*checkPtr) == 0 || (*checkPtr) == ' ') {
125117
currentPtr = checkPtr - 1;
126118
}
127119
}
128-
for (; currentPtr >= (unsigned char*) data; currentPtr--) {
120+
for (; currentPtr >= (unsigned char *) data; currentPtr--) {
129121
sum += (*currentPtr - 48) * currentMultiplier;
130122
currentMultiplier *= 8;
131123
}
132124
return sum;
133125
}
134126

135-
static bool TAR_encodeOctal(char* data, size_t size, PHYSFS_uint64 i) {
136-
if( snprintf(data, size, "%llo", i) < 0 )
137-
return false;
138-
return true;
139-
}
140-
141-
static int TAR_magic(union block* block) {
127+
static enum archive_format TAR_magic(union block *block) {
142128
if(strcmp(block->header.magic, OLDGNU_MAGIC) == 0 && strncmp(block->header.version, TVERSION, 2) == 0)
143-
return (int)OLDGNU_FORMAT;
129+
return OLDGNU_FORMAT;
144130
if(strncmp(block->header.magic, TMAGIC, TMAGLEN - 1) == 0)
145-
return (int)POSIX_FORMAT;
146-
return (int)DEFAULT_FORMAT;
131+
return POSIX_FORMAT;
132+
return DEFAULT_FORMAT;
147133
}
148134

149-
static size_t TAR_fileSize(union block* block) {
135+
static PHYSFS_uint64 TAR_fileSize(union block *block) {
150136
return TAR_decodeOctal(block->header.size, sizeof(block->header.size));
151137
}
152138

153-
static bool TAR_checksum(union block* block) {
139+
static bool TAR_checksum(union block *block) {
154140
PHYSFS_sint64 unsigned_sum = 0;
155141
PHYSFS_sint64 signed_sum = 0;
156142
PHYSFS_uint64 reference_chksum = 0;
@@ -161,23 +147,23 @@ static bool TAR_checksum(union block* block) {
161147
memset(block->header.chksum, ' ', 8);
162148

163149
for(; i < BLOCKSIZE; i++) {
164-
unsigned_sum += ((unsigned char*) block->buffer)[i];
165-
signed_sum += ((signed char*) block->buffer)[i];
150+
unsigned_sum += ((unsigned char *) block->buffer)[i];
151+
signed_sum += ((signed char *) block->buffer)[i];
166152
}
167153
memcpy(block->header.chksum, orig_chksum, 8);
168154
reference_chksum = TAR_decodeOctal(orig_chksum, 12);
169155
return (reference_chksum == unsigned_sum || reference_chksum == signed_sum);
170156
}
171157

172-
time_t TAR_time(union block* block)
158+
static PHYSFS_uint64 TAR_time(union block *block)
173159
{
174160
return TAR_decodeOctal(block->header.mtime, 12);
175161
}
176162

177-
bool TAR_posix_block(PHYSFS_Io* io, void* arc, union block* block, PHYSFS_uint64* count)
163+
static bool TAR_posix_block(PHYSFS_Io *io, void *arc, union block *block, PHYSFS_uint64 *count, bool *long_name)
178164
{
179165
static bool long_name = false;
180-
const PHYSFS_Allocator* allocator = PHYSFS_getAllocator();
166+
const PHYSFS_Allocator *allocator = PHYSFS_getAllocator();
181167
char name[PATH_MAX] = { 0 };
182168
PHYSFS_sint64 time = 0;
183169
PHYSFS_uint64 size = 0;
@@ -204,10 +190,10 @@ bool TAR_posix_block(PHYSFS_Io* io, void* arc, union block* block, PHYSFS_uint64
204190
/* add file type entry */
205191
if (block->header.typeflag == REGTYPE || block->header.typeflag == 0) {
206192
/* support long file names */
207-
if(long_name) {
193+
if(*long_name) {
208194
strcpy(&name[0], block->header.name);
209195
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, block->buffer, BLOCKSIZE), 0);
210-
long_name = false;
196+
*long_name = false;
211197
(*count)++;
212198
}
213199
size = TAR_fileSize(block);
@@ -228,7 +214,7 @@ bool TAR_posix_block(PHYSFS_Io* io, void* arc, union block* block, PHYSFS_uint64
228214
/* long name mode */
229215
else if(block->header.typeflag == GNUTYPE_LONGNAME)
230216
{
231-
long_name = true;
217+
*long_name = true;
232218
}
233219
else
234220
{

0 commit comments

Comments
 (0)