static int pkgs_providing_lib(struct pkgdb *db, const char *libname) { struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; const char *name, *version; int ret = EPKG_OK; int count = 0; if ((it = pkgdb_query_shlib_provided(db, libname)) == NULL) { return (EPKG_FATAL); } while ((ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) { if (count == 0) printf("%s is provided by the following packages:\n", libname); count++; pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version); printf("%s-%s\n", name, version); } if (ret == EPKG_END) { if (count == 0) printf("No packages provide %s.\n", libname); ret = EPKG_OK; } pkg_free(pkg); pkgdb_it_free(it); return (ret); }
static void check_summary(struct pkgdb *db, struct deps_head *dh) { struct deps_entry *e = NULL; struct pkg *pkg = NULL; struct pkgdb_it *it = NULL; bool fixed = true; assert(db != NULL); printf(">>> Summary of actions performed:\n\n"); STAILQ_FOREACH(e, dh, next) { if ((it = pkgdb_query(db, e->origin, MATCH_EXACT)) == NULL) return; if (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) != EPKG_OK) { fixed = false; printf("%s dependency failed to be fixed\n", e->origin); } else printf("%s dependency has been fixed\n", e->origin); pkgdb_it_free(it); } if (fixed) { printf("\n>>> Missing dependencies were fixed successfully.\n"); } else { printf("\n>>> There are still missing dependencies.\n"); printf(">>> You are advised to try fixing them manually.\n"); printf("\n>>> Also make sure to check 'pkg updating' for known issues.\n"); } pkg_free(pkg); }
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 int fix_deps(struct pkgdb *db, struct deps_head *dh, int nbpkgs, bool yes) { struct pkg *pkg = NULL; struct pkgdb_it *it = NULL; struct pkg_jobs *jobs = NULL; struct deps_entry *e = NULL; char **pkgs = NULL; int i = 0; assert(db != NULL); assert(nbpkgs > 0); if ((pkgs = calloc(nbpkgs, MAXPATHLEN + 1)) == NULL) err(1, "calloc()"); STAILQ_FOREACH(e, dh, next) pkgs[i++] = e->origin; if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) return (EPKG_ENODB); if (pkg_jobs_new(&jobs, PKG_JOBS_INSTALL, db) != EPKG_OK) free(pkgs); if ((it = pkgdb_query_installs(db, MATCH_EXACT, nbpkgs, pkgs, NULL, false)) == NULL) { free(pkgs); pkg_jobs_free(jobs); } while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC|PKG_LOAD_DEPS) == EPKG_OK) { pkg_jobs_add(jobs, pkg); pkg = NULL; } if (pkg_jobs_is_empty(jobs)) { printf("\n>>> Unable to find packages for installation.\n\n"); return (EPKG_FATAL); } /* print a summary before applying the jobs */ pkg = NULL; print_jobs_summary(jobs, PKG_JOBS_INSTALL, "The following packages will be installed:\n\n"); if (yes == false) yes = query_yesno("\n>>> Try to fix the missing dependencies [y/N]: "); if (yes == true) pkg_jobs_apply(jobs, 0); free(pkgs); pkg_free(pkg); pkg_jobs_free(jobs); pkgdb_it_free(it); return (EPKG_OK); }
static int pkg_create_matches(int argc, char **argv, match_t match, pkg_formats fmt, const char * const outdir, const char * const rootdir) { int i, ret = EPKG_OK, retcode = EPKG_OK; struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; int query_flags = PKG_LOAD_DEPS | PKG_LOAD_CONFLICTS | PKG_LOAD_FILES | PKG_LOAD_CATEGORIES | PKG_LOAD_DIRS | PKG_LOAD_SCRIPTS | PKG_LOAD_OPTIONS | PKG_LOAD_MTREE | PKG_LOAD_LICENSES; if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { pkgdb_close(db); return (EX_IOERR); } if (match != MATCH_ALL) { for (i = 0;i < argc; i++) { if ((it = pkgdb_query(db, argv[i], match)) == NULL) { goto cleanup; } while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) { printf("Creating package for %s-%s\n", pkg_get(pkg, PKG_NAME), pkg_get(pkg, PKG_VERSION)); if (pkg_create_installed(outdir, fmt, rootdir, pkg) != EPKG_OK) { retcode++; } } } } else { if ((it = pkgdb_query(db, NULL, match)) == NULL) { goto cleanup; } while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) { printf("Creating package for %s-%s\n", pkg_get(pkg, PKG_NAME), pkg_get(pkg, PKG_VERSION)); if (pkg_create_installed(outdir, fmt, rootdir, pkg) != EPKG_OK) { retcode++; } } } cleanup: if (ret != EPKG_END) { retcode++; } pkg_free(pkg); pkgdb_it_free(it); pkgdb_close(db); return (retcode); }
static pkg_chain_t * pkg_jobs_universe_get_remote(struct pkg_jobs_universe *universe, const char *uid, unsigned flag) { struct pkg *pkg = NULL; pkg_chain_t *result = NULL; struct pkgdb_it *it; struct pkg_job_universe_item *unit, *cur, *found; if (flag == 0) { flag = PKG_LOAD_BASIC|PKG_LOAD_DEPS|PKG_LOAD_OPTIONS| PKG_LOAD_PROVIDES|PKG_LOAD_REQUIRES| PKG_LOAD_SHLIBS_REQUIRED|PKG_LOAD_SHLIBS_PROVIDED| PKG_LOAD_ANNOTATIONS|PKG_LOAD_CONFLICTS; } HASH_FIND(hh, universe->items, uid, strlen(uid), unit); if (unit != NULL && unit->pkg->type != PKG_INSTALLED) { /* Search local in a universe chain */ cur = unit; found = NULL; do { if (cur->pkg->type != PKG_INSTALLED) { found = cur; break; } cur = cur->prev; } while (cur != unit); if (found) { /* Assume processed */ return (NULL); } } if ((it = pkgdb_repo_query(universe->j->db, uid, MATCH_EXACT, universe->j->reponame)) == NULL) return (NULL); while (pkgdb_it_next(it, &pkg, flag) == EPKG_OK) { if (result == NULL) result = calloc(1, sizeof(pkg_chain_t)); kv_prepend(typeof(pkg), *result, pkg); pkg = NULL; } pkgdb_it_free(it); return (result); }
struct pkg * pkg_jobs_universe_get_local(struct pkg_jobs_universe *universe, const char *uid, unsigned flag) { struct pkg *pkg = NULL; struct pkgdb_it *it; struct pkg_job_universe_item *unit, *cur, *found; if (flag == 0) { if (!IS_DELETE(universe->j)) flag = PKG_LOAD_BASIC|PKG_LOAD_DEPS|PKG_LOAD_RDEPS|PKG_LOAD_OPTIONS| PKG_LOAD_REQUIRES|PKG_LOAD_PROVIDES| PKG_LOAD_SHLIBS_REQUIRED|PKG_LOAD_SHLIBS_PROVIDED|PKG_LOAD_ANNOTATIONS| PKG_LOAD_CONFLICTS; else flag = PKG_LOAD_BASIC|PKG_LOAD_RDEPS|PKG_LOAD_DEPS|PKG_LOAD_ANNOTATIONS; } HASH_FIND(hh, universe->items, uid, strlen(uid), unit); if (unit != NULL) { /* Search local in a universe chain */ cur = unit; found = NULL; do { if (cur->pkg->type == PKG_INSTALLED) { found = cur; break; } cur = cur->prev; } while (cur != unit); if (found) { pkgdb_ensure_loaded(universe->j->db, unit->pkg, flag); return (unit->pkg); } } if ((it = pkgdb_query(universe->j->db, uid, MATCH_EXACT)) == NULL) return (NULL); if (pkgdb_it_next(it, &pkg, flag) != EPKG_OK) pkg = NULL; pkgdb_it_free(it); return (pkg); }
int exec_which(int argc, char **argv) { struct pkgdb *db; struct pkgdb_it *it; struct pkg *pkg = NULL; char pathabs[MAXPATHLEN + 1]; int ret = EPKG_OK, retcode = EPKG_OK; const char *name, *version; if (argc != 2) { usage_which(); return (EX_USAGE); } if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { pkgdb_close(db); return (EX_IOERR); } absolutepath(argv[1], pathabs, sizeof(pathabs)); if ((it = pkgdb_query_which(db, pathabs)) == NULL) { return (EX_IOERR); } if (( ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) { retcode = EPKG_OK; pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version); printf("%s was installed by package %s-%s\n", pathabs, name, version); } else if (ret != EPKG_END) { retcode = EPKG_WARN; } else { printf("%s was not found in the database\n", pathabs); retcode = EPKG_WARN; } pkg_free(pkg); pkgdb_it_free(it); pkgdb_close(db); return (retcode); }
int main(int argc, char **argv) { struct pkgdb *db; int err; if (argc != 2) { fprintf(stderr, "usage: %s packagename\n", argv[0]); return 1; } db = NULL; err = pkg_init(NULL); if (err == EPKG_OK) err = getdb(&db); else fprintf(stderr, "could not parse config file\n"); if (err == EPKG_OK) { struct pkgdb_it *it; it = pkgdb_query(db, argv[1], MATCH_EXACT); if (it == NULL) printf("no local matches!\n"); else handle_it(it); it = pkgdb_rquery(db, argv[1], MATCH_EXACT, NULL); if (it == NULL) printf("no remote matches!\n"); else handle_it(it); printf("shutting down\n"); pkgdb_it_free(it); pkgdb_close(db); pkg_shutdown(); printf("shutdown\n"); } }
int exec_query(int argc, char **argv) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; struct pkg_manifest_key *keys = NULL; char *pkgname = NULL; int query_flags = PKG_LOAD_BASIC; match_t match = MATCH_EXACT; int ch; int ret; int retcode = EX_OK; int i; char multiline = 0; char *condition = NULL; struct sbuf *sqlcond = NULL; const unsigned int q_flags_len = (sizeof(accepted_query_flags)/sizeof(accepted_query_flags[0])); while ((ch = getopt(argc, argv, "agixF:e:")) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'x': match = MATCH_REGEX; break; case 'F': pkgname = optarg; break; case 'e': match = MATCH_CONDITION; condition = optarg; break; default: usage_query(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc == 0) { usage_query(); return (EX_USAGE); } /* Default to all packages if no pkg provided */ if (argc == 1 && pkgname == NULL && condition == NULL && match == MATCH_EXACT) { match = MATCH_ALL; } else if ((argc == 1) ^ (match == MATCH_ALL) && pkgname == NULL && condition == NULL) { usage_query(); return (EX_USAGE); } if (analyse_query_string(argv[0], accepted_query_flags, q_flags_len, &query_flags, &multiline) != EPKG_OK) return (EX_USAGE); if (pkgname != NULL) { pkg_manifest_keys_new(&keys); if (pkg_open(&pkg, pkgname, keys, 0) != EPKG_OK) { return (EX_IOERR); } pkg_manifest_keys_free(keys); print_query(pkg, argv[0], multiline); pkg_free(pkg); return (EX_OK); } if (condition != NULL) { sqlcond = sbuf_new_auto(); if (format_sql_condition(condition, sqlcond, false) != EPKG_OK) { sbuf_delete(sqlcond); return (EX_USAGE); } sbuf_finish(sqlcond); } ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL); if (ret == EPKG_ENOACCESS) { warnx("Insufficient privilege to query package database"); return (EX_NOPERM); } else if (ret == EPKG_ENODB) { if (!quiet) warnx("No packages installed"); return (EX_OK); } else if (ret != EPKG_OK) return (EX_IOERR); ret = pkgdb_open(&db, PKGDB_DEFAULT); if (ret != EPKG_OK) return (EX_IOERR); if (match == MATCH_ALL || match == MATCH_CONDITION) { const char *condition_sql = NULL; if (match == MATCH_CONDITION && sqlcond) condition_sql = sbuf_data(sqlcond); if ((it = pkgdb_query(db, condition_sql, match)) == NULL) return (EX_IOERR); while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) print_query(pkg, argv[0], multiline); if (ret != EPKG_END) retcode = EX_SOFTWARE; pkgdb_it_free(it); } else { int nprinted = 0; for (i = 1; i < argc; i++) { pkgname = argv[i]; if ((it = pkgdb_query(db, pkgname, match)) == NULL) return (EX_IOERR); while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) { nprinted++; print_query(pkg, argv[0], multiline); } if (ret != EPKG_END) { retcode = EX_SOFTWARE; break; } pkgdb_it_free(it); } if (nprinted == 0 && retcode == EX_OK) { /* ensure to return a non-zero status when no package were found. */ retcode = EX_UNAVAILABLE; } } pkg_free(pkg); pkgdb_close(db); return (retcode); }
int exec_query(int argc, char **argv) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; char *pkgname = NULL; int query_flags = PKG_LOAD_BASIC; match_t match = MATCH_EXACT; int ch; int ret = EPKG_OK; int retcode = EXIT_SUCCESS; int i; char multiline = 0; while ((ch = getopt(argc, argv, "agxXf:")) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'g': match = MATCH_GLOB; break; case 'x': match = MATCH_REGEX; break; case 'X': match = MATCH_EREGEX; break; case 'f': pkgname = optarg; break; default: usage_query(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc == 0) { usage_query(); return (EX_USAGE); } if ((argc == 1) ^ (match == MATCH_ALL) && pkgname == NULL) { usage_query(); return (EX_USAGE); } if (analyse_query_string(argv[0], &query_flags, &multiline) != EPKG_OK) return (EX_USAGE); if (pkgname != NULL) { if (pkg_open(&pkg, pkgname, NULL) != EPKG_OK) { return (1); } print_query(pkg, argv[0], multiline); pkg_free(pkg); return (0); } if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) return (EX_IOERR); if (match == MATCH_ALL) { if ((it = pkgdb_query(db, NULL, match)) == NULL) return (EX_IOERR); while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) print_query(pkg, argv[0], multiline); if (ret != EPKG_END) retcode = EX_SOFTWARE; pkgdb_it_free(it); } else { for (i = 1; i < argc; i++) { pkgname = argv[i]; if ((it = pkgdb_query(db, pkgname, match)) == NULL) return (EX_IOERR); while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) print_query(pkg, argv[0], multiline); if (ret != EPKG_END) { retcode = EX_SOFTWARE; break; } pkgdb_it_free(it); } } pkg_free(pkg); pkgdb_close(db); return (retcode); }
int exec_set(int argc, char **argv) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; int ch; int i; match_t match = MATCH_EXACT; int64_t newautomatic = -1; bool automatic = false; bool rc = false; const char *changed = NULL; char *newvalue = NULL; char *oldvalue = NULL; unsigned int loads = PKG_LOAD_BASIC; unsigned int sets = 0; unsigned int field = 0, depfield = 0; int retcode; struct option longopts[] = { { "automatic", required_argument, NULL, 'A' }, { "all", no_argument, NULL, 'a' }, { "case-sensitive", no_argument, NULL, 'C' }, { "glob", no_argument, NULL, 'g' }, { "case-insensitive", no_argument, NULL, 'i' }, { "change-origin", required_argument, NULL, 'o' }, { "change-name", required_argument, NULL, 'n' }, { "regex", no_argument, NULL, 'x' }, { "yes", no_argument, NULL, 'y' }, { NULL, 0, NULL, 0 }, }; while ((ch = getopt_long(argc, argv, "+A:aCgio:xyn:", longopts, NULL)) != -1) { switch (ch) { case 'A': sets |= AUTOMATIC; newautomatic = optarg[0] - '0'; if (newautomatic != 0 && newautomatic != 1) errx(EX_USAGE, "Wrong value for -A. " "Expecting 0 or 1, got: %s", optarg); break; case 'a': match = MATCH_ALL; break; case 'C': pkgdb_set_case_sensitivity(true); break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'o': sets |= ORIGIN; loads |= PKG_LOAD_DEPS; match = MATCH_ALL; changed = "origin"; if (!check_change_values(optarg, &oldvalue, &newvalue, '/')) { errx(EX_USAGE, "Wrong format for -o. " "Expecting oldorigin:neworigin, got: %s", optarg); } break; case 'n': sets |= NAME; loads |= PKG_LOAD_DEPS; match = MATCH_ALL; changed = "name"; if (!check_change_values(optarg, &oldvalue, &newvalue, '\0')) { errx(EX_USAGE, "Wrong format for -n. " "Expecting oldname:newname, got: %s", optarg); } break; case 'x': match = MATCH_REGEX; break; case 'y': yes = true; break; default: free(oldvalue); usage_set(); return (EX_USAGE); } } argc -= optind; argv += optind; if ((argc < 1 && match != MATCH_ALL) || (newautomatic == -1 && newvalue == NULL) || (sets & (NAME|ORIGIN)) == (NAME|ORIGIN)) { usage_set(); return (EX_USAGE); } if (sets & NAME) { field = PKG_SET_NAME; depfield = PKG_SET_DEPNAME; } else if (sets & ORIGIN) { field = PKG_SET_ORIGIN; depfield = PKG_SET_DEPORIGIN; } retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE, PKGDB_DB_LOCAL); if (retcode == EPKG_ENODB) { if (match == MATCH_ALL) return (EX_OK); if (!quiet) warnx("No packages installed. Nothing to do!"); return (EX_OK); } else if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privileges to modify the package database"); return (EX_NOPERM); } else if (retcode != EPKG_OK) { warnx("Error accessing package database"); return (EX_SOFTWARE); } if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { free(newvalue); return (EX_IOERR); } if (pkgdb_obtain_lock(db, PKGDB_LOCK_EXCLUSIVE) != EPKG_OK) { pkgdb_close(db); free(newvalue); warnx("Cannot get an exclusive lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } if (pkgdb_transaction_begin(db, NULL) != EPKG_OK) { pkgdb_close(db); free(newvalue); warnx("Cannot start transaction for update"); return (EX_TEMPFAIL); } if (oldvalue != NULL) { match = MATCH_ALL; if ((it = pkgdb_query(db, oldvalue, MATCH_EXACT)) == NULL) { retcode = EX_IOERR; goto cleanup; } if (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) != EPKG_OK) { pkg = NULL; /* fprintf(stderr, "%s not installed\n", oldorigin); free(oldorigin); pkgdb_it_free(it); pkgdb_close(db); return (EX_SOFTWARE);*/ } rc = yes; if (!yes) { if (pkg != NULL) rc = query_yesno(false, "Change %S from %S to %S for %n-%v? ", changed, oldvalue, newvalue, pkg, pkg); else rc = query_yesno(false, "Change %S from %S to %S for all dependencies? ", changed, oldvalue, newvalue); } if (pkg != NULL && rc) { if (pkgdb_set(db, pkg, field, newvalue) != EPKG_OK) { retcode = EX_IOERR; goto cleanup; } } pkgdb_it_free(it); } i = 0; do { bool saved_rc = rc; if ((it = pkgdb_query(db, argv[i], match)) == NULL) { retcode = EX_IOERR; goto cleanup; } while (pkgdb_it_next(it, &pkg, loads) == EPKG_OK) { if ((sets & AUTOMATIC) == AUTOMATIC) { pkg_get(pkg, PKG_AUTOMATIC, &automatic); if (automatic == newautomatic) continue; if (!rc) { if (newautomatic) rc = query_yesno(false, "Mark %n-%v as automatically installed? ", pkg, pkg); else rc = query_yesno(false, "Mark %n-%v as not automatically installed? ", pkg, pkg); } if (rc) pkgdb_set(db, pkg, PKG_SET_AUTOMATIC, (int)newautomatic); rc = saved_rc; } if (sets & (ORIGIN|NAME)) { struct pkg_dep *d = NULL; while (pkg_deps(pkg, &d) == EPKG_OK) { /* * Do not query user when he has already * been queried. */ if (pkgdb_set(db, pkg, depfield, oldvalue, newvalue) != EPKG_OK) { retcode = EX_IOERR; goto cleanup; } } } } pkgdb_it_free(it); i++; } while (i < argc); cleanup: free(oldvalue); free(newvalue); pkg_free(pkg); if (retcode == 0) { pkgdb_transaction_commit(db, NULL); } else { pkgdb_transaction_rollback(db, NULL); } pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE); pkgdb_close(db); return (retcode); }
int exec_search(int argc, char **argv) { const char *pattern = NULL; const char *reponame = NULL; int ret = EPKG_OK, ch; int flags; unsigned int opt = 0; match_t match = MATCH_REGEX; pkgdb_field search = FIELD_NONE; pkgdb_field label = FIELD_NONE; struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; bool atleastone = false; while ((ch = getopt(argc, argv, "cDdefgiL:opqQ:r:S:sx")) != -1) { switch (ch) { case 'c': /* Same as -S comment */ search = search_label_opt("comment"); break; case 'D': /* Same as -S description */ search = search_label_opt("description"); break; case 'd': /* Same as -Q depends-on */ opt |= modifier_opt("depends-on"); break; case 'e': match = MATCH_EXACT; break; case 'f': /* Same as -Q full */ opt |= modifier_opt("full"); break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'L': label = search_label_opt(optarg); break; case 'o': /* Same as -L origin */ label = search_label_opt("origin"); break; case 'p': /* Same as -Q prefix */ opt |= modifier_opt("prefix"); break; case 'q': quiet = true; break; case 'Q': opt |= modifier_opt(optarg); break; case 'r': reponame = optarg; break; case 'S': search = search_label_opt(optarg); break; case 's': /* Same as -Q size */ opt |= modifier_opt("size"); break; case 'x': match = MATCH_REGEX; break; default: usage_search(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc != 1) { usage_search(); return (EX_USAGE); } pattern = argv[0]; if (pattern[0] == '\0') { fprintf(stderr, "Pattern must not be empty!\n"); return (EX_USAGE); } if (search == FIELD_NONE) { if (strchr(pattern, '/') != NULL) search = FIELD_ORIGIN; else search = FIELD_NAMEVER; /* Default search */ } if (label == FIELD_NONE) label = search; /* By default, show what was searched */ switch(label) { case FIELD_NONE: break; /* should never happen */ case FIELD_ORIGIN: opt |= INFO_TAG_ORIGIN; break; case FIELD_NAME: opt |= INFO_TAG_NAME; break; case FIELD_NAMEVER: opt |= INFO_TAG_NAMEVER; break; case FIELD_COMMENT: opt |= INFO_TAG_NAMEVER|INFO_COMMENT; break; case FIELD_DESC: opt |= INFO_TAG_NAMEVER|INFO_DESCR; break; } if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) return (EX_IOERR); if ((it = pkgdb_search(db, pattern, match, search, search, reponame)) == NULL) { pkgdb_close(db); return (EX_IOERR); } flags = info_flags(opt); while ((ret = pkgdb_it_next(it, &pkg, flags)) == EPKG_OK) { print_info(pkg, opt); atleastone = true; } pkg_free(pkg); pkgdb_it_free(it); pkgdb_close(db); if (!atleastone) ret = EPKG_FATAL; return ((ret == EPKG_OK || ret == EPKG_END) ? EX_OK : EX_SOFTWARE); }
static int pkg_update_incremental(const char *name, struct pkg_repo *repo, time_t *mtime) { FILE *fmanifest = NULL, *fdigests = NULL; sqlite3 *sqlite = NULL; struct pkg *pkg = NULL; int rc = EPKG_FATAL; const char *origin, *digest, *offset; struct pkgdb_it *it = NULL; char *linebuf = NULL, *p; int updated = 0, removed = 0, added = 0, processed = 0; long num_offset; time_t local_t = *mtime; struct pkg_increment_task_item *ldel = NULL, *ladd = NULL, *item, *tmp_item; const char *myarch; struct pkg_manifest_parser *parser = NULL; size_t linecap = 0; ssize_t linelen; char *map = MAP_FAILED; size_t len = 0; pkg_debug(1, "Pkgrepo, begin incremental update of '%s'", name); if ((rc = pkgdb_repo_open(name, false, &sqlite, false)) != EPKG_OK) { return (EPKG_FATAL); } if ((rc = pkgdb_repo_init(sqlite, false)) != EPKG_OK) goto cleanup; if ((rc = pkg_register_repo(repo, sqlite)) != EPKG_OK) goto cleanup; it = pkgdb_repo_origins(sqlite); if (it == NULL) { rc = EPKG_FATAL; goto cleanup; } while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) { pkg_get(pkg, PKG_ORIGIN, &origin, PKG_DIGEST, &digest); pkg_update_increment_item_new(&ldel, origin, digest, 4); } fdigests = repo_fetch_remote_extract_tmp(repo, repo_digests_archive, "txz", &local_t, &rc, repo_digests_file); if (fdigests == NULL) goto cleanup; local_t = *mtime; fmanifest = repo_fetch_remote_extract_tmp(repo, repo_packagesite_archive, "txz", &local_t, &rc, repo_packagesite_file); if (fmanifest == NULL) goto cleanup; *mtime = local_t; fseek(fmanifest, 0, SEEK_END); len = ftell(fmanifest); 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, ":"); if (origin == NULL || digest == NULL || offset == NULL) { pkg_emit_error("invalid digest file format"); assert(0); 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; } processed++; HASH_FIND_STR(ldel, __DECONST(char *, origin), item); if (item == NULL) { added++; pkg_update_increment_item_new(&ladd, origin, digest, num_offset); } else { if (strcmp(digest, item->digest) == 0) { free(item->origin); free(item->digest); HASH_DEL(ldel, item); free(item); item = NULL; } else { free(item->origin); free(item->digest); HASH_DEL(ldel, item); free(item); item = NULL; pkg_update_increment_item_new(&ladd, origin, digest, num_offset); updated++; } } } rc = EPKG_OK; pkg_debug(1, "Pkgrepo, removing old entries for '%s'", name); removed = HASH_COUNT(ldel) - updated; HASH_ITER(hh, ldel, item, tmp_item) { if (rc == EPKG_OK) { rc = pkgdb_repo_remove_package(item->origin); } free(item->origin); free(item->digest); HASH_DEL(ldel, item); free(item); } pkg_config_string(PKG_CONFIG_ABI, &myarch); pkg_debug(1, "Pkgrepo, pushing new entries for '%s'", name); pkg = NULL; if (len > 0 && len < SSIZE_MAX) { map = mmap(NULL, len, PROT_READ, MAP_SHARED, fileno(fmanifest), 0); fclose(fmanifest); } HASH_ITER(hh, ladd, item, tmp_item) { if (rc == EPKG_OK) { if (map != MAP_FAILED) { rc = pkg_add_from_manifest(NULL, map + item->offset, item->origin, len - item->offset, item->digest, myarch, sqlite, &parser, &pkg); } else { rc = pkg_add_from_manifest(fmanifest, NULL, item->origin, item->offset, item->digest, myarch, sqlite, &parser, &pkg); } } free(item->origin); free(item->digest); HASH_DEL(ladd, item); free(item); } pkg_manifest_parser_free(parser); pkg_emit_incremental_update(updated, removed, added, processed); cleanup: if (pkg != NULL) pkg_free(pkg); if (it != NULL) pkgdb_it_free(it); if (pkgdb_repo_close(sqlite, rc == EPKG_OK) != EPKG_OK) rc = EPKG_FATAL; if (map == MAP_FAILED && fmanifest) fclose(fmanifest); if (fdigests) fclose(fdigests); if (map != MAP_FAILED) munmap(map, len); return (rc); }
int exec_search(int argc, char **argv) { const char *pattern = NULL; const char *reponame = NULL; int ret = EPKG_OK, ch; int flags; uint64_t opt = 0; match_t match = MATCH_REGEX; pkgdb_field search = FIELD_NONE; pkgdb_field label = FIELD_NONE; struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; bool atleastone = false; bool old_quiet; struct option longopts[] = { { "case-sensitive", no_argument, NULL, 'C' }, { "comment", no_argument, NULL, 'c' }, { "description", no_argument, NULL, 'D' }, { "depends-on", no_argument, NULL, 'd' }, { "exact", no_argument, NULL, 'e' }, { "full", no_argument, NULL, 'f' }, { "glob", no_argument, NULL, 'g' }, { "case-insensitive", no_argument, NULL, 'i' }, { "label", required_argument, NULL, 'L' }, { "origins", no_argument, NULL, 'o' }, { "prefix", no_argument, NULL, 'p' }, { "quiet", no_argument, NULL, 'q' }, { "query-modifier", required_argument, NULL, 'Q' }, { "repository", required_argument, NULL, 'r' }, { "raw", no_argument, NULL, 'R' }, { "search", required_argument, NULL, 'S' }, { "size", no_argument, NULL, 's' }, { "no-repo-update", no_argument, NULL, 'U' }, { "regex", no_argument, NULL, 'x' }, { "raw-format", required_argument, NULL, 1 }, { NULL, 0, NULL, 0 }, }; while ((ch = getopt_long(argc, argv, "+CcDdefgiL:opqQ:r:RS:sUx", longopts, NULL)) != -1) { switch (ch) { case 'C': pkgdb_set_case_sensitivity(true); break; case 'c': /* Same as -S comment */ search = search_label_opt("comment"); break; case 'D': /* Same as -S description */ search = search_label_opt("description"); break; case 'd': /* Same as -Q depends-on */ opt |= modifier_opt("depends-on"); break; case 'e': match = MATCH_EXACT; break; case 'f': /* Same as -Q full */ opt |= modifier_opt("full"); break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'L': label = search_label_opt(optarg); break; case 'o': /* Same as -L origin */ label = search_label_opt("origin"); break; case 'p': /* Same as -Q prefix */ opt |= modifier_opt("prefix"); break; case 'q': quiet = true; break; case 'Q': opt |= modifier_opt(optarg); break; case 'r': reponame = optarg; break; case 'R': opt = INFO_RAW; break; case 'S': search = search_label_opt(optarg); break; case 's': /* Same as -Q size */ opt |= modifier_opt("size"); break; case 'U': auto_update = false; break; case 'x': match = MATCH_REGEX; break; case 1: if (strcasecmp(optarg, "json") == 0) opt |= INFO_RAW_JSON; else if (strcasecmp(optarg, "json-compact") == 0) opt |= INFO_RAW_JSON_COMPACT; else if (strcasecmp(optarg, "yaml") == 0) opt |= INFO_RAW_YAML; else if (strcasecmp(optarg, "ucl") == 0) opt |= INFO_RAW_UCL; else errx(EX_USAGE, "Invalid format '%s' for the " "raw output, expecting json, json-compact " "or yaml", optarg); break; default: usage_search(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc != 1) { usage_search(); return (EX_USAGE); } pattern = argv[0]; if (pattern[0] == '\0') { fprintf(stderr, "Pattern must not be empty.\n"); return (EX_USAGE); } if (search == FIELD_NONE) { if (strchr(pattern, '/') != NULL) search = FIELD_ORIGIN; else search = FIELD_NAMEVER; /* Default search */ } if (label == FIELD_NONE) label = search; /* By default, show what was searched */ switch(label) { case FIELD_NONE: break; /* should never happen */ case FIELD_ORIGIN: opt |= INFO_TAG_ORIGIN|INFO_COMMENT; break; case FIELD_NAME: opt |= INFO_TAG_NAME|INFO_COMMENT; break; case FIELD_NAMEVER: opt |= INFO_TAG_NAMEVER|INFO_COMMENT; break; case FIELD_COMMENT: opt |= INFO_TAG_NAMEVER|INFO_COMMENT; break; case FIELD_DESC: opt |= INFO_TAG_NAMEVER|INFO_DESCR; break; } if (quiet) { opt = INFO_TAG_NAMEVER; quiet = false; } ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO); switch(ret) { case EPKG_ENOACCESS: warnx("Insufficient privileges to query the package database"); return (EX_NOPERM); case EPKG_ENODB: if (!auto_update) { warnx("Unable to open remote repository catalogues. Try running '%s update' first.", getprogname()); return (EX_IOERR); } break; case EPKG_OK: break; default: return (EX_IOERR); } /* first update the remote repositories if needed */ old_quiet = quiet; quiet = true; if (auto_update && (ret = pkgcli_update(false, false, reponame)) != EPKG_OK) return (ret); quiet = old_quiet; if (pkgdb_open_all(&db, PKGDB_REMOTE, reponame) != EPKG_OK) return (EX_IOERR); if ((it = pkgdb_repo_search(db, pattern, match, search, search, reponame)) == NULL) { pkgdb_close(db); return (EX_IOERR); } if (opt & INFO_RAW) { if ((opt & (INFO_RAW_JSON|INFO_RAW_JSON_COMPACT)) == 0) opt |= INFO_RAW_YAML; } flags = info_flags(opt, true); while ((ret = pkgdb_it_next(it, &pkg, flags)) == EPKG_OK) { print_info(pkg, opt); atleastone = true; } pkg_free(pkg); pkgdb_it_free(it); pkgdb_close(db); if (!atleastone) ret = EPKG_FATAL; return ((ret == EPKG_OK || ret == EPKG_END) ? EX_OK : EX_SOFTWARE); }
int exec_fetch(int argc, char **argv) { struct pkg *pkg = NULL; struct pkgdb_it *it = NULL; struct pkgdb *db = NULL; struct pkg_jobs *jobs = NULL; const char *reponame = NULL; int retcode = EXIT_FAILURE; int ch; int flags = PKG_LOAD_BASIC; bool yes = false; bool auto_update = true; match_t match = MATCH_EXACT; while ((ch = getopt(argc, argv, "ygxXr:qaLd")) != -1) { switch (ch) { case 'y': yes = true; break; case 'a': match = MATCH_ALL; break; case 'g': match = MATCH_GLOB; break; case 'x': match = MATCH_REGEX; break; case 'X': match = MATCH_EREGEX; break; case 'r': reponame = optarg; break; case 'q': quiet = true; break; case 'L': auto_update = false; break; case 'd': flags |= PKG_LOAD_DEPS; break; default: usage_fetch(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc < 1 && match != MATCH_ALL) { usage_fetch(); return (EX_USAGE); } /* TODO: Allow the user to specify an output directory via -o outdir */ if (geteuid() != 0) { warnx("Fetching packages can only be done as root"); return (EX_NOPERM); } /* first update the remote repositories if needed */ if (auto_update && (retcode = pkgcli_update()) != EPKG_OK) return (retcode); if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) { return (EX_IOERR); } if (pkg_jobs_new(&jobs, PKG_JOBS_FETCH, db) != EPKG_OK) { goto cleanup; } if ((it = pkgdb_query_fetch(db, match, argc, argv, reponame, flags)) == NULL) goto cleanup; while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) { pkg_jobs_add(jobs, pkg); pkg = NULL; } pkgdb_it_free(it); if (pkg_jobs_is_empty(jobs)) goto cleanup; if (!quiet) { print_jobs_summary(jobs, PKG_JOBS_FETCH, "The following packages will be fetched:\n\n"); if (!yes) pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes); if (!yes) yes = query_yesno("\nProceed with fetching packages [y/N]: "); } if (yes) if (pkg_jobs_apply(jobs, 0) != EPKG_OK) goto cleanup; retcode = EXIT_SUCCESS; cleanup: pkg_jobs_free(jobs); pkgdb_close(db); return (retcode); }
int exec_check(int argc, char **argv) { struct pkg *pkg = NULL; struct pkgdb_it *it = NULL; struct pkgdb *db = NULL; match_t match = MATCH_EXACT; int flags = PKG_LOAD_BASIC; int ret; int ch; bool yes = false; bool dcheck = false; bool checksums = false; bool recompute = false; bool reanalyse_shlibs = false; bool shlibs; int nbpkgs = 0; int i; int verbose = 0; struct deps_head dh = STAILQ_HEAD_INITIALIZER(dh); while ((ch = getopt(argc, argv, "yagdBxsrv")) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'x': match = MATCH_REGEX; break; case 'g': match = MATCH_GLOB; break; case 'y': yes = true; break; case 'd': dcheck = true; flags |= PKG_LOAD_DEPS; break; case 'B': pkg_config_bool(PKG_CONFIG_SHLIBS, &shlibs); if (!shlibs) errx(EX_USAGE, "reanalyzing shlibs requires SHLIBS" " in pkg.conf."); reanalyse_shlibs = true; flags |= PKG_LOAD_FILES; break; case 's': checksums = true; flags |= PKG_LOAD_FILES; break; case 'r': recompute = true; flags |= PKG_LOAD_FILES; if (geteuid() != 0) errx(EX_USAGE, "recomputing the checksums" " and size can only be done as root"); break; case 'v': verbose = 1; break; default: usage_check(); return (EX_USAGE); } } argc -= optind; argv += optind; /* Default to all packages if no pkg provided */ if (argc == 0 && (dcheck || checksums || recompute || reanalyse_shlibs)) { match = MATCH_ALL; } else if ((argc == 0 && match != MATCH_ALL) || !(dcheck || checksums || recompute || reanalyse_shlibs)) { usage_check(); return (EX_USAGE); } ret = pkgdb_open(&db, PKGDB_DEFAULT); if (ret == EPKG_ENODB) { if (geteuid() == 0) return (EX_IOERR); return (EX_OK); } if (ret != EPKG_OK) return (EX_IOERR); i = 0; do { if ((it = pkgdb_query(db, argv[i], match)) == NULL) { pkgdb_close(db); return (EX_IOERR); } while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) { const char *pkgname = NULL; pkg_get(pkg, PKG_NAME, &pkgname); /* check for missing dependencies */ if (dcheck) { if (verbose) printf("Checking dependencies: %s\n", pkgname); nbpkgs += check_deps(db, pkg, &dh); } if (checksums) { if (verbose) printf("Checking checksums: %s\n", pkgname); pkg_test_filesum(pkg); } if (recompute) { if (verbose) printf("Recomputing size and checksums: %s\n", pkgname); pkg_recompute(db, pkg); } if (reanalyse_shlibs) { if (verbose) printf("Reanalyzing files for shlibs: %s\n", pkgname); if (pkgdb_reanalyse_shlibs(db, pkg) != EPKG_OK) printf("Failed to reanalyse for shlibs: %s\n", pkgname); } } if (geteuid() == 0 && nbpkgs > 0) { if (yes == false) pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes); printf("\n>>> Missing package dependencies were detected.\n"); printf(">>> Found %d issue(s) in total with your package database.\n\n", nbpkgs); ret = fix_deps(db, &dh, nbpkgs, yes); if (ret == EPKG_OK) check_summary(db, &dh); else if (ret == EPKG_ENODB) { db = NULL; return (EX_IOERR); } } pkgdb_it_free(it); i++; } while (i < argc); deps_free(&dh); pkg_free(pkg); pkgdb_close(db); return (EX_OK); }
static void pkg_repo_binary_it_free(struct pkg_repo_it *it) { pkgdb_it_free(it->data); free(it); }
int exec_set(int argc, char **argv) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; int ch; int i; bool yes; match_t match = MATCH_EXACT; int64_t newautomatic = -1; bool automatic = false; const char *errstr; char *neworigin = NULL; char *oldorigin = NULL; unsigned int loads = PKG_LOAD_BASIC; unsigned int sets = 0; int retcode; yes = pkg_object_bool(pkg_config_get("ASSUME_ALWAYS_YES")); while ((ch = getopt(argc, argv, "A:agio:xy")) != -1) { switch (ch) { case 'A': sets |= AUTOMATIC; newautomatic = strtonum(optarg, 0, 1, &errstr); if (errstr) errx(EX_USAGE, "Wrong value for -A. " "Expecting 0 or 1, got: %s (%s)", optarg, errstr); break; case 'a': match = MATCH_ALL; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'o': sets |= ORIGIN; loads |= PKG_LOAD_DEPS; match = MATCH_ALL; oldorigin = strdup(optarg); neworigin = strrchr(oldorigin, ':'); if (neworigin == NULL) { free(oldorigin); errx(EX_USAGE, "Wrong format for -o. " "Expecting oldorigin:neworigin, got: %s", optarg); } *neworigin = '\0'; neworigin++; if (strrchr(oldorigin, '/') == NULL || strrchr(neworigin, '/') == NULL) { free(oldorigin); errx(EX_USAGE, "Bad origin format, got: %s", optarg); } break; case 'x': match = MATCH_REGEX; break; case 'y': yes = true; break; default: if (oldorigin != NULL) free(oldorigin); usage_set(); return (EX_USAGE); } } argc -= optind; argv += optind; if ((argc < 1 && match != MATCH_ALL) || (newautomatic == -1 && neworigin == NULL)) { usage_set(); return (EX_USAGE); } retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE, PKGDB_DB_LOCAL); if (retcode == EPKG_ENODB) { if (match == MATCH_ALL) return (EX_OK); if (!quiet) warnx("No packages installed. Nothing to do!"); return (EX_OK); } else if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privileges to modify the package database"); return (EX_NOPERM); } else if (retcode != EPKG_OK) { warnx("Error accessing package database"); return (EX_SOFTWARE); } if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) return (EX_IOERR); if (pkgdb_obtain_lock(db, PKGDB_LOCK_EXCLUSIVE, 0, 0) != EPKG_OK) { pkgdb_close(db); warnx("Cannot get an exclusive lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } if (oldorigin != NULL) { match = MATCH_ALL; if ((it = pkgdb_query(db, oldorigin, MATCH_EXACT)) == NULL) { retcode = EX_IOERR; goto cleanup; } if (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) != EPKG_OK) { pkg = NULL; /* fprintf(stderr, "%s not installed\n", oldorigin); free(oldorigin); pkgdb_it_free(it); pkgdb_close(db); return (EX_SOFTWARE);*/ } if (!yes) { if (pkg != NULL) yes = query_yesno(false, "Change origin from %S to %S for %n-%v? [y/N]: ", oldorigin, neworigin, pkg, pkg); else yes = query_yesno(false, "Change origin from %S to %S for all dependencies? " "[y/N]: ", oldorigin, neworigin); } if (pkg != NULL && yes) { if (pkgdb_set(db, pkg, PKG_SET_ORIGIN, neworigin) != EPKG_OK) { retcode = EX_IOERR; goto cleanup; } } pkgdb_it_free(it); } i = 0; do { bool save_yes = yes; if ((it = pkgdb_query(db, argv[i], match)) == NULL) { retcode = EX_IOERR; goto cleanup; } while (pkgdb_it_next(it, &pkg, loads) == EPKG_OK) { if ((sets & AUTOMATIC) == AUTOMATIC) { pkg_get(pkg, PKG_AUTOMATIC, &automatic); if (automatic == newautomatic) continue; if (!yes) { if (newautomatic) yes = query_yesno(false, "Mark %n-%v as automatically installed? [y/N]: ", pkg, pkg); else yes = query_yesno(false, "Mark %n-%v as not automatically installed? [y/N]: ", pkg, pkg); } if (yes) pkgdb_set(db, pkg, PKG_SET_AUTOMATIC, newautomatic); yes = save_yes; } if ((sets & ORIGIN) == ORIGIN) { struct pkg_dep *d = NULL; while (pkg_deps(pkg, &d) == EPKG_OK) { /* * Do not query user when he has already * been queried. */ if (pkgdb_set(db, pkg, PKG_SET_DEPORIGIN, oldorigin, neworigin) != EPKG_OK) { retcode = EX_IOERR; goto cleanup; } } } } pkgdb_it_free(it); i++; } while (i < argc); cleanup: if (oldorigin) free(oldorigin); if (pkg != NULL) pkg_free(pkg); pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE); pkgdb_close(db); return (retcode); }
static int pkg_create_matches(int argc, char **argv, match_t match, pkg_formats fmt, const char * const outdir, const char * const rootdir, bool overwrite) { int i, ret = EPKG_OK, retcode = EPKG_OK; const char *name, *version; struct pkg *pkg = NULL; struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; int query_flags = PKG_LOAD_DEPS | PKG_LOAD_FILES | PKG_LOAD_CATEGORIES | PKG_LOAD_DIRS | PKG_LOAD_SCRIPTS | PKG_LOAD_OPTIONS | PKG_LOAD_MTREE | PKG_LOAD_LICENSES | PKG_LOAD_USERS | PKG_LOAD_GROUPS | PKG_LOAD_SHLIBS; struct pkg_head head = STAILQ_HEAD_INITIALIZER(head); struct pkg_entry *e = NULL; char pkgpath[MAXPATHLEN]; const char *format = NULL; bool foundone; if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { pkgdb_close(db); return (EX_IOERR); } switch (fmt) { case TXZ: format = "txz"; break; case TBZ: format = "tbz"; break; case TGZ: format = "tgz"; break; case TAR: format = "tar"; break; } for (i = 0; i < argc || match == MATCH_ALL; i++) { if (match == MATCH_ALL) { printf("Loading package list...\n"); if ((it = pkgdb_query(db, NULL, match)) == NULL) goto cleanup; match = !MATCH_ALL; } else if ((it = pkgdb_query(db, argv[i], match)) == NULL) goto cleanup; foundone = false; while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) { if ((e = malloc(sizeof(struct pkg_entry))) == NULL) err(1, "malloc(pkg_entry)"); e->pkg = pkg; pkg = NULL; STAILQ_INSERT_TAIL(&head, e, next); foundone = true; } if (!foundone) warnx("No installed package matching \"%s\" found\n", argv[i]); pkgdb_it_free(it); if (ret != EPKG_END) retcode++; } while (!STAILQ_EMPTY(&head)) { e = STAILQ_FIRST(&head); STAILQ_REMOVE_HEAD(&head, next); pkg_get(e->pkg, PKG_NAME, &name, PKG_VERSION, &version); if (!overwrite) { snprintf(pkgpath, MAXPATHLEN, "%s/%s-%s.%s", outdir, name, version, format); if (access(pkgpath, F_OK) == 0) { printf("%s-%s already packaged, skipping...\n", name, version); pkg_free(e->pkg); free(e); continue; } } printf("Creating package for %s-%s\n", name, version); if (pkg_create_installed(outdir, fmt, rootdir, e->pkg) != EPKG_OK) retcode++; pkg_free(e->pkg); free(e); } cleanup: pkgdb_close(db); return (retcode); }
int exec_info(int argc, char **argv) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; int query_flags; struct pkg *pkg = NULL; uint64_t opt = INFO_TAG_NAMEVER; match_t match = MATCH_GLOB; char *pkgname; char *pkgversion = NULL, *pkgversion2 = NULL; const char *file = NULL; int ch, fd; int ret = EPKG_OK; int retcode = 0; bool gotone = false; int i, j; int sign = 0; int sign2 = 0; int open_flags = 0; bool pkg_exists = false; bool origin_search = false; bool e_flag = false; struct pkg_manifest_key *keys = NULL; #ifdef HAVE_CAPSICUM cap_rights_t rights; #endif struct option longopts[] = { { "all", no_argument, NULL, 'a' }, { "annotations", no_argument, NULL, 'A' }, { "provided-shlibs", no_argument, NULL, 'b' }, { "required-shlibs", no_argument, NULL, 'B' }, { "case-sensitive", no_argument, NULL, 'C' }, { "dependencies", no_argument, NULL, 'd' }, { "pkg-message", no_argument, NULL, 'D' }, { "exists", no_argument, NULL, 'e' }, { "show-name-only", no_argument, NULL, 'E' }, { "full", no_argument, NULL, 'f' }, { "file", required_argument, NULL, 'F' }, { "glob", no_argument, NULL, 'g' }, { "case-insensitive", no_argument, NULL, 'i' }, { "comment", no_argument, NULL, 'I' }, { "locked", no_argument, NULL, 'k' }, { "list-files", no_argument, NULL, 'l' }, { "origin", no_argument, NULL, 'o' }, { "by-origin", no_argument, NULL, 'O' }, { "prefix", no_argument, NULL, 'p' }, { "quiet", no_argument, NULL, 'q' }, { "required-by", no_argument, NULL, 'r' }, { "raw", no_argument, NULL, 'R' }, { "size", no_argument, NULL, 's' }, { "regex", no_argument, NULL, 'x' }, { "raw-format", required_argument, NULL, 1 }, { NULL, 0, NULL, 0 }, }; /* TODO: exclusive opts ? */ while ((ch = getopt_long(argc, argv, "+aAbBCdDeEfF:giIkloOpqrRsx", longopts, NULL)) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'A': opt |= INFO_ANNOTATIONS; break; case 'b': opt |= INFO_SHLIBS_PROVIDED; break; case 'B': opt |= INFO_SHLIBS_REQUIRED; break; case 'C': pkgdb_set_case_sensitivity(true); break; case 'd': opt |= INFO_DEPS; break; case 'D': opt |= INFO_MESSAGE; break; case 'e': pkg_exists = true;; retcode = 1; break; case 'E': /* ports compatibility */ e_flag = true; break; case 'f': opt |= INFO_FULL; break; case 'F': file = optarg; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'I': opt |= INFO_COMMENT; break; case 'k': opt |= INFO_LOCKED; break; case 'l': opt |= INFO_FILES; break; case 'o': opt |= INFO_ORIGIN; break; case 'O': origin_search = true; /* only for ports compat */ break; case 'p': opt |= INFO_PREFIX; break; case 'q': quiet = true; break; case 'r': opt |= INFO_RDEPS; break; case 'R': opt |= INFO_RAW; break; case 's': opt |= INFO_FLATSIZE; break; case 'x': match = MATCH_REGEX; break; case 1: if (strcasecmp(optarg, "json") == 0) opt |= INFO_RAW_JSON; else if (strcasecmp(optarg, "json-compact") == 0) opt |= INFO_RAW_JSON_COMPACT; else if (strcasecmp(optarg, "yaml") == 0) opt |= INFO_RAW_YAML; else if (strcasecmp(optarg, "ucl") == 0) opt |= INFO_RAW_UCL; else errx(EX_USAGE, "Invalid format '%s' for the " "raw output, expecting json, json-compact " "or yaml", optarg); break; default: usage_info(); return(EX_USAGE); } } if (argc == 1 || (argc == 2 && quiet)) match = MATCH_ALL; argc -= optind; argv += optind; if (argc == 0 && file == NULL && match != MATCH_ALL) { /* which -O bsd.*.mk always execpt clean output */ if (origin_search) return (EX_OK); usage_info(); return (EX_USAGE); } /* When no other data is requested, default is to print * 'name-ver comment' For -O, just print name-ver */ if (!origin_search && (opt & INFO_ALL) == 0 && match == MATCH_ALL && !quiet) opt |= INFO_COMMENT; /* Special compatibility: handle -O and -q -O */ if (origin_search) { if (quiet) { opt = INFO_TAG_NAMEVER; quiet = false; } else { opt = INFO_TAG_NAMEVER|INFO_COMMENT; } } if (match == MATCH_ALL && opt == INFO_TAG_NAMEVER) quiet = false; if (file != NULL) { if ((fd = open(file, O_RDONLY)) == -1) { warn("Unable to open %s", file); return (EX_IOERR); } #ifdef HAVE_CAPSICUM cap_rights_init(&rights, CAP_READ, CAP_FSTAT); if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS ) { warn("cap_rights_limit() failed"); close(fd); return (EX_SOFTWARE); } if (cap_enter() < 0 && errno != ENOSYS) { warn("cap_enter() failed"); close(fd); return (EX_SOFTWARE); } #endif if (opt == INFO_TAG_NAMEVER) opt |= INFO_FULL; pkg_manifest_keys_new(&keys); if (opt & INFO_RAW) { if ((opt & (INFO_RAW_JSON|INFO_RAW_JSON_COMPACT|INFO_RAW_UCL)) == 0) opt |= INFO_RAW_YAML; } if ((opt & (INFO_RAW | INFO_FILES | INFO_DIRS)) == 0) open_flags = PKG_OPEN_MANIFEST_COMPACT; if (pkg_open_fd(&pkg, fd, keys, open_flags) != EPKG_OK) { close(fd); return (1); } pkg_manifest_keys_free(keys); print_info(pkg, opt); close(fd); pkg_free(pkg); return (EX_OK); } ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL); if (ret == EPKG_ENOACCESS) { warnx("Insufficient privileges to query the package database"); return (EX_NOPERM); } else if (ret == EPKG_ENODB) { if (match == MATCH_ALL) return (EX_OK); if (origin_search) return (EX_OK); if (!quiet) warnx("No packages installed"); return (EX_UNAVAILABLE); } else if (ret != EPKG_OK) return (EX_IOERR); ret = pkgdb_open(&db, PKGDB_DEFAULT); if (ret != EPKG_OK) return (EX_IOERR); if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) { pkgdb_close(db); warnx("Cannot get a read lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } i = 0; do { gotone = false; pkgname = argv[i]; /* * allow to search for origin with a trailing / * likes audio/linux-vsound depending on ${PORTSDIR}/audio/sox/ */ if (argc > 0 && pkgname[strlen(pkgname) -1] == '/') pkgname[strlen(pkgname) -1] = '\0'; if (argc > 0) { j=0; while (pkgname[j] != '\0') { if (pkgname[j] == '<') { if (pkgversion) { pkgversion2 = pkgname + j; sign2 = LT; pkgversion2[0] = '\0'; pkgversion2++; if (pkgversion2[0] == '=') { pkgversion2++; sign=LE; j++; } } else { pkgversion = pkgname + j; sign = LT; pkgversion[0] = '\0'; pkgversion++; if (pkgversion[0] == '=') { pkgversion++; sign=LE; j++; } } } else if (pkgname[j] == '>') { if (pkgversion) { pkgversion2 = pkgname + j; sign2 = GT; pkgversion2[0] = '\0'; pkgversion2++; if (pkgversion2[0] == '=') { pkgversion2++; sign=GE; j++; } } else { pkgversion = pkgname + j; sign = GT; pkgversion[0] = '\0'; pkgversion++; if (pkgversion[0] == '=') { pkgversion++; sign=GE; j++; } } } else if (pkgname[j] == '=') { if (pkgversion) { pkgversion2 = pkgname + j; sign2 = EQ; pkgversion2[0] = '\0'; pkgversion2++; if (pkgversion2[0] == '=') { pkgversion2++; sign=EQ; j++; } } else { pkgversion = pkgname + j; sign = EQ; pkgversion[0] = '\0'; pkgversion++; if (pkgversion[0] == '=') { pkgversion++; sign=EQ; j++; } } } j++; } } if (match != MATCH_ALL && pkgname[0] == '\0') { fprintf(stderr, "Pattern must not be empty.\n"); i++; continue; } if ((it = pkgdb_query(db, pkgname, match)) == NULL) { goto cleanup; } /* this is place for compatibility hacks */ /* ports infrastructure expects pkg info -q -O to * always return 0 even if the ports doesn't exists */ if (origin_search) gotone = true; /* end of compatibility hacks */ /* * only show full version in case of match glob with a * single argument specified which does not contains * any glob pattern */ if (argc == 1 && !origin_search && !quiet && !e_flag && match == MATCH_GLOB && strcspn(pkgname, "*[]{}()") == strlen(pkgname) && opt == INFO_TAG_NAMEVER) opt |= INFO_FULL; query_flags = info_flags(opt, false); while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) { gotone = true; const char *version; pkg_get(pkg, PKG_VERSION, &version); if (pkgversion != NULL) { switch (pkg_version_cmp(version, pkgversion)) { case -1: if (sign != LT && sign != LE) { gotone = false; continue; } break; case 0: if (sign != LE && sign != GE && sign != EQ) { gotone = false; continue; } break; case 1: if (sign != GT && sign != GE) { gotone = false; continue; } break; } } if (pkgversion2 != NULL) { switch (pkg_version_cmp(version, pkgversion2)) { case -1: if (sign2 != LT && sign2 != LE) { gotone = false; continue; } break; case 0: if (sign2 != LE && sign2 != GE && sign2 != EQ) { gotone = false; continue; } break; case 1: if (sign2 != GT && sign2 != GE) { gotone = false; continue; } break; } } if (pkg_exists) retcode = EX_OK; else print_info(pkg, opt); } if (ret != EPKG_END) { retcode = EX_IOERR; } if (retcode == EX_OK && !gotone && match != MATCH_ALL) { if (!quiet) warnx("No package(s) matching %s", argv[i]); retcode = EX_SOFTWARE; } pkgdb_it_free(it); i++; } while (i < argc); cleanup: pkg_free(pkg); pkgdb_release_lock(db, PKGDB_LOCK_READONLY); pkgdb_close(db); return (retcode); }
int exec_rquery(int argc, char **argv) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; char *pkgname = NULL; int query_flags = PKG_LOAD_BASIC; match_t match = MATCH_EXACT; int ch; int ret = EPKG_OK; int retcode = EX_OK; int i; char multiline = 0; char *condition = NULL; const char *portsdir; struct sbuf *sqlcond = NULL; const unsigned int q_flags_len = NELEM(accepted_rquery_flags); const char *reponame = NULL; bool auto_update; bool onematched = false; bool old_quiet; bool index_output = false; struct option longopts[] = { { "all", no_argument, NULL, 'a' }, { "case-sensitive", no_argument, NULL, 'C' }, { "evaluate", required_argument, NULL, 'e' }, { "glob", no_argument, NULL, 'g' }, { "case-insensitive", no_argument, NULL, 'i' }, { "index-line", no_argument, NULL, 'I' }, { "repository", required_argument, NULL, 'r' }, { "no-repo-update", no_argument, NULL, 'U' }, { "regex", no_argument, NULL, 'x' }, { NULL, 0, NULL, 0 }, }; portsdir = pkg_object_string(pkg_config_get("PORTSDIR")); while ((ch = getopt_long(argc, argv, "+aCgiIxe:r:U", longopts, NULL)) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'C': pkgdb_set_case_sensitivity(true); break; case 'e': match = MATCH_CONDITION; condition = optarg; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'I': index_output = true; break; case 'r': reponame = optarg; break; case 'U': auto_update = false; break; case 'x': match = MATCH_REGEX; break; default: usage_rquery(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc == 0 && !index_output) { usage_rquery(); return (EX_USAGE); } /* Default to all packages if no pkg provided */ if (!index_output) { if (argc == 1 && condition == NULL && match == MATCH_EXACT) { match = MATCH_ALL; } else if (((argc == 1) ^ (match == MATCH_ALL )) && condition == NULL) { usage_rquery(); return (EX_USAGE); } } else { if (argc == 0) match = MATCH_ALL; } if (!index_output && analyse_query_string(argv[0], accepted_rquery_flags, q_flags_len, &query_flags, &multiline) != EPKG_OK) return (EX_USAGE); if (condition != NULL) { sqlcond = sbuf_new_auto(); if (format_sql_condition(condition, sqlcond, true) != EPKG_OK) return (EX_USAGE); sbuf_finish(sqlcond); } ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_REPO); if (ret == EPKG_ENOACCESS) { warnx("Insufficient privileges to query the package database"); return (EX_NOPERM); } else if (ret != EPKG_OK) return (EX_IOERR); /* first update the remote repositories if needed */ old_quiet = quiet; quiet = true; if (auto_update && (ret = pkgcli_update(false, false, reponame)) != EPKG_OK) return (ret); quiet = old_quiet; ret = pkgdb_open_all(&db, PKGDB_REMOTE, reponame); if (ret != EPKG_OK) return (EX_IOERR); if (index_output) query_flags = PKG_LOAD_BASIC|PKG_LOAD_CATEGORIES|PKG_LOAD_DEPS; if (match == MATCH_ALL || match == MATCH_CONDITION) { const char *condition_sql = NULL; if (match == MATCH_CONDITION && sqlcond) condition_sql = sbuf_data(sqlcond); if ((it = pkgdb_repo_query(db, condition_sql, match, reponame)) == NULL) return (EX_IOERR); while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) { if (index_output) print_index(pkg, portsdir); else print_query(pkg, argv[0], multiline); } if (ret != EPKG_END) retcode = EX_SOFTWARE; pkgdb_it_free(it); } else { for (i = (index_output ? 0 : 1); i < argc; i++) { pkgname = argv[i]; if ((it = pkgdb_repo_query(db, pkgname, match, reponame)) == NULL) return (EX_IOERR); while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) { onematched = true; if (index_output) print_index(pkg, portsdir); else print_query(pkg, argv[0], multiline); } if (ret != EPKG_END) { retcode = EX_SOFTWARE; break; } pkgdb_it_free(it); } if (!onematched && retcode == EX_OK) retcode = EX_UNAVAILABLE; } pkg_free(pkg); pkgdb_close(db); return (retcode); }
static int analyse_elf(struct pkgdb *db, struct pkg *pkg, const char *fpath) { struct pkg **deps; struct pkg *p = NULL; struct pkgdb_it *it = NULL; Elf *e; Elf_Scn *scn = NULL; GElf_Shdr shdr; Elf_Data *data; GElf_Dyn *dyn, dyn_mem; size_t numdyn; size_t dynidx; void *handle; Link_map *map; char *name; bool found=false; int fd, i; if ((fd = open(fpath, O_RDONLY, 0)) < 0) return (EPKG_FATAL); if (( e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) return (EPKG_FATAL); if (elf_kind(e) != ELF_K_ELF) return (EPKG_FATAL); while (( scn = elf_nextscn(e, scn)) != NULL) { if (gelf_getshdr(scn, &shdr) != &shdr) return (EPKG_FATAL); if (shdr.sh_type == SHT_DYNAMIC) break; } data = elf_getdata(scn, NULL); numdyn = shdr.sh_size / shdr.sh_entsize; for (dynidx = 0; dynidx < numdyn; dynidx++) { if ((dyn = gelf_getdyn(data, dynidx, &dyn_mem)) == NULL) return (EPKG_FATAL); if (dyn->d_tag != DT_NEEDED) continue; name = elf_strptr(e, shdr.sh_link, dyn->d_un.d_val); handle = dlopen(name, RTLD_LAZY); if (handle != NULL) { dlinfo(handle, RTLD_DI_LINKMAP, &map); if ((it = pkgdb_query_which(db, map->l_name)) == NULL) return (EPKG_FATAL); if (pkgdb_it_next(it, &p, PKG_LOAD_BASIC) == EPKG_OK) { found = false; if (( deps = pkg_deps(pkg) ) != NULL) { for (i = 0; deps[i]; i++) { if (strcmp(pkg_get(deps[i], PKG_ORIGIN), pkg_get(p, PKG_ORIGIN)) == 0) found = true; } } if (!found) { warnx("adding forgotten depends (%s): %s-%s", map->l_name, pkg_get(p, PKG_NAME), pkg_get(p, PKG_VERSION)); pkg_adddep(pkg, pkg_get(p, PKG_NAME), pkg_get(p, PKG_ORIGIN), pkg_get(p, PKG_VERSION)); } } dlclose(handle); } pkgdb_it_free(it); } pkg_free(p); close(fd); return (EPKG_OK); }
int exec_set(int argc, char **argv) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; int ch; int i; bool yes_flag = false; bool yes = yes_flag; match_t match = MATCH_EXACT; int newautomatic = -1; bool automatic = false; const char *errstr; const char *name; const char *version; char *neworigin = NULL; char *oldorigin = NULL; unsigned int loads = PKG_LOAD_BASIC; unsigned int sets = 0; int retcode; while ((ch = getopt(argc, argv, "ayA:kxgo:")) != -1) { switch (ch) { case 'y': yes_flag = true; break; case 'a': match = MATCH_ALL; break; case 'x': match = MATCH_REGEX; break; case 'g': match = MATCH_GLOB; break; case 'A': sets |= AUTOMATIC; newautomatic = strtonum(optarg, 0, 1, &errstr); if (errstr) errx(EX_USAGE, "Wrong value for -A. " "Expecting 0 or 1, got: %s (%s)", optarg, errstr); break; case 'o': sets |= ORIGIN; loads |= PKG_LOAD_DEPS; match = MATCH_ALL; oldorigin = strdup(optarg); neworigin = strrchr(oldorigin, ':'); if (neworigin == NULL) { free(oldorigin); errx(EX_USAGE, "Wrong format for -o. " "Expecting oldorigin:neworigin, got: %s", optarg); } *neworigin = '\0'; neworigin++; if (strrchr(oldorigin, '/') == NULL || strrchr(neworigin, '/') == NULL) { free(oldorigin); errx(EX_USAGE, "Bad origin format, got: %s", optarg); } break; default: if (oldorigin != NULL) free(oldorigin); usage_set(); return (EX_USAGE); } } argc -= optind; argv += optind; if ((argc < 1 && match != MATCH_ALL) || (newautomatic == -1 && neworigin == NULL)) { usage_set(); return (EX_USAGE); } retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE, PKGDB_DB_LOCAL); if (retcode == EPKG_ENODB) { if (match == MATCH_ALL) return (EX_OK); if (!quiet) warnx("No packages installed. Nothing to do!"); return (EX_OK); } else if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privilege to modify package database"); return (EX_NOPERM); } else if (retcode != EPKG_OK) { warnx("Error accessing package database"); return (EX_SOFTWARE); } if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) return (EX_IOERR); if (!yes_flag) pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes_flag); if (oldorigin != NULL) { yes = yes_flag; match = MATCH_ALL; if ((it = pkgdb_query(db, oldorigin, MATCH_EXACT)) == NULL) { pkgdb_close(db); return (EX_IOERR); } if (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) != EPKG_OK) { pkg = NULL; /* fprintf(stderr, "%s not installed\n", oldorigin); free(oldorigin); pkgdb_it_free(it); pkgdb_close(db); return (EX_SOFTWARE);*/ } if (pkg != NULL) pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version); if (!yes) { if (pkg != NULL) yes = query_yesno("Change origin from %s to %s for %s-%s? [y/N]: ", oldorigin, neworigin, name, version); else yes = query_yesno("Change origin from %s to %s for all dependencies? " "[y/N]: ", oldorigin, neworigin); } if (pkg != NULL && yes) { if (pkgdb_set(db, pkg, PKG_SET_ORIGIN, neworigin) != EPKG_OK) return (EX_IOERR); } pkgdb_it_free(it); } i = 0; do { if ((it = pkgdb_query(db, argv[i], match)) == NULL) { free(oldorigin); pkgdb_close(db); return (EX_IOERR); } while (pkgdb_it_next(it, &pkg, loads) == EPKG_OK) { yes = yes_flag; if ((sets & AUTOMATIC) == AUTOMATIC) { pkg_get(pkg, PKG_AUTOMATIC, &automatic); if (automatic == newautomatic) continue; if (!yes) { pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version); if (newautomatic) yes = query_yesno("Mark %s-%s as automatically installed? [y/N]: ", name, version); else yes = query_yesno("Mark %s-%s as not automatically installed? [y/N]: ", name, version); } if (yes) pkgdb_set(db, pkg, PKG_SET_AUTOMATIC, newautomatic); } if ((sets & ORIGIN) == ORIGIN) { struct pkg_dep *d = NULL; while (pkg_deps(pkg, &d) == EPKG_OK) { /* * Do not query user when he has already * been queried. */ if (pkgdb_set(db, pkg, PKG_SET_DEPORIGIN, oldorigin, neworigin) != EPKG_OK) return (EX_IOERR); } } } pkgdb_it_free(it); i++; } while (i < argc); free(oldorigin); pkg_free(pkg); pkgdb_close(db); return (EX_OK); }
static int convert_to_old(const char *pkg_add_dbdir, bool dry_run) { struct pkgdb *db = NULL; struct pkg *pkg = NULL; struct pkg_dep *dep = NULL; struct pkgdb_it *it = NULL; char *content, *name, *version, *buf; const char *tmp; int ret = EX_OK; char path[MAXPATHLEN]; int query_flags = PKG_LOAD_DEPS | PKG_LOAD_FILES | PKG_LOAD_DIRS | PKG_LOAD_SCRIPTS | PKG_LOAD_OPTIONS | PKG_LOAD_MTREE | PKG_LOAD_USERS | PKG_LOAD_GROUPS | PKG_LOAD_RDEPS; FILE *fp, *rq; struct sbuf *install_script = sbuf_new_auto(); struct sbuf *deinstall_script = sbuf_new_auto(); if (mkdir(pkg_add_dbdir, 0755) != 0 && errno != EEXIST) err(EX_CANTCREAT, "%s", pkg_add_dbdir); if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { pkgdb_close(db); return (EX_IOERR); } if ((it = pkgdb_query(db, NULL, MATCH_ALL)) == NULL) { ret = EPKG_FATAL; goto cleanup; } while (pkgdb_it_next(it, &pkg, query_flags) == EPKG_OK) { rq = NULL; pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version); printf("Converting %s-%s...", name, version); if (dry_run) { printf("\n"); continue; } pkg_to_old(pkg); pkg_old_emit_content(pkg, &content); snprintf(path, MAXPATHLEN, "%s/%s-%s", pkg_add_dbdir, name, version); mkdir(path, 0755); snprintf(path, MAXPATHLEN, "%s/%s-%s/+CONTENTS", pkg_add_dbdir, name, version); fp = fopen(path, "w"); fputs(content, fp); fclose(fp); pkg_get(pkg, PKG_DESC, &buf); snprintf(path, MAXPATHLEN, "%s/%s-%s/+DESC", pkg_add_dbdir, name, version); fp = fopen(path, "w"); fputs(buf, fp); fclose(fp); pkg_get(pkg, PKG_COMMENT, &buf); snprintf(path, MAXPATHLEN, "%s/%s-%s/+COMMENT", pkg_add_dbdir, name, version); fp = fopen(path, "w"); fprintf(fp, "%s\n", buf); fclose(fp); pkg_get(pkg, PKG_MESSAGE, &buf); if (buf != NULL && buf[0] != '\0') { snprintf(path, MAXPATHLEN, "%s/%s-%s/+DISPLAY", pkg_add_dbdir, name, version); fp = fopen(path, "w"); fputs(buf, fp); fclose(fp); } pkg_get(pkg, PKG_MTREE, &buf); if (buf != NULL && buf[0] != '\0') { snprintf(path, MAXPATHLEN, "%s/%s-%s/+MTREE_DIRS", pkg_add_dbdir, name, version); fp = fopen(path, "w"); fputs(buf, fp); fclose(fp); } sbuf_clear(install_script); tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_INSTALL); if (tmp != NULL && tmp[0] != '\0') { if (sbuf_len(install_script) == 0) sbuf_cat(install_script, "#!/bin/sh\n\n"); sbuf_printf(install_script, "if [ \"$2\" = \"PRE-INSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_INSTALL); if (tmp != NULL && tmp[0] != '\0') { if (sbuf_len(install_script) == 0) sbuf_cat(install_script, "#!/bin/sh\n\n"); sbuf_cat(install_script, tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_INSTALL); if (tmp != NULL && tmp[0] != '\0') { if (sbuf_len(install_script) == 0) sbuf_cat(install_script, "#!/bin/sh\n\n"); sbuf_printf(install_script, "if [ \"$2\" = \"POST-INSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } if (sbuf_len(install_script) > 0) { sbuf_finish(install_script); snprintf(path, MAXPATHLEN, "%s/%s-%s/+INSTALL", pkg_add_dbdir, name, version); fp = fopen(path, "w"); fputs(sbuf_data(install_script), fp); fclose(fp); } sbuf_clear(deinstall_script); tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_DEINSTALL); if (tmp != NULL && tmp[0] != '\0') { if (sbuf_len(deinstall_script) == 0) sbuf_cat(deinstall_script, "#!/bin/sh\n\n"); sbuf_printf(deinstall_script, "if [ \"$2\" = \"DEINSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_DEINSTALL); if (tmp != NULL && tmp[0] != '\0') { if (sbuf_len(deinstall_script) == 0) sbuf_cat(deinstall_script, "#!/bin/sh\n\n"); sbuf_cat(deinstall_script, tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_DEINSTALL); if (tmp != NULL && tmp[0] != '\0') { if (sbuf_len(deinstall_script) == 0) sbuf_cat(deinstall_script, "#!/bin/sh\n\n"); sbuf_printf(deinstall_script, "if [ \"$2\" = \"POST-DEINSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } if (sbuf_len(deinstall_script) > 0) { sbuf_finish(deinstall_script); snprintf(path, MAXPATHLEN, "%s/%s-%s/+DEINSTALL", pkg_add_dbdir, name, version); fp = fopen(path, "w"); fputs(sbuf_data(deinstall_script), fp); fclose(fp); } snprintf(path, MAXPATHLEN, "%s/%s-%s/+REQUIRED_BY", pkg_add_dbdir, name, version); while (pkg_rdeps(pkg, &dep) == EPKG_OK) { if (rq == NULL) rq = fopen(path, "w"); fprintf(rq, "%s-%s\n", pkg_dep_name(dep), pkg_dep_version(dep)); } if (rq != NULL) fclose(rq); printf("done.\n"); free(content); } sbuf_delete(install_script); sbuf_delete(deinstall_script); cleanup: pkg_free(pkg); pkgdb_it_free(it); pkgdb_close(db); 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); }
int exec_query(int argc, char **argv) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; struct pkg_manifest_key *keys = NULL; char *pkgname = NULL; int query_flags = PKG_LOAD_BASIC; match_t match = MATCH_EXACT; int ch; int ret; int retcode = EX_OK; int i; char multiline = 0; char *condition = NULL; struct sbuf *sqlcond = NULL; const unsigned int q_flags_len = NELEM(accepted_query_flags); struct option longopts[] = { { "all", no_argument, NULL, 'a' }, { "case-sensitive", no_argument, NULL, 'C' }, { "evaluate", required_argument, NULL, 'e' }, { "file", required_argument, NULL, 'F' }, { "glob", no_argument, NULL, 'g' }, { "case-insensitive", no_argument, NULL, 'i' }, { "regex", no_argument, NULL, 'x' }, { NULL, 0, NULL, 0 }, }; while ((ch = getopt_long(argc, argv, "+aCe:F:gix", longopts, NULL)) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'C': pkgdb_set_case_sensitivity(true); break; case 'e': match = MATCH_CONDITION; condition = optarg; break; case 'F': pkgname = optarg; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'x': match = MATCH_REGEX; break; default: usage_query(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc == 0) { usage_query(); return (EX_USAGE); } /* Default to all packages if no pkg provided */ if (argc == 1 && pkgname == NULL && condition == NULL && match == MATCH_EXACT) { match = MATCH_ALL; } else if (((argc == 1) ^ (match == MATCH_ALL)) && pkgname == NULL && condition == NULL) { usage_query(); return (EX_USAGE); } if (analyse_query_string(argv[0], accepted_query_flags, q_flags_len, &query_flags, &multiline) != EPKG_OK) return (EX_USAGE); if (pkgname != NULL) { pkg_manifest_keys_new(&keys); if (pkg_open(&pkg, pkgname, keys, 0) != EPKG_OK) { return (EX_IOERR); } pkg_manifest_keys_free(keys); print_query(pkg, argv[0], multiline); pkg_free(pkg); return (EX_OK); } if (condition != NULL) { sqlcond = sbuf_new_auto(); if (format_sql_condition(condition, sqlcond, false) != EPKG_OK) { sbuf_delete(sqlcond); return (EX_USAGE); } sbuf_finish(sqlcond); } ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL); if (ret == EPKG_ENOACCESS) { warnx("Insufficient privileges to query the package database"); return (EX_NOPERM); } else if (ret == EPKG_ENODB) { if (!quiet) warnx("No packages installed"); return (EX_OK); } else if (ret != EPKG_OK) return (EX_IOERR); ret = pkgdb_open(&db, PKGDB_DEFAULT); if (ret != EPKG_OK) return (EX_IOERR); if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) { pkgdb_close(db); warnx("Cannot get a read lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } if (match == MATCH_ALL || match == MATCH_CONDITION) { const char *condition_sql = NULL; if (match == MATCH_CONDITION && sqlcond) condition_sql = sbuf_data(sqlcond); if ((it = pkgdb_query(db, condition_sql, match)) == NULL) return (EX_IOERR); while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) print_query(pkg, argv[0], multiline); if (ret != EPKG_END) retcode = EX_SOFTWARE; pkgdb_it_free(it); } else { int nprinted = 0; for (i = 1; i < argc; i++) { pkgname = argv[i]; if ((it = pkgdb_query(db, pkgname, match)) == NULL) { retcode = EX_IOERR; goto cleanup; } while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) { nprinted++; print_query(pkg, argv[0], multiline); } if (ret != EPKG_END) { retcode = EX_SOFTWARE; break; } pkgdb_it_free(it); } if (nprinted == 0 && retcode == EX_OK) { /* ensure to return a non-zero status when no package were found. */ retcode = EX_UNAVAILABLE; } } cleanup: pkg_free(pkg); pkgdb_release_lock(db, PKGDB_LOCK_READONLY); pkgdb_close(db); return (retcode); }
static int exec_lock_unlock(int argc, char **argv, enum action action) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; const char *pkgname; int match = MATCH_EXACT; int retcode; int exitcode = EX_OK; int ch; bool show_locked = false; struct option longopts[] = { { "all", no_argument, NULL, 'a' }, { "case-sensitive", no_argument, NULL, 'C' }, { "glob", no_argument, NULL, 'g' }, { "show-locked", no_argument, NULL, 'l' }, { "quiet", no_argument, NULL, 'q' }, { "regex", no_argument, NULL, 'x' }, { "yes", no_argument, NULL, 'y' }, { NULL, 0, NULL, 0 }, }; while ((ch = getopt_long(argc, argv, "aCgilqxy", longopts, NULL)) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'C': pkgdb_set_case_sensitivity(true); break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'l': show_locked = true; break; case 'q': quiet = true; break; case 'x': match = MATCH_REGEX; break; case 'y': yes = true; break; default: usage_lock(); return (EX_USAGE); } } argc -= optind; argv += optind; if (!(match == MATCH_ALL && argc == 0) && argc != 1 && !show_locked) { usage_lock(); return (EX_USAGE); } if (match == MATCH_ALL) pkgname = NULL; else pkgname = argv[0]; retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE, PKGDB_DB_LOCAL); if (retcode == EPKG_ENODB) { if (match == MATCH_ALL) return (EX_OK); if (!quiet) warnx("No packages installed. Nothing to do!"); return (EX_OK); } else if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privileges to modify the package database"); return (EX_NOPERM); } else if (retcode != EPKG_OK) { warnx("Error accessing the package database"); return (EX_SOFTWARE); } retcode = pkgdb_open(&db, PKGDB_DEFAULT); if (retcode != EPKG_OK) return (EX_IOERR); if (pkgdb_obtain_lock(db, PKGDB_LOCK_EXCLUSIVE) != EPKG_OK) { pkgdb_close(db); warnx("Cannot get an exclusive lock on database. " "It is locked by another process"); return (EX_TEMPFAIL); } if (match == MATCH_ALL || argc != 0) { if ((it = pkgdb_query(db, pkgname, match)) == NULL) { exitcode = EX_IOERR; goto cleanup; } while ((retcode = pkgdb_it_next(it, &pkg, 0)) == EPKG_OK) { if (action == LOCK) retcode = do_lock(db, pkg); else retcode = do_unlock(db, pkg); if (retcode != EPKG_OK) { exitcode = EX_IOERR; goto cleanup; } } } if (show_locked) retcode = list_locked(db); if (retcode != EPKG_END) exitcode = EX_IOERR; cleanup: if (pkg != NULL) pkg_free(pkg); if (it != NULL) pkgdb_it_free(it); pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE); pkgdb_close(db); return (exitcode); }
static int pkg_create_matches(int argc, char **argv, match_t match, pkg_formats fmt, const char * const outdir, bool overwrite) { int i, ret = EPKG_OK, retcode = EPKG_OK; struct pkg *pkg = NULL; struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; int query_flags = PKG_LOAD_DEPS | PKG_LOAD_FILES | PKG_LOAD_CATEGORIES | PKG_LOAD_DIRS | PKG_LOAD_SCRIPTS | PKG_LOAD_OPTIONS | PKG_LOAD_LICENSES | PKG_LOAD_USERS | PKG_LOAD_GROUPS | PKG_LOAD_SHLIBS_REQUIRED | PKG_LOAD_PROVIDES | PKG_LOAD_REQUIRES | PKG_LOAD_SHLIBS_PROVIDED | PKG_LOAD_ANNOTATIONS; struct pkg_entry *e = NULL, *etmp; char pkgpath[MAXPATHLEN]; const char *format = NULL; bool foundone; if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { pkgdb_close(db); return (EX_IOERR); } /* XXX: get rid of hardcoded timeouts */ if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) { pkgdb_close(db); warnx("Cannot get a read lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } switch (fmt) { case TXZ: format = "txz"; break; case TBZ: format = "tbz"; break; case TGZ: format = "tgz"; break; case TAR: format = "tar"; break; } for (i = 0; i < argc || match == MATCH_ALL; i++) { if (match == MATCH_ALL) { printf("Loading the package list...\n"); if ((it = pkgdb_query(db, NULL, match)) == NULL) goto cleanup; match = !MATCH_ALL; } else if ((it = pkgdb_query(db, argv[i], match)) == NULL) goto cleanup; foundone = false; while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) { if ((e = malloc(sizeof(struct pkg_entry))) == NULL) err(1, "malloc(pkg_entry)"); e->pkg = pkg; pkg = NULL; DL_APPEND(pkg_head, e); foundone = true; } if (!foundone) { warnx("No installed package matching \"%s\" found\n", argv[i]); retcode++; } pkgdb_it_free(it); if (ret != EPKG_END) retcode++; } DL_FOREACH_SAFE(pkg_head, e, etmp) { DL_DELETE(pkg_head, e); if (!overwrite) { pkg_snprintf(pkgpath, sizeof(pkgpath), "%S/%n-%v.%S", outdir, e->pkg, e->pkg, format); if (access(pkgpath, F_OK) == 0) { pkg_printf("%n-%v already packaged, skipping...\n", e->pkg, e->pkg); pkg_free(e->pkg); free(e); continue; } } pkg_printf("Creating package for %n-%v\n", e->pkg, e->pkg); if (pkg_create_installed(outdir, fmt, e->pkg) != EPKG_OK) retcode++; pkg_free(e->pkg); free(e); }