/* * Copyright (c) 2003-2007 Hypertriton, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include int verbose = 1; int iflag = 0; char *outdir = "."; static void printusage(void) { fprintf(stderr, "Usage: denuncomp [-qi] [-o outdir] archive.den\n"); } int main(int argc, char *argv[]) { extern char *optarg; extern int optind; AG_Den *den; int c, i; AG_InitError(); while ((c = getopt(argc, argv, "?qio:")) != -1) { switch (c) { case 'q': verbose = 0; break; case 'i': iflag = 1; break; case 'o': outdir = optarg; break; case '?': default: printusage(); goto fail; } } argc -= optind; argv += optind; if (argc < 1) { fprintf(stderr, "No den(5) file was given.\n"); printusage(); goto fail; } den = AG_DenOpen(argv[0], AG_DEN_READ); if (den == NULL) { fprintf(stderr, "opening %s: %s\n", argv[0], AG_GetError()); goto fail; } if (verbose) { printf("Extracting from `%s':\n", den->name); printf("\tHint: `%s'\n", den->hint); printf("\tAuthor: `%s'\n", den->author); printf("\tCopyright: `%s'\n", den->copyright); if (den->descr[0] != '\0') printf("\tDescr: `%s'\n", den->descr); if (den->keywords[0] != '\0') printf("\tKeywords: `%s'\n", den->keywords); } if (iflag) { goto out; } if (chdir(outdir) == -1) { fprintf(stderr, "%s: %s\n", outdir, strerror(errno)); goto fail; } for (i = 0; i < den->nmembers; i++) { char *buf; AG_DenMember *memb = &den->members[i]; FILE *f; size_t i, len, rv; for (i = 0, len = strlen(memb->name); i < len; i++) { if (memb->name[i] == '/') memb->name[i] = '_'; } printf("- %24s [%4s] (0x%04x+0x%04x)\n", memb->name, memb->lang, (unsigned)memb->offs, (unsigned)memb->size); if ((f = fopen(memb->name, "wb")) == NULL) { fprintf(stderr, "%s: %s\n", memb->name, strerror(errno)); goto fail; } buf = AG_Malloc(memb->size); AG_Seek(den->buf, memb->offs, AG_SEEK_SET); AG_Read(den->buf, buf, 1, memb->size); if (den->buf->rdLast > 0) { if (fwrite(buf, rv, 1, f) < 1) { fprintf(stderr, "%s: write error\n", memb->name); goto fail; } } fclose(f); AG_Free(buf); } out: AG_DenClose(den); AG_DestroyError(); return (0); fail: AG_DestroyError(); return (1); }