X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=lib%2Fzpm.c;h=f0a0ba256888317757b37f9df104fca9b8f25131;hb=f657628fd0709886002fdb0e2d8bde6873a34eb8;hp=6827caf629a13693cea6fb3bc73741f5d928b3b3;hpb=8cd48d5a0ad2bcb6e70861a8f94abb987680cc45;p=zpackage diff --git a/lib/zpm.c b/lib/zpm.c index 6827caf..f0a0ba2 100644 --- a/lib/zpm.c +++ b/lib/zpm.c @@ -258,7 +258,6 @@ static #include "newdb.c" int zpm_db_initialize(struct zpm *pkg) { - //fprintf(stderr, "initializing zpm database\n"); char *error; switch (sqlite3_exec(pkg->db, createdb, (int (*)(void *,int,char **,char **))0, NULL, &error)) { case SQLITE_OK: break; @@ -266,6 +265,7 @@ int zpm_db_initialize(struct zpm *pkg) { SQLERROR(sqlite3_errmsg(pkg->db)); fprintf(stderr, "error: %s\n", error); sqlite3_free(error); + zpm_rollback(pkg); return 0; break; } @@ -323,6 +323,22 @@ struct zpm *zpm_clearmem(struct zpm *zpm) { return zpm; } +static void zpm_set_db_errmsg(struct zpm *zpm, const char *msg) { + if (zpm) { + if (zpm->dberrmsg) { + free(zpm->dberrmsg); + } + if (msg) { + zpm->dberrmsg = strdup(msg); + if (!zpm->dberrmsg) { + zpm->error = 1; + } + } else { + zpm->dberrmsg = 0; + } + } +} + int zpm_init(struct zpm *pkg, char *path) { int rc; sqlite3 *db = 0; @@ -336,8 +352,15 @@ int zpm_init(struct zpm *pkg, char *path) { rc = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); if (rc) { - SQLERROR(sqlite3_errmsg(db)); - sqlite3_close(db); + pkg->error = 1; + pkg->dbresult = rc; + zpm_set_db_errmsg(pkg, sqlite3_errstr(rc)); + if (db) { + sqlite3_close(db); + } + fprintf(stderr, "error (%d): %s: %s\n", rc, + pkg->dberrmsg ? pkg->dberrmsg : "null", path); + return 0; } pkg->db = db; @@ -424,18 +447,21 @@ int zpm_addvercmp(struct zpm *pkg) { ); } -int zpm_extract(struct zpm *pkg, char *hash, char *path, int mode) { +int zpm_extract(struct zpm *pkg, char *hash, char *path, mode_t mode) { int rc; - int blobsize; - //int64_t size; void *xzdata; int type; - FILE *out; + int out; sqlite3_stmt *ifile; + size_t len; + char *tmpfile = 0; + sqlite3 *db; - /* TODO check null */ - sqlite3 *db = pkg->db; + if (!pkg || !pkg->db) { + return 0; + } + db = pkg->db; rc = sqlite3_prepare(db, "select size, content from files where hash = ?", -1, &ifile,0); if (rc != SQLITE_OK) { @@ -484,26 +510,55 @@ int zpm_extract(struct zpm *pkg, char *hash, char *path, int mode) { blobsize = sqlite3_column_bytes(ifile, 1); if (strcmp(path, "-")) { - out = fopen(path, "w"); + len = strlen(path); + tmpfile = malloc(len+8+1); + if (!tmpfile) { + fprintf(stderr, "malloc error\n"); + return 0; + } + sprintf(tmpfile, "%sXXXXXX", path); + + out = open(tmpfile, O_CREAT|O_WRONLY|O_TRUNC, 0600); + if (out == -1) { + fprintf(stderr, "can't open output file %s: %s\n", + tmpfile, strerror(errno)); + sqlite3_finalize(ifile); + sqlite3_close(db); + return 0; + } } else { - out = stdout; - } - if (!out) { - fprintf(stderr, "can't open output file %s\n", path); - sqlite3_finalize(ifile); - sqlite3_close(db); - return 0; + out = 1; } - //fwrite(xzdata, blobsize, 1, stdout); - //fprintf(stderr, "uncompressing %d bytes at %p, expect %lld\n", blobsize, xzdata, (long long int)size); +#if 0 + fprintf(stderr, "uncompressing %d bytes at %p, expect %lld\n", blobsize, xzdata, (long long int)size); +#endif uncompresslzma(xzdata, blobsize, out); - fclose(out); - chmod(path, mode); - + close(out); sqlite3_finalize(ifile); - return 1; + rc = 1; + if (tmpfile) { + if (chmod(tmpfile, mode) == -1) { + fprintf(stderr, "can't chmod %s: %s\n", tmpfile, + strerror(errno)); + rc = 0; + } else if (rename(tmpfile, path) == -1) { + fprintf(stderr, "extract rename failed: %s\n", + strerror(errno)); + rc = 0; + } + } + + if (rc == 0 && tmpfile) { + if (unlink(tmpfile) == -1) { + fprintf(stderr, "unlink tmpfile %s fail: %s\n", + tmpfile, + strerror(errno)); + } + } + + return rc; } static int run_for_hash(sqlite3 *db, char *sql, char *hash) { @@ -541,10 +596,6 @@ static int set_elf_info(sqlite3 *db, char *hash, char *content, size_t length) { int rc; /* clear existing for this hash */ - if (!run_for_hash(db, "delete from elfinfo where file = ?", hash)) { - SQLERP(db, "error clearing elf info"); - return 0; - } if (!run_for_hash(db, "delete from elflibraries where file = ?", hash)) { SQLERP(db, "error clearing elf library");