]> git.draconx.ca Git - liblbx.git/commitdiff
Implement stub list operation.
authorNick Bowler <draconx@gmail.com>
Sat, 22 Dec 2007 21:21:26 +0000 (16:21 -0500)
committerNick Bowler <draconx@gmail.com>
Sat, 22 Dec 2007 21:21:26 +0000 (16:21 -0500)
src/lbx.c
src/lbx.h
src/lbxtool.c

index 481123b5f774490ad4d517404ee9393bd7150081..73767305c4e3fb54690a3d09166612a5300ef4c8 100644 (file)
--- a/src/lbx.c
+++ b/src/lbx.c
@@ -1,14 +1,20 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <stdint.h>
+#include <errno.h>
 
 #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";
+}
index 4232b9f87c0d818b97e6ff21e0fb7c553d33246a..563ef4eb81e55b30195a05559cdaaad4c5d60773 100644 (file)
--- a/src/lbx.h
+++ b/src/lbx.h
@@ -1,10 +1,26 @@
 #ifndef LBX_H_
 #define LBX_H_
 
+#include <stddef.h>
+
+/* 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
index f9a17d10e9371e7e7aadbf6f011187d6731102de..a8b899ac80a10d4d0c7317b6d122e371b8d62d12 100644 (file)
@@ -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;
 }