From: Nathan Wagner Date: Wed, 5 Dec 2018 11:04:45 +0000 (+0000) Subject: allow partial hashes in zpm-extract X-Git-Tag: v0.3.6~6 X-Git-Url: https://pd.if.org/git/?p=zpackage;a=commitdiff_plain;h=06ea9ccb6a8d36c63d5f1dac4fd2430819b75a95 allow partial hashes in zpm-extract added new library function to search for hashes. --- diff --git a/lib/dbquery.c b/lib/dbquery.c index 1113164..d0edecc 100644 --- a/lib/dbquery.c +++ b/lib/dbquery.c @@ -2,6 +2,7 @@ #include #include +#include #include "sqlite3.h" #include "zpm.h" @@ -83,6 +84,27 @@ void zpm_db_run(struct zpm *zpm, char *query, ...) { return ; } +int zpm_findhash(struct zpm *zpm, char *find, char *dest) { + int count; + char *found; + + count = zpm_db_int(zpm, "select count(*) from files where hash like '%q%%';", find); + if (count != 1) { + return count; + } + if (dest) { + found = zpm_db_string(zpm, "select hash from files where hash like '%s%%' limit 1;", find); + if (find) { + strcpy(dest, found); + free(found); + } else { + count = 0; + } + } + return count; + +} + char *zpm_db_string(struct zpm *zpm, char *query, ...) { sqlite3_stmt *st; va_list args; diff --git a/lib/zpm.c b/lib/zpm.c index 9b208cc..55e2e12 100644 --- a/lib/zpm.c +++ b/lib/zpm.c @@ -337,6 +337,10 @@ int zpm_extract(struct zpm *pkg, char *hash, char *path, mode_t mode) { } db = pkg->db; + if (!path) { + path = "-"; + } + rc = sqlite3_prepare(db, "select size, content from files where hash = ?", -1, &ifile,0); if (rc != SQLITE_OK) { SQLERROR(sqlite3_errmsg(db)); diff --git a/t/add.t b/t/add.t index 2443218..cf14f52 100755 --- a/t/add.t +++ b/t/add.t @@ -22,7 +22,7 @@ PF=zpmtest-1.0-1.zpm require zpm newpackage -C $pkgid require zpm add $pkgid foo h=$(zpm hash foo) -require zpm extract zpmtest-1.0-1.zpm $h foo2 +require zpm extract -f zpmtest-1.0-1.zpm $h foo2 h2=$(zpm hash foo2) okstreq "$h" "$h2" "foo and foo2 hash match" @@ -38,7 +38,7 @@ rm -f $PF require zpm newpackage -f $PF -C $pkgid require zpm add -f $PF zpmtest foo rm -f foo2 -require zpm extract $PF $h foo2 +require zpm extract -f $PF $h foo2 h2=$(zpm hash foo2) okstreq "$h" "$h2" diff --git a/t/extract.t b/t/extract.t index d526b4c..0b8a610 100755 --- a/t/extract.t +++ b/t/extract.t @@ -20,13 +20,13 @@ okstreq "$hash" b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c rm -f foo -zpm-extract $PF $hash test.foo2 +zpm-extract -f $PF $hash test.foo2 okexit extract foo file content sha=$(zpm-hash test.foo2) okstreq $hash $sha extracted hash matches -sha=$(zpm-extract $PF $hash - | zpm-hash) +sha=$(zpm-extract -f $PF $hash - | zpm-hash) okstreq $hash $sha stdout extract hash matches finish diff --git a/zpm-extract.c b/zpm-extract.c index 220fafa..144fef4 100644 --- a/zpm-extract.c +++ b/zpm-extract.c @@ -1,9 +1,12 @@ +#define _POSIX_C_SOURCE 2 #include +#include #include #include #include #include #include +#include #include @@ -22,112 +25,76 @@ * 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 diff --git a/zpm.h b/zpm.h index f8ce56b..9be5f60 100644 --- a/zpm.h +++ b/zpm.h @@ -78,6 +78,7 @@ struct zpm_package { int zpm_parse_package(char *pstr, char *name, char *ver, int *rel); char *zpm_findpkg(struct zpm *zpm, char *pkgstr, char *where); +int zpm_findhash(struct zpm *zpm, char *find, char *dest); char *zpm_findlib(struct zpm *zpm, char *soname, char *where); int zpm_libraries_needed(struct zpm *zpm, char *pkgid, jsw_atree_t *list); int zpm_quote(char *value, char *dest, size_t n);