quakeforge/tools/pak/pakfile.c

92 lines
1.8 KiB
C
Raw Normal View History

2001-01-11 00:56:31 +00:00
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
/*
Structs for pack files on disk
*/
2001-01-18 00:59:42 +00:00
#define PAK_PATH_LENGTH 56
2001-01-11 00:56:31 +00:00
typedef struct {
char name[PAK_PATH_LENGTH];
int filepos, filelen;
} dpackfile_t;
typedef struct {
char id[4];
int dirofs;
int dirlen;
} dpackheader_t;
#define MAX_FILES_IN_PACK 2048
typedef struct pack_s {
char filename[MAX_PATH];
FILE *handle;
int numfiles;
2001-01-17 22:47:08 +00:00
int files_size;
dpackfile_t *files;
2001-01-11 00:56:31 +00:00
} pack_t;
pack_t *
new_pack (const char *name)
{
pack_t *pack = calloc (sizeof (*pack), 1);
if (!pack)
return 0;
strncpy (pack->filename, name, sizeof (pack->filename));
pack->filename[sizeof (pack->filename) - 1] = 0;
return pack;
}
void
del_pack (pack_t *pack)
{
if (pack->files)
free (pack->files);
if (pack->handle)
fclose (pack->handle);
free (pack);
}
pack_t *
open_pack (const char *name)
{
dpackheader_t header;
pack_t *pack = new_pack (name);
if (!pack)
return 0;
pack->handle = fopen (name, "rb");
if (!pack->handle) {
goto error;
}
if (fread (&header, sizeof (header), 1, pack->handle) != sizeof (header)) {
fprintf (stderr, "%s: not a pack file", name);
goto error;
}
if (strncmp (header.id, "PACK", 4)) {
fprintf (stderr, "%s: not a pack file", name);
goto error;
}
pack->numfiles = header.dirlen / sizeof (dpackfile_t);
2001-01-17 22:47:08 +00:00
pack->files_size = pack->numfiles;
2001-01-11 00:56:31 +00:00
if (pack->numfiles > MAX_FILES_IN_PACK) {
fprintf (stderr, "%s: too many files in pack: %d", name, pack->numfiles);
goto error;
}
pack->files = malloc (numpackfiles * sizeof (packfile_t));
2001-01-18 00:59:42 +00:00
if (!pack->files) {
2001-01-17 22:47:08 +00:00
fprintf (stderr, "out of memory\n");
goto error;
}
fseek (pack->handle, header.diroffs, SEEK_POS);
fread (pack->files, pack->numfiles, sizeof (pack->files[0]), pack->handle);
2001-01-11 00:56:31 +00:00
error:
del_pack (pack);
return 0;
}