+int filematch(char **argv, const char *name)
+{
+ int rc, i;
+
+ for (i = 0; argv[i]; i++) {
+ switch(fnmatch(argv[i], name, 0)) {
+ case 0:
+ return 0;
+ case FNM_NOMATCH:
+ break;
+ default:
+ errmsg("error matching glob: %s.\n", argv[i]);
+ return 1;
+ }
+ }
+
+ return i ? -1: 0;
+}
+
+int list(FILE *f, const char *name, int verbose, char **argv) {
+ LBX *lbx;
+ size_t nfiles;
+ unsigned int i;
+
+ lbx = lbx_fopen(f, name);
+ if (!lbx) {
+ errmsg("failed to open archive: %s.\n", lbx_strerror());
+ return EXIT_FAILURE;
+ }
+
+ nfiles = lbx_numfiles(lbx);
+ if (verbose) {
+ printf("Files in archive: %zu\n", nfiles);
+ }
+
+ for (i = 0; i < nfiles; i++) {
+ struct lbx_statbuf stat;
+
+ lbx_stat(lbx, i, &stat);
+
+ switch (filematch(argv, stat.name)) {
+ case -1: continue;
+ case 0: break;
+ default: goto err;
+ }
+
+ printf("%s", stat.name);
+ if (verbose) {
+ printf(" size=%zu bytes", stat.size);
+ }
+
+ putchar('\n');
+ }
+
+ lbx_close(lbx);
+ return EXIT_SUCCESS;
+err:
+ lbx_close(lbx);
+ return EXIT_FAILURE;
+}
+
+int extract(FILE *f, const char *name, int verbose, char **argv) {
+ LBX *lbx;
+ size_t nfiles;
+ unsigned int i;
+
+ lbx = lbx_fopen(f, name);