mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-21 18:01:15 +00:00
extraction works
This commit is contained in:
parent
311811bd25
commit
1757030521
3 changed files with 80 additions and 8 deletions
|
@ -22,8 +22,9 @@ main (int argc, char **argv)
|
|||
int c;
|
||||
const char *pack_file = 0;
|
||||
int verbose = 0;
|
||||
int pad = 0;
|
||||
|
||||
while ((c = getopt_long (argc, argv, "cf:tv", long_options, 0)) != -1) {
|
||||
while ((c = getopt_long (argc, argv, "cf:ptvx", long_options, 0)) != -1) {
|
||||
switch (c) {
|
||||
case 'f':
|
||||
pack_file = optarg;
|
||||
|
@ -34,9 +35,15 @@ main (int argc, char **argv)
|
|||
case 'c':
|
||||
mode = mo_create;
|
||||
break;
|
||||
case 'x':
|
||||
mode = mo_extract;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
case 'p':
|
||||
pad = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,15 +53,32 @@ main (int argc, char **argv)
|
|||
}
|
||||
|
||||
switch (mode) {
|
||||
case mo_extract:
|
||||
pack = pack_open (pack_file);
|
||||
if (!pack) {
|
||||
fprintf (stderr, "error opening %s\n", pack_file);
|
||||
return 1;
|
||||
}
|
||||
for (i = 0; i < pack->numfiles; i++) {
|
||||
if (verbose)
|
||||
fprintf (stderr, "%s\n", pack->files[i].name);
|
||||
pack_extract (pack, &pack->files[i]);
|
||||
}
|
||||
pack_close (pack);
|
||||
break;
|
||||
case mo_test:
|
||||
pack = pack_open (pack_file);
|
||||
if (!pack) {
|
||||
fprintf (stderr, "error opening %s\n", pack_file);
|
||||
return 1;
|
||||
}
|
||||
for (i = 0; i < pack->numfiles; i++)
|
||||
printf ("%6d %s\n", pack->files[i].filelen,
|
||||
pack->files[i].name);
|
||||
for (i = 0; i < pack->numfiles; i++) {
|
||||
if (verbose)
|
||||
printf ("%6d %s\n", pack->files[i].filelen,
|
||||
pack->files[i].name);
|
||||
else
|
||||
printf ("%s\n", pack->files[i].name);
|
||||
}
|
||||
pack_close (pack);
|
||||
break;
|
||||
case mo_create:
|
||||
|
@ -63,8 +87,12 @@ main (int argc, char **argv)
|
|||
fprintf (stderr, "error creating %s\n", pack_file);
|
||||
return 1;
|
||||
}
|
||||
while (optind < argc)
|
||||
pack->pad = pad;
|
||||
while (optind < argc) {
|
||||
if (verbose)
|
||||
fprintf (stderr, "%s\n", argv[optind]);
|
||||
pack_add (pack, argv[optind++]);
|
||||
}
|
||||
pack_close (pack);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <QF/qendian.h>
|
||||
|
||||
|
@ -196,7 +201,7 @@ pack_add (pack_t *pack, const char *filename)
|
|||
pf->filelen += bytes;
|
||||
}
|
||||
fclose (file);
|
||||
if (pf->filelen & 3) {
|
||||
if (pack->pad && pf->filelen & 3) {
|
||||
static char buf[4];
|
||||
fwrite (buf, 1, 4 - (pf->filelen & 3), pack->handle);
|
||||
}
|
||||
|
@ -204,11 +209,48 @@ pack_add (pack_t *pack, const char *filename)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
make_parents (const char *_path)
|
||||
{
|
||||
char *path;
|
||||
char *d, *p, t;
|
||||
|
||||
path = (char *) alloca (strlen (_path) + 1);
|
||||
strcpy (path, _path);
|
||||
for (p = path; *p && (d = strchr (p, '/')); p = d + 1) {
|
||||
t = *d;
|
||||
*d = 0;
|
||||
if (mkdir (path, 0777) < 0)
|
||||
if (errno != EEXIST)
|
||||
return -1;
|
||||
*d = t;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pack_extract (pack_t *pack, dpackfile_t *pf)
|
||||
{
|
||||
//const char *name = pf->name;
|
||||
const char *name = pf->name;
|
||||
int count;
|
||||
int len;
|
||||
FILE *file;
|
||||
char buffer[16384];
|
||||
|
||||
//fseek (pack->handle, pf->filepos, SEEK_SET);
|
||||
if (make_parents (name) == -1)
|
||||
return -1;
|
||||
if (!(file = fopen (name, "wb")))
|
||||
return -1;
|
||||
fseek (pack->handle, pf->filepos, SEEK_SET);
|
||||
len = pf->filelen;
|
||||
while (len) {
|
||||
count = len;
|
||||
if (count > sizeof (buffer))
|
||||
count = sizeof (buffer);
|
||||
count = fread (buffer, 1, count, pack->handle);
|
||||
fwrite (buffer, 1, count, file);
|
||||
len -= count;
|
||||
}
|
||||
fclose (file);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ typedef struct pack_s {
|
|||
|
||||
int modified;
|
||||
int old_numfiles;
|
||||
int pad;
|
||||
} pack_t;
|
||||
|
||||
pack_t *pack_new (const char *name);
|
||||
|
@ -23,3 +24,4 @@ pack_t *pack_open (const char *name);
|
|||
void pack_close (pack_t *pack);
|
||||
pack_t *pack_create (const char *name);
|
||||
int pack_add (pack_t *pack, const char *filename);
|
||||
int pack_extract (pack_t *pack, dpackfile_t *pf);
|
||||
|
|
Loading…
Reference in a new issue