]> pd.if.org Git - zpackage/blobdiff - zpm-extract.c
allow partial hashes in zpm-extract
[zpackage] / zpm-extract.c
index 220fafaa88e314d9685a7926d0f2f865ffb1c277..144fef490491857af23a99aba6e4af1d25aec79b 100644 (file)
@@ -1,9 +1,12 @@
+#define _POSIX_C_SOURCE 2
 #include <stdio.h>
+#include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
+#include <string.h>
 
 #include <sys/mman.h>
 
  *  nothing, unless -f is given
  */ 
 
-#if 1
+void usage(void) {
+       fprintf(stderr, "usage: zpm-extract [-d dbfile] [-t tmpfile] hash [output]\n");
+}
+
 int main(int ac, char **av){
        struct zpm pkg;
        int rv;
 
-       if (ac < 3) {
-               fprintf(stderr, "usage: db hash file\n");
-               return 1;
+       char *tmpfile = 0, *output = 0;
+       int opt;
+       mode_t mode;
+       uid_t uid = 0;
+       gid_t gid = 0;
+       char *dest = 0, *hashmatch = 0;
+       char hash[ZPM_HASH_STRLEN+1];
+       char *dbfile = getenv("ZPMDB");
+       if (!dbfile) {
+               dbfile = "/var/lib/zpm/local.db";
        }
-       zpm_open(&pkg, av[1]);
-       rv = zpm_extract(&pkg, av[2], av[3], 0600);
-       zpm_close(&pkg);
-
-       return rv ? 0 : 1;
-}
-#else
-
-int main(int ac, char **av) {
-       sqlite3 *db = 0;
-       int rc;
-
-       int blobsize;
-       int64_t size;
-       void *xzdata;
-       int type;
-       FILE *out;
-       sqlite3_stmt *ifile;
-
-       char *hash;
-       char *filename;
 
-       if (ac < 3) {
-               fprintf(stderr, "usage: db hash file\n");
-               return 1;
+       while ((opt = getopt(ac, av, "f:")) != -1) {
+               switch (opt) {
+                       case 'f': dbfile = optarg; break;
+                       case 't': tmpfile = optarg; break;
+                       case 'u': uid = atoi(optarg); break;
+                       case 'g': gid = atoi(optarg); break;
+                       case 'o': dest = optarg; break;
+                       case 'm': mode = atoi(optarg); break;
+                       default:
+                                 usage();
+                                 exit(EXIT_FAILURE);
+                                 break;
+               }
        }
 
-       rc = sqlite3_open(av[1], &db);
-       if (rc) {
-               SQLERROR(sqlite3_errmsg(db));
-               sqlite3_close(db);
-               return 1;
+       if (ac < optind) {
+               usage();
+               exit(EXIT_FAILURE);
        }
 
-       rc = sqlite3_prepare(db, "select size, content from files where hash = ?", -1, &ifile,0);
-       if (rc != SQLITE_OK) {
-               SQLERROR(sqlite3_errmsg(db));
-               return 1;
+       hashmatch = av[optind];
+
+       if (ac > optind) {
+               output = av[optind+1];
        }
 
-       /* hash, filename */
-       hash = av[2];
-       filename = av[3];
+       zpm_open(&pkg, dbfile);
+       fprintf(stderr, "db: %s\n", pkg.path);
 
-       sqlite3_bind_text(ifile, 1, hash, 64, SQLITE_STATIC);
+       rv = zpm_findhash(&pkg, hashmatch, hash);
+       if (rv == 0) {
+               fprintf(stderr, "no such hash %s\n", hashmatch);
+               exit(EXIT_FAILURE);
+       } else if (rv > 1) {
+               fprintf(stderr, "%d matching hashes for %s\n", rv, hashmatch);
+               exit(EXIT_FAILURE);
+       }
 
-       rc = sqlite3_step(ifile);
+       rv = zpm_extract(&pkg, hash, tmpfile ? tmpfile : output, 0600);
+       zpm_close(&pkg);
 
-       if (rc == SQLITE_DONE) {
-               /* didn't find a row */
-               sqlite3_finalize(ifile);
-               sqlite3_close(db);
-               fprintf(stderr, "no such hash\n");
-               return 1;
+       if (!rv) {
+               exit(EXIT_FAILURE);
        }
-       /* either way we're done with this now */
 
-       if (rc != SQLITE_ROW) {
-               SQLERROR(sqlite3_errmsg(db));
-               sqlite3_finalize(ifile);
-               sqlite3_close(db);
-               return 2;
-       }
+       /* set mode and such */
 
-       type = sqlite3_column_type(ifile, 0);
-       if (type == SQLITE_NULL) {
-               fprintf(stderr, "no file size\n");
-               sqlite3_finalize(ifile);
-               sqlite3_close(db);
-               return 3;
+       if (dest != tmpfile) {
+               rename(tmpfile, dest);
        }
-       type = sqlite3_column_type(ifile, 1);
-       if (type == SQLITE_NULL) {
-               fprintf(stderr, "no file data\n");
-               sqlite3_finalize(ifile);
-               sqlite3_close(db);
-               return 4;
-       }
-       size = sqlite3_column_int64(ifile, 0);
-       xzdata = (void *)sqlite3_column_blob(ifile, 1);
-       blobsize = sqlite3_column_bytes(ifile, 1);
-
-       out = fopen(filename, "w");
-       if (!out) {
-               fprintf(stderr, "can't open output file %s\n", filename);
-               sqlite3_finalize(ifile);
-               sqlite3_close(db);
-               return 5;
-       }
-       //fwrite(xzdata, blobsize, 1, stdout);
 
-       fprintf(stderr, "uncompressing %d bytes at %p, expect %lld\n", blobsize, xzdata, (long long int)size);
-       uncompresslzma(xzdata, blobsize, out);
-       fclose(out);
-
-       sqlite3_finalize(ifile);
-       sqlite3_close(db);
-       return 0;
+       return rv ? 0 : 1;
 }
-#endif