From: Nathan Wagner Date: Thu, 25 Oct 2018 17:12:08 +0000 (+0000) Subject: use tempfile when extracting X-Git-Tag: v0.2.16~57 X-Git-Url: https://pd.if.org/git/?p=zpackage;a=commitdiff_plain;h=a63f09fb0e19460727bc6a31b3a401a53e54e58f use tempfile when extracting --- diff --git a/lib/zpm.c b/lib/zpm.c index 644dc97..f0a0ba2 100644 --- a/lib/zpm.c +++ b/lib/zpm.c @@ -449,16 +449,19 @@ int zpm_addvercmp(struct zpm *pkg) { int zpm_extract(struct zpm *pkg, char *hash, char *path, mode_t mode) { int rc; - int blobsize; - //int64_t size; void *xzdata; int type; 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) { @@ -507,26 +510,55 @@ int zpm_extract(struct zpm *pkg, char *hash, char *path, mode_t mode) { blobsize = sqlite3_column_bytes(ifile, 1); if (strcmp(path, "-")) { - out = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0600); + 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 = 1; } - if (out == -1) { - fprintf(stderr, "can't open output file %s: %s\n", path, - strerror(errno)); - sqlite3_finalize(ifile); - sqlite3_close(db); - return 0; - } - //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); close(out); - chmod(path, mode); - 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) {