|
|
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
-
- #include "physfs.h"
-
-
- static int failure = 0;
-
- static void modTimeToStr(PHYSFS_sint64 modtime, char *modstr, size_t strsize)
- {
- const char *str = "unknown modtime";
- if (modtime != -1)
- {
- time_t t = (time_t) modtime;
- str = ctime(&t);
- } /* if */
-
- strncpy(modstr, str, strsize);
- modstr[strsize-1] = '\0';
- strsize = strlen(modstr);
- while ((modstr[strsize-1] == '\n') || (modstr[strsize-1] == '\r'))
- modstr[--strsize] = '\0';
- } /* modTimeToStr */
-
-
- static void fail(const char *what, const char *why)
- {
- if (why == NULL)
- why = PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode());
- fprintf(stderr, "%s failed: %s\n", what, why);
- failure = 1;
- } /* fail */
-
-
- static void dumpFile(const char *fname)
- {
- const int origfailure = failure;
- PHYSFS_File *out = NULL;
- PHYSFS_File *in = NULL;
-
- failure = 0;
-
- if ((in = PHYSFS_openRead(fname)) == NULL)
- fail("\nPHYSFS_openRead", NULL);
- else if ((out = PHYSFS_openWrite(fname)) == NULL)
- fail("\nPHYSFS_openWrite", NULL);
- else
- {
- char modstr[64];
- PHYSFS_sint64 size = PHYSFS_fileLength(in);
-
- printf("(");
- if (size == -1)
- printf("?");
- else
- printf("%lld", (long long) size);
- printf(" bytes");
-
- modTimeToStr(PHYSFS_getLastModTime(fname), modstr, sizeof (modstr));
- printf(", %s)\n", modstr);
-
- while ( (!failure) && (!PHYSFS_eof(in)) )
- {
- static char buf[64 * 1024];
- PHYSFS_sint64 br = PHYSFS_read(in, buf, 1, sizeof (buf));
- if (br == -1)
- fail("PHYSFS_read", NULL);
- else
- {
- PHYSFS_sint64 bw = PHYSFS_write(out, buf, 1, br);
- if (bw != br)
- fail("PHYSFS_write", NULL);
- else
- size -= bw;
- } /* else */
- } /* while */
-
- if ((!failure) && (size != 0))
- fail("PHYSFS_eof", "BUG! eof != PHYSFS_fileLength bytes!");
- } /* else */
-
- if (in != NULL)
- PHYSFS_close(in);
-
- if (out != NULL)
- {
- if (!PHYSFS_close(out))
- fail("PHYSFS_close", NULL);
- } /* if */
-
- if (failure)
- PHYSFS_delete(fname);
- else
- failure = origfailure;
- } /* dumpFile */
-
-
- static void unpackCallback(void *_depth, const char *origdir, const char *str)
- {
- int depth = *((int *) _depth);
- const int len = strlen(origdir) + strlen(str) + 2;
- char *fname = (char *) malloc(len);
- if (fname == NULL)
- fail("malloc", "Out of memory!");
- else
- {
- if (strcmp(origdir, "/") == 0)
- origdir = "";
-
- snprintf(fname, len, "%s/%s", origdir, str);
-
- printf("%s ", fname);
- if (PHYSFS_isDirectory(fname))
- {
- depth++;
- printf("(directory)\n");
- if (!PHYSFS_mkdir(fname))
- fail("PHYSFS_mkdir", NULL);
- else
- PHYSFS_enumerateFilesCallback(fname, unpackCallback, &depth);
- } /* if */
-
- else if (PHYSFS_isSymbolicLink(fname))
- {
- printf("(symlink)\n");
- /* !!! FIXME: ? if (!symlink(fname, */
- } /* else if */
-
- else /* ...file. */
- {
- dumpFile(fname);
- } /* else */
-
- free(fname);
- } /* else */
- } /* unpackCallback */
-
-
- int main(int argc, char **argv)
- {
- int zero = 0;
-
- if (argc != 3)
- {
- fprintf(stderr, "USAGE: %s <archive> <unpackDirectory>\n", argv[0]);
- return 1;
- } /* if */
-
- if (!PHYSFS_init(argv[0]))
- {
- fprintf(stderr, "PHYSFS_init() failed: %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
- return 2;
- } /* if */
-
- if (!PHYSFS_setWriteDir(argv[2]))
- {
- fprintf(stderr, "PHYSFS_setWriteDir('%s') failed: %s\n",
- argv[2], PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
- return 3;
- } /* if */
-
- if (!PHYSFS_mount(argv[1], NULL, 1))
- {
- fprintf(stderr, "PHYSFS_mount('%s') failed: %s\n",
- argv[1], PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
- return 4;
- } /* if */
-
- PHYSFS_permitSymbolicLinks(1);
- PHYSFS_enumerateFilesCallback("/", unpackCallback, &zero);
- PHYSFS_deinit();
- if (failure)
- return 5;
-
- return 0;
- } /* main */
-
- /* end of physfsunpack.c ... */
-
|