+#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>
#include "zpm.h"
-#if 1
+/* more usage:
+ * -t : use a temp file, then move into place, possible reverse the sense
+ * -u : userid
+ * -g : groupid
+ * -m : mode (i.e. final mode)
+ int mode = 0600;
+ * -l : log all actions
+ * -d : logging database file, if different
+ *
+ * check if file exists, if it does, and has the same hash, do
+ * nothing, unless -f is given
+ */
+
+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 mode = 0600;
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], mode);
- 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);
- 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