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) {
269 rc = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE, NULL);
271 SQLERROR(sqlite3_errmsg(db));
274 fprintf(stderr, "path = %s\n", path);
278 zpm->path = strdup(path);
291 int zpm_close(struct zpm *pkg) {
293 sqlite3_close(pkg->db);
296 /* TODO free any malloced names and such */
300 static int zpm_sqlite_vercmp(void *not_used, int lena, const void *a,
301 int lenb, const void *b) {
302 /* not sure what the ints are, possibly string lengths */
303 if (not_used != 0) fprintf(stderr, "sqlite vercmp not_used = %p\n",
305 if (lena == 0 && lenb > 0) return 1;
306 return zpm_vercmp(a, b);
309 int zpm_addvercmp(struct zpm *pkg) {
310 return sqlite3_create_collation(
311 pkg->db, "vercmp", SQLITE_UTF8, NULL,
316 int zpm_extract(struct zpm *pkg, char *hash, char *path, mode_t mode) {
327 if (!pkg || !pkg->db) {
332 rc = sqlite3_prepare(db, "select size, content from files where hash = ?", -1, &ifile,0);
333 if (rc != SQLITE_OK) {
334 SQLERROR(sqlite3_errmsg(db));
340 sqlite3_bind_text(ifile, 1, hash, 64, SQLITE_STATIC);
342 rc = sqlite3_step(ifile);
344 if (rc == SQLITE_DONE) {
345 /* didn't find a row */
346 sqlite3_finalize(ifile);
348 fprintf(stderr, "no such hash: %s\n", hash);
351 /* either way we're done with this now */
353 if (rc != SQLITE_ROW) {
354 SQLERROR(sqlite3_errmsg(db));
355 sqlite3_finalize(ifile);
360 type = sqlite3_column_type(ifile, 0);
361 if (type == SQLITE_NULL) {
362 fprintf(stderr, "no file size\n");
363 sqlite3_finalize(ifile);
367 type = sqlite3_column_type(ifile, 1);
368 if (type == SQLITE_NULL) {
369 fprintf(stderr, "no file data\n");
370 sqlite3_finalize(ifile);
374 //size = sqlite3_column_int64(ifile, 0);
375 xzdata = (void *)sqlite3_column_blob(ifile, 1);
376 blobsize = sqlite3_column_bytes(ifile, 1);
378 if (strcmp(path, "-")) {
380 tmpfile = malloc(len+8+1);
382 fprintf(stderr, "malloc error\n");
385 sprintf(tmpfile, "%sXXXXXX", path);
387 out = open(tmpfile, O_CREAT|O_WRONLY|O_TRUNC, 0600);
389 fprintf(stderr, "can't open output file %s: %s\n",
390 tmpfile, strerror(errno));
391 sqlite3_finalize(ifile);
400 fprintf(stderr, "uncompressing %d bytes at %p, expect %lld\n", blobsize, xzdata, (long long int)size);
402 uncompresslzma(xzdata, blobsize, out);
404 sqlite3_finalize(ifile);
408 if (chmod(tmpfile, mode) == -1) {
409 fprintf(stderr, "can't chmod %s: %s\n", tmpfile,
412 } else if (rename(tmpfile, path) == -1) {
413 fprintf(stderr, "extract rename failed: %s\n",
419 if (rc == 0 && tmpfile) {
420 if (unlink(tmpfile) == -1) {
421 fprintf(stderr, "unlink tmpfile %s fail: %s\n",
430 static int run_for_hash(sqlite3 *db, char *sql, char *hash) {
434 rc = sqlite3_prepare_v2(db, sql, -1, &ifile, 0);
435 if (rc != SQLITE_OK) {
436 SQLERROR(sqlite3_errmsg(db));
442 sqlite3_bind_text(ifile, 1, hash, 64, SQLITE_STATIC);
444 rc = sqlite3_step(ifile);
445 } while (rc == SQLITE_ROW);
447 sqlite3_finalize(ifile);
449 return rc == SQLITE_DONE;
452 #define SQLERP(db, msg) fprintf(stderr, "%s: %s\n", msg, sqlite3_errmsg(db))
454 static int set_elf_info(sqlite3 *db, char *hash, char *content, size_t length) {
455 if (length >= sizeof (Elf64_Ehdr) && libelf_iself(content)) {
464 /* clear existing for this hash */
466 if (!run_for_hash(db, "delete from elflibraries where file = ?", hash)) {
467 SQLERP(db, "error clearing elf library");
471 if (!run_for_hash(db, "delete from elfneeded where file = ?", hash)) {
472 SQLERP(db, "error clearing elf needed");
476 hdr = libelf_header(content);
477 /* if lib, set soname */
478 if (libelf_type(content) == ET_DYN) {
479 char *soname = libelf_soname(content);
482 sqlite3_prepare_v2(db, "insert into elflibraries (file,soname) values (?,?)",-1, &ifile, 0);
483 sqlite3_bind_text(ifile,1,hash,64,SQLITE_STATIC);
484 sqlite3_bind_text(ifile,2,soname,-1,SQLITE_STATIC);
485 rc = sqlite3_step(ifile);
486 if (rc != SQLITE_DONE) {
487 SQLERROR(sqlite3_errmsg(db));
488 sqlite3_finalize(ifile);
489 fprintf(stderr, "error setting library soname\n");
492 sqlite3_finalize(ifile);
494 fprintf(stderr, "can't find soname\n");
498 /* if exe, set neededs */
499 if (libelf_type(content) == ET_EXEC) {
500 Elf64_Shdr *dsect = 0;
503 elf = (char *)content;
504 /* find program header table */
505 for (i = 0; i < hdr->e_phnum; i++) {
506 phdr = (Elf64_Phdr *)(elf + hdr->e_phoff + i * hdr->e_phentsize);
507 if (phdr->p_type == PT_DYNAMIC) {
508 dsect = (Elf64_Shdr *)(elf + phdr->p_offset);
512 /* no dynamic section found */
517 dyn = (Elf64_Dyn *)(elf + dsect->sh_offset);
522 dyn = (Elf64_Dyn *)dsect;
524 dsect = libelf_section(elf, SHT_DYNAMIC);
527 strsect = libelf_section_n(elf, dsect->sh_link);
528 strtab = elf + strsect->sh_offset;
530 sqlite3_prepare_v2(db, "insert into elfneeded (file,needed) values (?,?)",-1, &ifile, 0);
531 sqlite3_bind_text(ifile,1,hash,64,SQLITE_STATIC);
532 while (dyn->d_tag != DT_NULL) {
533 if (dyn->d_tag == DT_NEEDED) {
537 need = strtab + dyn->d_un.d_val;
538 if (strlen(need) == 0) continue;
539 sqlite3_bind_text(ifile,2,need,strlen(need),SQLITE_STATIC);
541 fprintf(stderr, "%s needs %s\n", hash, need);
543 rc = sqlite3_step(ifile);
544 if (rc != SQLITE_DONE) {
545 SQLERP(db, "error setting needed library");
546 sqlite3_finalize(ifile);
549 sqlite3_reset(ifile);
553 sqlite3_finalize(ifile);
559 int zpm_import(struct zpm *zpm, char *path, uint32_t flags, char *hash) {
563 unsigned char tmp[32];
564 struct sha256_state md;
565 sqlite3_stmt *ifile = 0;
566 int haverow = 0,havedata = 0;
574 if (!zpm || !zpm->db || !path) {
578 /* use local if caller didn't pass in room */
584 fprintf(stderr, "zpm_import unused flags = %d\n", flags);
587 fd = open(path, O_RDONLY);
590 fprintf(stderr, "%s can't open %s: %s\n", __FUNCTION__, path,strerror(errno));
593 if (fstat(fd, &sbuf) == -1) {
595 fprintf(stderr, "%s can't fstat %s: %s\n", __FUNCTION__, path,strerror(errno));
598 /* not a regular file? */
599 if (!S_ISREG(sbuf.st_mode)) {
601 switch (sbuf.st_mode & S_IFMT) {
602 case S_IFSOCK: ftype = "socket"; break;
603 case S_IFLNK : ftype = "symlink"; break;
604 case S_IFBLK : ftype = "block device"; break;
605 case S_IFDIR : ftype = "directory"; break;
606 case S_IFCHR : ftype = "character device"; break;
607 case S_IFIFO : ftype = "fifo"; break;
608 default: ftype = "unknown file type"; break;
610 /* TODO this is ok, just stored differently */
611 fprintf(stderr, "%s can't import %s file: %s\n", __FUNCTION__, ftype, path);
616 content = mmap(0, sbuf.st_size, PROT_READ,MAP_PRIVATE, fd, 0);
620 fprintf(stderr, "%s can't mmap %s: %s\n", __FUNCTION__, path,strerror(errno));
626 sha256_process(&md, content, sbuf.st_size);
627 sha256_done(&md, tmp);
629 sprintf(hash+j*2, "%02x", (unsigned)tmp[j]);
633 /* TODO check null */
634 sqlite3 *db = zpm->db;
636 /* prepare and bind */
638 rc = sqlite3_prepare_v2(db, "select size, content is not null from files where hash = ?", -1, &ifile,0);
639 if (rc != SQLITE_OK) {
640 SQLERROR(sqlite3_errmsg(db));
641 munmap(content, sbuf.st_size);
647 sqlite3_bind_text(ifile, 1, hash, 64, SQLITE_STATIC);
649 rc = sqlite3_step(ifile);
651 if (rc != SQLITE_DONE) {
652 if (rc != SQLITE_ROW) {
653 /* didn't find a row */
654 SQLERROR(sqlite3_errmsg(db));
655 munmap(content, sbuf.st_size);
659 type = sqlite3_column_type(ifile, 0);
660 if (type == SQLITE_NULL) {
661 /* TODO assert, this shouldn't be possible? */
662 fprintf(stderr, "no file size\n");
663 sqlite3_finalize(ifile);
664 munmap(content, sbuf.st_size);
667 type = sqlite3_column_type(ifile, 1);
668 if (type == SQLITE_NULL) {
669 /* TODO assert, this shouldn't be possible? */
670 fprintf(stderr, "no file data\n");
671 sqlite3_finalize(ifile);
672 munmap(content, sbuf.st_size);
674 /* which is fine, just need to update the row then */
676 havedata = sqlite3_column_int(ifile, 1);
679 sqlite3_finalize(ifile);
683 outbuf = compresslzma(content, sbuf.st_size, &outlen);
685 fprintf(stderr, "compresslzma failed\n");
686 munmap(content, sbuf.st_size);
692 rc = sqlite3_prepare_v2(db, "update files set size = ?, content = ? where hash = ?", -1, &ifile,0);
694 rc = sqlite3_prepare_v2(db, "insert into files (size, content, hash) values (?,?,?)", -1, &ifile,0);
697 if (rc != SQLITE_OK) {
698 SQLERROR(sqlite3_errmsg(db));
699 fprintf(stderr, "cant prepare data\n");
700 munmap(content, sbuf.st_size);
704 rc = sqlite3_bind_int64(ifile, 1, (sqlite3_int64)sbuf.st_size);
705 if (rc != SQLITE_OK) {
706 SQLERROR(sqlite3_errmsg(db));
707 sqlite3_finalize(ifile);
708 fprintf(stderr, "cant bind size\n");
709 munmap(content, sbuf.st_size);
713 rc = sqlite3_bind_blob64(ifile, 2, outbuf,
714 (sqlite3_int64)outlen, SQLITE_STATIC);
715 if (rc != SQLITE_OK) {
716 SQLERROR(sqlite3_errmsg(db));
717 sqlite3_finalize(ifile);
718 fprintf(stderr, "cant bind content\n");
719 munmap(content, sbuf.st_size);
723 rc = sqlite3_bind_text(ifile, 3, hash, 64, SQLITE_STATIC);
724 if (rc != SQLITE_OK) {
725 SQLERROR(sqlite3_errmsg(db));
726 fprintf(stderr, "cant bind hash\n");
727 sqlite3_finalize(ifile);
728 munmap(content, sbuf.st_size);
732 rc = sqlite3_step(ifile);
733 if (rc != SQLITE_DONE) {
734 SQLERROR(sqlite3_errmsg(db));
735 sqlite3_finalize(ifile);
736 munmap(content, sbuf.st_size);
739 sqlite3_finalize(ifile);
741 /* don't need the original file now */
744 if (!set_elf_info(zpm->db, hash, content, sbuf.st_size)) {
745 fprintf(stderr, "setting elf info failed\n");
746 munmap(content, sbuf.st_size);
750 munmap(content, sbuf.st_size);