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) {
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) {