int exec_install(int argc, char **argv) { struct pkgdb *db = NULL; struct pkg_jobs *jobs = NULL; const char *reponame = NULL; int retcode; int updcode = EPKG_OK; int ch; int mode, repo_type; int done = 0; int lock_type = PKGDB_LOCK_ADVISORY; bool rc = true; bool local_only = false; match_t match = MATCH_EXACT; pkg_flags f = PKG_FLAG_NONE | PKG_FLAG_PKG_VERSION_TEST; struct option longopts[] = { { "automatic", no_argument, NULL, 'A' }, { "case-sensitive", no_argument, NULL, 'C' }, { "force", no_argument, NULL, 'f' }, { "fetch-only", no_argument, NULL, 'F' }, { "glob", no_argument, NULL, 'g' }, { "case-insensitive", no_argument, NULL, 'i' }, { "no-install-scripts", no_argument, NULL, 'I' }, { "local-only", no_argument, NULL, 'l' }, { "ignore-missing", no_argument, NULL, 'M' }, { "dry-run", no_argument, NULL, 'n' }, { "quiet", no_argument, NULL, 'q' }, { "repository", required_argument, NULL, 'r' }, { "from-root", no_argument, NULL, 'R' }, { "no-repo-update", no_argument, NULL, 'U' }, { "regex", no_argument, NULL, 'x' }, { "yes", no_argument, NULL, 'y' }, { NULL, 0, NULL, 0 }, }; nbactions = nbdone = 0; if (strcmp(argv[0], "add") == 0) { auto_update = false; local_only = true; yes = true; quiet = true; } while ((ch = getopt_long(argc, argv, "+ACfFgiIlMnqr:RUxy", longopts, NULL)) != -1) { switch (ch) { case 'A': f |= PKG_FLAG_AUTOMATIC; break; case 'C': pkgdb_set_case_sensitivity(true); break; case 'f': f |= PKG_FLAG_FORCE; break; case 'F': f |= PKG_FLAG_SKIP_INSTALL; lock_type = PKGDB_LOCK_READONLY; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'I': f |= PKG_FLAG_NOSCRIPT; break; case 'l': local_only = true; auto_update = false; break; case 'M': f |= PKG_FLAG_FORCE_MISSING; break; case 'n': f |= PKG_FLAG_DRY_RUN; lock_type = PKGDB_LOCK_READONLY; dry_run = true; break; case 'q': quiet = true; break; case 'r': reponame = optarg; break; case 'R': f |= PKG_FLAG_RECURSIVE; break; case 'U': auto_update = false; break; case 'x': match = MATCH_REGEX; break; case 'y': yes = true; break; default: usage_install(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc < 1) { usage_install(); return (EX_USAGE); } if (dry_run && !auto_update) mode = PKGDB_MODE_READ; else mode = PKGDB_MODE_READ | PKGDB_MODE_WRITE | PKGDB_MODE_CREATE; if (local_only) repo_type = PKGDB_DB_LOCAL; else repo_type = PKGDB_DB_LOCAL|PKGDB_DB_REPO; retcode = pkgdb_access(mode, repo_type); if (retcode == EPKG_ENOACCESS && dry_run) { auto_update = false; retcode = pkgdb_access(PKGDB_MODE_READ, repo_type); } if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privileges to install packages"); return (EX_NOPERM); } else if (retcode != EPKG_OK) return (EX_IOERR); else retcode = EX_SOFTWARE; /* first update the remote repositories if needed */ if (auto_update && (updcode = pkgcli_update(false, false, reponame)) != EPKG_OK) return (updcode); if (pkgdb_open_all(&db, local_only ? PKGDB_DEFAULT : PKGDB_MAYBE_REMOTE, reponame) != EPKG_OK) return (EX_IOERR); if (pkgdb_obtain_lock(db, lock_type) != EPKG_OK) { pkgdb_close(db); warnx("Cannot get an advisory lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } if (pkg_jobs_new(&jobs, PKG_JOBS_INSTALL, db) != EPKG_OK) goto cleanup; if (!local_only && reponame != NULL && pkg_jobs_set_repository(jobs, reponame) != EPKG_OK) goto cleanup; pkg_jobs_set_flags(jobs, f); if (pkg_jobs_add(jobs, match, argv, argc) == EPKG_FATAL) goto cleanup; if (pkg_jobs_solve(jobs) != EPKG_OK) goto cleanup; while ((nbactions = pkg_jobs_count(jobs)) > 0) { rc = yes; /* print a summary before applying the jobs */ if (!quiet || dry_run) { print_jobs_summary(jobs, "The following %d packages will be affected (of %d checked):\n\n", nbactions, pkg_jobs_total(jobs)); if (!dry_run) { rc = query_yesno(false, "\nProceed with this action? [y/N]: "); } else { rc = false; } } if (rc) { retcode = pkg_jobs_apply(jobs); done = 1; if (retcode == EPKG_CONFLICT) { printf("Conflicts with the existing packages " "have been found.\nOne more solver " "iteration is needed to resolve them.\n"); continue; } else if (retcode != EPKG_OK) goto cleanup; } if (messages != NULL) { sbuf_finish(messages); printf("%s", sbuf_data(messages)); } break; } if (done == 0 && rc) printf("The most recent version of packages are already installed\n"); retcode = EX_OK; cleanup: pkgdb_release_lock(db, lock_type); pkg_jobs_free(jobs); pkgdb_close(db); if (!rc && newpkgversion) newpkgversion = false; 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; 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); }
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); }
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_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_upgrade(int argc, char **argv) { struct pkgdb *db = NULL; struct pkg_jobs *jobs = NULL; const char *reponame = NULL; int retcode; int updcode; int ch; int lock_type = PKGDB_LOCK_ADVISORY; match_t match = MATCH_EXACT; int done = 0; bool rc = true; pkg_flags f = PKG_FLAG_NONE | PKG_FLAG_PKG_VERSION_TEST; size_t dlbytes, diffbytes, limbytes; limbytes = pkg_object_int(pkg_config_get("WARN_SIZE_LIMIT")); struct option longopts[] = { { "case-sensitive", no_argument, NULL, 'C' }, { "force", no_argument, NULL, 'f' }, { "fetch-only", no_argument, NULL, 'F' }, { "glob", no_argument, NULL, 'g' }, { "case-insensitive", no_argument, NULL, 'i' }, { "no-install-scripts", no_argument, NULL, 'I' }, { "dry-run", no_argument, NULL, 'n' }, { "quiet", no_argument, NULL, 'q' }, { "repository", required_argument, NULL, 'r' }, { "no-repo-update", no_argument, NULL, 'U' }, { "regex", no_argument, NULL, 'x' }, { "yes", no_argument, NULL, 'y' }, { NULL, 0, NULL, 0 }, }; nbactions = nbdone = 0; while ((ch = getopt_long(argc, argv, "+CfFgiInqr:Uxy", longopts, NULL)) != -1) { switch (ch) { case 'C': pkgdb_set_case_sensitivity(true); break; case 'f': f |= PKG_FLAG_FORCE; break; case 'F': f |= PKG_FLAG_SKIP_INSTALL; lock_type = PKGDB_LOCK_READONLY; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'I': f |= PKG_FLAG_NOSCRIPT; break; case 'n': f |= PKG_FLAG_DRY_RUN; lock_type = PKGDB_LOCK_READONLY; dry_run = true; break; case 'q': quiet = true; break; case 'r': reponame = optarg; break; case 'U': auto_update = false; break; case 'x': match = MATCH_REGEX; break; case 'y': yes = true; break; default: usage_upgrade(); return (EX_USAGE); /* NOTREACHED */ } } argc -= optind; argv += optind; if (dry_run && !auto_update) retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL|PKGDB_DB_REPO); else retcode = pkgdb_access(PKGDB_MODE_READ | PKGDB_MODE_WRITE | PKGDB_MODE_CREATE, PKGDB_DB_LOCAL|PKGDB_DB_REPO); if (retcode == EPKG_ENOACCESS && dry_run) { auto_update = false; retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL|PKGDB_DB_REPO); } if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privilege to upgrade packages"); return (EX_NOPERM); } else if (retcode != EPKG_OK) return (EX_IOERR); else retcode = EX_SOFTWARE; /* first update the remote repositories if needed */ if (auto_update && (updcode = pkgcli_update(false, false, reponame)) != EPKG_OK) return (updcode); if (pkgdb_open_all(&db, PKGDB_REMOTE, reponame) != EPKG_OK) return (EX_IOERR); if (pkgdb_obtain_lock(db, lock_type) != EPKG_OK) { pkgdb_close(db); warnx("Cannot get an advisory lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } if (pkg_jobs_new(&jobs, PKG_JOBS_UPGRADE, db) != EPKG_OK) goto cleanup; if (reponame != NULL && pkg_jobs_set_repository(jobs, reponame) != EPKG_OK) goto cleanup; pkg_jobs_set_flags(jobs, f); if (argc > 0) if (pkg_jobs_add(jobs, match, argv, argc) == EPKG_FATAL) goto cleanup; if (pkg_jobs_solve(jobs) != EPKG_OK) goto cleanup; while ((nbactions = pkg_jobs_count(jobs)) > 0) { /* print a summary before applying the jobs */ rc = yes; if (!quiet || dry_run) { print_jobs_summary(jobs, &diffbytes, &dlbytes, "The following %d package(s) will be affected (of %d checked):\n\n", nbactions, pkg_jobs_total(jobs)); if (!dry_run) { if (limbytes && (diffbytes > limbytes || dlbytes > limbytes)) { rc = query_yesno(false, "\nProceed with this " "action? "); } else { rc = true; } } else { rc = false; } } if (rc) { retcode = pkg_jobs_apply(jobs); done = 1; if (retcode == EPKG_CONFLICT) { printf("Conflicts with the existing packages " "have been found.\nOne more solver " "iteration is needed to resolve them.\n"); continue; } else if (retcode != EPKG_OK) goto cleanup; } if (messages != NULL) { sbuf_finish(messages); printf("%s", sbuf_data(messages)); } break; } if (done == 0 && rc && !quiet) printf("Your packages are up to date.\n"); retcode = EX_OK; cleanup: pkg_jobs_free(jobs); pkgdb_release_lock(db, lock_type); pkgdb_close(db); if (!dry_run) pkg_cache_full_clean(); if (!rc && newpkgversion) newpkgversion = false; return (retcode); }
int exec_check(int argc, char **argv) { struct pkg *pkg = NULL; struct pkgdb_it *it = NULL; struct pkgdb *db = NULL; struct sbuf *msg = NULL; match_t match = MATCH_EXACT; int flags = PKG_LOAD_BASIC; int ret, rc = EX_OK; int ch; bool dcheck = false; bool checksums = false; bool recompute = false; bool reanalyse_shlibs = false; bool noinstall = false; int nbpkgs = 0; int i, processed, total = 0; int verbose = 0; struct option longopts[] = { { "all", no_argument, NULL, 'a' }, { "shlibs", no_argument, NULL, 'B' }, { "case-sensitive", no_argument, NULL, 'C' }, { "dependencies", no_argument, NULL, 'd' }, { "glob", no_argument, NULL, 'g' }, { "case-insensitive", no_argument, NULL, 'i' }, { "dry-run", no_argument, NULL, 'n' }, { "recompute", no_argument, NULL, 'r' }, { "checksums", no_argument, NULL, 's' }, { "verbose", no_argument, NULL, 'v' }, { "regex", no_argument, NULL, 'x' }, { "yes", no_argument, NULL, 'y' }, { NULL, 0, NULL, 0 }, }; struct deps_head dh = STAILQ_HEAD_INITIALIZER(dh); processed = 0; while ((ch = getopt_long(argc, argv, "+aBCdginrsvxy", longopts, NULL)) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'B': reanalyse_shlibs = true; flags |= PKG_LOAD_FILES; break; case 'C': pkgdb_set_case_sensitivity(true); break; case 'd': dcheck = true; flags |= PKG_LOAD_DEPS; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'n': noinstall = true; break; case 'r': recompute = true; flags |= PKG_LOAD_FILES; break; case 's': checksums = true; flags |= PKG_LOAD_FILES; break; case 'v': verbose = 1; break; case 'x': match = MATCH_REGEX; break; case 'y': yes = true; 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); } if (recompute || reanalyse_shlibs) ret = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE, PKGDB_DB_LOCAL); else ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL); if (ret == EPKG_ENODB) { warnx("No packages installed. Nothing to do!"); return (EX_OK); } else if (ret == EPKG_ENOACCESS) { warnx("Insufficient privileges to access the package database"); return (EX_NOPERM); } else if (ret != EPKG_OK) { warnx("Error accessing the package database"); return (EX_SOFTWARE); } ret = pkgdb_open(&db, PKGDB_DEFAULT); if (ret != EPKG_OK) return (EX_IOERR); if (pkgdb_obtain_lock(db, PKGDB_LOCK_ADVISORY) != EPKG_OK) { pkgdb_close(db); warnx("Cannot get an advisory lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } i = 0; nbdone = 0; do { /* XXX: This is really quirky, it would be cleaner to pass * in multiple matches and only run this top-loop once. */ if ((it = pkgdb_query(db, argv[i], match)) == NULL) { rc = EX_IOERR; goto cleanup; } if (msg == NULL) msg = sbuf_new_auto(); if (!verbose) { if (match == MATCH_ALL) progressbar_start("Checking all packages"); else { sbuf_printf(msg, "Checking %s", argv[i]); sbuf_finish(msg); progressbar_start(sbuf_data(msg)); } processed = 0; total = pkgdb_it_count(it); } else { if (match == MATCH_ALL) nbactions = pkgdb_it_count(it); else nbactions = argc; } while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) { if (!verbose) progressbar_tick(processed, total); else { ++nbdone; job_status_begin(msg); pkg_sbuf_printf(msg, "Checking %n-%v:", pkg, pkg); sbuf_flush(msg); } /* check for missing dependencies */ if (dcheck) { if (verbose) printf(" dependencies..."); nbpkgs += check_deps(db, pkg, &dh, noinstall); if (noinstall && nbpkgs > 0) { rc = EX_UNAVAILABLE; } } if (checksums) { if (verbose) printf(" checksums..."); if (pkg_test_filesum(pkg) != EPKG_OK) { rc = EX_DATAERR; } } if (recompute) { if (pkgdb_upgrade_lock(db, PKGDB_LOCK_ADVISORY, PKGDB_LOCK_EXCLUSIVE) == EPKG_OK) { if (verbose) printf(" recomputing..."); if (pkg_recompute(db, pkg) != EPKG_OK) { rc = EX_DATAERR; } pkgdb_downgrade_lock(db, PKGDB_LOCK_EXCLUSIVE, PKGDB_LOCK_ADVISORY); } else { rc = EX_TEMPFAIL; } } if (reanalyse_shlibs) { if (pkgdb_upgrade_lock(db, PKGDB_LOCK_ADVISORY, PKGDB_LOCK_EXCLUSIVE) == EPKG_OK) { if (verbose) printf(" shared libraries..."); if (pkgdb_reanalyse_shlibs(db, pkg) != EPKG_OK) { pkg_fprintf(stderr, "Failed to " "reanalyse for shlibs: " "%n-%v\n", pkg, pkg); rc = EX_UNAVAILABLE; } pkgdb_downgrade_lock(db, PKGDB_LOCK_EXCLUSIVE, PKGDB_LOCK_ADVISORY); } else { rc = EX_TEMPFAIL; } } if (!verbose) ++processed; else printf(" done\n"); } if (!verbose) progressbar_tick(processed, total); if (msg != NULL) { sbuf_delete(msg); msg = NULL; } if (dcheck && nbpkgs > 0 && !noinstall) { printf("\n>>> Missing package dependencies were detected.\n"); printf(">>> Found %d issue(s) in the package database.\n\n", nbpkgs); if (pkgdb_upgrade_lock(db, PKGDB_LOCK_ADVISORY, PKGDB_LOCK_EXCLUSIVE) == EPKG_OK) { ret = fix_deps(db, &dh, nbpkgs, yes); if (ret == EPKG_OK) check_summary(db, &dh); else if (ret == EPKG_ENODB) { db = NULL; rc = EX_IOERR; } pkgdb_downgrade_lock(db, PKGDB_LOCK_EXCLUSIVE, PKGDB_LOCK_ADVISORY); if (rc == EX_IOERR) goto cleanup; } else { rc = EX_TEMPFAIL; goto cleanup; } } pkgdb_it_free(it); i++; } while (i < argc); cleanup: if (!verbose) progressbar_stop(); if (msg != NULL) sbuf_delete(msg); deps_free(&dh); pkg_free(pkg); pkgdb_release_lock(db, PKGDB_LOCK_ADVISORY); pkgdb_close(db); return (rc); }
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); }
int exec_fetch(int argc, char **argv) { struct pkgdb *db = NULL; struct pkg_jobs *jobs = NULL; const char *reponame = NULL; int ch; int retcode = EX_SOFTWARE; bool auto_update; bool upgrades_for_installed = false; bool yes; unsigned mode; match_t match = MATCH_EXACT; pkg_flags f = PKG_FLAG_NONE; pkg_config_bool(PKG_CONFIG_REPO_AUTOUPDATE, &auto_update); pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes); while ((ch = getopt(argc, argv, "adgiqr:Uuxy")) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'd': f |= PKG_FLAG_WITH_DEPS; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'U': auto_update = false; break; case 'q': quiet = true; break; case 'r': reponame = optarg; break; case 'u': f |= PKG_FLAG_UPGRADES_FOR_INSTALLED; upgrades_for_installed = true; break; case 'x': match = MATCH_REGEX; break; case 'y': yes = true; break; default: usage_fetch(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc < 1 && match != MATCH_ALL && !upgrades_for_installed) { usage_fetch(); return (EX_USAGE); } if (match == MATCH_ALL && upgrades_for_installed) { usage_fetch(); return (EX_USAGE); } /* TODO: Allow the user to specify an output directory via -o outdir */ if (auto_update) mode = PKGDB_MODE_READ|PKGDB_MODE_WRITE|PKGDB_MODE_CREATE; else mode = PKGDB_MODE_READ; retcode = pkgdb_access(mode, PKGDB_DB_REPO); if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privileges to access repo catalogue"); return (EX_NOPERM); } else if (retcode != EPKG_OK) return (EX_IOERR); if (upgrades_for_installed) { retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL); if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privileges to access the package database"); return (EX_NOPERM); } else if (retcode != EPKG_OK) return (EX_IOERR); } /* first update the remote repositories if needed */ if (auto_update && (retcode = pkgcli_update(false)) != 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 (reponame != NULL && pkg_jobs_set_repository(jobs, reponame) != EPKG_OK) goto cleanup; pkg_jobs_set_flags(jobs, f); if (!upgrades_for_installed && pkg_jobs_add(jobs, match, argv, argc) != EPKG_OK) goto cleanup; if (pkg_jobs_solve(jobs) != EPKG_OK) goto cleanup; if (pkg_jobs_count(jobs) == 0) goto cleanup; if (!quiet) { print_jobs_summary(jobs, "The following packages will be fetched:\n\n"); if (!yes) yes = query_yesno("\nProceed with fetching packages [y/N]: "); } if (!yes || pkg_jobs_apply(jobs) != EPKG_OK) goto cleanup; retcode = EX_OK; cleanup: pkg_jobs_free(jobs); pkgdb_close(db); return (retcode); }
int exec_annotate(int argc, char **argv) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; enum action action = NONE; const char *tag; const char *value; const char *pkgname; struct sbuf *input = NULL; int ch; int match = MATCH_EXACT; int retcode; int exitcode = EX_OK; int flags = 0; struct option longopts[] = { { "all", no_argument, NULL, 'a' }, { "add", no_argument, NULL, 'A' }, { "case-insensitive", no_argument, NULL, 'C' }, { "delete", no_argument, NULL, 'D' }, { "glob", no_argument, NULL, 'g' }, { "case-insensitive", no_argument, NULL, 'i' }, { "modify", no_argument, NULL, 'M' }, { "quiet", no_argument, NULL, 'q' }, { "show", no_argument, NULL, 'S' }, { "regex", no_argument, NULL, 'x' }, { "yes", no_argument, NULL, 'y' }, { NULL, 0, NULL, 0 }, }; /* Set default case sensitivity for searching */ pkgdb_set_case_sensitivity( pkg_object_bool(pkg_config_get("CASE_SENSITIVE_MATCH")) ); while ((ch = getopt_long(argc, argv, "+aACDgiMqSxy", longopts, NULL)) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'A': action = ADD; break; case 'C': pkgdb_set_case_sensitivity(true); break; case 'D': action = DELETE; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'M': action = MODIFY; break; case 'q': quiet = true; break; case 'S': action = SHOW; flags |= PKG_LOAD_ANNOTATIONS; break; case 'x': match = MATCH_REGEX; break; case 'y': yes = true; break; default: usage_annotate(); return (EX_USAGE); } } argc -= optind; argv += optind; if (action == NONE || (match == MATCH_ALL && argc < 1) || (match != MATCH_ALL && argc < 2)) { usage_annotate(); return (EX_USAGE); } if (match == MATCH_ALL) { pkgname = NULL; tag = argv[0]; value = (argc > 1) ? argv[1] : NULL; } else { pkgname = argv[0]; tag = argv[1]; value = (argc > 2) ? argv[2] : NULL; } if ((action == ADD || action == MODIFY) && value == NULL) { /* try and read data for the value from stdin. */ input = read_input(); value = sbuf_data(input); } retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE, PKGDB_DB_LOCAL); if (retcode == EPKG_ENODB) { if (match == MATCH_ALL) { exitcode = EX_OK; goto cleanup; } if (!quiet) warnx("No packages installed. Nothing to do!"); exitcode = EX_OK; goto cleanup; } else if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privileges to modify the package database"); exitcode = EX_NOPERM; goto cleanup; } else if (retcode != EPKG_OK) { warnx("Error accessing the package database"); exitcode = EX_SOFTWARE; goto cleanup; } 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 a database, it is locked by another process"); return (EX_TEMPFAIL); } if ((it = pkgdb_query(db, pkgname, match)) == NULL) { exitcode = EX_IOERR; goto cleanup; } while ((retcode = pkgdb_it_next(it, &pkg, flags)) == EPKG_OK) { switch(action) { case NONE: /* Should never happen */ usage_annotate(); exitcode = EX_USAGE; break; case ADD: retcode = do_add(db, pkg, tag, value); break; case MODIFY: retcode = do_modify(db, pkg, tag, value); break; case DELETE: retcode = do_delete(db, pkg, tag); break; case SHOW: retcode = do_show(pkg, tag); break; } if (retcode == EPKG_WARN) exitcode = EX_DATAERR; if (retcode != EPKG_OK && retcode != EPKG_WARN) { exitcode = EX_IOERR; goto cleanup; } } cleanup: pkg_free(pkg); pkgdb_it_free(it); pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE); pkgdb_close(db); if (input != NULL) sbuf_delete(input); return (exitcode); }
int exec_delete(int argc, char **argv) { struct pkg_jobs *jobs = NULL; struct pkgdb *db = NULL; match_t match = MATCH_EXACT; int ch; bool force = false; bool yes; bool dry_run = false; int retcode = EX_SOFTWARE; nbactions = nbdone = 0; pkg_flags f = PKG_FLAG_NONE; int i; pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes); while ((ch = getopt(argc, argv, "aDfginqRxy")) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'D': f |= PKG_FLAG_NOSCRIPT; break; case 'f': f |= PKG_FLAG_FORCE; force = true; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'n': f |= PKG_FLAG_DRY_RUN; dry_run = true; break; case 'q': quiet = true; break; case 'R': f |= PKG_FLAG_RECURSIVE; break; case 'x': match = MATCH_REGEX; break; case 'y': yes = true; break; default: usage_delete(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc < 1 && match != MATCH_ALL) { usage_delete(); return (EX_USAGE); } retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE, PKGDB_DB_LOCAL); if (retcode == EPKG_ENODB) { warnx("No packages installed. Nothing to do!"); return (EX_OK); } else if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privilege to delete packages"); 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 (pkg_jobs_new(&jobs, PKG_JOBS_DEINSTALL, db) != EPKG_OK) { pkgdb_close(db); return (EX_IOERR); } pkg_jobs_set_flags(jobs, f); if (match == MATCH_EXACT) { for (i = 0; i < argc; i++) { if (strchr(argv[i], '*') != NULL) { match = MATCH_GLOB; break; } } } if (pkg_jobs_add(jobs, match, argv, argc) == EPKG_FATAL) goto cleanup; if (pkg_jobs_solve(jobs) != EPKG_OK) goto cleanup; if ((pkg_jobs_find(jobs, "ports-mgmt/pkg", NULL) == EPKG_OK) && !force) { warnx("You are about to delete 'ports-mgmt/pkg' which is really " "dangerous, you can't do that without specifying -f"); goto cleanup; } /* check if we have something to deinstall */ if ((nbactions = pkg_jobs_count(jobs)) == 0) { if (argc == 0) { if (!quiet) printf("Nothing to do.\n"); retcode = EX_OK; } else { fprintf(stderr, "Package(s) not found!\n"); retcode = EX_DATAERR; } goto cleanup; } if (!quiet || dry_run) { print_jobs_summary(jobs, "Deinstallation has been requested for the following %d packages:\n\n", nbactions); if (!yes && !dry_run) yes = query_yesno( "\nProceed with deinstalling packages [y/N]: "); if (dry_run) yes = false; } if (!yes || (retcode = pkg_jobs_apply(jobs)) != EPKG_OK) goto cleanup; pkgdb_compact(db); retcode = EX_OK; cleanup: pkg_jobs_free(jobs); pkgdb_close(db); return (retcode); }
int exec_fetch(int argc, char **argv) { struct pkgdb *db = NULL; struct pkg_jobs *jobs = NULL; const char *reponame = NULL; int ch; int retcode = EX_SOFTWARE; bool upgrades_for_installed = false, rc; unsigned mode; match_t match = MATCH_EXACT; pkg_flags f = PKG_FLAG_NONE; struct option longopts[] = { { "all", no_argument, NULL, 'a' }, { "case-sensitive", no_argument, NULL, 'C' }, { "dependencies", no_argument, NULL, 'd' }, { "glob", no_argument, NULL, 'g' }, { "case-insensitive", no_argument, NULL, 'i' }, { "quiet", no_argument, NULL, 'q' }, { "repository", required_argument, NULL, 'r' }, { "avaialbe-updates", no_argument, NULL, 'u' }, { "no-repo-update", no_argument, NULL, 'U' }, { "regex", no_argument, NULL, 'x' }, { "yes", no_argument, NULL, 'y' }, { NULL, 0, NULL, 0 }, }; while ((ch = getopt_long(argc, argv, "aCdgiqr:Uuxy", longopts, NULL)) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'C': pkgdb_set_case_sensitivity(true); break; case 'd': f |= PKG_FLAG_WITH_DEPS | PKG_FLAG_RECURSIVE; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'q': quiet = true; break; case 'r': reponame = optarg; break; case 'u': f |= PKG_FLAG_UPGRADES_FOR_INSTALLED; upgrades_for_installed = true; break; case 'U': auto_update = false; break; case 'x': match = MATCH_REGEX; break; case 'y': yes = true; break; default: usage_fetch(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc < 1 && match != MATCH_ALL && !upgrades_for_installed) { usage_fetch(); return (EX_USAGE); } if (match == MATCH_ALL && upgrades_for_installed) { usage_fetch(); return (EX_USAGE); } /* TODO: Allow the user to specify an output directory via -o outdir */ if (auto_update) mode = PKGDB_MODE_READ|PKGDB_MODE_WRITE|PKGDB_MODE_CREATE; else mode = PKGDB_MODE_READ; retcode = pkgdb_access(mode, PKGDB_DB_REPO); if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privileges to access repo catalogue"); return (EX_NOPERM); } else if (retcode != EPKG_OK) return (EX_IOERR); if (upgrades_for_installed) { retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL); if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privileges to access the package database"); return (EX_NOPERM); } else if (retcode != EPKG_OK) return (EX_IOERR); } /* first update the remote repositories if needed */ if (auto_update && (retcode = pkgcli_update(false, reponame)) != EPKG_OK) return (retcode); if (pkgdb_open_all(&db, PKGDB_REMOTE, reponame) != 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 (pkg_jobs_new(&jobs, PKG_JOBS_FETCH, db) != EPKG_OK) goto cleanup; if (reponame != NULL && pkg_jobs_set_repository(jobs, reponame) != EPKG_OK) goto cleanup; pkg_jobs_set_flags(jobs, f); if (!upgrades_for_installed && pkg_jobs_add(jobs, match, argv, argc) != EPKG_OK) goto cleanup; if (pkg_jobs_solve(jobs) != EPKG_OK) goto cleanup; if (pkg_jobs_count(jobs) == 0) goto cleanup; if (!quiet) { print_jobs_summary(jobs, "The following packages will be fetched:\n\n"); rc = query_yesno(false, "\nProceed with fetching packages [y/N]: "); } else { rc = true; } if (!rc || pkg_jobs_apply(jobs) != EPKG_OK) goto cleanup; retcode = EX_OK; cleanup: pkg_jobs_free(jobs); 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; struct sbuf *sqlcond = NULL; const unsigned int q_flags_len = (sizeof(accepted_rquery_flags)/sizeof(accepted_rquery_flags[0])); const char *reponame = NULL; bool auto_update; bool onematched = false; bool old_quiet; pkg_config_bool(PKG_CONFIG_REPO_AUTOUPDATE, &auto_update); while ((ch = getopt(argc, argv, "agixe:r:U")) != -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 'e': match = MATCH_CONDITION; condition = optarg; break; case 'r': reponame = optarg; break; case 'U': auto_update = false; break; default: usage_rquery(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc == 0) { usage_rquery(); 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) && condition == NULL) { usage_rquery(); return (EX_USAGE); } if (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 privilege to query 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)) != EPKG_OK) return (ret); quiet = old_quiet; ret = pkgdb_open(&db, PKGDB_REMOTE); 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_rquery(db, condition_sql, match, reponame)) == 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_rquery(db, pkgname, match, reponame)) == NULL) return (EX_IOERR); while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) { onematched = true; 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); }
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); }
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, rc = EX_OK; int ch; bool yes; bool dcheck = false; bool checksums = false; bool recompute = false; bool reanalyse_shlibs = false; bool noinstall = false; int nbpkgs = 0; int i; int verbose = 0; pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes); struct deps_head dh = STAILQ_HEAD_INITIALIZER(dh); while ((ch = getopt(argc, argv, "yagidnBxsrv")) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'B': reanalyse_shlibs = true; flags |= PKG_LOAD_FILES; break; case 'd': dcheck = true; flags |= PKG_LOAD_DEPS; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'n': noinstall = true; break; case 'r': recompute = true; flags |= PKG_LOAD_FILES; break; case 's': checksums = true; flags |= PKG_LOAD_FILES; break; case 'v': verbose = 1; break; case 'x': match = MATCH_REGEX; break; case 'y': yes = true; 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); } if (recompute || reanalyse_shlibs) ret = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE, PKGDB_DB_LOCAL); else ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL); if (ret == EPKG_ENODB) { warnx("No packages installed. Nothing to do!"); return (EX_OK); } else if (ret == EPKG_ENOACCESS) { warnx("Insufficient privileges to access the package database"); return (EX_NOPERM); } else if (ret != EPKG_OK) { warnx("Error accessing the package database"); return (EX_SOFTWARE); } ret = pkgdb_open(&db, PKGDB_DEFAULT); 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) { /* check for missing dependencies */ if (dcheck) { if (verbose) pkg_printf("Checking dependencies: %n\n", pkg); nbpkgs += check_deps(db, pkg, &dh, noinstall); if (noinstall && nbpkgs > 0) { rc = EX_UNAVAILABLE; } } if (checksums) { if (verbose) pkg_printf("Checking checksums: %n\n", pkg); if (pkg_test_filesum(pkg) != EPKG_OK) { rc = EX_DATAERR; } } if (recompute) { if (verbose) pkg_printf("Recomputing size and checksums: %n\n", pkg); if (pkg_recompute(db, pkg) != EPKG_OK) { rc = EX_DATAERR; } } if (reanalyse_shlibs) { if (verbose) pkg_printf("Reanalyzing files for shlibs: %n\n", pkg); if (pkgdb_reanalyse_shlibs(db, pkg) != EPKG_OK) { pkg_printf("Failed to reanalyse for shlibs: %n\n", pkg); rc = EX_UNAVAILABLE; } } } if (dcheck && nbpkgs > 0 && !noinstall) { printf("\n>>> Missing package dependencies were detected.\n"); printf(">>> Found %d issue(s) in the 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 (rc); }
int exec_delete(int argc, char **argv) { struct pkg_jobs *jobs = NULL; struct pkgdb *db = NULL; match_t match = MATCH_EXACT; pkg_flags f = PKG_FLAG_NONE; bool recursive_flag = false, rc = false; int retcode = EX_SOFTWARE; int ch; int i; int lock_type = PKGDB_LOCK_ADVISORY; struct option longopts[] = { { "all", no_argument, NULL, 'a' }, { "case-sensitive", no_argument, NULL, 'C' }, { "no-deinstall-script", no_argument, NULL, 'D' }, { "force", no_argument, NULL, 'f' }, { "glob", no_argument, NULL, 'g' }, { "case-insensitive", no_argument, NULL, 'i' }, { "dry-run", no_argument, NULL, 'n' }, { "quiet", no_argument, NULL, 'q' }, { "recursive", no_argument, NULL, 'R' }, { "regex", no_argument, NULL, 'x' }, { "yes", no_argument, NULL, 'y' }, { NULL, 0, NULL, 0 }, }; nbactions = nbdone = 0; while ((ch = getopt_long(argc, argv, "+aCDfginqRxy", longopts, NULL)) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'C': pkgdb_set_case_sensitivity(true); break; case 'D': f |= PKG_FLAG_NOSCRIPT; break; case 'f': f |= PKG_FLAG_FORCE; force = true; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'n': f |= PKG_FLAG_DRY_RUN; lock_type = PKGDB_LOCK_READONLY; dry_run = true; break; case 'q': quiet = true; break; case 'R': recursive_flag = true; break; case 'x': match = MATCH_REGEX; break; case 'y': yes = true; break; default: usage_delete(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc < 1 && match != MATCH_ALL) { usage_delete(); return (EX_USAGE); } if (dry_run) retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL); else retcode = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE, PKGDB_DB_LOCAL); if (retcode == EPKG_ENODB) { warnx("No packages installed. Nothing to do!"); return (EX_OK); } else if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privileges to delete packages"); return (EX_NOPERM); } else if (retcode != EPKG_OK) { warnx("Error accessing the package database"); return (EX_SOFTWARE); } if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) return (EX_IOERR); if (pkgdb_obtain_lock(db, lock_type) != EPKG_OK) { pkgdb_close(db); warnx("Cannot get an advisory lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } if (pkg_jobs_new(&jobs, PKG_JOBS_DEINSTALL, db) != EPKG_OK) { pkgdb_close(db); return (EX_IOERR); } /* * By default delete packages recursively. * If force mode is enabled then we try to remove packages non-recursively. * However, if -f and -R flags are both enabled then we return to * recursive deletion. */ if (!force || recursive_flag) f |= PKG_FLAG_RECURSIVE; pkg_jobs_set_flags(jobs, f); if (match == MATCH_EXACT) { for (i = 0; i < argc; i++) { if (strchr(argv[i], '*') != NULL) { match = MATCH_GLOB; break; } } } if (pkg_jobs_add(jobs, match, argv, argc) == EPKG_FATAL) goto cleanup; if (pkg_jobs_solve(jobs) != EPKG_OK) { fprintf(stderr, "Cannot perform request\n"); retcode = EX_NOPERM; goto cleanup; } /* check if we have something to deinstall */ if ((nbactions = pkg_jobs_count(jobs)) == 0) { if (argc == 0) { if (!quiet) printf("Nothing to do.\n"); retcode = EX_OK; } else { fprintf(stderr, "Package(s) not found!\n"); retcode = EX_DATAERR; } goto cleanup; } if (!quiet || dry_run) { if (!quiet) { print_jobs_summary(jobs, "Deinstallation has been requested for the following %d packages " "(of %d packages in the universe):\n\n", nbactions, pkg_jobs_total(jobs)); } if (dry_run) { retcode = EX_OK; goto cleanup; } rc = query_yesno(false, "\nProceed with deinstalling packages? "); } else rc = yes; if (!rc || (retcode = pkg_jobs_apply(jobs)) != EPKG_OK) goto cleanup; pkgdb_compact(db); retcode = EX_OK; cleanup: pkgdb_release_lock(db, lock_type); pkg_jobs_free(jobs); pkgdb_close(db); return (retcode); }
int exec_install(int argc, char **argv) { struct pkgdb *db = NULL; struct pkg_jobs *jobs = NULL; const char *reponame = NULL; int retcode; int updcode = EPKG_OK; int ch; bool yes; bool auto_update; match_t match = MATCH_EXACT; bool dry_run = false; nbactions = nbdone = 0; pkg_flags f = PKG_FLAG_NONE | PKG_FLAG_PKG_VERSION_TEST; pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes); pkg_config_bool(PKG_CONFIG_REPO_AUTOUPDATE, &auto_update); while ((ch = getopt(argc, argv, "AfgIiFnqRr:Uxy")) != -1) { switch (ch) { case 'A': f |= PKG_FLAG_AUTOMATIC; break; case 'f': f |= PKG_FLAG_FORCE; break; case 'g': match = MATCH_GLOB; break; case 'I': f |= PKG_FLAG_NOSCRIPT; break; case 'F': f |= PKG_FLAG_SKIP_INSTALL; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'U': auto_update = false; break; case 'n': f |= PKG_FLAG_DRY_RUN; dry_run = true; break; case 'q': quiet = true; break; case 'R': f |= PKG_FLAG_RECURSIVE; break; case 'r': reponame = optarg; break; case 'x': match = MATCH_REGEX; break; case 'y': yes = true; break; default: usage_install(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc < 1) { usage_install(); return (EX_USAGE); } if (dry_run && !auto_update) retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL | PKGDB_DB_REPO); else retcode = pkgdb_access(PKGDB_MODE_READ | PKGDB_MODE_WRITE | PKGDB_MODE_CREATE, PKGDB_DB_LOCAL | PKGDB_DB_REPO); if (retcode == EPKG_ENOACCESS && dry_run) { auto_update = false; retcode = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL|PKGDB_DB_REPO); } if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privileges to install packages"); return (EX_NOPERM); } else if (retcode != EPKG_OK) return (EX_IOERR); else retcode = EX_SOFTWARE; /* first update the remote repositories if needed */ if (auto_update && (updcode = pkgcli_update(false)) != EPKG_OK) return (updcode); if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) return (EX_IOERR); if (pkg_jobs_new(&jobs, PKG_JOBS_INSTALL, db) != EPKG_OK) goto cleanup; if (reponame != NULL && pkg_jobs_set_repository(jobs, reponame) != EPKG_OK) goto cleanup; pkg_jobs_set_flags(jobs, f); if (pkg_jobs_add(jobs, match, argv, argc) == EPKG_FATAL) goto cleanup; if (pkg_jobs_solve(jobs) != EPKG_OK) goto cleanup; if ((nbactions = pkg_jobs_count(jobs)) > 0) { /* print a summary before applying the jobs */ if (!quiet || dry_run) { print_jobs_summary(jobs, "The following %d packages will be installed:\n\n", nbactions); if (!yes && !dry_run) yes = query_yesno( "\nProceed with installing packages [y/N]: "); if (dry_run) yes = false; } if (yes && pkg_jobs_apply(jobs) != EPKG_OK) goto cleanup; if (messages != NULL) { sbuf_finish(messages); printf("%s", sbuf_data(messages)); } } retcode = EX_OK; cleanup: pkg_jobs_free(jobs); pkgdb_close(db); if (!yes && newpkgversion) newpkgversion = false; 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_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); }
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); }
int exec_info(int argc, char **argv) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; int query_flags; struct pkg *pkg = NULL; unsigned int opt = INFO_TAG_NAMEVER; match_t match = MATCH_EXACT; char *pkgname; char *pkgversion = NULL, *pkgversion2 = NULL; const char *file = NULL; int ch; int ret = EPKG_OK; int retcode = 0; bool gotone = false; int i, j; int sign = 0; int sign2 = 0; bool pkg_exists = false; bool origin_search = false; /* TODO: exclusive opts ? */ while ((ch = getopt(argc, argv, "aDegixEIdrklBsqopOfF:R")) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'O': origin_search = true; /* only for ports compat */ break; case 'e': pkg_exists = true;; retcode = 1; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'x': match = MATCH_REGEX; break; case 'D': opt |= INFO_MESSAGE; break; case 'd': opt |= INFO_DEPS; break; case 'I': opt |= INFO_COMMENT; break; case 'r': opt |= INFO_RDEPS; break; case 'k': opt |= INFO_LOCKED; break; case 'l': opt |= INFO_FILES; break; case 'B': opt |= INFO_SHLIBS; break; case 's': opt |= INFO_FLATSIZE; break; case 'E': /* ports compatibility */ /* FALLSTHROUGH */ case 'q': quiet = true; break; case 'o': opt |= INFO_ORIGIN; break; case 'p': opt |= INFO_PREFIX; break; case 'f': opt |= INFO_FULL; break; case 'F': file = optarg; break; case 'R': opt |= INFO_RAW; break; default: usage_info(); return(EX_USAGE); } } if (argc == 1) 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 (pkg_open(&pkg, file) != EPKG_OK) { return (1); } print_info(pkg, opt); pkg_free(pkg); return (0); } 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 (match == MATCH_ALL) 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); i = 0; do { gotone = false; pkgname = argv[i]; if (match != MATCH_ALL && pkgname[0] == '\0') { fprintf(stderr, "Pattern must not be empty.\n"); i++; continue; } /* * 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++; } } else pkgversion = NULL; if ((it = pkgdb_query(db, pkgname, match)) == NULL) { return (EX_IOERR); } /* 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 */ query_flags = info_flags(opt); 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); pkg_free(pkg); pkgdb_close(db); return (retcode); }