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); }
int exec_backup(int argc, char **argv) { struct pkgdb *db = NULL; char *backup_file = NULL; bool dump = false; bool restore = false; int ch; struct option longopts[] = { { "dump", required_argument, NULL, 'd' }, { "restore", required_argument, NULL, 'r' }, { NULL, 0, NULL, 0 }, }; while ((ch = getopt_long(argc, argv, "+d:r:", longopts, NULL)) != -1) { switch (ch) { case 'd': dump = true; backup_file = optarg; break; case 'r': restore = true; backup_file = optarg; break; default: usage_backup(); return (EX_USAGE); } } argc -= optind; argv += optind; if ( dump == restore ) { usage_backup(); return (EX_USAGE); } if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) return (EX_IOERR); if (dump) { if (isatty(fileno(stdout))) printf("Dumping database:\n"); if (pkgdb_dump(db, backup_file) == EPKG_FATAL) return (EX_IOERR); } if (restore) { if (!quiet) printf("Restoring database:\n"); if (pkgdb_load(db, backup_file) == EPKG_FATAL) return (EX_IOERR); } pkgdb_close(db); return (EX_OK); }
static void delete1pkg(const char *pkgdir) { if (!pkgdb_open(ReadWrite)) err(EXIT_FAILURE, "cannot open pkgdb"); (void) pkgdb_remove_pkg(pkgdir); pkgdb_close(); }
int exec_add(int argc, char **argv) { struct pkgdb *db = NULL; struct sbuf *failedpkgs = sbuf_new_auto(); char path[MAXPATHLEN + 1]; char *file; int retcode = EPKG_OK; int i; int failedpkgcount = 0; struct pkg *p = NULL; if (argc < 2) { usage_add(); return (EX_USAGE); } if (geteuid() != 0) { warnx("adding packages can only be done as root"); return (EX_NOPERM); } if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { return (EX_IOERR); } for (i = 1; i < argc; i++) { if (is_url(argv[i]) == EPKG_OK) { snprintf(path, sizeof(path), "./%s", basename(argv[i])); if ((retcode = pkg_fetch_file(argv[i], path)) != EPKG_OK) break; file = path; } else file = argv[i]; pkg_open(&p, file, NULL); if ((retcode = pkg_add(db, file, 0)) != EPKG_OK) { sbuf_cat(failedpkgs, argv[i]); if (i != argc - 1) sbuf_printf(failedpkgs, ", "); failedpkgcount++; } } pkgdb_close(db); if(failedpkgcount > 0) { sbuf_finish(failedpkgs); printf("Failed to install the following %d package(s): %s.\n", failedpkgcount, sbuf_data(failedpkgs)); } sbuf_delete(failedpkgs); return (retcode == EPKG_OK ? EX_OK : EX_SOFTWARE); }
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 exec_stats(int argc, char **argv) { struct pkgdb *db = NULL; int64_t flatsize = 0; char size[7]; int retcode = EX_OK; int ch; while ((ch = getopt(argc, argv, "q")) != -1) { switch (ch) { case 'q': quiet = true; break; default: usage_stats(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc > 2) { usage_stats(); return (EX_USAGE); } if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) { return (EX_IOERR); } printf("Local package database:\n"); printf("\tInstalled packages: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_LOCAL_COUNT)); flatsize = pkgdb_stats(db, PKG_STATS_LOCAL_SIZE); humanize_number(size, sizeof(flatsize), flatsize, "B", HN_AUTOSCALE, 0); printf("\tDisk space occupied: %s\n\n", size); printf("Remote package database(s):\n"); printf("\tNumber of repositories: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_REMOTE_REPOS)); printf("\tPackages available: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_REMOTE_COUNT)); printf("\tUnique packages: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_REMOTE_UNIQUE)); flatsize = pkgdb_stats(db, PKG_STATS_REMOTE_SIZE); humanize_number(size, sizeof(flatsize), flatsize, "B", HN_AUTOSCALE, 0); printf("\tTotal size of packages: %s\n", size); pkgdb_close(db); return (retcode); }
int exec_shlib(int argc, char **argv) { struct pkgdb *db = NULL; char libname[MAXPATHLEN + 1]; int retcode = EPKG_OK; int ch; bool provides_only = false; bool requires_only = false; while ((ch = getopt(argc, argv, "PR")) != -1) { switch (ch) { case 'P': provides_only = true; break; case 'R': requires_only = true; break; default: usage_shlib(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc < 1 || (provides_only && requires_only)) { usage_shlib(); return (EX_USAGE); } if (sanitize(libname, argv[0], sizeof(libname)) == NULL) { usage_shlib(); return (EX_USAGE); } retcode = pkgdb_open(&db, PKGDB_DEFAULT); if (retcode == EPKG_OK && !provides_only) retcode = pkgs_providing_lib(db, libname); if (retcode == EPKG_OK && !requires_only) retcode = pkgs_requiring_lib(db, libname); if (retcode != EPKG_OK) retcode = (EX_IOERR); pkgdb_close(db); return (retcode); }
static void update_iinf(struct i3ctx *ictx, int vrfy) { int i, is_installed = 1; const tn_array *unpkgs = iset_packages(ictx->unset); const tn_array *inpkgs = iset_packages(ictx->inset); if (vrfy) pkgdb_reopen(ictx->ts->db, O_RDONLY); for (i=0; i < n_array_size(inpkgs); i++) { struct pkg *pkg = n_array_nth(inpkgs, i); if (vrfy) { int cmprc = 0; is_installed = i3_is_pkg_installed(ictx->ts, pkg, &cmprc); if (is_installed && cmprc != 0) is_installed = 0; } if (is_installed) n_array_push(ictx->ts->pkgs_installed, pkg_link(pkg)); } if (vrfy == 0) is_installed = 0; for (i=0; i < n_array_size(unpkgs); i++) { struct pkg *dbpkg = n_array_nth(unpkgs, i); struct pkg *pkg = dbpkg; if (vrfy) { int cmprc = 0; is_installed = i3_is_pkg_installed(ictx->ts, pkg, &cmprc); if (is_installed && cmprc != 0) is_installed = 0; } if (is_installed == 0) n_array_push(ictx->ts->pkgs_removed, pkg_link(pkg)); } if (vrfy) pkgdb_close(ictx->ts->db); }
/* dump contents of the database to stdout */ int pkgdb_dump(void) { DBT key; DBT val; int type; if (pkgdb_open(ReadOnly)) { for (type = R_FIRST ; (*pkgdbp->seq)(pkgdbp, &key, &val, type) == 0 ; type = R_NEXT) { printf("file: %.*s pkg: %.*s\n", (int) key.size, (char *) key.data, (int) val.size, (char *) val.data); } pkgdb_close(); return 0; } else return -1; }
static int list_locked(struct pkgdb *db) { struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; if ((it = pkgdb_query(db, " where locked=1", MATCH_CONDITION)) == NULL) { pkgdb_close(db); return (EX_UNAVAILABLE); } printf("Currently locked packages:\n"); while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) { pkg_printf("%n-%v\n", pkg, pkg); } return (EX_OK); }
/* Add indexes to the repo */ static int remote_add_indexes(const char *reponame) { struct pkgdb *db = NULL; int ret = EPKG_FATAL; if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) goto cleanup; /* Initialize the remote remote */ if (pkgdb_remote_init(db, reponame) != EPKG_OK) goto cleanup; ret = EPKG_OK; cleanup: if (db) pkgdb_close(db); return (ret); }
static int convert_from_old(const char *pkg_add_dbdir, bool dry_run) { DIR *d; struct dirent *dp; struct pkg *p = NULL; char path[MAXPATHLEN]; struct pkgdb *db = NULL; if ((d = opendir(pkg_add_dbdir)) == NULL) err(EX_NOINPUT, "%s", pkg_add_dbdir); if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { return (EX_IOERR); } while ((dp = readdir(d)) != NULL) { if (dp->d_type == DT_DIR) { if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) continue; if (p == NULL) { if (pkg_new(&p, PKG_OLD_FILE) != EPKG_OK) err(EX_OSERR, "malloc"); } else pkg_reset(p, PKG_OLD_FILE); printf("Converting %s...\n", dp->d_name); snprintf(path, MAXPATHLEN, "%s/%s", pkg_add_dbdir, dp->d_name); if (pkg_old_load_from_path(p, path) != EPKG_OK) { fprintf(stderr, "Skipping invalid package: %s\n", path); continue; } pkg_from_old(p); if (!dry_run) pkgdb_register_ports(db, p); } } pkg_free(p); pkgdb_close(db); return (EX_OK); }
int exec_backup(int argc, char **argv) { struct pkgdb *db = NULL; char *dest = NULL; if (argc < 2 || argc > 3 || argv[1][0] != '-') { usage_backup(); return (EX_USAGE); } if (argc == 3) dest = argv[2]; if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) return (EX_IOERR); if (argv[1][1] == 'd') { if (isatty(fileno(stdin))) printf("Dumping database...\n"); if (pkgdb_dump(db, dest) == EPKG_FATAL) return (EX_IOERR); if (isatty(fileno(stdin))) printf("done\n"); } if (argv[1][1] == 'r') { if (isatty(fileno(stdin))) printf("Restoring database...\n"); if (pkgdb_load(db, dest) == EPKG_FATAL) return (EX_IOERR); if (isatty(fileno(stdin))) printf("done\n"); } pkgdb_close(db); return (EX_OK); }
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"); } }
/* * Delete the results of a package installation. * * This is here rather than in the pkg_delete code because pkg_add needs to * run it too in cases of failure. */ int delete_package(Boolean ign_err, package_t *pkg, Boolean NoDeleteFiles, const char *destdir) { plist_t *p; const char *last_file = ""; int fail = SUCCESS; Boolean preserve; char tmp[MaxPathSize]; const char *prefix = NULL, *name = NULL; if (!pkgdb_open(ReadWrite)) { err(EXIT_FAILURE, "cannot open pkgdb"); } preserve = find_plist_option(pkg, "preserve") ? TRUE : FALSE; for (p = pkg->head; p; p = p->next) { switch (p->type) { case PLIST_NAME: name = p->name; break; case PLIST_CWD: if (prefix == NULL) prefix = p->name; break; default: break; } } if (name == NULL || prefix == NULL) errx(EXIT_FAILURE, "broken PLIST"); /* * Remove database entries first, directory removal is done * in the main loop below. */ for (p = pkg->head; p; p = p->next) { if (p->type == PLIST_PKGDIR) delete_pkgdir(name, prefix, p->name); } for (p = pkg->head; p; p = p->next) { switch (p->type) { case PLIST_NAME: /* Handled already */ break; case PLIST_PKGDIR: case PLIST_DIR_RM: (void) snprintf(tmp, sizeof(tmp), "%s/%s", prefix, p->name); if (has_pkgdir(tmp)) continue; (void) snprintf(tmp, sizeof(tmp), "%s%s%s/%s", destdir ? destdir : "", destdir ? "/" : "", prefix, p->name); if (!fexists(tmp)) { if (p->type == PLIST_PKGDIR) warnx("Directory `%s' disappeared, skipping", tmp); } else if (!isdir(tmp)) { warnx("attempting to delete a file `%s' as a directory\n" "this packing list is incorrect - ignoring delete request", tmp); } else if (delete_with_parents(tmp, ign_err, TRUE)) fail = FAIL; break; case PLIST_IGNORE: p = p->next; break; case PLIST_UNEXEC: if (NoDeleteFiles) break; format_cmd(tmp, sizeof(tmp), p->name, prefix, last_file); printf("Executing `%s'\n", tmp); if (!Fake && system(tmp)) { warnx("unexec command for `%s' failed", tmp); fail = FAIL; } break; case PLIST_FILE: last_file = p->name; (void) snprintf(tmp, sizeof(tmp), "%s%s%s/%s", destdir ? destdir : "", destdir ? "/" : "", prefix, p->name); if (isdir(tmp)) { warnx("attempting to delete directory `%s' as a file\n" "this packing list is incorrect - ignoring delete request", tmp); } else { int restored = 0; /* restored from preserve? */ if (p->next && p->next->type == PLIST_COMMENT) { if (strncmp(p->next->name, CHECKSUM_HEADER, ChecksumHeaderLen) == 0) { char *cp, buf[LegibleChecksumLen]; if ((cp = MD5File(tmp, buf)) != NULL) { /* Mismatch? */ if (strcmp(cp, p->next->name + ChecksumHeaderLen) != 0) { printf("original MD5 checksum failed, %s: %s\n", Force ? "deleting anyway" : "not deleting", tmp); if (!Force) { fail = FAIL; goto pkgdb_cleanup; } } } } else if (strncmp(p->next->name, SYMLINK_HEADER, SymlinkHeaderLen) == 0) { char buf[MaxPathSize + SymlinkHeaderLen]; int cc; (void) strlcpy(buf, SYMLINK_HEADER, sizeof(buf)); if ((cc = readlink(tmp, &buf[SymlinkHeaderLen], sizeof(buf) - SymlinkHeaderLen - 1)) < 0) { warn("can't readlink `%s'", tmp); goto pkgdb_cleanup; } buf[SymlinkHeaderLen + cc] = 0x0; if (strcmp(buf, p->next->name) != 0) { if ((cc = readlink(&buf[SymlinkHeaderLen], &buf[SymlinkHeaderLen], sizeof(buf) - SymlinkHeaderLen)) < 0) { printf("symlink %s is not same as recorded value, %s: %s\n", buf, Force ? "deleting anyway" : "not deleting", tmp); if (!Force) { fail = FAIL; goto pkgdb_cleanup; } } buf[SymlinkHeaderLen + cc] = 0x0; if (strcmp(buf, p->next->name) != 0) { printf("symlink %s is not same as recorded value, %s: %s\n", buf, Force ? "deleting anyway" : "not deleting", tmp); if (!Force) { fail = FAIL; goto pkgdb_cleanup; } } } } } if (Verbose && !NoDeleteFiles) printf("Delete file %s\n", tmp); if (!Fake && !NoDeleteFiles) { if (delete_with_parents(tmp, ign_err, FALSE)) fail = FAIL; if (preserve && name) { char tmp2[MaxPathSize]; if (make_preserve_name(tmp2, MaxPathSize, name, tmp)) { if (fexists(tmp2)) { if (rename(tmp2, tmp)) warn("preserve: unable to restore %s as %s", tmp2, tmp); else restored = 1; } } } } pkgdb_cleanup: if (!Fake) { if (!restored) { errno = 0; if (pkgdb_remove(tmp) && errno) perror("pkgdb_remove"); } } } break; default: break; } } pkgdb_close(); return fail; }
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_stats(int argc, char **argv) { struct pkgdb *db = NULL; int64_t flatsize = 0; unsigned int opt = 0; char size[7]; int ch; bool show_bytes = false; struct option longopts[] = { { "bytes", no_argument, NULL, 'b' }, { "local", no_argument, NULL, 'l' }, { "quiet", no_argument, NULL, 'q' }, { "remote", no_argument, NULL, 'r' }, { NULL, 0, NULL, 0 }, }; while ((ch = getopt_long(argc, argv, "+blqr", longopts, NULL)) != -1) { switch (ch) { case 'b': show_bytes = true; break; case 'l': opt |= STATS_LOCAL; break; case 'q': quiet = true; break; case 'r': opt |= STATS_REMOTE; break; default: usage_stats(); return (EX_USAGE); } } argc -= optind; argv += optind; /* default is to show everything we have */ if (opt == 0) opt |= (STATS_LOCAL | STATS_REMOTE); if (pkgdb_open(&db, PKGDB_REMOTE) != 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 (opt & STATS_LOCAL) { printf("Local package database:\n"); printf("\tInstalled packages: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_LOCAL_COUNT)); flatsize = pkgdb_stats(db, PKG_STATS_LOCAL_SIZE); if (show_bytes) printf("\tDisk space occupied: %" PRId64 "\n\n", flatsize); else { humanize_number(size, sizeof(size), flatsize, "B", HN_AUTOSCALE, 0); printf("\tDisk space occupied: %s\n\n", size); } } if ((opt & STATS_REMOTE) && pkg_repos_total_count() > 0) { printf("Remote package database(s):\n"); printf("\tNumber of repositories: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_REMOTE_REPOS)); printf("\tPackages available: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_REMOTE_COUNT)); printf("\tUnique packages: %" PRId64 "\n", pkgdb_stats(db, PKG_STATS_REMOTE_UNIQUE)); flatsize = pkgdb_stats(db, PKG_STATS_REMOTE_SIZE); if (show_bytes) printf("\tTotal size of packages: %" PRId64 "\n", flatsize); else { humanize_number(size, sizeof(size), flatsize, "B", HN_AUTOSCALE, 0); printf("\tTotal size of packages: %s\n", size); } } pkgdb_release_lock(db, PKGDB_LOCK_READONLY); pkgdb_close(db); return (EX_OK); }
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_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_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_register(int argc, char **argv) { struct pkg *pkg = NULL; struct pkgdb *db = NULL; struct pkg_manifest_key *keys = NULL; regex_t preg; regmatch_t pmatch[2]; char *arch = NULL; char myarch[BUFSIZ]; char *www = NULL; char fpath[MAXPATHLEN]; const char *plist = NULL; const char *mdir = NULL; const char *mfile = NULL; const char *input_path = NULL; const char *desc = NULL; const char *location = NULL; size_t size; bool developer; bool legacy = false; bool old = false; bool __unused metadata_only = false; bool testing_mode = false; int ch; int i; int ret = EPKG_OK; int retcode = EX_OK; /* options descriptor */ struct option longopts[] = { { "automatic", no_argument, NULL, 'A' }, { "plist", required_argument, NULL, 'f' }, { "root", required_argument, NULL, 'i' }, { "legacy", no_argument, NULL, 'l' }, { "manifest", required_argument, NULL, 'M' }, { "metadata", required_argument, NULL, 'm' }, { "old", no_argument, NULL, 'O' }, { "test", no_argument, NULL, 't' }, { "relocate", required_argument, NULL, 1 }, { NULL, 0, NULL, 0}, }; developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE")); if (pkg_new(&pkg, PKG_INSTALLED) != EPKG_OK) err(EX_OSERR, "malloc"); while ((ch = getopt_long(argc, argv, "Adf:i:lM:m:Ot", longopts, NULL)) != -1) { switch (ch) { case 'A': case 'd': pkg_set(pkg, PKG_AUTOMATIC, (bool)true); break; case 'f': plist = optarg; break; case 'i': input_path = optarg; break; case 'l': legacy = true; break; case 'M': metadata_only = true; mfile = optarg; break; case 'm': mdir = optarg; break; case 'O': old = true; break; case 't': testing_mode = true; break; case 1: location = optarg; break; default: warnx("Unrecognised option -%c\n", ch); usage_register(); return (EX_USAGE); } } if (!old) { retcode = pkgdb_access(PKGDB_MODE_READ | PKGDB_MODE_WRITE | PKGDB_MODE_CREATE, PKGDB_DB_LOCAL); if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privileges to register packages"); return (EX_NOPERM); } else if (retcode != EPKG_OK) return (EX_IOERR); else retcode = EX_OK; } /* * Ideally, the +MANIFEST should be all that is necessary, * since it can contain all of the meta-data supplied by the * other files mentioned below. These are here for backwards * compatibility with the way the ports tree works with * pkg_tools. * * The -M option specifies one manifest file to read the * meta-data from, and overrides the use of legacy meta-data * inputs. * * Dependencies, shlibs, files etc. may be derived by * analysing the package files (maybe discovered as the * content of the staging directory) unless -t (testing_mode) * is used. */ if (mfile != NULL && mdir != NULL) { warnx("Cannot use both -m and -M together"); usage_register(); return (EX_USAGE); } if (mfile == NULL && mdir == NULL) { warnx("One of either -m or -M flags is required"); usage_register(); return (EX_USAGE); } if (mfile != NULL && plist != NULL) { warnx("-M incompatible with -f option"); usage_register(); return (EX_USAGE); } if (testing_mode && input_path != NULL) { warnx("-i incompatible with -t option"); usage_register(); return (EX_USAGE); } pkg_manifest_keys_new(&keys); if (mfile != NULL) { ret = pkg_parse_manifest_file(pkg, mfile, keys); pkg_manifest_keys_free(keys); if (ret != EPKG_OK) return (EX_IOERR); } else { snprintf(fpath, sizeof(fpath), "%s/+MANIFEST", mdir); ret = pkg_parse_manifest_file(pkg, fpath, keys); pkg_manifest_keys_free(keys); if (ret != EPKG_OK) return (EX_IOERR); snprintf(fpath, sizeof(fpath), "%s/+DESC", mdir); pkg_set_from_file(pkg, PKG_DESC, fpath, false); snprintf(fpath, sizeof(fpath), "%s/+DISPLAY", mdir); if (access(fpath, F_OK) == 0) pkg_set_from_file(pkg, PKG_MESSAGE, fpath, false); snprintf(fpath, sizeof(fpath), "%s/+MTREE_DIRS", mdir); if (access(fpath, F_OK) == 0) pkg_set_from_file(pkg, PKG_MTREE, fpath, false); for (i = 0; scripts[i] != NULL; i++) { snprintf(fpath, sizeof(fpath), "%s/%s", mdir, scripts[i]); if (access(fpath, F_OK) == 0) pkg_addscript_file(pkg, fpath); } if (www != NULL) { pkg_set(pkg, PKG_WWW, www); free(www); } pkg_get(pkg, PKG_WWW, &www); /* * if www is not given then try to determine it from * description */ if (www == NULL) { pkg_get(pkg, PKG_DESC, &desc); regcomp(&preg, "^WWW:[[:space:]]*(.*)$", REG_EXTENDED|REG_ICASE|REG_NEWLINE); if (regexec(&preg, desc, 2, pmatch, 0) == 0) { size = pmatch[1].rm_eo - pmatch[1].rm_so; www = strndup(&desc[pmatch[1].rm_so], size); pkg_set(pkg, PKG_WWW, www); free(www); } else { pkg_set(pkg, PKG_WWW, "UNKNOWN"); } regfree(&preg); } if (plist != NULL) ret += ports_parse_plist(pkg, plist, input_path); } if (ret != EPKG_OK) { return (EX_IOERR); } if (!old) { if (pkgdb_open(&db, PKGDB_DEFAULT) != 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); } } /* * testing_mode allows updating the local package database * without any check that the files etc. listed in the meta * data actually exist on the system. Inappropriate use of * testing_mode can really screw things up. */ if (!testing_mode) pkg_analyse_files(db, pkg, input_path); pkg_get(pkg, PKG_ARCH, &arch); if (arch == NULL) { /* * do not take the one from configuration on purpose * but the real abi of the package. */ pkg_get_myarch(myarch, BUFSIZ); if (developer) pkg_suggest_arch(pkg, myarch, true); pkg_set(pkg, PKG_ARCH, myarch); } else { if (developer) pkg_suggest_arch(pkg, arch, false); } if (!testing_mode && input_path != NULL) pkg_copy_tree(pkg, input_path, location ? location : "/"); if (location != NULL) pkg_addannotation(pkg, "relocated", location); if (old) { if (pkg_register_old(pkg) != EPKG_OK) retcode = EX_SOFTWARE; } else { if (pkgdb_register_ports(db, pkg) != EPKG_OK) retcode = EX_SOFTWARE; } if (!legacy && pkg_has_message(pkg)) pkg_printf("%M\n", pkg); if (!old) { pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE); pkgdb_close(db); } pkg_free(pkg); return (retcode); }
/* * add1pkg(<pkg>) * adds the files listed in the +CONTENTS of <pkg> into the * pkgdb.byfile.db database file in the current package dbdir. It * returns the number of files added to the database file. */ static int add_pkg(const char *pkgdir, void *vp) { FILE *f; plist_t *p; package_t Plist; char *contents; char *PkgName, *dirp; char file[MaxPathSize]; struct pkgdb_count *count; if (!pkgdb_open(ReadWrite)) err(EXIT_FAILURE, "cannot open pkgdb"); count = vp; ++count->packages; contents = pkgdb_pkg_file(pkgdir, CONTENTS_FNAME); if ((f = fopen(contents, "r")) == NULL) errx(EXIT_FAILURE, "%s: can't open `%s'", pkgdir, CONTENTS_FNAME); free(contents); read_plist(&Plist, f); if ((p = find_plist(&Plist, PLIST_NAME)) == NULL) { errx(EXIT_FAILURE, "Package `%s' has no @name, aborting.", pkgdir); } PkgName = p->name; dirp = NULL; for (p = Plist.head; p; p = p->next) { switch(p->type) { case PLIST_FILE: if (dirp == NULL) { errx(EXIT_FAILURE, "@cwd not yet found, please send-pr!"); } (void) snprintf(file, sizeof(file), "%s/%s", dirp, p->name); if (!(isfile(file) || islinktodir(file))) { if (isbrokenlink(file)) { warnx("%s: Symlink `%s' exists and is in %s but target does not exist!", PkgName, file, CONTENTS_FNAME); } else { warnx("%s: File `%s' is in %s but not on filesystem!", PkgName, file, CONTENTS_FNAME); } } else { pkgdb_store(file, PkgName); ++count->files; } break; case PLIST_PKGDIR: add_pkgdir(PkgName, dirp, p->name); ++count->directories; break; case PLIST_CWD: if (strcmp(p->name, ".") != 0) dirp = p->name; else dirp = pkgdb_pkg_dir(pkgdir); break; case PLIST_IGNORE: p = p->next; break; case PLIST_SHOW_ALL: case PLIST_SRC: case PLIST_CMD: case PLIST_CHMOD: case PLIST_CHOWN: case PLIST_CHGRP: case PLIST_COMMENT: case PLIST_NAME: case PLIST_UNEXEC: case PLIST_DISPLAY: case PLIST_PKGDEP: case PLIST_DIR_RM: case PLIST_OPTION: case PLIST_PKGCFL: case PLIST_BLDDEP: break; } } free_plist(&Plist); fclose(f); pkgdb_close(); return 0; }
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); }
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_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); }
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); }
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 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_upgrade(int argc, char **argv) { struct pkgdb *db = NULL; struct pkg_jobs *jobs = NULL; const char *reponame = NULL; int retcode; int updcode; int ch; bool yes; bool dry_run = false; bool auto_update; 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, "fLnqFr:Uy")) != -1) { switch (ch) { case 'f': f |= PKG_FLAG_FORCE; break; case 'I': f |= PKG_FLAG_NOSCRIPT; break; case 'L': warnx("!!! The -L flag is deprecated and will be removed. Please use -U now."); /* FALLTHROUGH */ case 'U': auto_update = false; break; case 'n': f |= PKG_FLAG_DRY_RUN; dry_run = true; break; case 'F': f |= PKG_FLAG_SKIP_INSTALL; break; case 'q': quiet = true; break; case 'r': reponame = optarg; break; case 'y': yes = true; break; default: usage_upgrade(); return (EX_USAGE); /* NOTREACHED */ } } argc -= optind; argv += optind; if (argc != 0) { usage_upgrade(); return (EX_USAGE); } if (dry_run) 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) { 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 (!dry_run && 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_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 (pkg_jobs_solve(jobs) != EPKG_OK) goto cleanup; if ((nbactions = pkg_jobs_count(jobs)) == 0) { if (!quiet) printf("Nothing to do\n"); retcode = EXIT_SUCCESS; goto cleanup; } if (!quiet || dry_run) { print_jobs_summary(jobs, "Uprgades have been requested for the following %d " "packages:\n\n", nbactions); if (!yes && !dry_run) yes = query_yesno("\nProceed with upgrading " "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 = EXIT_SUCCESS; cleanup: pkg_jobs_free(jobs); pkgdb_close(db); return (retcode); }