int pkgdb_unregister_pkg(struct pkgdb *db, const char *origin) { sqlite3_stmt *stmt_del; int ret; const char sql[] = "DELETE FROM packages WHERE origin = ?1;"; if (db == NULL) return (ERROR_BAD_ARG("db")); if (origin == NULL) return (ERROR_BAD_ARG("origin")); if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt_del, NULL) != SQLITE_OK) return (ERROR_SQLITE(db->sqlite)); sqlite3_bind_text(stmt_del, 1, origin, -1, SQLITE_STATIC); ret = sqlite3_step(stmt_del); sqlite3_finalize(stmt_del); if (ret != SQLITE_DONE) return (ERROR_SQLITE(db->sqlite)); return (EPKG_OK); }
int pkg_delete(struct pkg *pkg, struct pkgdb *db, int force) { struct pkg **rdeps; int i, ret; struct sbuf *rdep_msg; if (pkg == NULL) return (ERROR_BAD_ARG("pkg")); if (db == NULL) return (ERROR_BAD_ARG("db")); /* * Ensure that we have all the informations we need */ if ((ret = pkgdb_loadrdeps(db, pkg)) != EPKG_OK) return (ret); if ((ret = pkgdb_loadfiles(db, pkg)) != EPKG_OK) return (ret); if ((ret = pkgdb_loadscripts(db, pkg)) != EPKG_OK) return (ret); if ((ret = pkgdb_loadmtree(db, pkg)) != EPKG_OK) return (ret); rdeps = pkg_rdeps(pkg); if (rdeps[0] != NULL) { rdep_msg = sbuf_new_auto(); sbuf_printf(rdep_msg, "%s-%s is required by other packages:", pkg_get(pkg, PKG_NAME), pkg_get(pkg, PKG_VERSION)); for (i = 0;rdeps[i] != NULL; i++) { sbuf_cat(rdep_msg, " "); sbuf_printf(rdep_msg, "%s-%s", pkg_get(rdeps[i], PKG_NAME), pkg_get(rdeps[i], PKG_VERSION)); } if (!force) { sbuf_finish(rdep_msg); ret = pkg_error_set(EPKG_REQUIRED, "%s", sbuf_get(rdep_msg)); sbuf_free(rdep_msg); return ret; } sbuf_cat(rdep_msg, ", deleting anyway"); sbuf_finish(rdep_msg); fprintf(stderr, "%s\n", sbuf_get(rdep_msg)); sbuf_free(rdep_msg); } if ((ret = pkg_script_pre_deinstall(pkg)) != EPKG_OK) return (ret); if ((ret = pkg_delete_files(pkg, force)) != EPKG_OK) return (ret); if ((ret = pkg_script_post_deinstall(pkg)) != EPKG_OK) return (ret); return (pkgdb_unregister_pkg(db, pkg_get(pkg, PKG_ORIGIN))); }
int pkgdb_compact(struct pkgdb *db) { int64_t page_count = 0; int64_t freelist_count = 0; char *errmsg; int retcode = EPKG_OK; if (db == NULL) return (ERROR_BAD_ARG("db")); if (get_pragma(db->sqlite, "PRAGMA page_count;", &page_count) != EPKG_OK) return (EPKG_FATAL); if (get_pragma(db->sqlite, "PRAGMA freelist_count;", &freelist_count) != EPKG_OK) return (EPKG_FATAL); /* * Only compact if we will save 25% (or more) of the current used space. */ if (freelist_count / (float)page_count < 0.25) return (EPKG_OK); if (sqlite3_exec(db->sqlite, "VACUUM;", NULL, NULL, &errmsg) != SQLITE_OK){ retcode = pkg_error_set(EPKG_FATAL, "%s", errmsg); sqlite3_free(errmsg); } return (retcode); }
int pkgdb_loadfiles(struct pkgdb *db, struct pkg *pkg) { sqlite3_stmt *stmt; struct pkg_file *f; int ret; const char sql[] = "" "SELECT path, sha256 " "FROM files " "WHERE package_id = ?1 " "ORDER BY PATH ASC"; const char sqldir[] = "" "SELECT path " "FROM pkg_dirs " "WHERE origin = ?1 " "ORDER by path DESC"; if (pkg->type != PKG_INSTALLED) return (ERROR_BAD_ARG("pkg")); if (pkg->flags & PKG_LOAD_FILES) return (EPKG_OK); array_init(&pkg->files, 10); if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) return (ERROR_SQLITE(db->sqlite)); sqlite3_bind_int64(stmt, 1, pkg->rowid); while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) { pkg_file_new(&f); strlcpy(f->path, sqlite3_column_text(stmt, 0), sizeof(f->path)); strlcpy(f->sha256, sqlite3_column_text(stmt, 1), sizeof(f->sha256)); array_append(&pkg->files, f); } sqlite3_finalize(stmt); if (ret != SQLITE_DONE) { array_reset(&pkg->files, &free); return (ERROR_SQLITE(db->sqlite)); } if (sqlite3_prepare_v2(db->sqlite, sqldir, -1, &stmt, NULL) != SQLITE_OK) return (ERROR_SQLITE(db->sqlite)); sqlite3_bind_text(stmt, 1, pkg_get(pkg, PKG_ORIGIN), -1, SQLITE_STATIC); while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) { pkg_file_new(&f); strlcpy(f->path, sqlite3_column_text(stmt, 0), sizeof(f->path)); array_append(&pkg->files, f); } sqlite3_finalize(stmt); pkg->flags |= PKG_LOAD_FILES; return (EPKG_OK); }
int pkg_script_run(struct pkg *pkg, pkg_script_t type) { struct pkg_script *script = NULL; pkg_script_t stype; struct sbuf *script_cmd = sbuf_new_auto(); size_t i; struct { const char *arg; const pkg_script_t b; const pkg_script_t a; } const map[] = { /* a implies b with argument arg */ {"PRE-INSTALL", PKG_SCRIPT_INSTALL, PKG_SCRIPT_PRE_INSTALL}, {"POST-INSTALL", PKG_SCRIPT_INSTALL, PKG_SCRIPT_POST_INSTALL}, {"PRE-UPGRADE", PKG_SCRIPT_UPGRADE, PKG_SCRIPT_PRE_UPGRADE}, {"POST-UPGRADE", PKG_SCRIPT_UPGRADE, PKG_SCRIPT_POST_UPGRADE}, {"DEINSTALL", PKG_SCRIPT_DEINSTALL, PKG_SCRIPT_PRE_DEINSTALL}, {"POST-DEINSTALL", PKG_SCRIPT_DEINSTALL, PKG_SCRIPT_POST_DEINSTALL}, }; for (i = 0; i < sizeof(map) / sizeof(map[0]); i++) { if (map[i].a == type) break; } if (map[i].a != type) return (ERROR_BAD_ARG("type")); while (pkg_scripts(pkg, &script) == EPKG_OK) { stype = pkg_script_type(script); if (stype == map[i].a || stype == map[i].b) { sbuf_reset(script_cmd); sbuf_printf(script_cmd, "PKG_PREFIX=%s\nset -- %s-%s", pkg_get(pkg, PKG_PREFIX), pkg_get(pkg, PKG_NAME), pkg_get(pkg, PKG_VERSION)); if (stype == map[i].b) { /* add arg **/ sbuf_cat(script_cmd, " "); sbuf_cat(script_cmd, map[i].arg); } sbuf_cat(script_cmd, "\n"); sbuf_cat(script_cmd, pkg_script_data(script)); sbuf_finish(script_cmd); system(sbuf_data(script_cmd)); } } sbuf_delete(script_cmd); return (EPKG_OK); }
int file_to_buffer(const char *path, char **buffer, off_t *sz) { int fd; struct stat st; if (path == NULL || path[0] == '\0') return (ERROR_BAD_ARG("path")); if (buffer == NULL) return (ERROR_BAD_ARG("buffer")); if ((fd = open(path, O_RDONLY)) == -1) { return (pkg_error_set(EPKG_FATAL, "can not open %s: %s", path, strerror(errno))); } if (fstat(fd, &st) == -1) { close(fd); return (pkg_error_set(EPKG_FATAL, "fstat(): %s", strerror(errno))); } if ((*buffer = malloc(st.st_size + 1)) == NULL) { close(fd); return (pkg_error_set(EPKG_FATAL, "malloc(): %s", strerror(errno))); } if (read(fd, *buffer, st.st_size) == -1) { close(fd); return (pkg_error_set(EPKG_FATAL, "read(): %s", strerror(errno))); } close(fd); /* NULL terminate the buffer so it can be used by stdio.h functions */ (*buffer)[st.st_size] = '\0'; *sz = st.st_size; return (EPKG_OK); }
int pkgdb_loaddeps(struct pkgdb *db, struct pkg *pkg) { sqlite3_stmt *stmt; struct pkgdb_it it; struct pkg *p; int ret; const char sql[] = "" "SELECT p.rowid, p.origin, p.name, p.version, p.comment, p.desc, " "p.message, p.arch, p.osversion, p.maintainer, p.www, " "p.prefix, p.flatsize " "FROM packages AS p, deps AS d " "WHERE p.origin = d.origin " "AND d.package_id = ?1;"; if (pkg->type != PKG_INSTALLED) return (ERROR_BAD_ARG("pkg")); if (pkg->flags & PKG_LOAD_DEPS) return (EPKG_OK); array_init(&pkg->deps, 10); if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) return (ERROR_SQLITE(db->sqlite)); sqlite3_bind_int64(stmt, 1, pkg->rowid); it.stmt = stmt; it.db = db; p = NULL; while ((ret = pkgdb_it_next(&it, &p, PKG_LOAD_BASIC)) == EPKG_OK) { array_append(&pkg->deps, p); p = NULL; } sqlite3_finalize(stmt); if (ret != EPKG_END) { array_reset(&pkg->deps, &pkg_free_void); return (ret); } pkg->flags |= PKG_LOAD_DEPS; return (EPKG_OK); }
int pkg_create_installed(const char *outdir, pkg_formats format, const char *rootdir, struct pkg *pkg) { struct packing *pkg_archive; int required_flags = PKG_LOAD_DEPS | PKG_LOAD_CONFLICTS | PKG_LOAD_FILES | PKG_LOAD_SCRIPTS | PKG_LOAD_OPTIONS | PKG_LOAD_MTREE; if (pkg->type != PKG_INSTALLED) return (ERROR_BAD_ARG("pkg")); pkg_archive = pkg_create_archive(outdir, pkg, format, required_flags); if (pkg_archive == NULL) return pkg_error_set(EPKG_FATAL, "unable to create archive"); /* XXX do better */ pkg_create_from_dir(pkg, rootdir, pkg_archive); return packing_finish(pkg_archive); }
int pkgdb_loadoptions(struct pkgdb *db, struct pkg *pkg) { sqlite3_stmt *stmt; struct pkg_option *o; int ret; const char sql[] = "" "SELECT option, value " "FROM options " "WHERE package_id = ?1"; if (pkg->type != PKG_INSTALLED) return (ERROR_BAD_ARG("pkg")); if (pkg->flags & PKG_LOAD_OPTIONS) return (EPKG_OK); array_init(&pkg->options, 5); if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) return (ERROR_SQLITE(db->sqlite)); sqlite3_bind_int64(stmt, 1, pkg->rowid); while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) { pkg_option_new(&o); sbuf_set(&o->opt, sqlite3_column_text(stmt, 0)); sbuf_set(&o->value, sqlite3_column_text(stmt, 1)); array_append(&pkg->options, o); } sqlite3_finalize(stmt); if (ret != SQLITE_DONE) { array_reset(&pkg->options, &pkg_option_free_void); return (ERROR_SQLITE(db->sqlite)); } pkg->flags |= PKG_LOAD_OPTIONS; return (EPKG_OK); }
int pkgdb_loadscripts(struct pkgdb *db, struct pkg *pkg) { sqlite3_stmt *stmt; struct pkg_script *s; int ret; const char sql[] = "" "SELECT script, type " "FROM scripts " "WHERE package_id = ?1"; if (pkg->type != PKG_INSTALLED) return (ERROR_BAD_ARG("pkg")); if (pkg->flags & PKG_LOAD_SCRIPTS) return (EPKG_OK); array_init(&pkg->scripts, 6); if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) return (ERROR_SQLITE(db->sqlite)); sqlite3_bind_int64(stmt, 1, pkg->rowid); while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) { pkg_script_new(&s); sbuf_set(&s->data, sqlite3_column_text(stmt, 0)); s->type = sqlite3_column_int(stmt, 1); array_append(&pkg->scripts, s); } sqlite3_finalize(stmt); if (ret != SQLITE_DONE) { array_reset(&pkg->scripts, &pkg_script_free_void); return (ERROR_SQLITE(db->sqlite)); } pkg->flags |= PKG_LOAD_SCRIPTS; return (EPKG_OK); }
int pkgdb_loadconflicts(struct pkgdb *db, struct pkg *pkg) { sqlite3_stmt *stmt; struct pkg_conflict *c; int ret; const char sql[] = "" "SELECT name " "FROM conflicts " "WHERE package_id = ?1;"; if (pkg->type != PKG_INSTALLED) return (ERROR_BAD_ARG("pkg")); if (pkg->flags & PKG_LOAD_CONFLICTS) return (EPKG_OK); array_init(&pkg->conflicts, 5); if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) return (ERROR_SQLITE(db->sqlite)); sqlite3_bind_int64(stmt, 1, pkg->rowid); while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) { pkg_conflict_new(&c); sbuf_set(&c->glob, sqlite3_column_text(stmt, 0)); array_append(&pkg->conflicts, c); } sqlite3_finalize(stmt); if (ret != SQLITE_DONE) { array_reset(&pkg->conflicts, &pkg_conflict_free_void); return (ERROR_SQLITE(db->sqlite)); } pkg->flags |= PKG_LOAD_CONFLICTS; return (EPKG_OK); }
int pkgdb_loadmtree(struct pkgdb *db, struct pkg *pkg) { sqlite3_stmt *stmt; int ret; const char sql[] = "" "SELECT m.content " "FROM mtree AS m, packages AS p " "WHERE m.id = p.mtree_id " " AND p.id = ?1;"; if (pkg->type != PKG_INSTALLED) return (ERROR_BAD_ARG("pkg")); if (pkg->flags & PKG_LOAD_MTREE) return (EPKG_OK); if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) return (ERROR_SQLITE(db->sqlite)); sqlite3_bind_int64(stmt, 1, pkg->rowid); ret = sqlite3_step(stmt); if (ret == SQLITE_ROW) { sbuf_set(&pkg->fields[PKG_MTREE].value, sqlite3_column_text(stmt, 0)); ret = SQLITE_DONE; } sqlite3_finalize(stmt); if (ret != SQLITE_DONE) return (ERROR_SQLITE(db->sqlite)); pkg->flags |= PKG_LOAD_MTREE; return (EPKG_OK); }
struct pkgdb_it * pkgdb_query(struct pkgdb *db, const char *pattern, match_t match) { char sql[BUFSIZ]; sqlite3_stmt *stmt; const char *comp = NULL; char *checkorigin = NULL; if (match != MATCH_ALL && pattern == NULL) { ERROR_BAD_ARG("pattern"); return (NULL); } if (pattern != NULL) checkorigin = strchr(pattern, '/'); switch (match) { case MATCH_ALL: comp = ""; break; case MATCH_EXACT: if (checkorigin == NULL) comp = " WHERE p.name = ?1"; else comp = " WHERE p.origin = ?1"; break; case MATCH_GLOB: if (checkorigin == NULL) comp = " WHERE p.name GLOB ?1"; else comp = " WHERE p.origin GLOB ?1"; break; case MATCH_REGEX: if (checkorigin == NULL) comp = " WHERE p.name REGEXP ?1"; else comp = " WHERE p.origin REGEXP ?1"; break; case MATCH_EREGEX: if (checkorigin == NULL) comp = " WHERE EREGEXP(?1, p.name)"; else comp = " WHERE EREGEXP(?1, p.origin)"; break; } snprintf(sql, sizeof(sql), "SELECT p.rowid, p.origin, p.name, p.version, p.comment, p.desc, " "p.message, p.arch, p.osversion, p.maintainer, p.www, " "p.prefix, p.flatsize " "FROM packages AS p%s " "ORDER BY p.name;", comp); if (sqlite3_prepare_v2(db->sqlite, sql, -1, &stmt, NULL) != SQLITE_OK) { ERROR_SQLITE(db->sqlite); return (NULL); } if (match != MATCH_ALL) sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_TRANSIENT); return (pkgdb_it_new(db, stmt, IT_LOCAL)); }
int pkgdb_it_next(struct pkgdb_it *it, struct pkg **pkg_p, int flags) { struct pkg *pkg; int ret; if (it == NULL) return (ERROR_BAD_ARG("it")); switch (sqlite3_step(it->stmt)) { case SQLITE_ROW: if (*pkg_p == NULL) pkg_new(pkg_p, PKG_INSTALLED); else pkg_reset(*pkg_p, PKG_INSTALLED); pkg = *pkg_p; pkg->rowid = sqlite3_column_int64(it->stmt, 0); pkg_set(pkg, PKG_ORIGIN, sqlite3_column_text(it->stmt, 1)); pkg_set(pkg, PKG_NAME, sqlite3_column_text(it->stmt, 2)); pkg_set(pkg, PKG_VERSION, sqlite3_column_text(it->stmt, 3)); pkg_set(pkg, PKG_COMMENT, sqlite3_column_text(it->stmt, 4)); pkg_set(pkg, PKG_DESC, sqlite3_column_text(it->stmt, 5)); pkg_set(pkg, PKG_MESSAGE, sqlite3_column_text(it->stmt, 6)); pkg_set(pkg, PKG_ARCH, sqlite3_column_text(it->stmt, 7)); pkg_set(pkg, PKG_OSVERSION, sqlite3_column_text(it->stmt, 8)); pkg_set(pkg, PKG_MAINTAINER, sqlite3_column_text(it->stmt, 9)); pkg_set(pkg, PKG_WWW, sqlite3_column_text(it->stmt, 10)); pkg_set(pkg, PKG_PREFIX, sqlite3_column_text(it->stmt, 11)); pkg_setflatsize(pkg, sqlite3_column_int64(it->stmt, 12)); if (it->type == IT_UPGRADE) { pkg->type = PKG_UPGRADE; pkg_set(pkg, PKG_NEWVERSION, sqlite3_column_text(it->stmt, 13)); pkg_setnewflatsize(pkg, sqlite3_column_int64(it->stmt, 14)); pkg_setnewpkgsize(pkg, sqlite3_column_int64(it->stmt, 15)); pkg_set(pkg, PKG_REPOPATH, sqlite3_column_text(it->stmt, 16)); } if (flags & PKG_LOAD_DEPS) if ((ret = pkgdb_loaddeps(it->db, pkg)) != EPKG_OK) return (ret); if (flags & PKG_LOAD_RDEPS) if ((ret = pkgdb_loadrdeps(it->db, pkg)) != EPKG_OK) return (ret); if (flags & PKG_LOAD_CONFLICTS) if ((ret = pkgdb_loadconflicts(it->db, pkg)) != EPKG_OK) return (ret); if (flags & PKG_LOAD_FILES) if ((ret = pkgdb_loadfiles(it->db, pkg)) != EPKG_OK) return (ret); if (flags & PKG_LOAD_SCRIPTS) if ((ret = pkgdb_loadscripts(it->db, pkg)) != EPKG_OK) return (ret); if (flags & PKG_LOAD_OPTIONS) if ((ret = pkgdb_loadoptions(it->db, pkg)) != EPKG_OK) return (ret); if (flags & PKG_LOAD_MTREE) if ((ret = pkgdb_loadmtree(it->db, pkg)) != EPKG_OK) return (ret); return (EPKG_OK); case SQLITE_DONE: return (EPKG_END); default: return (ERROR_SQLITE(it->db->sqlite)); } }