]> git.draconx.ca Git - liblbx.git/blob - src/lbxtool.c
Initial implementation of list and extract operations.
[liblbx.git] / src / lbxtool.c
1 #define _GNU_SOURCE
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <getopt.h>
6
7 #include "lbx.h"
8
9 static const char *progname;
10 #define errmsg(fmt, ...) (\
11         fprintf(stderr, "%s: " fmt, progname, __VA_ARGS__)\
12 )
13
14 enum {
15         MODE_NONE,
16         MODE_LIST,
17         MODE_EXTRACT,
18 };
19
20 int list(FILE *f, const char *name, int verbose) {
21         LBX *lbx;
22         size_t nfiles;
23         unsigned int i;
24
25         lbx = lbx_fopen(f, name);
26         if (!lbx) {
27                 errmsg("failed to open archive: %s.\n", lbx_strerror());
28                 return EXIT_FAILURE;
29         }
30
31         nfiles = lbx_numfiles(lbx);
32         if (verbose) {
33                 printf("Files in archive: %zu\n", nfiles);
34         }
35
36         for (i = 0; i < nfiles; i++) {
37                 struct lbx_statbuf stat;
38
39                 lbx_stat(lbx, i, &stat);
40                 printf("%s", stat.name);
41                 if (verbose) {
42                         printf(" size=%zu bytes", stat.size);
43                 }
44
45                 putchar('\n');
46         }
47
48         lbx_close(lbx);
49         return EXIT_SUCCESS;
50 }
51
52 int extract(FILE *f, const char *name, int verbose) {
53         LBX *lbx;
54         size_t nfiles;
55         unsigned int i;
56
57         lbx = lbx_fopen(f, name);
58         if (!lbx) {
59                 errmsg("failed to open archive: %s.\n", lbx_strerror());
60                 return EXIT_FAILURE;
61         }
62
63         nfiles = lbx_numfiles(lbx);
64         if (verbose) {
65                 printf("Files in archive: %zu\n", nfiles);
66         }
67
68         for (i = 0; i < nfiles; i++) {
69                 struct lbx_statbuf stat;
70                 size_t rc;
71                 FILE *of;
72
73                 lbx_stat(lbx, i, &stat);
74                 of = fopen(stat.name, "wbx");
75                 if (!of) {
76                         errmsg("failed to create output file %s: %m.\n",
77                                                              stat.name);
78                         break;
79                 }
80
81                 if (verbose) printf("extracting %s...\n", stat.name);
82                 rc = lbx_extract(lbx, i, of);
83                 if (rc < stat.size) {
84                         errmsg("error extracting %s: %s.\n",
85                                stat.name, lbx_strerror());
86                         break;
87                 }
88                 if (verbose) printf("wrote %zu bytes.\n", rc);
89         }
90
91         lbx_close(lbx);
92         return EXIT_SUCCESS;
93 }
94
95 int main(int argc, char **argv)
96 {
97         int mode = MODE_NONE, verbose = 0;
98         const char *name = "stdin";
99         FILE *f  = stdin;
100         int opt;
101
102         static const char         *sopts   = "lxf:i:v";
103         static const struct option lopts[] = {
104                 { "list",    0, NULL, 'l' },
105                 { "extract", 0, NULL, 'x' },
106
107                 { "file",    1, NULL, 'f' },
108                 { "index",   1, NULL, 'i' },
109
110                 { "verbose", 0, NULL, 'v' },
111
112                 { 0 }
113         };
114
115         progname = "lbxtool"; /* argv[0]; */
116         while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
117                 switch(opt) {
118                 case 'l':
119                         mode = MODE_LIST;
120                         break;
121                 case 'x':
122                         mode = MODE_EXTRACT;
123                         break;
124                 case 'f':
125                         if (strcmp(optarg, "-") == 0)
126                                 break;
127
128                         name = strrchr(optarg, '/');
129                         name = name ? name+1 : optarg;
130
131                         f = fopen(optarg, "rb");
132                         if (!f) {
133                                 errmsg("failed to open file %s: %m\n", optarg);
134                                 return EXIT_FAILURE;
135                         }
136                         break;
137                 case 'i':
138                         /* FIXME: Add index file support. */
139                         break;
140                 case 'v':
141                         verbose = 1;
142                         break;
143                 default:
144                         return EXIT_FAILURE;
145                 }
146         }
147
148         switch (mode) {
149         case MODE_LIST:
150                 return list(f, name, verbose);
151         case MODE_EXTRACT:
152                 return extract(f, name, verbose);
153         }
154
155         fprintf(stderr, "%s: you must specify a mode.\n", progname);
156         return EXIT_FAILURE;
157 }