struct pkg_repo_it * pkg_repo_binary_shlib_require(struct pkg_repo *repo, const char *provide) { sqlite3_stmt *stmt; sqlite3 *sqlite = PRIV_GET(repo); UT_string *sql = NULL; int ret; const char basesql[] = "" "SELECT p.id, p.origin, p.name, p.version, p.comment, " "p.name as uniqueid, " "p.prefix, p.desc, p.arch, p.maintainer, p.www, " "p.licenselogic, p.flatsize, p.pkgsize, " "p.cksum, p.manifestdigest, p.path AS repopath, '%s' AS dbname " "FROM packages AS p INNER JOIN pkg_shlibs_required AS ps ON " "p.id = ps.package_id " "WHERE ps.shlib_id = (SELECT id FROM shlibs WHERE name=?1);"; utstring_new(sql); utstring_printf(sql, basesql, repo->name); pkg_debug(4, "Pkgdb: running '%s'", utstring_body(sql)); ret = sqlite3_prepare_v2(sqlite, utstring_body(sql), -1, &stmt, NULL); if (ret != SQLITE_OK) { ERROR_SQLITE(sqlite, utstring_body(sql)); utstring_free(sql); return (NULL); } utstring_free(sql); pkg_debug(1, "> loading provides"); sqlite3_bind_text(stmt, 1, provide, -1, SQLITE_TRANSIENT); return (pkg_repo_binary_it_new(repo, stmt, PKGDB_IT_FLAG_ONCE)); }
int packing_init(struct packing **pack, const char *path, pkg_formats format) { char archive_path[MAXPATHLEN]; const char *ext; assert(pack != NULL); if ((*pack = calloc(1, sizeof(struct packing))) == NULL) { pkg_emit_errno("calloc", "packing"); return (EPKG_FATAL); } (*pack)->aread = archive_read_disk_new(); archive_read_disk_set_standard_lookup((*pack)->aread); archive_read_disk_set_symlink_physical((*pack)->aread); if (!is_dir(path)) { (*pack)->pass = false; (*pack)->awrite = archive_write_new(); archive_write_set_format_pax_restricted((*pack)->awrite); ext = packing_set_format((*pack)->awrite, format); if (ext == NULL) { archive_read_close((*pack)->aread); archive_read_free((*pack)->aread); archive_write_close((*pack)->awrite); archive_write_free((*pack)->awrite); *pack = NULL; return EPKG_FATAL; /* error set by _set_format() */ } snprintf(archive_path, sizeof(archive_path), "%s.%s", path, ext); pkg_debug(1, "Packing to file '%s'", archive_path); if (archive_write_open_filename( (*pack)->awrite, archive_path) != ARCHIVE_OK) { pkg_emit_errno("archive_write_open_filename", archive_path); archive_read_close((*pack)->aread); archive_read_free((*pack)->aread); archive_write_close((*pack)->awrite); archive_write_free((*pack)->awrite); *pack = NULL; return EPKG_FATAL; } } else { /* pass mode directly write to the disk */ pkg_debug(1, "Packing to directory '%s' (pass mode)", path); (*pack)->pass = true; (*pack)->awrite = archive_write_disk_new(); archive_write_disk_set_options((*pack)->awrite, EXTRACT_ARCHIVE_FLAGS); } (*pack)->resolver = archive_entry_linkresolver_new(); archive_entry_linkresolver_set_strategy((*pack)->resolver, ARCHIVE_FORMAT_TAR_PAX_RESTRICTED); return (EPKG_OK); }
static void __unused pkg_repo_binary_parse_conflicts(FILE *f, sqlite3 *sqlite) { size_t linecap = 0; ssize_t linelen; char *linebuf = NULL, *p, **deps; const char *origin, *pdep; int ndep, i; const char conflicts_clean_sql[] = "" "DELETE FROM pkg_conflicts;"; pkg_debug(4, "pkg_parse_conflicts_file: running '%s'", conflicts_clean_sql); (void)sql_exec(sqlite, conflicts_clean_sql); while ((linelen = getline(&linebuf, &linecap, f)) > 0) { p = linebuf; origin = strsep(&p, ":"); /* Check dependencies number */ pdep = p; ndep = 1; while (*pdep != '\0') { if (*pdep == ',') ndep ++; pdep ++; } deps = malloc(sizeof(char *) * ndep); for (i = 0; i < ndep; i ++) { deps[i] = strsep(&p, ",\n"); } pkg_repo_binary_register_conflicts(origin, deps, ndep, sqlite); free(deps); } free(linebuf); }
static void load_repo_files(const char *repodir, pkg_init_flags flags) { struct dirent **ent; char *p; size_t n; int nents, i; char path[MAXPATHLEN]; pkg_debug(1, "PkgConfig: loading repositories in %s", repodir); nents = scandir(repodir, &ent, nodots, alphasort); for (i = 0; i < nents; i++) { if ((n = strlen(ent[i]->d_name)) <= 5) continue; p = &ent[i]->d_name[n - 5]; if (strcmp(p, ".conf") == 0) { snprintf(path, sizeof(path), "%s%s%s", repodir, repodir[strlen(repodir) - 1] == '/' ? "" : "/", ent[i]->d_name); load_repo_file(path, flags); } free(ent[i]); } if (nents >= 0) free(ent); }
static void load_repo_file(const char *repofile, pkg_init_flags flags) { struct ucl_parser *p; ucl_object_t *obj = NULL; const char *myarch = NULL; const char *myarch_legacy = NULL; p = ucl_parser_new(0); myarch = pkg_object_string(pkg_config_get("ABI")); ucl_parser_register_variable (p, "ABI", myarch); myarch_legacy = pkg_object_string(pkg_config_get("ALTABI")); ucl_parser_register_variable (p, "ALTABI", myarch_legacy); pkg_debug(1, "PKgConfig: loading %s", repofile); if (!ucl_parser_add_file(p, repofile)) { pkg_emit_error("Error parsing: %s: %s", repofile, ucl_parser_get_error(p)); ucl_parser_free(p); return; } obj = ucl_parser_get_object(p); if (obj == NULL) return; if (obj->type == UCL_OBJECT) walk_repo_obj(obj, repofile, flags); ucl_object_unref(obj); }
static void load_repo_files(const char *repodir, pkg_init_flags flags) { struct dirent *ent; DIR *d; char *p; size_t n; char path[MAXPATHLEN]; if ((d = opendir(repodir)) == NULL) return; pkg_debug(1, "PkgConfig: loading repositories in %s", repodir); while ((ent = readdir(d))) { if ((n = strlen(ent->d_name)) <= 5) continue; p = &ent->d_name[n - 5]; if (strcmp(p, ".conf") == 0) { snprintf(path, sizeof(path), "%s%s%s", repodir, repodir[strlen(repodir) - 1] == '/' ? "" : "/", ent->d_name); load_repo_file(path, flags); } } closedir(d); }
static int pkg_load_message_from_file(int fd, struct pkg *pkg, const char *path) { char *buf = NULL; off_t size = 0; int ret; ucl_object_t *obj; assert(pkg != NULL); assert(path != NULL); if (faccessat(fd, path, F_OK, 0) == 0) { pkg_debug(1, "Reading message: '%s'", path); if ((ret = file_to_bufferat(fd, path, &buf, &size)) != EPKG_OK) { return (ret); } if (*buf == '[') { ret = pkg_message_from_str(pkg, buf, size); free(buf); return (ret); } else { obj = ucl_object_fromstring_common(buf, size, UCL_STRING_RAW|UCL_STRING_TRIM); ret = pkg_message_from_ucl(pkg, obj); ucl_object_unref(obj); free(buf); return (ret); } } return (EPKG_FATAL); }
void pkg_add_dir_to_del(struct pkg *pkg, const char *file, const char *dir) { char path[MAXPATHLEN]; char *tmp; size_t i, len, len2; strlcpy(path, file != NULL ? file : dir, MAXPATHLEN); if (file != NULL) { tmp = strrchr(path, '/'); tmp[1] = '\0'; } len = strlen(path); /* make sure to finish by a / */ if (path[len - 1] != '/') { path[len] = '/'; len++; path[len] = '\0'; } for (i = 0; i < pkg->dir_to_del_len ; i++) { len2 = strlen(pkg->dir_to_del[i]); if (len2 >= len && strncmp(path, pkg->dir_to_del[i], len) == 0) return; if (strncmp(path, pkg->dir_to_del[i], len2) == 0) { pkg_debug(1, "Replacing in deletion %s with %s", pkg->dir_to_del[i], path); free(pkg->dir_to_del[i]); pkg->dir_to_del[i] = strdup(path); return; } } pkg_debug(1, "Adding to deletion %s", path); if (pkg->dir_to_del_len + 1 > pkg->dir_to_del_cap) { pkg->dir_to_del_cap += 64; pkg->dir_to_del = reallocf(pkg->dir_to_del, pkg->dir_to_del_cap * sizeof(char *)); } pkg->dir_to_del[pkg->dir_to_del_len++] = strdup(path); }
static int pkg_jobs_universe_process_provides_requires(struct pkg_jobs_universe *universe, struct pkg *pkg) { struct pkg_job_provide *pr; struct pkgdb_it *it; char *buf = NULL; int rc; while (pkg_requires(pkg, &buf) == EPKG_OK) { HASH_FIND_STR(universe->provides, buf, pr); if (pr != NULL) continue; /* Check for local provides */ it = pkgdb_query_provide(universe->j->db, buf); if (it != NULL) { rc = pkg_jobs_universe_handle_provide(universe, it, buf, false, pkg); pkgdb_it_free(it); if (rc != EPKG_OK) { pkg_debug(1, "cannot find local packages that provide %s " "required for %s", buf, pkg->name); } } /* Not found, search in the repos */ it = pkgdb_repo_provide(universe->j->db, buf, universe->j->reponame); if (it != NULL) { rc = pkg_jobs_universe_handle_provide(universe, it, buf, false, pkg); pkgdb_it_free(it); if (rc != EPKG_OK) { pkg_debug(1, "cannot find remote packages that provide %s " "required for %s", buf, pkg->name); return (rc); } } } return (EPKG_OK); }
static int test_depends(void *actdata, struct pkg *pkg, const char *fpath, const char *name, bool is_shlib) { struct pkgdb *db = actdata; struct pkg_dep *dep = NULL; struct pkgdb_it *it = NULL; struct pkg *d; const char *deporigin, *depname, *depversion; const char *pkgname, *pkgversion; bool deplocked; char pathbuf[MAXPATHLEN]; assert(db != NULL); switch(filter_system_shlibs(name, pathbuf, sizeof(pathbuf))) { case EPKG_OK: /* A non-system library */ break; case EPKG_END: /* A system library */ return (EPKG_OK); default: /* Ignore link resolution errors if we're analysing a shared library. */ if (is_shlib) return (EPKG_OK); pkg_get(pkg, PKG_NAME, &pkgname, PKG_VERSION, &pkgversion); warnx("(%s-%s) %s - shared library %s not found", pkgname, pkgversion, fpath, name); return (EPKG_FATAL); } pkg_addshlib_required(pkg, name); if ((it = pkgdb_query_which(db, pathbuf, false)) == NULL) return (EPKG_OK); d = NULL; if (pkgdb_it_next(it, &d, PKG_LOAD_BASIC) == EPKG_OK) { pkg_get(d, PKG_ORIGIN, &deporigin, PKG_NAME, &depname, PKG_VERSION, &depversion, PKG_LOCKED, &deplocked); dep = pkg_dep_lookup(pkg, deporigin); if (dep == NULL) { pkg_debug(1, "Autodeps: adding unlisted depends (%s): %s-%s", pathbuf, depname, depversion); pkg_adddep(pkg, depname, deporigin, depversion, deplocked); } pkg_free(d); } pkgdb_it_free(it); return (EPKG_OK); }
static void pkg_load_from_file(int fd, struct pkg *pkg, pkg_attr attr, const char *path) { if (faccessat(fd, path, F_OK, 0) == 0) { pkg_debug(1, "Reading: '%s'", path); pkg_set_from_fileat(fd, pkg, attr, path, false); } }
struct pkgdb_it * pkgdb_rquery_provide(struct pkgdb *db, const char *provide, const char *repo) { sqlite3_stmt *stmt; struct sbuf *sql = NULL; const char *reponame = NULL; int ret; const char basesql[] = "" "SELECT p.id, p.origin, p.name, p.version, p.comment, " "p.name || '~' || p.origin as uniqueid, " "p.prefix, p.desc, p.arch, p.maintainer, p.www, " "p.licenselogic, p.flatsize, p.pkgsize, " "p.cksum, p.manifestdigest, p.path AS repopath, '%1$s' AS dbname " "FROM '%1$s'.packages AS p, '%1$s'.pkg_provides AS pp, " "'%1$s'.provides AS pr " "WHERE p.id = pp.package_id " "AND pp.provide_id = pr.id " "AND pr.name = ?1;"; assert(db != NULL); reponame = pkgdb_get_reponame(db, repo); sql = sbuf_new_auto(); /* * Working on multiple remote repositories */ if (reponame == NULL) { /* duplicate the query via UNION for all the attached * databases */ ret = pkgdb_sql_all_attached(db->sqlite, sql, basesql, " UNION ALL "); if (ret != EPKG_OK) { sbuf_delete(sql); return (NULL); } } else sbuf_printf(sql, basesql, reponame); sbuf_finish(sql); pkg_debug(4, "Pkgdb: running '%s'", sbuf_get(sql)); ret = sqlite3_prepare_v2(db->sqlite, sbuf_get(sql), -1, &stmt, NULL); if (ret != SQLITE_OK) { ERROR_SQLITE(db->sqlite, sbuf_get(sql)); sbuf_delete(sql); return (NULL); } sbuf_delete(sql); sqlite3_bind_text(stmt, 1, provide, -1, SQLITE_TRANSIENT); return (pkgdb_it_new(db, stmt, PKG_REMOTE, PKGDB_IT_FLAG_ONCE)); }
static void walk_repo_obj(const ucl_object_t *obj, const char *file, pkg_init_flags flags) { const ucl_object_t *cur; ucl_object_iter_t it = NULL; struct pkg_repo *r; const char *key; while ((cur = ucl_iterate_object(obj, &it, true))) { key = ucl_object_key(cur); pkg_debug(1, "PkgConfig: parsing key '%s'", key); r = pkg_repo_find(key); if (r != NULL) pkg_debug(1, "PkgConfig: overwriting repository %s", key); if (cur->type == UCL_OBJECT) add_repo(cur, r, key, flags); else pkg_emit_error("Ignoring bad configuration entry in %s: %s", file, ucl_object_emit(cur, UCL_EMIT_YAML)); } }
/* The "no concessions to old pkg_tools" variant: just get everything * from the manifest */ int pkg_create_from_manifest(const char *outdir, pkg_formats format, const char *rootdir, const char *manifest, const char *plist) { struct pkg *pkg = NULL; struct packing *pkg_archive = NULL; char arch[BUFSIZ]; int ret = ENOMEM; struct pkg_manifest_key *keys = NULL; pkg_debug(1, "Creating package from stage directory: '%s'", rootdir); if(pkg_new(&pkg, PKG_FILE) != EPKG_OK) { ret = EPKG_FATAL; goto cleanup; } pkg_manifest_keys_new(&keys); if ((ret = pkg_parse_manifest_file(pkg, manifest, keys)) != EPKG_OK) { ret = EPKG_FATAL; goto cleanup; } /* if no arch autodetermine it */ if (pkg->abi == NULL) { pkg_get_myarch(arch, BUFSIZ); pkg->abi = strdup(arch); } if (plist != NULL && ports_parse_plist(pkg, plist, rootdir) != EPKG_OK) { ret = EPKG_FATAL; goto cleanup; } /* Create the archive */ pkg_archive = pkg_create_archive(outdir, pkg, format, 0); if (pkg_archive == NULL) { ret = EPKG_FATAL; /* XXX do better */ goto cleanup; } pkg_create_from_dir(pkg, rootdir, pkg_archive); ret = EPKG_OK; cleanup: free(pkg); pkg_manifest_keys_free(keys); packing_finish(pkg_archive); return (ret); }
int64_t pkg_repo_binary_stat(struct pkg_repo *repo, pkg_stats_t type) { sqlite3 *sqlite = PRIV_GET(repo); sqlite3_stmt *stmt = NULL; int64_t stats = 0; struct sbuf *sql = NULL; int ret; sql = sbuf_new_auto(); switch(type) { case PKG_STATS_LOCAL_COUNT: goto out; break; case PKG_STATS_LOCAL_SIZE: goto out; break; case PKG_STATS_REMOTE_UNIQUE: sbuf_printf(sql, "SELECT COUNT(id) FROM main.packages;"); break; case PKG_STATS_REMOTE_COUNT: sbuf_printf(sql, "SELECT COUNT(id) FROM main.packages;"); break; case PKG_STATS_REMOTE_SIZE: sbuf_printf(sql, "SELECT SUM(pkgsize) FROM main.packages;"); break; case PKG_STATS_REMOTE_REPOS: goto out; break; } sbuf_finish(sql); pkg_debug(4, "binary_repo: running '%s'", sbuf_data(sql)); ret = sqlite3_prepare_v2(sqlite, sbuf_data(sql), -1, &stmt, NULL); if (ret != SQLITE_OK) { ERROR_SQLITE(sqlite, sbuf_data(sql)); goto out; } while (sqlite3_step(stmt) != SQLITE_DONE) { stats = sqlite3_column_int64(stmt, 0); } out: sbuf_free(sql); if (stmt != NULL) sqlite3_finalize(stmt); return (stats); }
void pkg_cache_full_clean(void) { const char *cachedir; if (!pkg_object_bool(pkg_config_get("AUTOCLEAN"))) return; pkg_debug(1, "Cleaning up cachedir"); cachedir = pkg_object_string(pkg_config_get("PKG_CACHEDIR")); return (rm_rf(cachedir)); }
/* The "no concessions to old pkg_tools" variant: just get everything * from the manifest */ int pkg_create_from_manifest(const char *outdir, pkg_formats format, const char *rootdir, const char *manifest, bool old) { struct pkg *pkg = NULL; struct packing *pkg_archive = NULL; char arch[BUFSIZ]; int ret = ENOMEM; char *buf; struct pkg_manifest_key *keys = NULL; pkg_debug(1, "Creating package from stage directory: '%s'", rootdir); if(pkg_new(&pkg, old ? PKG_OLD_FILE : PKG_FILE) != EPKG_OK) { ret = EPKG_FATAL; goto cleanup; } pkg_manifest_keys_new(&keys); if ((ret = pkg_parse_manifest_file(pkg, manifest, keys)) != EPKG_OK) { ret = EPKG_FATAL; goto cleanup; } /* if no arch autodetermine it */ pkg_get(pkg, PKG_ARCH, &buf); if (buf == NULL) { pkg_get_myarch(arch, BUFSIZ); pkg_set(pkg, PKG_ARCH, arch); } /* Create the archive */ pkg_archive = pkg_create_archive(outdir, pkg, format, 0); if (pkg_archive == NULL) { ret = EPKG_FATAL; /* XXX do better */ goto cleanup; } pkg_create_from_dir(pkg, rootdir, pkg_archive); ret = EPKG_OK; cleanup: free(pkg); pkg_manifest_keys_free(keys); if (ret == EPKG_OK) ret = packing_finish(pkg_archive); return (ret); }
static void load_repo_file(const char *repofile) { struct ucl_parser *p; ucl_object_t *obj = NULL; bool fallback = false; const char *myarch = NULL; p = ucl_parser_new(0); myarch = pkg_object_string(pkg_config_get("ABI")); ucl_parser_register_variable (p, "ABI", myarch); pkg_debug(1, "PKgConfig: loading %s", repofile); if (!ucl_parser_add_file(p, repofile)) { pkg_emit_error("Error parsing: %s: %s", repofile, ucl_parser_get_error(p)); if (errno == ENOENT) { ucl_parser_free(p); return; } fallback = true; } if (fallback) { obj = yaml_to_ucl(repofile, NULL, 0); if (obj == NULL) return; } if (fallback) { pkg_emit_error("%s file is using a deprecated format. " "Please replace it with the following:\n" "====== BEGIN %s ======\n" "%s" "\n====== END %s ======\n", repofile, repofile, ucl_object_emit(obj, UCL_EMIT_YAML), repofile); } obj = ucl_parser_get_object(p); if (obj->type == UCL_OBJECT) walk_repo_obj(obj, repofile); ucl_object_free(obj); }
int packing_init(struct packing **pack, const char *path, pkg_formats format) { char archive_path[MAXPATHLEN]; const char *ext; assert(pack != NULL); *pack = xcalloc(1, sizeof(struct packing)); (*pack)->aread = archive_read_disk_new(); archive_read_disk_set_standard_lookup((*pack)->aread); archive_read_disk_set_symlink_physical((*pack)->aread); (*pack)->awrite = archive_write_new(); archive_write_set_format_pax_restricted((*pack)->awrite); ext = packing_set_format((*pack)->awrite, format); if (ext == NULL) { archive_read_close((*pack)->aread); archive_read_free((*pack)->aread); archive_write_close((*pack)->awrite); archive_write_free((*pack)->awrite); *pack = NULL; return EPKG_FATAL; /* error set by _set_format() */ } snprintf(archive_path, sizeof(archive_path), "%s.%s", path, ext); pkg_debug(1, "Packing to file '%s'", archive_path); if (archive_write_open_filename( (*pack)->awrite, archive_path) != ARCHIVE_OK) { pkg_emit_errno("archive_write_open_filename", archive_path); archive_read_close((*pack)->aread); archive_read_free((*pack)->aread); archive_write_close((*pack)->awrite); archive_write_free((*pack)->awrite); *pack = NULL; return EPKG_FATAL; } (*pack)->resolver = archive_entry_linkresolver_new(); archive_entry_linkresolver_set_strategy((*pack)->resolver, archive_format((*pack)->awrite)); return (EPKG_OK); }
struct pkg_repo_it * pkg_repo_binary_query(struct pkg_repo *repo, const char *pattern, match_t match) { sqlite3 *sqlite = PRIV_GET(repo); sqlite3_stmt *stmt = NULL; struct sbuf *sql = NULL; const char *comp = NULL; int ret; char basesql[BUFSIZ] = "" "SELECT id, origin, name, name as uniqueid, version, comment, " "prefix, desc, arch, maintainer, www, " "licenselogic, flatsize, pkgsize, " "cksum, manifestdigest, path AS repopath, '%s' AS dbname " "FROM packages AS p"; if (match != MATCH_ALL && (pattern == NULL || pattern[0] == '\0')) return (NULL); sql = sbuf_new_auto(); comp = pkgdb_get_pattern_query(pattern, match); if (comp && comp[0]) strlcat(basesql, comp, sizeof(basesql)); sbuf_printf(sql, basesql, repo->name); sbuf_cat(sql, " ORDER BY name;"); sbuf_finish(sql); pkg_debug(4, "Pkgdb: running '%s' query for %s", sbuf_data(sql), pattern == NULL ? "all": pattern); ret = sqlite3_prepare_v2(sqlite, sbuf_data(sql), sbuf_len(sql), &stmt, NULL); if (ret != SQLITE_OK) { ERROR_SQLITE(sqlite, sbuf_data(sql)); sbuf_delete(sql); return (NULL); } sbuf_delete(sql); if (match != MATCH_ALL && match != MATCH_CONDITION) sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_TRANSIENT); return (pkg_repo_binary_it_new(repo, stmt, PKGDB_IT_FLAG_ONCE)); }
int pkg_repo_binary_ensure_loaded(struct pkg_repo *repo, struct pkg *pkg, unsigned flags) { sqlite3 *sqlite = PRIV_GET(repo); struct pkg_manifest_key *keys = NULL; struct pkg *cached = NULL; char path[MAXPATHLEN]; if (pkg->type != PKG_INSTALLED && (flags & (PKG_LOAD_FILES|PKG_LOAD_DIRS)) != 0 && (pkg->flags & (PKG_LOAD_FILES|PKG_LOAD_DIRS)) == 0) { /* * Try to get that information from fetched package in cache */ pkg_manifest_keys_new(&keys); if (pkg_repo_cached_name(pkg, path, sizeof(path)) != EPKG_OK) return (EPKG_FATAL); pkg_debug(1, "Binary> loading %s", path); if (pkg_open(&cached, path, keys, PKG_OPEN_TRY) != EPKG_OK) { pkg_free(cached); return (EPKG_FATAL); } /* Now move required elements to the provided package */ pkg_list_free(pkg, PKG_FILES); pkg_list_free(pkg, PKG_DIRS); pkg->files = cached->files; pkg->filehash = cached->filehash; pkg->dirs = cached->dirs; pkg->dirhash = cached->dirhash; cached->files = NULL; cached->filehash = NULL; cached->dirs = NULL; cached->dirhash = NULL; pkg_free(cached); pkg->flags |= (PKG_LOAD_FILES|PKG_LOAD_DIRS); } return (pkgdb_ensure_loaded_sqlite(sqlite, pkg, flags)); }
static int upgrade_repo_schema(struct pkgdb *db, const char *database, int current_version) { int version; int next_version; int ret = EPKG_OK; for (version = current_version; version < REPO_SCHEMA_VERSION; version = next_version) { ret = apply_repo_change(db, database, repo_upgrades, "upgrade", version, &next_version); if (ret != EPKG_OK) break; pkg_debug(1, "Upgrading repo database schema from %d to %d", version, next_version); } return (ret); }
static int pkg_repo_binary_upgrade(struct pkg_repo *repo, sqlite3 *sqlite, int current_version) { int version; int next_version; int ret = EPKG_OK; for (version = current_version; version < REPO_SCHEMA_VERSION; version = next_version) { ret = pkg_repo_binary_apply_change(repo, sqlite, repo_upgrades, "upgrade", version, &next_version); if (ret != EPKG_OK) break; pkg_debug(1, "Upgrading repo database schema from %d to %d", version, next_version); } return (ret); }
int pkg_create_staged(const char *outdir, pkg_formats format, const char *rootdir, const char *md_dir, char *plist) { struct pkg *pkg = NULL; struct pkg_file *file = NULL; struct pkg_dir *dir = NULL; struct packing *pkg_archive = NULL; int ret = EPKG_FATAL; pkg_debug(1, "Creating package from stage directory: '%s'", rootdir); if ((ret = pkg_new(&pkg, PKG_FILE)) != EPKG_OK) goto cleanup; if ((ret = pkg_load_metadata(pkg, NULL, md_dir, plist, rootdir, false)) != EPKG_OK) goto cleanup; /* Create the archive */ pkg_archive = pkg_create_archive(outdir, pkg, format, 0); if (pkg_archive == NULL) { ret = EPKG_FATAL; /* XXX do better */ goto cleanup; } /* XXX: autoplist support doesn't work right with meta-ports */ if (0 && pkg_files(pkg, &file) != EPKG_OK && pkg_dirs(pkg, &dir) != EPKG_OK) { /* Now traverse the file directories, adding to the archive */ packing_append_tree(pkg_archive, md_dir, NULL); packing_append_tree(pkg_archive, rootdir, "/"); ret = EPKG_OK; } else { ret = pkg_create_from_dir(pkg, rootdir, pkg_archive); } cleanup: free(pkg); packing_finish(pkg_archive); return (ret); }
struct pkg_repo_it * pkg_repo_binary_search(struct pkg_repo *repo, const char *pattern, match_t match, pkgdb_field field, pkgdb_field sort) { sqlite3 *sqlite = PRIV_GET(repo); sqlite3_stmt *stmt = NULL; struct sbuf *sql = NULL; int ret; const char *multireposql = "" "SELECT id, origin, name, version, comment, " "prefix, desc, arch, maintainer, www, " "licenselogic, flatsize, pkgsize, " "cksum, path AS repopath, '%1$s' AS dbname, '%2$s' AS repourl " "FROM packages "; if (pattern == NULL || pattern[0] == '\0') return (NULL); sql = sbuf_new_auto(); sbuf_printf(sql, multireposql, repo->name, repo->url); /* close the UNIONs and build the search query */ sbuf_cat(sql, "WHERE "); pkg_repo_binary_build_search_query(sql, match, field, sort); sbuf_cat(sql, ";"); sbuf_finish(sql); pkg_debug(4, "Pkgdb: running '%s'", sbuf_data(sql)); ret = sqlite3_prepare_v2(sqlite, sbuf_data(sql), -1, &stmt, NULL); if (ret != SQLITE_OK) { ERROR_SQLITE(sqlite, sbuf_data(sql)); sbuf_delete(sql); return (NULL); } sbuf_delete(sql); sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_TRANSIENT); return (pkg_repo_binary_it_new(repo, stmt, PKGDB_IT_FLAG_ONCE)); }
sqlite3_stmt * pkg_repo_binary_get_origins(sqlite3 *sqlite) { sqlite3_stmt *stmt = NULL; int ret; const char query_sql[] = "" "SELECT id, origin, name, name || '~' || origin as uniqueid, version, comment, " "prefix, desc, arch, maintainer, www, " "licenselogic, flatsize, pkgsize, " "cksum, path AS repopath, manifestdigest " "FROM packages " "ORDER BY origin;"; pkg_debug(4, "binary_repo: running '%s'", query_sql); ret = sqlite3_prepare_v2(sqlite, query_sql, -1, &stmt, NULL); if (ret != SQLITE_OK) { ERROR_SQLITE(sqlite, query_sql); return (NULL); } return (stmt); }
struct pkg_repo_it * pkg_repo_binary_provide(struct pkg_repo *repo, const char *require) { sqlite3_stmt *stmt; sqlite3 *sqlite = PRIV_GET(repo); struct sbuf *sql = NULL; int ret; const char basesql[] = "" "SELECT p.id, p.origin, p.name, p.version, p.comment, " "p.name as uniqueid, " "p.prefix, p.desc, p.arch, p.maintainer, p.www, " "p.licenselogic, p.flatsize, p.pkgsize, " "p.cksum, p.manifestdigest, p.path AS repopath, '%s' AS dbname " "FROM packages AS p INNER JOIN pkg_provides AS ps ON " "p.id = ps.package_id " "WHERE ps.provide_id IN (SELECT id from provides WHERE " "provide = ?1 );"; sql = sbuf_new_auto(); sbuf_printf(sql, basesql, repo->name); sbuf_finish(sql); pkg_debug(4, "Pkgdb: running '%s'", sbuf_data(sql)); ret = sqlite3_prepare_v2(sqlite, sbuf_data(sql), -1, &stmt, NULL); if (ret != SQLITE_OK) { ERROR_SQLITE(sqlite, sbuf_data(sql)); sbuf_delete(sql); return (NULL); } sbuf_delete(sql); sqlite3_bind_text(stmt, 1, require, -1, SQLITE_TRANSIENT); return (pkg_repo_binary_it_new(repo, stmt, PKGDB_IT_FLAG_ONCE)); }
/* The "no concessions to old pkg_tools" variant: just get everything * from the manifest */ int pkg_create_from_manifest(const char *outdir, pkg_formats format, const char *rootdir, const char *manifest, const char *plist) { struct pkg *pkg = NULL; struct packing *pkg_archive = NULL; int ret = ENOMEM; pkg_debug(1, "Creating package from stage directory: '%s'", rootdir); if(pkg_new(&pkg, PKG_FILE) != EPKG_OK) { ret = EPKG_FATAL; goto cleanup; } if ((ret = pkg_load_metadata(pkg, manifest, NULL, plist, rootdir, false)) != EPKG_OK) { ret = EPKG_FATAL; goto cleanup; } /* Create the archive */ pkg_archive = pkg_create_archive(outdir, pkg, format, 0); if (pkg_archive == NULL) { ret = EPKG_FATAL; /* XXX do better */ goto cleanup; } if ((ret = pkg_create_from_dir(pkg, rootdir, pkg_archive)) != EPKG_OK) pkg_emit_error("package creation failed"); cleanup: free(pkg); packing_finish(pkg_archive); return (ret); }
static int pkg_repo_binary_update_incremental(const char *name, struct pkg_repo *repo, time_t *mtime, bool force) { FILE *fmanifest = NULL, *fdigests = NULL /*, *fconflicts = NULL*/; struct pkg *pkg = NULL; int rc = EPKG_FATAL; sqlite3 *sqlite = NULL; sqlite3_stmt *stmt; const char *origin, *digest, *offset, *length, *checksum; char *linebuf = NULL, *p; int updated = 0, removed = 0, added = 0, processed = 0, pushed = 0; long num_offset, num_length; time_t local_t; time_t digest_t; time_t packagesite_t; struct pkg_increment_task_item *ldel = NULL, *ladd = NULL, *item, *tmp_item; struct pkg_manifest_key *keys = NULL; size_t linecap = 0; ssize_t linelen; char *map = MAP_FAILED; size_t len = 0; int hash_it = 0; bool in_trans = false, legacy_repo = false; /* Required for making iterator */ struct pkgdb_it *it = NULL; struct pkgdb fakedb; pkg_debug(1, "Pkgrepo, begin incremental update of '%s'", name); /* In forced mode, ignore mtime */ if (force) *mtime = 0; /* Fetch meta */ local_t = *mtime; if (pkg_repo_fetch_meta(repo, &local_t) == EPKG_FATAL) pkg_emit_notice("repository %s has no meta file, using " "default settings", repo->name); /* Fetch digests */ local_t = *mtime; fdigests = pkg_repo_fetch_remote_extract_tmp(repo, repo->meta->digests, &local_t, &rc); if (fdigests == NULL) goto cleanup; /* Fetch packagesite */ digest_t = local_t; local_t = *mtime; fmanifest = pkg_repo_fetch_remote_extract_tmp(repo, repo->meta->manifests, &local_t, &rc); if (fmanifest == NULL) goto cleanup; packagesite_t = local_t; *mtime = digest_t; /*fconflicts = repo_fetch_remote_extract_tmp(repo, repo_conflicts_archive, "txz", &local_t, &rc, repo_conflicts_file);*/ fseek(fmanifest, 0, SEEK_END); len = ftell(fmanifest); /* Detect whether we have legacy repo */ if ((linelen = getline(&linebuf, &linecap, fdigests)) > 0) { p = linebuf; origin = strsep(&p, ":"); digest = strsep(&p, ":"); if (digest == NULL) { pkg_emit_error("invalid digest file format"); rc = EPKG_FATAL; goto cleanup; } if (!pkg_checksum_is_valid(digest, strlen(digest))) { legacy_repo = true; pkg_debug(1, "repository '%s' has a legacy digests format", repo->name); } } fseek(fdigests, 0, SEEK_SET); /* Load local repository data */ rc = pkg_repo_binary_init_update(repo, name, force); if (rc == EPKG_END) { /* Need to perform forced update */ repo->ops->close(repo, false); return (pkg_repo_binary_update_incremental(name, repo, mtime, true)); } if (rc != EPKG_OK) { rc = EPKG_FATAL; goto cleanup; } /* Here sqlite is initialized */ sqlite = PRIV_GET(repo); stmt = pkg_repo_binary_get_origins(sqlite); if (stmt == NULL) { rc = EPKG_FATAL; goto cleanup; } fakedb.sqlite = sqlite; it = pkgdb_it_new_sqlite(&fakedb, stmt, PKG_REMOTE, PKGDB_IT_FLAG_ONCE); if (it != NULL) { while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) { pkg_get(pkg, PKG_ORIGIN, &origin, legacy_repo ? PKG_OLD_DIGEST : PKG_DIGEST, &digest, PKG_CKSUM, &checksum); pkg_repo_binary_update_item_new(&ldel, origin, digest, 0, 0, checksum); } pkgdb_it_free(it); } else { sqlite3_finalize(stmt); } pkg_debug(1, "Pkgrepo, reading new packagesite.yaml for '%s'", name); /* load the while digests */ while ((linelen = getline(&linebuf, &linecap, fdigests)) > 0) { p = linebuf; origin = strsep(&p, ":"); digest = strsep(&p, ":"); offset = strsep(&p, ":"); /* files offset */ strsep(&p, ":"); length = p ? strsep(&p, ":\n") : NULL; checksum = p ? strsep(&p, ":\n") : NULL; if (origin == NULL || digest == NULL || offset == NULL) { pkg_emit_error("invalid digest file format"); rc = EPKG_FATAL; goto cleanup; } errno = 0; num_offset = (long)strtoul(offset, NULL, 10); if (errno != 0) { pkg_emit_errno("strtoul", "digest format error"); rc = EPKG_FATAL; goto cleanup; } if (length != NULL) { errno = 0; num_length = (long)strtoul(length, NULL, 10); if (errno != 0) { pkg_emit_errno("strtoul", "digest format error"); rc = EPKG_FATAL; goto cleanup; } } else { num_length = 0; } processed++; HASH_FIND_STR(ldel, origin, item); if (item == NULL) { added++; pkg_repo_binary_update_item_new(&ladd, origin, digest, num_offset, num_length, checksum); } else { HASH_DEL(ldel, item); if (checksum == NULL || item->checksum == NULL) { pkg_repo_binary_update_item_new(&ladd, origin, digest, num_offset, num_length, checksum); updated++; } else if (strcmp(checksum, item->checksum) != 0) { /* Allow checksum to be used as unique mark */ pkg_repo_binary_update_item_new(&ladd, origin, digest, num_offset, num_length, checksum); updated++; } pkg_repo_binary_update_item_free(item); } } rc = EPKG_OK; pkg_debug(1, "Pkgrepo, removing old entries for '%s'", name); rc = pkgdb_transaction_begin(sqlite, "REPO"); if (rc != EPKG_OK) goto cleanup; in_trans = true; removed = HASH_COUNT(ldel); hash_it = 0; if (removed > 0) pkg_emit_progress_start("Removing expired repository entries"); HASH_ITER(hh, ldel, item, tmp_item) { pkg_emit_progress_tick(++hash_it, removed); if (rc == EPKG_OK) { rc = pkgdb_repo_remove_package(item->origin); } else { pkg_emit_progress_tick(removed, removed); } HASH_DEL(ldel, item); pkg_repo_binary_update_item_free(item); }
static int pkg_repo_binary_register_conflicts(const char *origin, char **conflicts, int conflicts_num, sqlite3 *sqlite) { const char clean_conflicts_sql[] = "" "DELETE FROM pkg_conflicts " "WHERE package_id = ?1;"; const char select_id_sql[] = "" "SELECT id FROM packages " "WHERE origin = ?1;"; const char insert_conflict_sql[] = "" "INSERT INTO pkg_conflicts " "(package_id, conflict_id) " "VALUES (?1, ?2);"; sqlite3_stmt *stmt = NULL; int ret, i; int64_t origin_id, conflict_id; pkg_debug(4, "pkgdb_repo_register_conflicts: running '%s'", select_id_sql); if (sqlite3_prepare_v2(sqlite, select_id_sql, -1, &stmt, NULL) != SQLITE_OK) { ERROR_SQLITE(sqlite, select_id_sql); return (EPKG_FATAL); } sqlite3_bind_text(stmt, 1, origin, -1, SQLITE_TRANSIENT); ret = sqlite3_step(stmt); if (ret == SQLITE_ROW) { origin_id = sqlite3_column_int64(stmt, 0); } else { ERROR_SQLITE(sqlite, select_id_sql); return (EPKG_FATAL); } sqlite3_finalize(stmt); pkg_debug(4, "pkgdb_repo_register_conflicts: running '%s'", clean_conflicts_sql); if (sqlite3_prepare_v2(sqlite, clean_conflicts_sql, -1, &stmt, NULL) != SQLITE_OK) { ERROR_SQLITE(sqlite, clean_conflicts_sql); return (EPKG_FATAL); } sqlite3_bind_int64(stmt, 1, origin_id); /* Ignore cleanup result */ (void)sqlite3_step(stmt); sqlite3_finalize(stmt); for (i = 0; i < conflicts_num; i ++) { /* Select a conflict */ pkg_debug(4, "pkgdb_repo_register_conflicts: running '%s'", select_id_sql); if (sqlite3_prepare_v2(sqlite, select_id_sql, -1, &stmt, NULL) != SQLITE_OK) { ERROR_SQLITE(sqlite, select_id_sql); return (EPKG_FATAL); } sqlite3_bind_text(stmt, 1, conflicts[i], -1, SQLITE_TRANSIENT); ret = sqlite3_step(stmt); if (ret == SQLITE_ROW) { conflict_id = sqlite3_column_int64(stmt, 0); } else { ERROR_SQLITE(sqlite, select_id_sql); return (EPKG_FATAL); } sqlite3_finalize(stmt); /* Insert a pair */ pkg_debug(4, "pkgdb_repo_register_conflicts: running '%s'", insert_conflict_sql); if (sqlite3_prepare_v2(sqlite, insert_conflict_sql, -1, &stmt, NULL) != SQLITE_OK) { ERROR_SQLITE(sqlite, insert_conflict_sql); return (EPKG_FATAL); } sqlite3_bind_int64(stmt, 1, origin_id); sqlite3_bind_int64(stmt, 2, conflict_id); ret = sqlite3_step(stmt); if (ret != SQLITE_DONE) { ERROR_SQLITE(sqlite, insert_conflict_sql); return (EPKG_FATAL); } sqlite3_finalize(stmt); } return (EPKG_OK); }