X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=lib%2Fzpm.c;h=b8b77b0861b2e3f9a28d16b71fbe56f54ab0425a;hb=b7a4dd34227b6cf84908ffde9f2c4395f29fe1b4;hp=b5c362f818fd3ae2b2a0af70c7a30bbff652934f;hpb=3d3b00b1d14f9126bb9b3b83935ef0ffd9aa3501;p=zpackage diff --git a/lib/zpm.c b/lib/zpm.c index b5c362f..b8b77b0 100644 --- a/lib/zpm.c +++ b/lib/zpm.c @@ -114,18 +114,6 @@ void uncompresslzma(void *buf, size_t bufsize, FILE *out); #define SQLERROR(x) fprintf(stderr, "%s %d: %s\n", __func__, __LINE__, (x)) #endif -static char *dupstr(char *s) { - size_t n; - char *d; - - n = strlen(s); - d = malloc(n+1); - if (d) { - d = strcpy(d, s); - } - return d; -} - #if 0 int zpm_newpkg(struct zpm *z, char *base, char *version, int release) { char *sql = "insert or ignore into packages (package,version,release) values (?,?,?)"; @@ -284,18 +272,63 @@ int zpm_db_initialize(struct zpm *pkg) { return 1; } -/* NULL? Create? */ -int zpm_open(struct zpm *pkg, char *path) { - int rc; + +/* assumes pkg->db is set */ +static int setupdb(struct zpm *zpm) { char *errstr = 0; - sqlite3 *db = 0; int appid, dbver; - pkg->db = 0; - pkg->path = 0; - pkg->current_package = 0; - pkg->pkgid = 0; - pkg->errmsg = 0; + zpm->error = 0; + + appid = zpm_db_pragma(zpm, 1); + dbver = zpm_db_pragma(zpm, 2); + + if (appid != 0x5a504442) { + fprintf(stderr, "unknown database type\n"); + zpm->error = 1; + return 0; + } + + if (dbver > 1) { + fprintf(stderr, "version %d zpm db detected, this program only works with version 1 databases\n", dbver); + zpm->error = 1; + return 0; + } + + sqlite3_exec(zpm->db, "pragma foreign_keys = ON;", NULL, NULL, &errstr); + + if (errstr) { + free(zpm->errmsg); + zpm->errmsg = strdup(errstr); + fprintf(stderr, "sqlite foreign key error: %s\n", errstr); + sqlite3_free(errstr); + zpm->error = 1; + return 0; + } + + /* TODO add vercmp */ + + return 1; +} + +struct zpm *zpm_clearmem(struct zpm *zpm) { + if (!zpm) { + zpm = malloc(sizeof *zpm); + } + + if (zpm) { + *zpm = (struct zpm){0}; + } + + return zpm; +} + +int zpm_init(struct zpm *pkg, char *path) { + int rc; + sqlite3 *db = 0; + int appid; + + zpm_clearmem(pkg); rc = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); if (rc) { @@ -304,43 +337,61 @@ int zpm_open(struct zpm *pkg, char *path) { return 0; } pkg->db = db; - pkg->path = dupstr(path); + pkg->path = strdup(path); appid = zpm_db_pragma(pkg, 1); - dbver = zpm_db_pragma(pkg, 2); - //fprintf(stderr, "db appid = %x, dbver = %d\n", appid, dbver); switch (appid) { case 0: if (!zpm_db_initialize(pkg)) { sqlite3_close(db); return 1; }; break; - case 0x5a504442: break; + case 0x5a504442: + /* already initialized */ + break; default: fprintf(stderr, "unknown database type\n"); sqlite3_close(db); return 0; break; } - if (dbver > 1) { - fprintf(stderr, "version %d zpm db detected, this program only works with version 1 databases\n", dbver); - sqlite3_close(db); - return 0; - } - sqlite3_exec(pkg->db, "pragma foreign_keys = ON;", NULL, NULL, &errstr); - if (errstr) { - fprintf(stderr, "sqlite foreign key error: %s\n", errstr); - sqlite3_free(errstr); + if (!setupdb(pkg)) { sqlite3_close(db); + pkg->db = 0; return 0; } + zpm_addvercmp(pkg); + + return 1; +} + +int zpm_open(struct zpm *zpm, char *path) { + int rc; + sqlite3 *db = 0; + zpm_clearmem(zpm); - /* TODO if this is a new database, create structures */ + rc = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE, NULL); + if (rc) { + SQLERROR(sqlite3_errmsg(db)); + sqlite3_close(db); + zpm->error = 1; + fprintf(stderr, "path = %s\n", path); + return 0; + } + zpm->db = db; + zpm->path = strdup(path); + + if (!setupdb(zpm)) { + sqlite3_close(db); + zpm->db = 0; + zpm->error = 1; + return 0; + } + zpm_addvercmp(zpm); - /* get a package. what if more than one? what if none? */ return 1; } @@ -369,37 +420,6 @@ int zpm_addvercmp(struct zpm *pkg) { ); } -/* set package struct variables, database, environment, then command line */ -int zpm_readopts(struct zpm *zpm, int ac, char **av) { - char *ev; - struct zpm_package *pkg; - - if (!zpm) { - return -1; - } - - pkg = zpm->current_package; - - if (pkg) { - ev = getenv("ZPMPACKAGE"); - if (ev) { - pkg->name = dupstr(ev); - } - ev = getenv("ZPMPKGREL"); - if (ev) { - pkg->release = strtol(ev, 0, 0); - } - ev = getenv("ZPMPKGVER"); - if (ev) { - pkg->version = dupstr(ev); - } - } - - /* now, parse the options, return optind so the caller can adjust if needed */ - - return av ? ac : 1; -} - int zpm_extract(struct zpm *pkg, char *hash, char *path, int mode) { int rc; @@ -482,7 +502,7 @@ int zpm_extract(struct zpm *pkg, char *hash, char *path, int mode) { return 1; } -static sqlite3_stmt *run_for_hash(sqlite3 *db, char *sql, char *hash) { +static int run_for_hash(sqlite3 *db, char *sql, char *hash) { int rc; sqlite3_stmt *ifile; @@ -495,10 +515,17 @@ static sqlite3_stmt *run_for_hash(sqlite3 *db, char *sql, char *hash) { /* hash, filename */ sqlite3_bind_text(ifile, 1, hash, 64, SQLITE_STATIC); + do { + rc = sqlite3_step(ifile); + } while (rc == SQLITE_ROW); - return ifile; + sqlite3_finalize(ifile); + + return rc == SQLITE_DONE; } +#define SQLERP(db, msg) fprintf(stderr, "%s: %s\n", msg, sqlite3_errmsg(db)) + static int set_elf_info(sqlite3 *db, char *hash, char *content, size_t length) { if (length >= sizeof (Elf64_Ehdr) && libelf_iself(content)) { char *strtab; @@ -509,54 +536,21 @@ static int set_elf_info(sqlite3 *db, char *hash, char *content, size_t length) { sqlite3_stmt *ifile; int rc; - /* go ahead and set up elf information now */ /* clear existing for this hash */ - ifile = run_for_hash(db, "delete from elfinfo where file = ?", hash); - do { - rc = sqlite3_step(ifile); -#if 0 - if (rc == SQLITE_ROW) { - int nc; - fprintf(stderr, "delete row has %d columns: ", sqlite3_column_count(ifile)); - nc = sqlite3_column_count(ifile); - for (i = 0; i < nc; i++) { - char *r; - r = sqlite3_column_text(ifile, i); - fprintf(stderr, ", %s", r); - } - fprintf(stderr, "\n"); - } -#endif - } while (rc == SQLITE_ROW); - if (rc != SQLITE_DONE) { - SQLERROR(sqlite3_errmsg(db)); - sqlite3_finalize(ifile); - fprintf(stderr, "error clearing elf info: %d\n", rc); + if (!run_for_hash(db, "delete from elfinfo where file = ?", hash)) { + SQLERP(db, "error clearing elf info"); return 0; } - sqlite3_finalize(ifile); - ifile = run_for_hash(db, "delete from elflibraries where file = ?", hash); - do { - rc = sqlite3_step(ifile); - } while (rc == SQLITE_ROW); - if (rc != SQLITE_DONE) { - SQLERROR(sqlite3_errmsg(db)); - sqlite3_finalize(ifile); - fprintf(stderr, "error clearing elf library: %d\n", rc); + + if (!run_for_hash(db, "delete from elflibraries where file = ?", hash)) { + SQLERP(db, "error clearing elf library"); return 0; } - sqlite3_finalize(ifile); - ifile = run_for_hash(db, "delete from elfneeded where file = ?", hash); - do { - rc = sqlite3_step(ifile); - } while (rc == SQLITE_ROW); - if (rc != SQLITE_DONE) { - SQLERROR(sqlite3_errmsg(db)); - sqlite3_finalize(ifile); - fprintf(stderr, "error clearing elf needed\n"); + + if (!run_for_hash(db, "delete from elfneeded where file = ?", hash)) { + SQLERP(db, "error clearing elf needed"); return 0; } - sqlite3_finalize(ifile); hdr = libelf_header(content); /* if lib, set soname */ @@ -620,9 +614,8 @@ static int set_elf_info(sqlite3 *db, char *hash, char *content, size_t length) { #endif rc = sqlite3_step(ifile); if (rc != SQLITE_DONE) { - SQLERROR(sqlite3_errmsg(db)); + SQLERP(db, "error setting needed library"); sqlite3_finalize(ifile); - fprintf(stderr, "error setting needed library\n"); return 0; } sqlite3_reset(ifile);