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_db_set_pragma(struct zpm *db, int pragma, int value) {
62 case 1: sql = "pragma application_id = ?;"; break;
63 case 2: sql = "pragma user_version = ?;"; break;
64 default: return -1; break;
67 rc = sqlite3_prepare_v2(db->db, sql, -1, &s, 0);
69 if (rc != SQLITE_OK) {
70 SQLERROR(sqlite3_errmsg(db->db));
74 sqlite3_bind_int(s, 1, value);
75 if (rc != SQLITE_OK) {
76 SQLERROR(sqlite3_errmsg(db->db));
77 fprintf(stderr, "cant bind pragma value\n");
82 if (rc != SQLITE_DONE) {
83 SQLERROR(sqlite3_errmsg(db->db));
84 fprintf(stderr, "cant set pragma\n");
93 int zpm_db_pragma(struct zpm *db, int pragma) {
100 case 1: sql = "pragma application_id;"; break;
101 case 2: sql = "pragma user_version;"; break;
102 default: return -1; break;
105 rc = sqlite3_prepare_v2(db->db, sql, -1, &s, 0);
107 if (rc != SQLITE_OK) {
108 SQLERROR(sqlite3_errmsg(db->db));
109 fprintf(stderr, "%s, errnum = %d\n", sqlite3_errmsg(db->db), rc);
110 /* TODO just abort? */
114 rc = sqlite3_step(s);
115 if (rc == SQLITE_ROW) {
116 value = sqlite3_column_int(s, 0);
126 int zpm_db_initialize(struct zpm *pkg) {
128 switch (sqlite3_exec(pkg->db, createdb, (int (*)(void *,int,char **,char **))0, NULL, &error)) {
129 case SQLITE_OK: break;
131 SQLERROR(sqlite3_errmsg(pkg->db));
132 fprintf(stderr, "error: %s\n", error);
142 /* assumes pkg->db is set */
143 static int setupdb(struct zpm *zpm) {
149 appid = zpm_db_pragma(zpm, 1);
150 dbver = zpm_db_pragma(zpm, 2);
152 if (appid != 0x5a504442) {
153 fprintf(stderr, "unknown database type\n");
159 fprintf(stderr, "version %d zpm db detected, this program only works with version 1 databases\n", dbver);
164 sqlite3_exec(zpm->db, "pragma foreign_keys = ON;", NULL, NULL, &errstr);
168 zpm->errmsg = strdup(errstr);
169 fprintf(stderr, "sqlite foreign key error: %s\n", errstr);
170 sqlite3_free(errstr);
175 /* TODO add vercmp */
180 struct zpm *zpm_clearmem(struct zpm *zpm) {
182 zpm = malloc(sizeof *zpm);
186 *zpm = (struct zpm){0};
192 static void zpm_set_db_errmsg(struct zpm *zpm, const char *msg) {
198 zpm->dberrmsg = strdup(msg);
199 if (!zpm->dberrmsg) {
208 int zpm_init(struct zpm *pkg, char *path) {
219 rc = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
223 zpm_set_db_errmsg(pkg, sqlite3_errstr(rc));
227 fprintf(stderr, "error (%d): %s: %s\n", rc,
228 pkg->dberrmsg ? pkg->dberrmsg : "null", path);
233 pkg->path = strdup(path);
235 appid = zpm_db_pragma(pkg, 1);
238 case 0: if (!zpm_db_initialize(pkg)) {
244 /* already initialized */
247 fprintf(stderr, "unknown database type\n");
263 int zpm_open(struct zpm *zpm, char *path) {
270 path = getenv("ZPMDB");
274 path = "/var/lib/zpm/local.db";
277 rc = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE, NULL);
279 SQLERROR(sqlite3_errmsg(db));
282 fprintf(stderr, "path = %s\n", path);
286 zpm->path = strdup(path);
299 int zpm_close(struct zpm *pkg) {
301 sqlite3_close(pkg->db);
304 /* TODO free any malloced names and such */
308 static int zpm_sqlite_vercmp(void *not_used, int lena, const void *a,
309 int lenb, const void *b) {
313 if (not_used != 0) fprintf(stderr, "sqlite vercmp not_used = %p\n",
315 if (lena == 0 && lenb > 0) return 1;
316 if (lenb == 0 && lena > 0) return -1;
318 bufa = sqlite3_malloc(lena+1);
319 bufb = sqlite3_malloc(lenb+1);
321 strncpy(bufa, a, lena);
322 strncpy(bufb, b, lenb);
326 rv = zpm_vercmp(bufa, bufb);
332 int zpm_addvercmp(struct zpm *pkg) {
333 return sqlite3_create_collation(
334 pkg->db, "vercmp", SQLITE_UTF8, NULL,
339 int zpm_extract(struct zpm *pkg, char *hash, char *path, mode_t mode) {
350 if (!pkg || !pkg->db) {
359 rc = sqlite3_prepare(db, "select size, content from files where hash = ?", -1, &ifile,0);
360 if (rc != SQLITE_OK) {
361 SQLERROR(sqlite3_errmsg(db));
367 sqlite3_bind_text(ifile, 1, hash, 64, SQLITE_STATIC);
369 rc = sqlite3_step(ifile);
371 if (rc == SQLITE_DONE) {
372 /* didn't find a row */
373 sqlite3_finalize(ifile);
375 fprintf(stderr, "no such hash: %s\n", hash);
378 /* either way we're done with this now */
380 if (rc != SQLITE_ROW) {
381 SQLERROR(sqlite3_errmsg(db));
382 sqlite3_finalize(ifile);
387 type = sqlite3_column_type(ifile, 0);
388 if (type == SQLITE_NULL) {
389 fprintf(stderr, "no file size\n");
390 sqlite3_finalize(ifile);
394 type = sqlite3_column_type(ifile, 1);
395 if (type == SQLITE_NULL) {
396 fprintf(stderr, "no file data\n");
397 sqlite3_finalize(ifile);
401 //size = sqlite3_column_int64(ifile, 0);
402 xzdata = (void *)sqlite3_column_blob(ifile, 1);
403 blobsize = sqlite3_column_bytes(ifile, 1);
405 if (strcmp(path, "-")) {
407 tmpfile = malloc(len+8+1);
409 fprintf(stderr, "malloc error\n");
412 sprintf(tmpfile, "%sXXXXXX", path);
414 out = open(tmpfile, O_CREAT|O_WRONLY|O_TRUNC, 0600);
416 fprintf(stderr, "can't open output file %s: %s\n",
417 tmpfile, strerror(errno));
418 sqlite3_finalize(ifile);
428 fprintf(stderr, "uncompressing %d bytes at %p, expect %lld\n", blobsize, xzdata, (long long int)size);
430 uncompresslzma(xzdata, blobsize, out);
432 sqlite3_finalize(ifile);
436 if (chmod(tmpfile, mode) == -1) {
437 fprintf(stderr, "can't chmod %s: %s\n", tmpfile,
440 } else if (rename(tmpfile, path) == -1) {
441 fprintf(stderr, "extract rename failed: %s\n",
447 if (rc == 0 && tmpfile) {
448 if (unlink(tmpfile) == -1) {
449 fprintf(stderr, "unlink tmpfile %s fail: %s\n",
459 static int run_for_hash(sqlite3 *db, char *sql, char *hash) {
463 rc = sqlite3_prepare_v2(db, sql, -1, &ifile, 0);
464 if (rc != SQLITE_OK) {
465 SQLERROR(sqlite3_errmsg(db));
471 sqlite3_bind_text(ifile, 1, hash, 64, SQLITE_STATIC);
473 rc = sqlite3_step(ifile);
474 } while (rc == SQLITE_ROW);
476 sqlite3_finalize(ifile);
478 return rc == SQLITE_DONE;
481 #define SQLERP(db, msg) fprintf(stderr, "%s: %s\n", msg, sqlite3_errmsg(db))
483 static int set_elf_info(struct zpm *zpm, char *hash, char *content,
492 sqlite3 *db = zpm->db;
494 if (length < sizeof (Elf64_Ehdr) || !libelf_iself(content)) {
495 /* not an elf file */
499 /* clear existing for this hash */
501 if (!run_for_hash(db, "delete from elflibraries where file = ?", hash)) {
502 SQLERP(db, "error clearing elf library");
506 if (!run_for_hash(db, "delete from elfneeded where file = ?", hash)) {
507 SQLERP(db, "error clearing elf needed");
511 hdr = libelf_header(content);
512 /* if lib, set soname */
513 if (libelf_type(content) == ET_DYN) {
514 char *soname = libelf_soname(content);
516 zpm_db_run(zpm, "insert into elflibraries (file,soname) values (%Q,%Q);", hash, soname);
521 /* some dyn don't have an soname, so we don't
525 /* if exe, set neededs */
526 /* libraries can have neededs too */
527 if (libelf_type(content) == ET_EXEC || libelf_type(content) == ET_DYN) {
528 Elf64_Shdr *dsect = 0;
531 elf = (char *)content;
532 /* find program header table */
533 for (i = 0; i < hdr->e_phnum; i++) {
534 phdr = (Elf64_Phdr *)(elf + hdr->e_phoff + i * hdr->e_phentsize);
535 if (phdr->p_type == PT_DYNAMIC) {
536 dsect = (Elf64_Shdr *)(elf + phdr->p_offset);
540 /* no dynamic section found */
544 dyn = (Elf64_Dyn *)dsect;
546 dsect = libelf_section(elf, SHT_DYNAMIC);
549 strsect = libelf_section_n(elf, dsect->sh_link);
550 strtab = elf + strsect->sh_offset;
552 sqlite3_prepare_v2(db, "insert into elfneeded (file,needed) values (?,?)",-1, &ifile, 0);
553 sqlite3_bind_text(ifile,1,hash,64,SQLITE_STATIC);
554 while (dyn->d_tag != DT_NULL) {
555 if (dyn->d_tag == DT_NEEDED) {
559 need = strtab + dyn->d_un.d_val;
560 if (strlen(need) == 0) continue;
561 sqlite3_bind_text(ifile,2,need,strlen(need),SQLITE_STATIC);
563 fprintf(stderr, "%s needs %s\n", hash, need);
565 rc = sqlite3_step(ifile);
566 if (rc != SQLITE_DONE) {
567 SQLERP(db, "error setting needed library");
568 sqlite3_finalize(ifile);
571 sqlite3_reset(ifile);
575 sqlite3_finalize(ifile);
580 int zpm_import(struct zpm *zpm, char *path, uint32_t flags, char *hash) {
584 unsigned char tmp[32];
585 struct sha256_state md;
586 sqlite3_stmt *ifile = 0;
587 int haverow = 0,havedata = 0;
595 if (!zpm || !zpm->db || !path) {
599 /* use local if caller didn't pass in room */
605 fprintf(stderr, "zpm_import unused flags = %d\n", flags);
608 fd = open(path, O_RDONLY);
611 fprintf(stderr, "%s can't open %s: %s\n", __FUNCTION__, path,strerror(errno));
614 if (fstat(fd, &sbuf) == -1) {
616 fprintf(stderr, "%s can't fstat %s: %s\n", __FUNCTION__, path,strerror(errno));
619 /* not a regular file? */
620 if (!S_ISREG(sbuf.st_mode)) {
622 switch (sbuf.st_mode & S_IFMT) {
623 case S_IFSOCK: ftype = "socket"; break;
624 case S_IFLNK : ftype = "symlink"; break;
625 case S_IFBLK : ftype = "block device"; break;
626 case S_IFDIR : ftype = "directory"; break;
627 case S_IFCHR : ftype = "character device"; break;
628 case S_IFIFO : ftype = "fifo"; break;
629 default: ftype = "unknown file type"; break;
631 /* TODO this is ok, just stored differently */
632 fprintf(stderr, "%s can't import %s file: %s\n", __FUNCTION__, ftype, path);
637 content = mmap(0, sbuf.st_size, PROT_READ,MAP_PRIVATE, fd, 0);
641 fprintf(stderr, "%s can't mmap %s: %s\n", __FUNCTION__, path,strerror(errno));
647 sha256_process(&md, content, sbuf.st_size);
648 sha256_done(&md, tmp);
650 sprintf(hash+j*2, "%02x", (unsigned)tmp[j]);
654 /* TODO check null */
655 sqlite3 *db = zpm->db;
657 /* prepare and bind */
659 rc = sqlite3_prepare_v2(db, "select size, content is not null from files where hash = ?", -1, &ifile,0);
660 if (rc != SQLITE_OK) {
661 SQLERROR(sqlite3_errmsg(db));
662 munmap(content, sbuf.st_size);
668 sqlite3_bind_text(ifile, 1, hash, 64, SQLITE_STATIC);
670 rc = sqlite3_step(ifile);
672 if (rc != SQLITE_DONE) {
673 if (rc != SQLITE_ROW) {
674 /* didn't find a row */
675 SQLERROR(sqlite3_errmsg(db));
676 munmap(content, sbuf.st_size);
680 type = sqlite3_column_type(ifile, 0);
681 if (type == SQLITE_NULL) {
682 /* TODO assert, this shouldn't be possible? */
683 fprintf(stderr, "no file size\n");
684 sqlite3_finalize(ifile);
685 munmap(content, sbuf.st_size);
688 type = sqlite3_column_type(ifile, 1);
689 if (type == SQLITE_NULL) {
690 /* TODO assert, this shouldn't be possible? */
691 fprintf(stderr, "no file data\n");
692 sqlite3_finalize(ifile);
693 munmap(content, sbuf.st_size);
695 /* which is fine, just need to update the row then */
697 havedata = sqlite3_column_int(ifile, 1);
700 sqlite3_finalize(ifile);
704 // fprintf(stderr, "compressing\n");
705 outbuf = compresslzma(content, sbuf.st_size, &outlen);
707 fprintf(stderr, "compresslzma failed\n");
708 munmap(content, sbuf.st_size);
711 //// fprintf(stderr, "compress finished\n");
715 rc = sqlite3_prepare_v2(db, "update files set size = ?, content = ? where hash = ?", -1, &ifile,0);
717 rc = sqlite3_prepare_v2(db, "insert into files (size, content, hash) values (?,?,?)", -1, &ifile,0);
720 if (rc != SQLITE_OK) {
721 SQLERROR(sqlite3_errmsg(db));
722 fprintf(stderr, "cant prepare data\n");
723 munmap(content, sbuf.st_size);
727 rc = sqlite3_bind_int64(ifile, 1, (sqlite3_int64)sbuf.st_size);
728 if (rc != SQLITE_OK) {
729 SQLERROR(sqlite3_errmsg(db));
730 sqlite3_finalize(ifile);
731 fprintf(stderr, "cant bind size\n");
732 munmap(content, sbuf.st_size);
736 rc = sqlite3_bind_blob64(ifile, 2, outbuf,
737 (sqlite3_int64)outlen, SQLITE_STATIC);
738 if (rc != SQLITE_OK) {
739 SQLERROR(sqlite3_errmsg(db));
740 sqlite3_finalize(ifile);
741 fprintf(stderr, "cant bind content\n");
742 munmap(content, sbuf.st_size);
746 rc = sqlite3_bind_text(ifile, 3, hash, 64, SQLITE_STATIC);
747 if (rc != SQLITE_OK) {
748 SQLERROR(sqlite3_errmsg(db));
749 fprintf(stderr, "cant bind hash\n");
750 sqlite3_finalize(ifile);
751 munmap(content, sbuf.st_size);
755 rc = sqlite3_step(ifile);
756 if (rc != SQLITE_DONE) {
757 SQLERROR(sqlite3_errmsg(db));
758 sqlite3_finalize(ifile);
759 munmap(content, sbuf.st_size);
762 sqlite3_finalize(ifile);
764 /* don't need the original file now */
767 if (!set_elf_info(zpm, hash, content, sbuf.st_size)) {
768 fprintf(stderr, "setting elf info failed\n");
769 munmap(content, sbuf.st_size);
773 munmap(content, sbuf.st_size);