1 #define _POSIX_C_SOURCE 200809L
18 int zpm_begin(struct zpm *z) {
20 sqlite3_exec(z->db, "begin;", NULL, NULL, &errstr);
22 fprintf(stderr, "sqlite begin error: %s\n", errstr);
29 int zpm_commit(struct zpm *z) {
31 sqlite3_exec(z->db, "commit;", NULL, NULL, &errstr);
33 fprintf(stderr, "sqlite commit error: %s\n", errstr);
40 /* wrapper for sqlite3_exec */
41 int zpm_exec(struct zpm *z, const char *sql, int(*callback)(void *, int, char **, char**), void *arg, char **errmsg) {
42 return sqlite3_exec(z->db, sql, callback, arg, errmsg);
45 int zpm_rollback(struct zpm *z) {
47 sqlite3_exec(z->db, "rollback;", NULL, NULL, &errstr);
49 fprintf(stderr, "sqlite rollback error: %s\n", errstr);
56 int zpm_readonly(struct zpm *z) {
57 if (z->db && sqlite3_db_readonly(z->db, "main")) {
63 int zpm_db_set_pragma(struct zpm *db, int pragma, int value) {
69 case 1: sql = "pragma application_id = ?;"; break;
70 case 2: sql = "pragma user_version = ?;"; break;
71 default: return -1; break;
74 rc = sqlite3_prepare_v2(db->db, sql, -1, &s, 0);
76 if (rc != SQLITE_OK) {
77 SQLERROR(sqlite3_errmsg(db->db));
81 sqlite3_bind_int(s, 1, value);
82 if (rc != SQLITE_OK) {
83 SQLERROR(sqlite3_errmsg(db->db));
84 fprintf(stderr, "cant bind pragma value\n");
89 if (rc != SQLITE_DONE) {
90 SQLERROR(sqlite3_errmsg(db->db));
91 fprintf(stderr, "cant set pragma\n");
100 int zpm_db_pragma(struct zpm *db, int pragma) {
107 case 1: sql = "pragma application_id;"; break;
108 case 2: sql = "pragma user_version;"; break;
109 default: return -1; break;
112 rc = sqlite3_prepare_v2(db->db, sql, -1, &s, 0);
114 if (rc != SQLITE_OK) {
115 SQLERROR(sqlite3_errmsg(db->db));
116 fprintf(stderr, "%s, errnum = %d\n", sqlite3_errmsg(db->db), rc);
117 /* TODO just abort? */
121 rc = sqlite3_step(s);
122 if (rc == SQLITE_ROW) {
123 value = sqlite3_column_int(s, 0);
133 int zpm_db_initialize(struct zpm *pkg) {
135 switch (sqlite3_exec(pkg->db, createdb, (int (*)(void *,int,char **,char **))0, NULL, &error)) {
136 case SQLITE_OK: break;
138 SQLERROR(sqlite3_errmsg(pkg->db));
139 fprintf(stderr, "error: %s\n", error);
149 /* assumes pkg->db is set */
150 static int setupdb(struct zpm *zpm) {
156 appid = zpm_db_pragma(zpm, 1);
157 dbver = zpm_db_pragma(zpm, 2);
159 if (appid != 0x5a504442) {
160 fprintf(stderr, "unknown database type\n");
166 fprintf(stderr, "version %d zpm db detected, this program only works with version 1 databases\n", dbver);
171 sqlite3_exec(zpm->db, "pragma foreign_keys = ON;", NULL, NULL, &errstr);
175 zpm->errmsg = strdup(errstr);
176 fprintf(stderr, "sqlite foreign key error: %s\n", errstr);
177 sqlite3_free(errstr);
182 /* TODO add vercmp */
187 struct zpm *zpm_clearmem(struct zpm *zpm) {
189 zpm = malloc(sizeof *zpm);
193 *zpm = (struct zpm){0};
199 static void zpm_set_db_errmsg(struct zpm *zpm, const char *msg) {
205 zpm->dberrmsg = strdup(msg);
206 if (!zpm->dberrmsg) {
215 int zpm_init(struct zpm *pkg, char *path) {
226 rc = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
230 zpm_set_db_errmsg(pkg, sqlite3_errstr(rc));
234 fprintf(stderr, "error (%d): %s: %s\n", rc,
235 pkg->dberrmsg ? pkg->dberrmsg : "null", path);
240 pkg->path = strdup(path);
242 appid = zpm_db_pragma(pkg, 1);
245 case 0: if (!zpm_db_initialize(pkg)) {
251 /* already initialized */
254 fprintf(stderr, "unknown database type\n");
270 int zpm_open(struct zpm *zpm, char *path) {
277 path = getenv("ZPMDB");
281 path = "/var/lib/zpm/local.db";
284 rc = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE, NULL);
286 SQLERROR(sqlite3_errmsg(db));
289 fprintf(stderr, "path = %s\n", path);
293 zpm->path = strdup(path);
306 int zpm_close(struct zpm *pkg) {
308 sqlite3_close(pkg->db);
311 /* TODO free any malloced names and such */
315 static int zpm_sqlite_vercmp(void *not_used, int lena, const void *a,
316 int lenb, const void *b) {
320 if (not_used != 0) fprintf(stderr, "sqlite vercmp not_used = %p\n",
322 if (lena == 0 && lenb > 0) return 1;
323 if (lenb == 0 && lena > 0) return -1;
325 bufa = sqlite3_malloc(lena+1);
326 bufb = sqlite3_malloc(lenb+1);
328 strncpy(bufa, a, lena);
329 strncpy(bufb, b, lenb);
333 rv = zpm_vercmp(bufa, bufb);
339 int zpm_addvercmp(struct zpm *pkg) {
340 return sqlite3_create_collation(
341 pkg->db, "vercmp", SQLITE_UTF8, NULL,
346 int zpm_extract(struct zpm *pkg, char *hash, char *path, mode_t mode) {
357 if (!pkg || !pkg->db) {
366 rc = sqlite3_prepare(db, "select size, content from files where hash = ?", -1, &ifile,0);
367 if (rc != SQLITE_OK) {
368 SQLERROR(sqlite3_errmsg(db));
374 sqlite3_bind_text(ifile, 1, hash, 64, SQLITE_STATIC);
376 rc = sqlite3_step(ifile);
378 if (rc == SQLITE_DONE) {
379 /* didn't find a row */
380 sqlite3_finalize(ifile);
382 fprintf(stderr, "no such hash: %s\n", hash);
385 /* either way we're done with this now */
387 if (rc != SQLITE_ROW) {
388 SQLERROR(sqlite3_errmsg(db));
389 sqlite3_finalize(ifile);
394 type = sqlite3_column_type(ifile, 0);
395 if (type == SQLITE_NULL) {
396 fprintf(stderr, "no file size\n");
397 sqlite3_finalize(ifile);
401 type = sqlite3_column_type(ifile, 1);
402 if (type == SQLITE_NULL) {
403 fprintf(stderr, "no file data\n");
404 sqlite3_finalize(ifile);
408 //size = sqlite3_column_int64(ifile, 0);
409 xzdata = (void *)sqlite3_column_blob(ifile, 1);
410 blobsize = sqlite3_column_bytes(ifile, 1);
412 if (strcmp(path, "-")) {
414 tmpfile = malloc(len+8+1);
416 fprintf(stderr, "malloc error\n");
419 sprintf(tmpfile, "%sXXXXXX", path);
421 out = open(tmpfile, O_CREAT|O_WRONLY|O_TRUNC, 0600);
423 fprintf(stderr, "can't open output file %s: %s\n",
424 tmpfile, strerror(errno));
425 sqlite3_finalize(ifile);
435 fprintf(stderr, "uncompressing %d bytes at %p, expect %lld\n", blobsize, xzdata, (long long int)size);
437 uncompresslzma(xzdata, blobsize, out);
439 sqlite3_finalize(ifile);
443 if (chmod(tmpfile, mode) == -1) {
444 fprintf(stderr, "can't chmod %s: %s\n", tmpfile,
447 } else if (rename(tmpfile, path) == -1) {
448 fprintf(stderr, "extract rename failed: %s\n",
454 if (rc == 0 && tmpfile) {
455 if (unlink(tmpfile) == -1) {
456 fprintf(stderr, "unlink tmpfile %s fail: %s\n",
466 static int run_for_hash(sqlite3 *db, char *sql, char *hash) {
470 rc = sqlite3_prepare_v2(db, sql, -1, &ifile, 0);
471 if (rc != SQLITE_OK) {
472 SQLERROR(sqlite3_errmsg(db));
478 sqlite3_bind_text(ifile, 1, hash, 64, SQLITE_STATIC);
480 rc = sqlite3_step(ifile);
481 } while (rc == SQLITE_ROW);
483 sqlite3_finalize(ifile);
485 return rc == SQLITE_DONE;
488 #define SQLERP(db, msg) fprintf(stderr, "%s: %s\n", msg, sqlite3_errmsg(db))
490 static int set_elf_info(struct zpm *zpm, char *hash, char *content,
499 sqlite3 *db = zpm->db;
501 if (length < sizeof (Elf64_Ehdr) || !libelf_iself(content)) {
502 /* not an elf file */
506 /* clear existing for this hash */
508 if (!run_for_hash(db, "delete from elflibraries where file = ?", hash)) {
509 SQLERP(db, "error clearing elf library");
513 if (!run_for_hash(db, "delete from elfneeded where file = ?", hash)) {
514 SQLERP(db, "error clearing elf needed");
518 hdr = libelf_header(content);
519 /* if lib, set soname */
520 if (libelf_type(content) == ET_DYN) {
521 char *soname = libelf_soname(content);
523 zpm_db_run(zpm, "insert into elflibraries (file,soname) values (%Q,%Q);", hash, soname);
528 /* some dyn don't have an soname, so we don't
532 /* if exe, set neededs */
533 /* libraries can have neededs too */
534 if (libelf_type(content) == ET_EXEC || libelf_type(content) == ET_DYN) {
535 Elf64_Shdr *dsect = 0;
538 elf = (char *)content;
539 /* find program header table */
540 for (i = 0; i < hdr->e_phnum; i++) {
541 phdr = (Elf64_Phdr *)(elf + hdr->e_phoff + i * hdr->e_phentsize);
542 if (phdr->p_type == PT_DYNAMIC) {
543 dsect = (Elf64_Shdr *)(elf + phdr->p_offset);
547 /* no dynamic section found */
551 dyn = (Elf64_Dyn *)dsect;
553 dsect = libelf_section(elf, SHT_DYNAMIC);
556 strsect = libelf_section_n(elf, dsect->sh_link);
557 strtab = elf + strsect->sh_offset;
559 sqlite3_prepare_v2(db, "insert into elfneeded (file,needed) values (?,?)",-1, &ifile, 0);
560 sqlite3_bind_text(ifile,1,hash,64,SQLITE_STATIC);
561 while (dyn->d_tag != DT_NULL) {
562 if (dyn->d_tag == DT_NEEDED) {
566 need = strtab + dyn->d_un.d_val;
567 if (strlen(need) == 0) continue;
568 sqlite3_bind_text(ifile,2,need,strlen(need),SQLITE_STATIC);
570 fprintf(stderr, "%s needs %s\n", hash, need);
572 rc = sqlite3_step(ifile);
573 if (rc != SQLITE_DONE) {
574 SQLERP(db, "error setting needed library");
575 sqlite3_finalize(ifile);
578 sqlite3_reset(ifile);
582 sqlite3_finalize(ifile);
587 int zpm_import(struct zpm *zpm, char *path, uint32_t flags, char *hash) {
591 sqlite3_stmt *ifile = 0;
592 int haverow = 0,havedata = 0;
600 if (!zpm || !zpm->db || !path) {
604 /* use local if caller didn't pass in room */
610 fprintf(stderr, "zpm_import unused flags = %d\n", flags);
613 fd = open(path, O_RDONLY);
616 fprintf(stderr, "%s can't open %s: %s\n", __FUNCTION__, path,strerror(errno));
619 if (fstat(fd, &sbuf) == -1) {
621 fprintf(stderr, "%s can't fstat %s: %s\n", __FUNCTION__, path,strerror(errno));
624 /* not a regular file? */
625 if (!S_ISREG(sbuf.st_mode)) {
627 switch (sbuf.st_mode & S_IFMT) {
628 case S_IFSOCK: ftype = "socket"; break;
629 case S_IFLNK : ftype = "symlink"; break;
630 case S_IFBLK : ftype = "block device"; break;
631 case S_IFDIR : ftype = "directory"; break;
632 case S_IFCHR : ftype = "character device"; break;
633 case S_IFIFO : ftype = "fifo"; break;
634 default: ftype = "unknown file type"; break;
636 /* TODO this is ok, just stored differently */
637 fprintf(stderr, "%s can't import %s file: %s\n", __FUNCTION__, ftype, path);
642 content = mmap(0, sbuf.st_size, PROT_READ,MAP_PRIVATE, fd, 0);
646 fprintf(stderr, "%s can't mmap %s: %s\n", __FUNCTION__, path,strerror(errno));
650 zpm_hash_mem(content, sbuf.st_size, hash);
653 /* TODO check null */
654 sqlite3 *db = zpm->db;
656 /* prepare and bind */
658 rc = sqlite3_prepare_v2(db, "select size, content is not null from files where hash = ?", -1, &ifile,0);
659 if (rc != SQLITE_OK) {
660 SQLERROR(sqlite3_errmsg(db));
661 munmap(content, sbuf.st_size);
667 sqlite3_bind_text(ifile, 1, hash, 64, SQLITE_STATIC);
669 rc = sqlite3_step(ifile);
671 if (rc != SQLITE_DONE) {
672 if (rc != SQLITE_ROW) {
673 /* didn't find a row */
674 SQLERROR(sqlite3_errmsg(db));
675 munmap(content, sbuf.st_size);
679 type = sqlite3_column_type(ifile, 0);
680 if (type == SQLITE_NULL) {
681 /* TODO assert, this shouldn't be possible? */
682 fprintf(stderr, "no file size\n");
683 sqlite3_finalize(ifile);
684 munmap(content, sbuf.st_size);
687 type = sqlite3_column_type(ifile, 1);
688 if (type == SQLITE_NULL) {
689 /* TODO assert, this shouldn't be possible? */
690 fprintf(stderr, "no file data\n");
691 sqlite3_finalize(ifile);
692 munmap(content, sbuf.st_size);
694 /* which is fine, just need to update the row then */
696 havedata = sqlite3_column_int(ifile, 1);
699 sqlite3_finalize(ifile);
703 // fprintf(stderr, "compressing\n");
704 outbuf = compresslzma(content, sbuf.st_size, &outlen);
706 fprintf(stderr, "compresslzma failed\n");
707 munmap(content, sbuf.st_size);
710 //// fprintf(stderr, "compress finished\n");
714 rc = sqlite3_prepare_v2(db, "update files set size = ?, content = ? where hash = ?", -1, &ifile,0);
716 rc = sqlite3_prepare_v2(db, "insert into files (size, content, hash) values (?,?,?)", -1, &ifile,0);
719 if (rc != SQLITE_OK) {
720 SQLERROR(sqlite3_errmsg(db));
721 fprintf(stderr, "cant prepare data\n");
722 munmap(content, sbuf.st_size);
726 rc = sqlite3_bind_int64(ifile, 1, (sqlite3_int64)sbuf.st_size);
727 if (rc != SQLITE_OK) {
728 SQLERROR(sqlite3_errmsg(db));
729 sqlite3_finalize(ifile);
730 fprintf(stderr, "cant bind size\n");
731 munmap(content, sbuf.st_size);
735 rc = sqlite3_bind_blob64(ifile, 2, outbuf,
736 (sqlite3_int64)outlen, SQLITE_STATIC);
737 if (rc != SQLITE_OK) {
738 SQLERROR(sqlite3_errmsg(db));
739 sqlite3_finalize(ifile);
740 fprintf(stderr, "cant bind content\n");
741 munmap(content, sbuf.st_size);
745 rc = sqlite3_bind_text(ifile, 3, hash, 64, SQLITE_STATIC);
746 if (rc != SQLITE_OK) {
747 SQLERROR(sqlite3_errmsg(db));
748 fprintf(stderr, "cant bind hash\n");
749 sqlite3_finalize(ifile);
750 munmap(content, sbuf.st_size);
754 rc = sqlite3_step(ifile);
755 if (rc != SQLITE_DONE) {
756 SQLERROR(sqlite3_errmsg(db));
757 sqlite3_finalize(ifile);
758 munmap(content, sbuf.st_size);
761 sqlite3_finalize(ifile);
763 /* don't need the original file now */
766 if (!set_elf_info(zpm, hash, content, sbuf.st_size)) {
767 fprintf(stderr, "setting elf info failed\n");
768 munmap(content, sbuf.st_size);
772 munmap(content, sbuf.st_size);