From: Nick Bowler Date: Sat, 22 Dec 2007 21:21:26 +0000 (-0500) Subject: Implement stub list operation. X-Git-Url: http://git.draconx.ca/gitweb/liblbx.git/commitdiff_plain/8ecf99dea1442f58a460c7eef60872ce5f5c94f1 Implement stub list operation. --- diff --git a/src/lbx.c b/src/lbx.c index 481123b..7376730 100644 --- a/src/lbx.c +++ b/src/lbx.c @@ -1,14 +1,20 @@ #include #include +#include #include +#include #include "byteorder.h" #include "lbx.h" #define LBX_MAGIC 0x0000fead +int lbx_errno = 0; + struct lbx_state { FILE *f; + long offset; + uint16_t nfiles; uint32_t offsets[]; }; @@ -19,20 +25,24 @@ struct lbx_state *lbx_fopen(FILE *f) uint16_t nfiles, version; uint32_t magic; - if (fread(&nfiles, sizeof nfiles, 1, f) != 1) return NULL; - if (fread(&magic, sizeof magic, 1, f) != 1) return NULL; - if (fread(&version, sizeof version, 1, f) != 1) return NULL; + if (fread(&nfiles, sizeof nfiles, 1, f) != 1) goto readerr; + if (fread(&magic, sizeof magic, 1, f) != 1) goto readerr; + if (fread(&version, sizeof version, 1, f) != 1) goto readerr; nfiles = letohs(nfiles); magic = letohl(magic); version = letohs(version); - if (magic != LBX_MAGIC) + if (magic != LBX_MAGIC) { + lbx_errno = LBX_EMAGIC; return NULL; + } new = malloc(sizeof *new + (nfiles+1)*(sizeof *new->offsets)); - if (!new) + if (!new) { + lbx_errno = -errno; return NULL; + } *new = (struct lbx_state){ .nfiles = nfiles, @@ -40,9 +50,18 @@ struct lbx_state *lbx_fopen(FILE *f) }; if (fread(new->offsets, sizeof *new->offsets, nfiles+1, f) != nfiles+1) - return free(new), NULL; + goto readerr; return new; +readerr: + if (feof(f)) { + lbx_errno = LBX_EEOF; + } else { + lbx_errno = -errno; + } + + free(new); + return NULL; } struct lbx_state *lbx_open(const char *path) @@ -50,14 +69,38 @@ struct lbx_state *lbx_open(const char *path) struct lbx_state *new = NULL; FILE *f; - if ((f = fopen(path, "rb"))) + if ((f = fopen(path, "rb"))) { new = lbx_fopen(f); + } else { + lbx_errno = -errno; + } return new; } +size_t lbx_numfiles(struct lbx_state *lbx) +{ + return lbx->nfiles; +} + void lbx_close(struct lbx_state *lbx) { + if (!lbx) return; + fclose(lbx->f); free(lbx); } + +const char *lbx_strerror(void) +{ + if (lbx_errno < 0) + return strerror(-lbx_errno); + + switch (lbx_errno) { + case LBX_ESUCCESS: return "Success"; + case LBX_EMAGIC: return "Bad magic number"; + case LBX_EEOF: return "Unexpected end-of-file"; + } + + return "Unknown error"; +} diff --git a/src/lbx.h b/src/lbx.h index 4232b9f..563ef4e 100644 --- a/src/lbx.h +++ b/src/lbx.h @@ -1,10 +1,26 @@ #ifndef LBX_H_ #define LBX_H_ +#include + +/* Errors */ +enum { + LBX_ESUCCESS, + LBX_EMAGIC, + LBX_EEOF, +}; +extern int lbx_errno; + +/* Opaque */ typedef struct lbx_state LBX; -LBX *lbx_fopen(FILE *); -LBX *lbx_open(const char *); -void lbx_close(LBX *); +/* File operations */ +LBX *lbx_fopen(FILE *); +LBX *lbx_open(const char *); +void lbx_close(LBX *); +size_t lbx_numfiles(LBX *); + +/* Misc operations */ +const char *lbx_strerror(void); #endif diff --git a/src/lbxtool.c b/src/lbxtool.c index f9a17d1..a8b899a 100644 --- a/src/lbxtool.c +++ b/src/lbxtool.c @@ -7,7 +7,7 @@ static const char *progname; #define errmsg(fmt, ...) (\ - fprintf(stderr, "%s: " fmt ": %m.\n", progname, __VA_ARGS__)\ + fprintf(stderr, "%s: " fmt, progname, __VA_ARGS__)\ ) enum { @@ -16,23 +16,40 @@ enum { MODE_EXTRACT, }; +int list(FILE *f, int verbose) { + LBX *lbx = lbx_fopen(f); + if (!lbx) { + errmsg("failed to open archive: %s.\n", lbx_strerror()); + return EXIT_FAILURE; + } + + if (verbose) { + printf("Files in archive: %zd\n", lbx_numfiles(lbx)); + } + + lbx_close(lbx); +} + int main(int argc, char **argv) { - int mode = MODE_NONE; + int mode = MODE_NONE, verbose = 0; FILE *f = stdin; int opt; - struct option longopts[] = { + static const char *sopts = "lxf:v"; + static const struct option lopts[] = { { "list", 0, NULL, 'l' }, { "extract", 0, NULL, 'x' }, { "file", 1, NULL, 'f' }, + { "verbose", 0, NULL, 'v' }, + { 0 } }; - progname = argv[0]; - while ((opt = getopt_long(argc, argv, "lxf:", longopts, NULL)) != -1) { + progname = "lbxtool"; /* argv[0]; */ + while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) { switch(opt) { case 'l': mode = MODE_LIST; @@ -43,17 +60,25 @@ int main(int argc, char **argv) case 'f': f = fopen(optarg, "rb"); if (!f) { - errmsg("failed to open file", 0, 4); + errmsg("failed to open file %s: %m\n", optarg); return EXIT_FAILURE; } break; + case 'v': + verbose = 1; + break; default: return EXIT_FAILURE; } } - if (mode == MODE_NONE) { - fprintf(stderr, "%s: you must specify a mode.\n", progname); - return EXIT_FAILURE; + switch (mode) { + case MODE_LIST: + return list(f, verbose); + case MODE_EXTRACT: + return EXIT_SUCCESS; } + + fprintf(stderr, "%s: you must specify a mode.\n", progname); + return EXIT_FAILURE; }