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, "fLnqr:y")) != -1) { switch (ch) { case 'f': f |= PKG_FLAG_FORCE; break; case 'I': f |= PKG_FLAG_NOSCRIPT; break; case 'L': auto_update = false; break; case 'n': f |= PKG_FLAG_DRY_RUN; dry_run = true; 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; 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); }
static void pipeevent(struct pkg_event *ev) { int i; struct pkg_dep *dep = NULL; struct sbuf *msg, *buf; struct pkg_event_conflict *cur_conflict; if (eventpipe < 0) return; msg = sbuf_new_auto(); buf = sbuf_new_auto(); switch(ev->type) { case PKG_EVENT_ERRNO: sbuf_printf(msg, "{ \"type\": \"ERROR\", " "\"data\": {" "\"msg\": \"%s(%s): %s\"," "\"errno\": %d}}", sbuf_json_escape(buf, ev->e_errno.func), sbuf_json_escape(buf, ev->e_errno.arg), sbuf_json_escape(buf, strerror(ev->e_errno.no)), ev->e_errno.no); break; case PKG_EVENT_ERROR: sbuf_printf(msg, "{ \"type\": \"ERROR\", " "\"data\": {\"msg\": \"%s\"}}", sbuf_json_escape(buf, ev->e_pkg_error.msg)); break; case PKG_EVENT_NOTICE: sbuf_printf(msg, "{ \"type\": \"NOTICE\", " "\"data\": {\"msg\": \"%s\"}}", sbuf_json_escape(buf, ev->e_pkg_notice.msg)); break; case PKG_EVENT_DEVELOPER_MODE: sbuf_printf(msg, "{ \"type\": \"ERROR\", " "\"data\": {\"msg\": \"DEVELOPER_MODE: %s\"}}", sbuf_json_escape(buf, ev->e_pkg_error.msg)); break; case PKG_EVENT_UPDATE_ADD: sbuf_printf(msg, "{ \"type\": \"INFO_UPDATE_ADD\", " "\"data\": { " "\"fetched\": %d, " "\"total\": %d" "}}", ev->e_upd_add.done, ev->e_upd_add.total ); break; case PKG_EVENT_UPDATE_REMOVE: sbuf_printf(msg, "{ \"type\": \"INFO_UPDATE_REMOVE\", " "\"data\": { " "\"fetched\": %d, " "\"total\": %d" "}}", ev->e_upd_remove.done, ev->e_upd_remove.total ); break; case PKG_EVENT_FETCH_BEGIN: sbuf_printf(msg, "{ \"type\": \"INFO_FETCH_BEGIN\", " "\"data\": { " "\"url\": \"%s\" " "}}", sbuf_json_escape(buf, ev->e_fetching.url) ); break; case PKG_EVENT_FETCH_FINISHED: sbuf_printf(msg, "{ \"type\": \"INFO_FETCH_FINISHED\", " "\"data\": { " "\"url\": \"%s\" " "}}", sbuf_json_escape(buf, ev->e_fetching.url) ); break; case PKG_EVENT_INSTALL_BEGIN: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_BEGIN\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\"" "}}", ev->e_install_begin.pkg, ev->e_install_begin.pkg); break; case PKG_EVENT_EXTRACT_BEGIN: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_EXTRACT_BEGIN\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\"" "}}", ev->e_extract_begin.pkg, ev->e_extract_begin.pkg); break; case PKG_EVENT_EXTRACT_FINISHED: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_EXTRACT_FINISHED\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\"" "}}", ev->e_extract_finished.pkg, ev->e_extract_finished.pkg); break; case PKG_EVENT_INSTALL_FINISHED: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_FINISHED\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\", " "\"message\": \"%S\"" "}}", ev->e_install_finished.pkg, ev->e_install_finished.pkg, ev->e_install_finished.pkg->message ? sbuf_json_escape(buf, ev->e_install_finished.pkg->message->str) : ""); break; case PKG_EVENT_INTEGRITYCHECK_BEGIN: sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_BEGIN\", " "\"data\": {}}"); break; case PKG_EVENT_INTEGRITYCHECK_CONFLICT: sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_CONFLICT\"," "\"data\": { " "\"pkguid\": \"%s\", " "\"pkgpath\": \"%s\", " "\"conflicts\": [", ev->e_integrity_conflict.pkg_uid, ev->e_integrity_conflict.pkg_path); cur_conflict = ev->e_integrity_conflict.conflicts; while (cur_conflict != NULL) { if (cur_conflict->next != NULL) { sbuf_printf(msg, "{\"uid\":\"%s\"},", cur_conflict->uid); } else { sbuf_printf(msg, "{\"uid\":\"%s\"}", cur_conflict->uid); break; } cur_conflict = cur_conflict->next; } sbuf_cat(msg, "]}}"); break; case PKG_EVENT_INTEGRITYCHECK_FINISHED: sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_FINISHED\", " "\"data\": {\"conflicting\": %d}}", ev->e_integrity_finished.conflicting); break; case PKG_EVENT_DEINSTALL_BEGIN: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_BEGIN\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\"" "}}", ev->e_deinstall_begin.pkg, ev->e_deinstall_begin.pkg); break; case PKG_EVENT_DEINSTALL_FINISHED: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_FINISHED\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\"" "}}", ev->e_deinstall_finished.pkg, ev->e_deinstall_finished.pkg); break; case PKG_EVENT_UPGRADE_BEGIN: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_BEGIN\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\" ," "\"pkgnewversion\": \"%v\"" "}}", ev->e_upgrade_begin.o, ev->e_upgrade_begin.o, ev->e_upgrade_begin.n); break; case PKG_EVENT_UPGRADE_FINISHED: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_FINISHED\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\" ," "\"pkgnewversion\": \"%v\"" "}}", ev->e_upgrade_finished.o, ev->e_upgrade_finished.o, ev->e_upgrade_finished.n); break; case PKG_EVENT_LOCKED: pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_LOCKED\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%n\"" "}}", ev->e_locked.pkg, ev->e_locked.pkg); break; case PKG_EVENT_REQUIRED: pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_REQUIRED\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\", " "\"force\": %S, " "\"required_by\": [", ev->e_required.pkg, ev->e_required.pkg, ev->e_required.force == 1 ? "true": "false"); while (pkg_rdeps(ev->e_required.pkg, &dep) == EPKG_OK) sbuf_printf(msg, "{ \"pkgname\": \"%s\", " "\"pkgversion\": \"%s\" }, ", dep->name, dep->version); sbuf_setpos(msg, sbuf_len(msg) - 2); sbuf_cat(msg, "]}}"); break; case PKG_EVENT_ALREADY_INSTALLED: pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_ALREADY_INSTALLED\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\"" "}}", ev->e_already_installed.pkg, ev->e_already_installed.pkg); break; case PKG_EVENT_MISSING_DEP: sbuf_printf(msg, "{ \"type\": \"ERROR_MISSING_DEP\", " "\"data\": { " "\"depname\": \"%s\", " "\"depversion\": \"%s\"" "}}" , ev->e_missing_dep.dep->name, ev->e_missing_dep.dep->version); break; case PKG_EVENT_NOREMOTEDB: sbuf_printf(msg, "{ \"type\": \"ERROR_NOREMOTEDB\", " "\"data\": { " "\"url\": \"%s\" " "}}" , ev->e_remotedb.repo); break; case PKG_EVENT_NOLOCALDB: sbuf_printf(msg, "{ \"type\": \"ERROR_NOLOCALDB\", " "\"data\": {} "); break; case PKG_EVENT_NEWPKGVERSION: sbuf_printf(msg, "{ \"type\": \"INFO_NEWPKGVERSION\", " "\"data\": {} "); break; case PKG_EVENT_FILE_MISMATCH: pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_FILE_MISMATCH\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\", " "\"path\": \"%S\"" "}}", ev->e_file_mismatch.pkg, ev->e_file_mismatch.pkg, sbuf_json_escape(buf, ev->e_file_mismatch.file->path)); break; case PKG_EVENT_PLUGIN_ERRNO: sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", " "\"data\": {" "\"plugin\": \"%s\", " "\"msg\": \"%s(%s): %s\"," "\"errno\": %d" "}}", pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME), sbuf_json_escape(buf, ev->e_plugin_errno.func), sbuf_json_escape(buf, ev->e_plugin_errno.arg), sbuf_json_escape(buf, strerror(ev->e_plugin_errno.no)), ev->e_plugin_errno.no); break; case PKG_EVENT_PLUGIN_ERROR: sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", " "\"data\": {" "\"plugin\": \"%s\", " "\"msg\": \"%s\"" "}}", pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME), sbuf_json_escape(buf, ev->e_plugin_error.msg)); break; case PKG_EVENT_PLUGIN_INFO: sbuf_printf(msg, "{ \"type\": \"INFO_PLUGIN\", " "\"data\": {" "\"plugin\": \"%s\", " "\"msg\": \"%s\"" "}}", pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME), sbuf_json_escape(buf, ev->e_plugin_info.msg)); break; case PKG_EVENT_INCREMENTAL_UPDATE: sbuf_printf(msg, "{ \"type\": \"INFO_INCREMENTAL_UPDATE\", " "\"data\": {" "\"name\": \"%s\", " "\"processed\": %d" "}}", ev->e_incremental_update.reponame, ev->e_incremental_update.processed); break; case PKG_EVENT_QUERY_YESNO: sbuf_printf(msg, "{ \"type\": \"QUERY_YESNO\", " "\"data\": {" "\"msg\": \"%s\"," "\"default\": \"%d\"" "}}", ev->e_query_yesno.msg, ev->e_query_yesno.deft); break; case PKG_EVENT_QUERY_SELECT: sbuf_printf(msg, "{ \"type\": \"QUERY_SELECT\", " "\"data\": {" "\"msg\": \"%s\"," "\"ncnt\": \"%d\"," "\"default\": \"%d\"," "\"items\": [" , ev->e_query_select.msg, ev->e_query_select.ncnt, ev->e_query_select.deft); for (i = 0; i < ev->e_query_select.ncnt - 1; i++) { sbuf_printf(msg, "{ \"text\": \"%s\" },", ev->e_query_select.items[i]); } sbuf_printf(msg, "{ \"text\": \"%s\" } ] }}", ev->e_query_select.items[i]); break; case PKG_EVENT_PROGRESS_START: sbuf_printf(msg, "{ \"type\": \"INFO_PROGRESS_START\", " "\"data\": {}}"); break; case PKG_EVENT_PROGRESS_TICK: sbuf_printf(msg, "{ \"type\": \"INFO_PROGRESS_TICK\", " "\"data\": { \"current\": %ld, \"total\" : %ld}}", ev->e_progress_tick.current, ev->e_progress_tick.total); break; case PKG_EVENT_BACKUP: case PKG_EVENT_RESTORE: break; default: break; } sbuf_finish(msg); dprintf(eventpipe, "%s\n", sbuf_data(msg)); sbuf_delete(msg); sbuf_delete(buf); }
static int pkg_create_from_dir(struct pkg *pkg, const char *root, struct packing *pkg_archive) { char fpath[MAXPATHLEN]; struct pkg_file *file = NULL; struct pkg_dir *dir = NULL; int ret; struct stat st; int64_t flatsize = 0; int64_t nfiles; const char *relocation; hardlinks_t *hardlinks; if (pkg_is_valid(pkg) != EPKG_OK) { pkg_emit_error("the package is not valid"); return (EPKG_FATAL); } relocation = pkg_kv_get(&pkg->annotations, "relocated"); if (relocation == NULL) relocation = ""; if (pkg_rootdir != NULL) relocation = pkg_rootdir; /* * Get / compute size / checksum if not provided in the manifest */ nfiles = kh_count(pkg->filehash); counter_init("file sizes/checksums", nfiles); hardlinks = kh_init_hardlinks(); while (pkg_files(pkg, &file) == EPKG_OK) { snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "", relocation, file->path); if (lstat(fpath, &st) == -1) { pkg_emit_error("file '%s' is missing", fpath); return (EPKG_FATAL); } if (file->size == 0) file->size = (int64_t)st.st_size; if (st.st_nlink == 1 || !check_for_hardlink(hardlinks, &st)) { flatsize += file->size; } file->sum = pkg_checksum_generate_file(fpath, PKG_HASH_TYPE_SHA256_HEX); if (file->sum == NULL) return (EPKG_FATAL); counter_count(); } kh_destroy_hardlinks(hardlinks); counter_end(); pkg->flatsize = flatsize; if (pkg->type == PKG_OLD_FILE) { pkg_emit_error("Cannot create an old format package"); return (EPKG_FATAL); } else { /* * Register shared libraries used by the package if * SHLIBS enabled in conf. Deletes shlib info if not. */ struct sbuf *b = sbuf_new_auto(); pkg_analyse_files(NULL, pkg, root); pkg_emit_manifest_sbuf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, NULL); packing_append_buffer(pkg_archive, sbuf_data(b), "+COMPACT_MANIFEST", sbuf_len(b)); sbuf_clear(b); pkg_emit_manifest_sbuf(pkg, b, 0, NULL); sbuf_finish(b); packing_append_buffer(pkg_archive, sbuf_data(b), "+MANIFEST", sbuf_len(b)); sbuf_delete(b); } counter_init("packing files", nfiles); while (pkg_files(pkg, &file) == EPKG_OK) { snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "", relocation, file->path); ret = packing_append_file_attr(pkg_archive, fpath, file->path, file->uname, file->gname, file->perm, file->fflags); if (developer_mode && ret != EPKG_OK) return (ret); counter_count(); } counter_end(); nfiles = kh_count(pkg->dirhash); counter_init("packing directories", nfiles); while (pkg_dirs(pkg, &dir) == EPKG_OK) { snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "", relocation, dir->path); ret = packing_append_file_attr(pkg_archive, fpath, dir->path, dir->uname, dir->gname, dir->perm, dir->fflags); if (developer_mode && ret != EPKG_OK) return (ret); counter_count(); } counter_end(); return (EPKG_OK); }
static void format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, void *data) { char size[7]; const char *tmp; bool tmp2; int64_t flatsize; int64_t timestamp; lic_t licenselogic; sbuf_clear(dest); while (qstr[0] != '\0') { if (qstr[0] == '%') { qstr++; switch (qstr[0]) { case 'n': pkg_get(pkg, PKG_NAME, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'v': pkg_get(pkg, PKG_VERSION, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'o': pkg_get(pkg, PKG_ORIGIN, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'R': pkg_get(pkg, PKG_REPONAME, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'p': pkg_get(pkg, PKG_PREFIX, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'm': pkg_get(pkg, PKG_MAINTAINER, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'c': pkg_get(pkg, PKG_COMMENT, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'w': pkg_get(pkg, PKG_WWW, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'i': pkg_get(pkg, PKG_INFOS, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'a': pkg_get(pkg, PKG_AUTOMATIC, &tmp2); sbuf_printf(dest, "%d", tmp2); break; case 'k': pkg_get(pkg, PKG_LOCKED, &tmp2); sbuf_printf(dest, "%d", tmp2); break; case 't': pkg_get(pkg, PKG_TIME, ×tamp); sbuf_printf(dest, "%" PRId64, timestamp); break; case 's': qstr++; pkg_get(pkg, PKG_FLATSIZE, &flatsize); if (qstr[0] == 'h') { humanize_number(size, sizeof(size), flatsize, "B", HN_AUTOSCALE, 0); sbuf_cat(dest, size); } else if (qstr[0] == 'b') { sbuf_printf(dest, "%" PRId64, flatsize); } break; case 'e': pkg_get(pkg, PKG_DESC, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case '?': qstr++; switch (qstr[0]) { case 'd': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DEPS) > 0); break; case 'r': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_RDEPS) > 0); break; case 'C': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_CATEGORIES) > 0); break; case 'F': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_FILES) > 0); break; case 'O': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_OPTIONS) > 0); break; case 'D': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DIRS) > 0); break; case 'L': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_LICENSES) > 0); break; case 'U': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_USERS) > 0); break; case 'G': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_GROUPS) > 0); break; case 'B': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_REQUIRED) > 0); break; case 'b': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_PROVIDED) > 0); break; case 'A': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_ANNOTATIONS) > 0); break; } break; case '#': qstr++; switch (qstr[0]) { case 'd': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DEPS)); break; case 'r': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_RDEPS)); break; case 'C': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_CATEGORIES)); break; case 'F': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_FILES)); break; case 'O': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_OPTIONS)); break; case 'D': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DIRS)); break; case 'L': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_LICENSES)); break; case 'U': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_USERS)); break; case 'G': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_GROUPS)); break; case 'B': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_REQUIRED)); break; case 'b': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_PROVIDED)); break; case 'A': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_ANNOTATIONS)); break; } break; case 'l': pkg_get(pkg, PKG_LICENSE_LOGIC, &licenselogic); switch (licenselogic) { case LICENSE_SINGLE: sbuf_cat(dest, "single"); break; case LICENSE_OR: sbuf_cat(dest, "or"); break; case LICENSE_AND: sbuf_cat(dest, "and"); break; } break; case 'd': qstr++; if (qstr[0] == 'n') sbuf_cat(dest, pkg_dep_name((struct pkg_dep *)data)); else if (qstr[0] == 'o') sbuf_cat(dest, pkg_dep_origin((struct pkg_dep *)data)); else if (qstr[0] == 'v') sbuf_cat(dest, pkg_dep_version((struct pkg_dep *)data)); break; case 'r': qstr++; if (qstr[0] == 'n') sbuf_cat(dest, pkg_dep_name((struct pkg_dep *)data)); else if (qstr[0] == 'o') sbuf_cat(dest, pkg_dep_origin((struct pkg_dep *)data)); else if (qstr[0] == 'v') sbuf_cat(dest, pkg_dep_version((struct pkg_dep *)data)); break; case 'C': sbuf_cat(dest, pkg_category_name((struct pkg_category *)data)); break; case 'F': qstr++; if (qstr[0] == 'p') sbuf_cat(dest, pkg_file_path((struct pkg_file *)data)); else if (qstr[0] == 's') sbuf_cat(dest, pkg_file_cksum((struct pkg_file *)data)); break; case 'O': qstr++; if (qstr[0] == 'k') sbuf_cat(dest, pkg_option_opt((struct pkg_option *)data)); else if (qstr[0] == 'v') sbuf_cat(dest, pkg_option_value((struct pkg_option *)data)); break; case 'D': sbuf_cat(dest, pkg_dir_path((struct pkg_dir *)data)); break; case 'L': sbuf_cat(dest, pkg_license_name((struct pkg_license *)data)); break; case 'U': sbuf_cat(dest, pkg_user_name((struct pkg_user *)data)); break; case 'G': sbuf_cat(dest, pkg_group_name((struct pkg_group *)data)); break; case 'B': case 'b': sbuf_cat(dest, pkg_shlib_name((struct pkg_shlib *)data)); break; case 'A': qstr++; if (qstr[0] == 't') sbuf_cat(dest, pkg_annotation_tag((struct pkg_note *)data)); else if (qstr[0] == 'v') sbuf_cat(dest, pkg_annotation_value((struct pkg_note *)data)); break; case 'M': pkg_get(pkg, PKG_MESSAGE, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case '%': sbuf_putc(dest, '%'); break; } } else if (qstr[0] == '\\') { qstr++; switch (qstr[0]) { case 'n': sbuf_putc(dest, '\n'); break; case 'a': sbuf_putc(dest, '\a'); break; case 'b': sbuf_putc(dest, '\b'); break; case 'f': sbuf_putc(dest, '\f'); break; case 'r': sbuf_putc(dest, '\r'); break; case '\\': sbuf_putc(dest, '\\'); break; case 't': sbuf_putc(dest, '\t'); break; } } else { sbuf_putc(dest, qstr[0]); } qstr++; } sbuf_finish(dest); }
int exec_add(int argc, char **argv) { struct pkgdb *db = NULL; struct sbuf *failedpkgs = NULL; char path[MAXPATHLEN]; char *file; int retcode; int ch; int i; int failedpkgcount = 0; pkg_flags f = PKG_FLAG_NONE; struct pkg_manifest_key *keys = NULL; const char *location = NULL; /* options descriptor */ struct option longopts[] = { { "no-scripts", no_argument, NULL, 'I' }, { "automatic", no_argument, NULL, 'A' }, { "force", no_argument, NULL, 'f' }, { "accept-missing", no_argument, NULL, 'M' }, { "quiet", no_argument, NULL, 'q' }, { "relocate", required_argument, NULL, 1 }, { NULL, 0, NULL, 0 } }; while ((ch = getopt_long(argc, argv, "+IAfqM", longopts, NULL)) != -1) { switch (ch) { case 'I': f |= PKG_ADD_NOSCRIPT; break; case 'A': f |= PKG_ADD_AUTOMATIC; break; case 'f': f |= PKG_ADD_FORCE; force = true; break; case 'M': f |= PKG_ADD_FORCE_MISSING; break; case 'q': quiet = true; break; case 1: location = optarg; break; default: usage_add(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc < 1) { usage_add(); return (EX_USAGE); } retcode = pkgdb_access(PKGDB_MODE_READ | PKGDB_MODE_WRITE | PKGDB_MODE_CREATE, PKGDB_DB_LOCAL); if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privileges to add packages"); return (EX_NOPERM); } else if (retcode != EPKG_OK) return (EX_IOERR); 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); } failedpkgs = sbuf_new_auto(); pkg_manifest_keys_new(&keys); for (i = 0; i < argc; i++) { if (is_url(argv[i]) == EPKG_OK) { snprintf(path, sizeof(path), "%s/%s.XXXXX", getenv("TMPDIR") != NULL ? getenv("TMPDIR") : "/tmp", basename(argv[i])); if ((retcode = pkg_fetch_file(NULL, argv[i], path, 0)) != EPKG_OK) break; file = path; } else { file = argv[i]; /* Special case: treat a filename of "-" as meaning 'read from stdin.' It doesn't make sense to have a filename of "-" more than once per command line, but we aren't testing for that at the moment */ if (strcmp(file, "-") != 0 && access(file, F_OK) != 0) { warn("%s", file); if (errno == ENOENT) warnx("Was 'pkg install %s' meant?", file); sbuf_cat(failedpkgs, argv[i]); if (i != argc - 1) sbuf_printf(failedpkgs, ", "); failedpkgcount++; continue; } } if ((retcode = pkg_add(db, file, f, keys, location)) != EPKG_OK) { sbuf_cat(failedpkgs, argv[i]); if (i != argc - 1) sbuf_printf(failedpkgs, ", "); failedpkgcount++; } if (is_url(argv[i]) == EPKG_OK) unlink(file); } pkg_manifest_keys_free(keys); pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE); pkgdb_close(db); if(failedpkgcount > 0) { sbuf_finish(failedpkgs); printf("\nFailed to install the following %d package(s): %s\n", failedpkgcount, sbuf_data(failedpkgs)); retcode = EPKG_FATAL; } sbuf_delete(failedpkgs); if (messages != NULL) { sbuf_finish(messages); printf("%s", sbuf_data(messages)); } return (retcode == EPKG_OK ? EX_OK : EX_SOFTWARE); }
static void pr_header(time_t *nowp, int nusers) { double avenrun[3]; time_t uptime; struct timespec tp; int days, hrs, i, mins, secs; char buf[256]; struct sbuf *upbuf; upbuf = sbuf_new_auto(); /* * Print time of day. */ if (strftime(buf, sizeof(buf), use_ampm ? "%l:%M%p" : "%k:%M", localtime(nowp)) != 0) xo_emit("{:time-of-day/%s} ", buf); /* * Print how long system has been up. */ if (clock_gettime(CLOCK_UPTIME, &tp) != -1) { uptime = tp.tv_sec; if (uptime > 60) uptime += 30; days = uptime / 86400; uptime %= 86400; hrs = uptime / 3600; uptime %= 3600; mins = uptime / 60; secs = uptime % 60; xo_emit(" up"); xo_emit("{e:uptime/%lu}", (unsigned long) tp.tv_sec); xo_emit("{e:days/%d}{e:hours/%d}{e:minutes/%d}{e:seconds/%d}", days, hrs, mins, secs); if (days > 0) sbuf_printf(upbuf, " %d day%s,", days, days > 1 ? "s" : ""); if (hrs > 0 && mins > 0) sbuf_printf(upbuf, " %2d:%02d,", hrs, mins); else if (hrs > 0) sbuf_printf(upbuf, " %d hr%s,", hrs, hrs > 1 ? "s" : ""); else if (mins > 0) sbuf_printf(upbuf, " %d min%s,", mins, mins > 1 ? "s" : ""); else sbuf_printf(upbuf, " %d sec%s,", secs, secs > 1 ? "s" : ""); if (sbuf_finish(upbuf) != 0) xo_err(1, "Could not generate output"); xo_emit("{:uptime-human/%s}", sbuf_data(upbuf)); sbuf_delete(upbuf); } /* Print number of users logged in to system */ xo_emit(" {:users/%d} {N:user%s}", nusers, nusers == 1 ? "" : "s"); /* * Print 1, 5, and 15 minute load averages. */ if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) == -1) xo_emit(", no load average information available\n"); else { static const char *format[] = { " {:load-average-1/%.2f}", " {:load-average-5/%.2f}", " {:load-average-15/%.2f}", }; xo_emit(", load averages:"); for (i = 0; i < (int)(sizeof(avenrun) / sizeof(avenrun[0])); i++) { if (use_comma && i > 0) xo_emit(","); xo_emit(format[i], avenrun[i]); } xo_emit("\n"); } }
static int pkg_create_from_dir(struct pkg *pkg, const char *root, struct packing *pkg_archive) { char fpath[MAXPATHLEN]; struct pkg_file *file = NULL; struct pkg_dir *dir = NULL; char *m; int ret; const char *mtree; bool developer; struct stat st; char sha256[SHA256_DIGEST_LENGTH * 2 + 1]; int64_t flatsize = 0; const ucl_object_t *obj, *an; struct hardlinks *hardlinks = NULL; if (pkg_is_valid(pkg) != EPKG_OK) { pkg_emit_error("the package is not valid"); return (EPKG_FATAL); } pkg_get(pkg, PKG_ANNOTATIONS, &an); obj = pkg_object_find(an, "relocated"); /* * Get / compute size / checksum if not provided in the manifest */ while (pkg_files(pkg, &file) == EPKG_OK) { const char *pkg_path = pkg_file_path(file); const char *pkg_sum = pkg_file_cksum(file); snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "", obj ? pkg_object_string(obj) : "", pkg_path); if (lstat(fpath, &st) == -1) { pkg_emit_error("file '%s' is missing", fpath); return (EPKG_FATAL); } if (file->size == 0) file->size = (int64_t)st.st_size; if (st.st_nlink == 1 || !check_for_hardlink(hardlinks, &st)) { flatsize += file->size; } if (S_ISLNK(st.st_mode)) { if (pkg_sum == NULL || pkg_sum[0] == '\0') { if (pkg_symlink_cksum(fpath, root, sha256) == EPKG_OK) strlcpy(file->sum, sha256, sizeof(file->sum)); else return (EPKG_FATAL); } } else { if (pkg_sum == NULL || pkg_sum[0] == '\0') { if (pkg->type == PKG_OLD_FILE) { if (md5_file(fpath, sha256) != EPKG_OK) return (EPKG_FATAL); } else { if (sha256_file(fpath, sha256) != EPKG_OK) return (EPKG_FATAL); } strlcpy(file->sum, sha256, sizeof(file->sum)); } } } pkg_set(pkg, PKG_FLATSIZE, flatsize); HASH_FREE(hardlinks, free); if (pkg->type == PKG_OLD_FILE) { const char *desc, *display, *comment; char oldcomment[BUFSIZ]; pkg_old_emit_content(pkg, &m); packing_append_buffer(pkg_archive, m, "+CONTENTS", strlen(m)); free(m); pkg_get(pkg, PKG_DESC, &desc, PKG_MESSAGE, &display, PKG_COMMENT, &comment); packing_append_buffer(pkg_archive, desc, "+DESC", strlen(desc)); packing_append_buffer(pkg_archive, display, "+DISPLAY", strlen(display)); snprintf(oldcomment, sizeof(oldcomment), "%s\n", comment); packing_append_buffer(pkg_archive, oldcomment, "+COMMENT", strlen(oldcomment)); } else { /* * Register shared libraries used by the package if * SHLIBS enabled in conf. Deletes shlib info if not. */ struct sbuf *b = sbuf_new_auto(); pkg_register_shlibs(pkg, root); pkg_emit_manifest_sbuf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, NULL); packing_append_buffer(pkg_archive, sbuf_data(b), "+COMPACT_MANIFEST", sbuf_len(b)); sbuf_clear(b); pkg_emit_manifest_sbuf(pkg, b, 0, NULL); sbuf_finish(b); packing_append_buffer(pkg_archive, sbuf_data(b), "+MANIFEST", sbuf_len(b)); sbuf_delete(b); } pkg_get(pkg, PKG_MTREE, &mtree); if (mtree != NULL) packing_append_buffer(pkg_archive, mtree, "+MTREE_DIRS", strlen(mtree)); while (pkg_files(pkg, &file) == EPKG_OK) { const char *pkg_path = pkg_file_path(file); snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "", obj ? pkg_object_string(obj) : "", pkg_path); ret = packing_append_file_attr(pkg_archive, fpath, pkg_path, file->uname, file->gname, file->perm); developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE")); if (developer && ret != EPKG_OK) return (ret); } while (pkg_dirs(pkg, &dir) == EPKG_OK) { const char *pkg_path = pkg_dir_path(dir); snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "", obj ? pkg_object_string(obj) : "", pkg_path); ret = packing_append_file_attr(pkg_archive, fpath, pkg_path, dir->uname, dir->gname, dir->perm); developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE")); if (developer && ret != EPKG_OK) return (ret); } return (EPKG_OK); }
struct t_rename_pattern * t_rename_parse(const char *source) { const char sep = '%'; const char *c = source; struct t_rename_pattern *pattern = NULL; struct t_rename_token *token; struct sbuf *sb = NULL; enum { PARSING_STRING, PARSING_SIMPLE_TAG, PARSING_BRACE_TAG } state; sb = sbuf_new_auto(); if (sb == NULL) goto error_label; pattern = malloc(sizeof(struct t_rename_pattern)); if (pattern == NULL) goto error_label; TAILQ_INIT(pattern); state = PARSING_STRING; while (*c != '\0') { /* if we parse a litteral string, check if this is the start of a tag */ if (state == PARSING_STRING && *c == sep) { /* avoid to add a empty token. This can happen when when parsing two consecutive tags like `%tag%tag' */ if (sbuf_len(sb) > 0) { if (sbuf_finish(sb) == -1) goto error_label; token = t_rename_token_new(T_STRING, sbuf_data(sb)); if (token == NULL) goto error_label; TAILQ_INSERT_TAIL(pattern, token, entries); } sbuf_clear(sb); c += 1; if (*c == '{') { c += 1; state = PARSING_BRACE_TAG; } else { state = PARSING_SIMPLE_TAG; } /* if we parse a tag, check for the end of it */ } else if ((state == PARSING_SIMPLE_TAG && (*c == sep || !isalnum(*c))) || (state == PARSING_BRACE_TAG && *c == '}')) { if (sbuf_len(sb) == 0) warnx("empty tag in rename pattern"); if (sbuf_finish(sb) == -1) goto error_label; token = t_rename_token_new(T_TAG, sbuf_data(sb)); if (token == NULL) goto error_label; sbuf_clear(sb); TAILQ_INSERT_TAIL(pattern, token, entries); if (state == PARSING_BRACE_TAG) { /* eat the closing `}' */ c += 1; } state = PARSING_STRING; } else { /* default case for both string and tags. `\' escape everything */ if (*c == '\\') { c += 1; if (*c == '\0') break; } sbuf_putc(sb, *c); c += 1; } } /* we've hit the end of the source. Check in which state we are and try to finish cleany */ switch (state) { case PARSING_BRACE_TAG: warnx("missing closing `}' at the end of the rename pattern"); goto error_label; case PARSING_SIMPLE_TAG: if (sbuf_len(sb) == 0) warnx("empty tag at the end of the rename pattern"); case PARSING_STRING: /* FALLTHROUGH */ default: /* all is right */; } /* finish the last tag unless it is the empty string */ if (state != PARSING_STRING || sbuf_len(sb) > 0) { if (sbuf_finish(sb) == -1) goto error_label; token = t_rename_token_new( (state == PARSING_STRING ? T_STRING : T_TAG), sbuf_data(sb)); if (token == NULL) goto error_label; TAILQ_INSERT_TAIL(pattern, token, entries); } sbuf_delete(sb); return (pattern); /* NOTREACHED */ error_label: sbuf_delete(sb); t_rename_pattern_delete(pattern); return (NULL); }
char * t_rename_eval(struct t_tune *tune, const struct t_rename_pattern *pattern) { struct t_rename_token *token; struct sbuf *sb = NULL; struct t_taglist *tlist = NULL, *l = NULL; char *s = NULL, *ret; assert(tune != NULL); assert(pattern != NULL); sb = sbuf_new_auto(); if (sb == NULL) goto error; tlist = t_tune_tags(tune); if (tlist == NULL) goto error; TAILQ_FOREACH(token, pattern, entries) { if (token->is_tag) { l = t_taglist_find_all(tlist, token->value); if (l == NULL) goto error; if (l->count > 0) { /* tag exist */ if ((s = t_taglist_join(l, " + ")) == NULL) goto error; if (l->count > 1) { warnx("%s: has many `%s' tags, joined with `+'", t_tune_path(tune), token->value); } } t_taglist_delete(l); l = NULL; if (s != NULL) { char *slash = strchr(s, '/'); /* check for slash in tag value */ if (slash != NULL) { warnx("%s: tag `%s' has / in value, replacing by `-'", t_tune_path(tune), token->value); do { *slash = '-'; slash = strchr(slash, '/'); } while (slash != NULL); } } } if (s != NULL) { (void)sbuf_cat(sb, s); free(s); s = NULL; } else (void)sbuf_cat(sb, token->value); } ret = NULL; if (sbuf_len(sb) > MAXPATHLEN) warnx("t_rename_eval result is too long (>MAXPATHLEN)"); else { if (sbuf_finish(sb) != -1) ret = strdup(sbuf_data(sb)); } sbuf_delete(sb); t_taglist_delete(tlist); return (ret); error: free(s); t_taglist_delete(l); sbuf_delete(sb); t_taglist_delete(tlist); return (NULL); }
static void config_parse(const ucl_object_t *obj, pkg_conf_file_t conftype) { struct sbuf *buf = sbuf_new_auto(); const ucl_object_t *cur, *seq; ucl_object_iter_t it = NULL, itseq = NULL; struct config_entry *temp_config; struct config_value *cv; const char *key; int i; size_t j; /* Temporary config for configs that may be disabled. */ temp_config = calloc(CONFIG_SIZE, sizeof(struct config_entry)); while ((cur = ucl_iterate_object(obj, &it, true))) { key = ucl_object_key(cur); if (key == NULL) continue; sbuf_clear(buf); if (conftype == CONFFILE_PKG) { for (j = 0; j < strlen(key); ++j) sbuf_putc(buf, key[j]); sbuf_finish(buf); } else if (conftype == CONFFILE_REPO) { if (strcasecmp(key, "url") == 0) sbuf_cpy(buf, "PACKAGESITE"); else if (strcasecmp(key, "mirror_type") == 0) sbuf_cpy(buf, "MIRROR_TYPE"); else if (strcasecmp(key, "signature_type") == 0) sbuf_cpy(buf, "SIGNATURE_TYPE"); else if (strcasecmp(key, "fingerprints") == 0) sbuf_cpy(buf, "FINGERPRINTS"); else if (strcasecmp(key, "enabled") == 0) { if ((cur->type != UCL_BOOLEAN) || !ucl_object_toboolean(cur)) goto cleanup; } else continue; sbuf_finish(buf); } for (i = 0; i < CONFIG_SIZE; i++) { if (strcmp(sbuf_data(buf), c[i].key) == 0) break; } /* Silently skip unknown keys to be future compatible. */ if (i == CONFIG_SIZE) continue; /* env has priority over config file */ if (c[i].envset) continue; /* Parse sequence value ["item1", "item2"] */ switch (c[i].type) { case PKG_CONFIG_LIST: if (cur->type != UCL_ARRAY) { warnx("Skipping invalid array " "value for %s.\n", c[i].key); continue; } temp_config[i].list = malloc(sizeof(*temp_config[i].list)); STAILQ_INIT(temp_config[i].list); while ((seq = ucl_iterate_object(cur, &itseq, true))) { if (seq->type != UCL_STRING) continue; cv = malloc(sizeof(struct config_value)); cv->value = strdup(ucl_object_tostring(seq)); STAILQ_INSERT_TAIL(temp_config[i].list, cv, next); } break; case PKG_CONFIG_BOOL: temp_config[i].value = strdup(ucl_object_toboolean(cur) ? "yes" : "no"); break; default: /* Normal string value. */ temp_config[i].value = strdup(ucl_object_tostring(cur)); break; } } /* Repo is enabled, copy over all settings from temp_config. */ for (i = 0; i < CONFIG_SIZE; i++) { if (c[i].envset) continue; /* Prevent overriding ABI, ASSUME_ALWAYS_YES, etc. */ if (conftype != CONFFILE_PKG && c[i].main_only == true) continue; switch (c[i].type) { case PKG_CONFIG_LIST: c[i].list = temp_config[i].list; break; default: c[i].value = temp_config[i].value; break; } } cleanup: free(temp_config); sbuf_delete(buf); }
void procstat_cs(struct procstat *procstat, struct kinfo_proc *kipp) { cpusetid_t cs; cpuset_t mask; struct kinfo_proc *kip; struct sbuf *cpusetbuf; unsigned int count, i; int once, twice, lastcpu, cpu; if ((procstat_opts & PS_OPT_NOHEADER) == 0) xo_emit("{T:/%5s %6s %-19s %-19s %2s %4s %-7s}\n", "PID", "TID", "COMM", "TDNAME", "CPU", "CSID", "CPU MASK"); kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD, kipp->ki_pid, &count); if (kip == NULL) return; kinfo_proc_sort(kip, count); for (i = 0; i < count; i++) { kipp = &kip[i]; xo_emit("{k:process_id/%5d/%d} ", kipp->ki_pid); xo_emit("{:thread_id/%6d/%d} ", kipp->ki_tid); xo_emit("{:command/%-19s/%s} ", strlen(kipp->ki_comm) ? kipp->ki_comm : "-"); xo_emit("{:thread_name/%-19s/%s} ", kinfo_proc_thread_name(kipp)); if (kipp->ki_oncpu != 255) xo_emit("{:cpu/%3d/%d} ", kipp->ki_oncpu); else if (kipp->ki_lastcpu != 255) xo_emit("{:cpu/%3d/%d} ", kipp->ki_lastcpu); else xo_emit("{:cpu/%3s/%s} ", "-"); if (cpuset_getid(CPU_LEVEL_CPUSET, CPU_WHICH_TID, kipp->ki_tid, &cs) != 0) { cs = CPUSET_INVALID; } xo_emit("{:cpu_set_id/%4d/%d} ", cs); if ((cs != CPUSET_INVALID) && (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, kipp->ki_tid, sizeof(mask), &mask) == 0)) { lastcpu = -1; once = 0; twice = 0; cpusetbuf = sbuf_new_auto(); for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { if (CPU_ISSET(cpu, &mask)) { if (once == 0) { sbuf_printf(cpusetbuf, "%d", cpu); once = 1; } else if (cpu == lastcpu + 1) { twice = 1; } else if (twice == 1) { sbuf_printf(cpusetbuf, "-%d,%d", lastcpu, cpu); twice = 0; } else sbuf_printf(cpusetbuf, ",%d", cpu); lastcpu = cpu; } } if (once && twice) sbuf_printf(cpusetbuf, "-%d", lastcpu); if (sbuf_finish(cpusetbuf) != 0) xo_err(1, "Could not generate output"); xo_emit("{:cpu_set/%s}", sbuf_data(cpusetbuf)); sbuf_delete(cpusetbuf); } xo_emit("\n"); } procstat_freeprocs(procstat, kip); }
static void pipeevent(struct pkg_event *ev) { struct pkg *pkg = NULL; struct pkg_dep *dep = NULL; struct sbuf *msg, *buf; const char *message; const char *name, *version, *newversion; if (eventpipe < 0) return; msg = sbuf_new_auto(); buf = sbuf_new_auto(); switch(ev->type) { case PKG_EVENT_ERRNO: sbuf_printf(msg, "{ \"type\": \"ERROR\", " "\"data\": {" "\"msg\": \"%s(%s): %s\"," "\"errno\": %d}}", sbuf_json_escape(buf, ev->e_errno.func), sbuf_json_escape(buf, ev->e_errno.arg), sbuf_json_escape(buf, strerror(ev->e_errno.no)), ev->e_errno.no); break; case PKG_EVENT_ERROR: sbuf_printf(msg, "{ \"type\": \"ERROR\", " "\"data\": {\"msg\": \"%s\"}}", sbuf_json_escape(buf, ev->e_pkg_error.msg)); break; case PKG_EVENT_DEVELOPER_MODE: sbuf_printf(msg, "{ \"type\": \"ERROR\", " "\"data\": {\"msg\": \"DEVELOPER_MODE: %s\"}}", sbuf_json_escape(buf, ev->e_pkg_error.msg)); break; case PKG_EVENT_FETCHING: sbuf_printf(msg, "{ \"type\": \"INFO_FETCH\", " "\"data\": { " "\"url\": \"%s\", " "\"fetched\": %" PRId64 ", " "\"total\": %" PRId64 "}}", sbuf_json_escape(buf, ev->e_fetching.url), ev->e_fetching.done, ev->e_fetching.total ); break; case PKG_EVENT_INSTALL_BEGIN: pkg_get(ev->e_install_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_BEGIN\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\"" "}}", name, version ); break; case PKG_EVENT_INSTALL_FINISHED: pkg_get(ev->e_install_finished.pkg, PKG_MESSAGE, &message, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_FINISHED\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\", " "\"message\": \"%s\"" "}}", name, version, sbuf_json_escape(buf, message)); break; case PKG_EVENT_INTEGRITYCHECK_BEGIN: sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_BEGIN\", " "\"data\": {}}"); break; case PKG_EVENT_INTEGRITYCHECK_FINISHED: sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_FINISHED\", " "\"data\": {}}"); break; case PKG_EVENT_DEINSTALL_BEGIN: pkg_get(ev->e_deinstall_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_BEGIN\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\"" "}}", name, version); break; case PKG_EVENT_DEINSTALL_FINISHED: pkg_get(ev->e_deinstall_finished.pkg, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_FINISHED\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\"" "}}", name, version); break; case PKG_EVENT_UPGRADE_BEGIN: pkg_get(ev->e_upgrade_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version, PKG_NEWVERSION, &newversion); sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_BEGIN\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\" ," "\"pkgnewversion\": \"%s\"" "}}", name, version, newversion); break; case PKG_EVENT_UPGRADE_FINISHED: pkg_get(ev->e_upgrade_finished.pkg, PKG_NAME, &name, PKG_VERSION, &version, PKG_NEWVERSION, &newversion); sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_FINISHED\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\" ," "\"pkgnewversion\": \"%s\"" "}}", name, version, newversion); break; case PKG_EVENT_LOCKED: pkg_get(ev->e_locked.pkg, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"ERROR_LOCKED\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\"" "}}", name, version); break; case PKG_EVENT_REQUIRED: pkg_get(ev->e_required.pkg, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"ERROR_REQUIRED\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\", " "\"force\": %s, " "\"required_by\": [", name, version, ev->e_required.force == 1 ? "true": "false"); while (pkg_rdeps(pkg, &dep) == EPKG_OK) sbuf_printf(msg, "{ \"pkgname\": \"%s\", " "\"pkgversion\": \"%s\" }, ", pkg_dep_name(dep), pkg_dep_version(dep)); sbuf_setpos(msg, sbuf_len(msg) - 2); sbuf_cat(msg, "]}}"); break; case PKG_EVENT_ALREADY_INSTALLED: pkg_get(ev->e_already_installed.pkg, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"ERROR_ALREADY_INSTALLED\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\"" "}}", name, version); break; case PKG_EVENT_MISSING_DEP: sbuf_printf(msg, "{ \"type\": \"ERROR_MISSING_DEP\", " "\"data\": { " "\"depname\": \"%s\", " "\"depversion\": \"%s\"" "}}" , pkg_dep_name(ev->e_missing_dep.dep), pkg_dep_version(ev->e_missing_dep.dep)); break; case PKG_EVENT_NOREMOTEDB: sbuf_printf(msg, "{ \"type\": \"ERROR_NOREMOTEDB\", " "\"data\": { " "\"url\": \"%s\" " "}}" , ev->e_remotedb.repo); break; case PKG_EVENT_NOLOCALDB: sbuf_printf(msg, "{ \"type\": \"ERROR_NOLOCALDB\", " "\"data\": {} "); break; case PKG_EVENT_NEWPKGVERSION: sbuf_printf(msg, "{ \"type\": \"INFO_NEWPKGVERSION\", " "\"data\": {} "); break; case PKG_EVENT_FILE_MISMATCH: pkg_get(ev->e_file_mismatch.pkg, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"ERROR_FILE_MISMATCH\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\", " "\"path\": \"%s\"" "}}", name, version, sbuf_json_escape(buf, pkg_file_path(ev->e_file_mismatch.file))); break; case PKG_EVENT_PLUGIN_ERRNO: sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", " "\"data\": {" "\"plugin\": \"%s\", " "\"msg\": \"%s(%s): %s\"," "\"errno\": %d" "}}", pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME), sbuf_json_escape(buf, ev->e_plugin_errno.func), sbuf_json_escape(buf, ev->e_plugin_errno.arg), sbuf_json_escape(buf, strerror(ev->e_plugin_errno.no)), ev->e_plugin_errno.no); break; case PKG_EVENT_PLUGIN_ERROR: sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", " "\"data\": {" "\"plugin\": \"%s\", " "\"msg\": \"%s\"" "}}", pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME), sbuf_json_escape(buf, ev->e_plugin_error.msg)); break; case PKG_EVENT_PLUGIN_INFO: sbuf_printf(msg, "{ \"type\": \"INFO_PLUGIN\", " "\"data\": {" "\"plugin\": \"%s\", " "\"msg\": \"%s\"" "}}", pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME), sbuf_json_escape(buf, ev->e_plugin_info.msg)); break; default: break; } sbuf_finish(msg); dprintf(eventpipe, "%s\n", sbuf_data(msg)); sbuf_delete(msg); sbuf_delete(buf); }
/* * Produce a readable status description */ static int text_status(node_p node, struct priv *priv, char *arg, u_int len) { struct sbuf sbuf; sbuf_new(&sbuf, arg, len, 0); if (priv->upper) sbuf_printf(&sbuf, "upper hook: %s connected to %s:%s\n", NG_HOOK_NAME(priv->upper), NG_NODE_NAME(NG_HOOK_NODE(NG_HOOK_PEER(priv->upper))), NG_HOOK_NAME(NG_HOOK_PEER(priv->upper))); else sbuf_printf(&sbuf, "upper hook: <not connected>\n"); if (priv->lower) sbuf_printf(&sbuf, "lower hook: %s connected to %s:%s\n", NG_HOOK_NAME(priv->lower), NG_NODE_NAME(NG_HOOK_NODE(NG_HOOK_PEER(priv->lower))), NG_HOOK_NAME(NG_HOOK_PEER(priv->lower))); else sbuf_printf(&sbuf, "lower hook: <not connected>\n"); if (priv->manage) sbuf_printf(&sbuf, "manage hook: %s connected to %s:%s\n", NG_HOOK_NAME(priv->manage), NG_NODE_NAME(NG_HOOK_NODE(NG_HOOK_PEER(priv->manage))), NG_HOOK_NAME(NG_HOOK_PEER(priv->manage))); else sbuf_printf(&sbuf, "manage hook: <not connected>\n"); sbuf_printf(&sbuf, "sscop state: %s\n", !priv->enabled ? "<disabled>" : sscop_statename(sscop_getstate(priv->sscop))); sbuf_printf(&sbuf, "input packets: %ju\n", (uintmax_t)priv->stats.in_packets); sbuf_printf(&sbuf, "input dropped: %ju\n", (uintmax_t)priv->stats.in_dropped); sbuf_printf(&sbuf, "output packets: %ju\n", (uintmax_t)priv->stats.out_packets); sbuf_printf(&sbuf, "output dropped: %ju\n", (uintmax_t)priv->stats.out_dropped); sbuf_printf(&sbuf, "aa signals: %ju\n", (uintmax_t)priv->stats.aa_signals); sbuf_printf(&sbuf, "aa dropped: %ju\n", (uintmax_t)priv->stats.aa_dropped); sbuf_printf(&sbuf, "maa signals: %ju\n", (uintmax_t)priv->stats.maa_signals); sbuf_printf(&sbuf, "maa dropped: %ju\n", (uintmax_t)priv->stats.maa_dropped); sbuf_printf(&sbuf, "errors: %ju\n", (uintmax_t)priv->stats.errors); sbuf_printf(&sbuf, "data delivered: %ju\n", (uintmax_t)priv->stats.data_delivered); sbuf_printf(&sbuf, "window: %u\n", sscop_window(priv->sscop, 0)); sbuf_finish(&sbuf); return (sbuf_len(&sbuf)); }
int sys_abort2(struct thread *td, struct abort2_args *uap) { struct proc *p = td->td_proc; struct sbuf *sb; void *uargs[16]; int error, i, sig; /* * Do it right now so we can log either proper call of abort2(), or * note, that invalid argument was passed. 512 is big enough to * handle 16 arguments' descriptions with additional comments. */ sb = sbuf_new(NULL, NULL, 512, SBUF_FIXEDLEN); sbuf_clear(sb); sbuf_printf(sb, "%s(pid %d uid %d) aborted: ", p->p_comm, p->p_pid, td->td_ucred->cr_uid); /* * Since we can't return from abort2(), send SIGKILL in cases, where * abort2() was called improperly */ sig = SIGKILL; /* Prevent from DoSes from user-space. */ if (uap->nargs < 0 || uap->nargs > 16) goto out; if (uap->nargs > 0) { if (uap->args == NULL) goto out; error = copyin(uap->args, uargs, uap->nargs * sizeof(void *)); if (error != 0) goto out; } /* * Limit size of 'reason' string to 128. Will fit even when * maximal number of arguments was chosen to be logged. */ if (uap->why != NULL) { error = sbuf_copyin(sb, uap->why, 128); if (error < 0) goto out; } else { sbuf_printf(sb, "(null)"); } if (uap->nargs > 0) { sbuf_printf(sb, "("); for (i = 0;i < uap->nargs; i++) sbuf_printf(sb, "%s%p", i == 0 ? "" : ", ", uargs[i]); sbuf_printf(sb, ")"); } /* * Final stage: arguments were proper, string has been * successfully copied from userspace, and copying pointers * from user-space succeed. */ sig = SIGABRT; out: if (sig == SIGKILL) { sbuf_trim(sb); sbuf_printf(sb, " (Reason text inaccessible)"); } sbuf_cat(sb, "\n"); sbuf_finish(sb); log(LOG_INFO, "%s", sbuf_data(sb)); sbuf_delete(sb); exit1(td, W_EXITCODE(0, sig)); return (0); }
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); }
/* * Read from a file */ static int pfs_read(struct vop_read_args *va) { struct vnode *vn = va->a_vp; struct pfs_vdata *pvd = vn->v_data; struct pfs_node *pn = pvd->pvd_pn; struct uio *uio = va->a_uio; struct proc *proc; struct sbuf *sb = NULL; int error, locked; unsigned int buflen, offset, resid; PFS_TRACE(("%s", pn->pn_name)); pfs_assert_not_owned(pn); if (vn->v_type != VREG) PFS_RETURN (EINVAL); KASSERT_PN_IS_FILE(pn); if (!(pn->pn_flags & PFS_RD)) PFS_RETURN (EBADF); if (pn->pn_fill == NULL) PFS_RETURN (EIO); /* * This is necessary because either process' privileges may * have changed since the open() call. */ if (!pfs_visible(curthread, pn, pvd->pvd_pid, &proc)) PFS_RETURN (EIO); if (proc != NULL) { _PHOLD(proc); PROC_UNLOCK(proc); } vhold(vn); locked = VOP_ISLOCKED(vn); VOP_UNLOCK(vn, 0); if (pn->pn_flags & PFS_RAWRD) { PFS_TRACE(("%zd resid", uio->uio_resid)); error = pn_fill(curthread, proc, pn, NULL, uio); PFS_TRACE(("%zd resid", uio->uio_resid)); goto ret; } /* beaucoup sanity checks so we don't ask for bogus allocation */ if (uio->uio_offset < 0 || uio->uio_resid < 0 || (offset = uio->uio_offset) != uio->uio_offset || (resid = uio->uio_resid) != uio->uio_resid || (buflen = offset + resid + 1) < offset || buflen > INT_MAX) { if (proc != NULL) PRELE(proc); error = EINVAL; goto ret; } if (buflen > MAXPHYS + 1) buflen = MAXPHYS + 1; sb = sbuf_new(sb, NULL, buflen, 0); if (sb == NULL) { error = EIO; goto ret; } error = pn_fill(curthread, proc, pn, sb, uio); if (error) { sbuf_delete(sb); goto ret; } sbuf_finish(sb); error = uiomove_frombuf(sbuf_data(sb), sbuf_len(sb), uio); sbuf_delete(sb); ret: vn_lock(vn, locked | LK_RETRY); vdrop(vn); if (proc != NULL) PRELE(proc); PFS_RETURN (error); }
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 = (sizeof(accepted_rquery_flags)/sizeof(accepted_rquery_flags[0])); const char *reponame = NULL; bool auto_update; bool onematched = false; bool old_quiet; bool index_output = false; auto_update = pkg_object_bool(pkg_config_get("REPO_AUTOUPDATE")); portsdir = pkg_object_string(pkg_config_get("PORTSDIR")); /* Set default case sensitivity for searching */ pkgdb_set_case_sensitivity( pkg_object_bool(pkg_config_get("CASE_SENSITIVE_MATCH")) ); while ((ch = getopt(argc, argv, "aCgiIxe:r:U")) != -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': index_output = true; 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 && !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, 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; 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) { 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_rquery(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_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 write_userconfig(struct userconf *cnf, const char *file) { int fd; int i, j; struct sbuf *buf; FILE *fp; if (file == NULL) file = _PATH_PW_CONF; if ((fd = open(file, O_CREAT|O_RDWR|O_TRUNC|O_EXLOCK, 0644)) == -1) return (0); if ((fp = fdopen(fd, "w")) == NULL) { close(fd); return (0); } buf = sbuf_new_auto(); for (i = _UC_NONE; i < _UC_FIELDS; i++) { int quote = 1; sbuf_clear(buf); switch (i) { case _UC_DEFAULTPWD: sbuf_cat(buf, boolean_str(cnf->default_password)); break; case _UC_REUSEUID: sbuf_cat(buf, boolean_str(cnf->reuse_uids)); break; case _UC_REUSEGID: sbuf_cat(buf, boolean_str(cnf->reuse_gids)); break; case _UC_NISPASSWD: sbuf_cat(buf, cnf->nispasswd ? cnf->nispasswd : ""); quote = 0; break; case _UC_DOTDIR: sbuf_cat(buf, cnf->dotdir ? cnf->dotdir : boolean_str(0)); break; case _UC_NEWMAIL: sbuf_cat(buf, cnf->newmail ? cnf->newmail : boolean_str(0)); break; case _UC_LOGFILE: sbuf_cat(buf, cnf->logfile ? cnf->logfile : boolean_str(0)); break; case _UC_HOMEROOT: sbuf_cat(buf, cnf->home); break; case _UC_HOMEMODE: sbuf_printf(buf, "%04o", cnf->homemode); quote = 0; break; case _UC_SHELLPATH: sbuf_cat(buf, cnf->shelldir); break; case _UC_SHELLS: for (j = 0; j < _UC_MAXSHELLS && system_shells[j] != NULL; j++) sbuf_printf(buf, "%s\"%s\"", j ? "," : "", system_shells[j]); quote = 0; break; case _UC_DEFAULTSHELL: sbuf_cat(buf, cnf->shell_default ? cnf->shell_default : bourne_shell); break; case _UC_DEFAULTGROUP: sbuf_cat(buf, cnf->default_group ? cnf->default_group : ""); break; case _UC_EXTRAGROUPS: for (j = 0; cnf->groups != NULL && j < (int)cnf->groups->sl_cur; j++) sbuf_printf(buf, "%s\"%s\"", j ? "," : "", cnf->groups->sl_str[j]); quote = 0; break; case _UC_DEFAULTCLASS: sbuf_cat(buf, cnf->default_class ? cnf->default_class : ""); break; case _UC_MINUID: sbuf_printf(buf, "%ju", (uintmax_t)cnf->min_uid); quote = 0; break; case _UC_MAXUID: sbuf_printf(buf, "%ju", (uintmax_t)cnf->max_uid); quote = 0; break; case _UC_MINGID: sbuf_printf(buf, "%ju", (uintmax_t)cnf->min_gid); quote = 0; break; case _UC_MAXGID: sbuf_printf(buf, "%ju", (uintmax_t)cnf->max_gid); quote = 0; break; case _UC_EXPIRE: sbuf_printf(buf, "%jd", (intmax_t)cnf->expire_days); quote = 0; break; case _UC_PASSWORD: sbuf_printf(buf, "%jd", (intmax_t)cnf->password_days); quote = 0; break; case _UC_NONE: break; } sbuf_finish(buf); if (comments[i]) fputs(comments[i], fp); if (*kwds[i]) { if (quote) fprintf(fp, "%s = \"%s\"\n", kwds[i], sbuf_data(buf)); else fprintf(fp, "%s = %s\n", kwds[i], sbuf_data(buf)); #if debugging printf("WROTE: %s = %s\n", kwds[i], sbuf_data(buf)); #endif } } sbuf_delete(buf); return (fclose(fp) != EOF); }
static void format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, void *data) { bool automatic; bool locked; sbuf_clear(dest); while (qstr[0] != '\0') { if (qstr[0] == '%') { qstr++; switch (qstr[0]) { case 'n': pkg_sbuf_printf(dest, "%n", pkg); break; case 'v': pkg_sbuf_printf(dest, "%v", pkg); break; case 'o': pkg_sbuf_printf(dest, "%o", pkg); break; case 'R': pkg_sbuf_printf(dest, "%N", pkg); break; case 'p': pkg_sbuf_printf(dest, "%p", pkg); break; case 'm': pkg_sbuf_printf(dest, "%m", pkg); break; case 'c': pkg_sbuf_printf(dest, "%c", pkg); break; case 'w': pkg_sbuf_printf(dest, "%w", pkg); break; case 'a': pkg_get(pkg, PKG_AUTOMATIC, &automatic); sbuf_printf(dest, "%d", automatic); break; case 'k': pkg_get(pkg, PKG_LOCKED, &locked); sbuf_printf(dest, "%d", locked); break; case 't': pkg_sbuf_printf(dest, "%t", pkg); break; case 's': qstr++; if (qstr[0] == 'h') pkg_sbuf_printf(dest, "%?sB", pkg); else if (qstr[0] == 'b') pkg_sbuf_printf(dest, "%s", pkg); break; case 'e': pkg_sbuf_printf(dest, "%e", pkg); break; case '?': qstr++; switch (qstr[0]) { case 'd': pkg_sbuf_printf(dest, "%?d", pkg); break; case 'r': pkg_sbuf_printf(dest, "%?r", pkg); break; case 'C': pkg_sbuf_printf(dest, "%?C", pkg); break; case 'F': pkg_sbuf_printf(dest, "%?F", pkg); break; case 'O': pkg_sbuf_printf(dest, "%?O", pkg); break; case 'D': pkg_sbuf_printf(dest, "%?D", pkg); break; case 'L': pkg_sbuf_printf(dest, "%?L", pkg); break; case 'U': pkg_sbuf_printf(dest, "%?U", pkg); break; case 'G': pkg_sbuf_printf(dest, "%?G", pkg); break; case 'B': pkg_sbuf_printf(dest, "%?B", pkg); break; case 'b': pkg_sbuf_printf(dest, "%?b", pkg); break; case 'A': pkg_sbuf_printf(dest, "%?A", pkg); break; } break; case '#': qstr++; switch (qstr[0]) { case 'd': pkg_sbuf_printf(dest, "%#d", pkg); break; case 'r': pkg_sbuf_printf(dest, "%#r", pkg); break; case 'C': pkg_sbuf_printf(dest, "%#C", pkg); break; case 'F': pkg_sbuf_printf(dest, "%#F", pkg); break; case 'O': pkg_sbuf_printf(dest, "%#O", pkg); break; case 'D': pkg_sbuf_printf(dest, "%#D", pkg); break; case 'L': pkg_sbuf_printf(dest, "%#L", pkg); break; case 'U': pkg_sbuf_printf(dest, "%#U", pkg); break; case 'G': pkg_sbuf_printf(dest, "%#G", pkg); break; case 'B': pkg_sbuf_printf(dest, "%#B", pkg); break; case 'b': pkg_sbuf_printf(dest, "%#b", pkg); break; case 'A': pkg_sbuf_printf(dest, "%#A", pkg); break; } break; case 'q': pkg_sbuf_printf(dest, "%q", pkg); break; case 'l': pkg_sbuf_printf(dest, "%l", pkg); break; case 'd': qstr++; if (qstr[0] == 'n') pkg_sbuf_printf(dest, "%dn", data); else if (qstr[0] == 'o') pkg_sbuf_printf(dest, "%do", data); else if (qstr[0] == 'v') pkg_sbuf_printf(dest, "%dv", data); break; case 'r': qstr++; if (qstr[0] == 'n') pkg_sbuf_printf(dest, "%rn", data); else if (qstr[0] == 'o') pkg_sbuf_printf(dest, "%ro", data); else if (qstr[0] == 'v') pkg_sbuf_printf(dest, "%rv", data); break; case 'C': pkg_sbuf_printf(dest, "%Cn", data); break; case 'F': qstr++; if (qstr[0] == 'p') pkg_sbuf_printf(dest, "%Fn", data); else if (qstr[0] == 's') pkg_sbuf_printf(dest, "%Fs", data); break; case 'O': qstr++; if (qstr[0] == 'k') pkg_sbuf_printf(dest, "%On", data); else if (qstr[0] == 'v') pkg_sbuf_printf(dest, "%Ov", data); else if (qstr[0] == 'd') /* default value */ pkg_sbuf_printf(dest, "%Od", data); else if (qstr[0] == 'D') /* description */ pkg_sbuf_printf(dest, "%OD", data); break; case 'D': pkg_sbuf_printf(dest, "%Dn", data); break; case 'L': pkg_sbuf_printf(dest, "%Ln", data); break; case 'U': pkg_sbuf_printf(dest, "%Un", data); break; case 'G': pkg_sbuf_printf(dest, "%Gn", data); break; case 'B': pkg_sbuf_printf(dest, "%Bn", data); break; case 'b': pkg_sbuf_printf(dest, "%bn", data); break; case 'A': qstr++; if (qstr[0] == 't') pkg_sbuf_printf(dest, "%An", data); else if (qstr[0] == 'v') pkg_sbuf_printf(dest, "%Av", data); break; case 'M': if (pkg_has_message(pkg)) pkg_sbuf_printf(dest, "%M", pkg); break; case '%': sbuf_putc(dest, '%'); break; } } else if (qstr[0] == '\\') { qstr++; switch (qstr[0]) { case 'n': sbuf_putc(dest, '\n'); break; case 'a': sbuf_putc(dest, '\a'); break; case 'b': sbuf_putc(dest, '\b'); break; case 'f': sbuf_putc(dest, '\f'); break; case 'r': sbuf_putc(dest, '\r'); break; case '\\': sbuf_putc(dest, '\\'); break; case 't': sbuf_putc(dest, '\t'); break; } } else { sbuf_putc(dest, qstr[0]); } qstr++; } sbuf_finish(dest); }
int event_callback(void *data, struct pkg_event *ev) { struct pkg *pkg = NULL, *pkg_new, *pkg_old; int *debug = data; struct pkg_event_conflict *cur_conflict; const char *filename; if (msg_buf == NULL) { msg_buf = sbuf_new_auto(); } /* * If a progressbar has been interrupted by another event, then * we need to add a newline to prevent bad formatting. */ if (progress_started && ev->type != PKG_EVENT_PROGRESS_TICK && !progress_interrupted) { putchar('\n'); progress_interrupted = true; } switch(ev->type) { case PKG_EVENT_ERRNO: warnx("%s(%s): %s", ev->e_errno.func, ev->e_errno.arg, strerror(ev->e_errno.no)); break; case PKG_EVENT_ERROR: warnx("%s", ev->e_pkg_error.msg); break; case PKG_EVENT_NOTICE: if (!quiet) printf("%s\n", ev->e_pkg_notice.msg); break; case PKG_EVENT_DEVELOPER_MODE: warnx("DEVELOPER_MODE: %s", ev->e_pkg_error.msg); break; case PKG_EVENT_UPDATE_ADD: if (quiet || !isatty(STDOUT_FILENO)) break; printf("\rPushing new entries %d/%d", ev->e_upd_add.done, ev->e_upd_add.total); if (ev->e_upd_add.total == ev->e_upd_add.done) printf("\n"); break; case PKG_EVENT_UPDATE_REMOVE: if (quiet || !isatty(STDOUT_FILENO)) break; printf("\rRemoving entries %d/%d", ev->e_upd_remove.done, ev->e_upd_remove.total); if (ev->e_upd_remove.total == ev->e_upd_remove.done) printf("\n"); break; case PKG_EVENT_FETCH_BEGIN: if (quiet) break; filename = strrchr(ev->e_fetching.url, '/'); if (filename != NULL) { filename++; } else { /* * We failed at being smart, so display * the entire url. */ filename = ev->e_fetching.url; } job_status_begin(msg_buf); progress_debit = true; sbuf_printf(msg_buf, "Fetching %s", filename); break; case PKG_EVENT_FETCH_FINISHED: progress_debit = false; break; case PKG_EVENT_INSTALL_BEGIN: if (quiet) break; else { nbdone++; job_status_begin(msg_buf); pkg = ev->e_install_begin.pkg; pkg_sbuf_printf(msg_buf, "Installing %n-%v...\n", pkg, pkg); sbuf_finish(msg_buf); printf("%s", sbuf_data(msg_buf)); } break; case PKG_EVENT_INSTALL_FINISHED: if (quiet) break; pkg = ev->e_install_finished.pkg; if (pkg_has_message(pkg)) { if (messages == NULL) messages = sbuf_new_auto(); pkg_sbuf_printf(messages, "Message for %n-%v:\n%M\n", pkg, pkg, pkg); } break; case PKG_EVENT_EXTRACT_BEGIN: if (quiet) break; else { job_status_begin(msg_buf); pkg = ev->e_install_begin.pkg; pkg_sbuf_printf(msg_buf, "Extracting %n-%v", pkg, pkg); } break; case PKG_EVENT_EXTRACT_FINISHED: break; case PKG_EVENT_ADD_DEPS_BEGIN: ++add_deps_depth; break; case PKG_EVENT_ADD_DEPS_FINISHED: --add_deps_depth; break; case PKG_EVENT_INTEGRITYCHECK_BEGIN: if (quiet) break; printf("Checking integrity..."); break; case PKG_EVENT_INTEGRITYCHECK_FINISHED: if (quiet) break; printf(" done (%d conflicting)\n", ev->e_integrity_finished.conflicting); break; case PKG_EVENT_INTEGRITYCHECK_CONFLICT: if (*debug == 0) break; printf("\nConflict found on path %s between %s and ", ev->e_integrity_conflict.pkg_path, ev->e_integrity_conflict.pkg_uid); cur_conflict = ev->e_integrity_conflict.conflicts; while (cur_conflict) { if (cur_conflict->next) printf("%s, ", cur_conflict->uid); else printf("%s", cur_conflict->uid); cur_conflict = cur_conflict->next; } printf("\n"); break; case PKG_EVENT_DEINSTALL_BEGIN: if (quiet) break; nbdone++; job_status_begin(msg_buf); pkg = ev->e_install_begin.pkg; pkg_sbuf_printf(msg_buf, "Deinstalling %n-%v...\n", pkg, pkg); sbuf_finish(msg_buf); printf("%s", sbuf_data(msg_buf)); break; case PKG_EVENT_DEINSTALL_FINISHED: if (quiet) break; break; case PKG_EVENT_DELETE_FILES_BEGIN: if (quiet) break; else { job_status_begin(msg_buf); pkg = ev->e_install_begin.pkg; pkg_sbuf_printf(msg_buf, "Deleting files for %n-%v", pkg, pkg); } break; case PKG_EVENT_DELETE_FILES_FINISHED: break; case PKG_EVENT_UPGRADE_BEGIN: if (quiet) break; pkg_new = ev->e_upgrade_begin.n; pkg_old = ev->e_upgrade_begin.o; nbdone++; job_status_begin(msg_buf); switch (pkg_version_change_between(pkg_new, pkg_old)) { case PKG_DOWNGRADE: pkg_sbuf_printf(msg_buf, "Downgrading %n from %v to %v...\n", pkg_new, pkg_old, pkg_new); break; case PKG_REINSTALL: pkg_sbuf_printf(msg_buf, "Reinstalling %n-%v...\n", pkg_old, pkg_old); break; case PKG_UPGRADE: pkg_sbuf_printf(msg_buf, "Upgrading %n from %v to %v...\n", pkg_new, pkg_old, pkg_new); break; } sbuf_finish(msg_buf); printf("%s", sbuf_data(msg_buf)); break; case PKG_EVENT_UPGRADE_FINISHED: if (quiet) break; pkg_new = ev->e_upgrade_finished.n; if (pkg_has_message(pkg_new)) { if (messages == NULL) messages = sbuf_new_auto(); pkg_sbuf_printf(messages, "Message for %n-%v:\n %M\n", pkg_new, pkg_new, pkg_new); } break; case PKG_EVENT_LOCKED: pkg = ev->e_locked.pkg; pkg_printf("\n%n-%v is locked and may not be modified\n", pkg, pkg); break; case PKG_EVENT_REQUIRED: pkg = ev->e_required.pkg; pkg_printf("\n%n-%v is required by: %r%{%rn-%rv%| %}", pkg, pkg, pkg); if (ev->e_required.force == 1) fprintf(stderr, ", deleting anyway\n"); else fprintf(stderr, "\n"); break; case PKG_EVENT_ALREADY_INSTALLED: if (quiet) break; pkg = ev->e_already_installed.pkg; pkg_printf("the most recent version of %n-%v is already installed\n", pkg, pkg); break; case PKG_EVENT_NOT_FOUND: printf("Package '%s' was not found in " "the repositories\n", ev->e_not_found.pkg_name); break; case PKG_EVENT_MISSING_DEP: warnx("Missing dependency '%s-%s'", pkg_dep_name(ev->e_missing_dep.dep), pkg_dep_version(ev->e_missing_dep.dep)); break; case PKG_EVENT_NOREMOTEDB: fprintf(stderr, "Unable to open remote database \"%s\". " "Try running '%s update' first.\n", ev->e_remotedb.repo, getprogname()); break; case PKG_EVENT_NOLOCALDB: fprintf(stderr, "Local package database nonexistent!\n"); break; case PKG_EVENT_NEWPKGVERSION: newpkgversion = true; printf("New version of pkg detected; it needs to be " "installed first.\n"); break; case PKG_EVENT_FILE_MISMATCH: pkg = ev->e_file_mismatch.pkg; pkg_fprintf(stderr, "%n-%v: checksum mismatch for %Fn\n", pkg, pkg, ev->e_file_mismatch.file); break; case PKG_EVENT_PLUGIN_ERRNO: warnx("%s: %s(%s): %s", pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME), ev->e_plugin_errno.func, ev->e_plugin_errno.arg, strerror(ev->e_plugin_errno.no)); break; case PKG_EVENT_PLUGIN_ERROR: warnx("%s: %s", pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME), ev->e_plugin_error.msg); break; case PKG_EVENT_PLUGIN_INFO: if (quiet) break; printf("%s: %s\n", pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME), ev->e_plugin_info.msg); break; case PKG_EVENT_INCREMENTAL_UPDATE: if (!quiet) printf("%s repository update completed. %d packages processed.\n", ev->e_incremental_update.reponame, ev->e_incremental_update.processed); break; case PKG_EVENT_DEBUG: fprintf(stderr, "DBG(%d)[%d]> %s\n", ev->e_debug.level, (int)getpid(), ev->e_debug.msg); break; case PKG_EVENT_QUERY_YESNO: return ( ev->e_query_yesno.deft ? query_yesno(true, ev->e_query_yesno.msg, "[Y/n]") : query_yesno(false, ev->e_query_yesno.msg, "[y/N]") ); break; case PKG_EVENT_QUERY_SELECT: return query_select(ev->e_query_select.msg, ev->e_query_select.items, ev->e_query_select.ncnt, ev->e_query_select.deft); break; case PKG_EVENT_SANDBOX_CALL: return ( event_sandboxed_call(ev->e_sandbox_call.call, ev->e_sandbox_call.fd, ev->e_sandbox_call.userdata) ); break; case PKG_EVENT_SANDBOX_GET_STRING: return ( event_sandboxed_get_string(ev->e_sandbox_call_str.call, ev->e_sandbox_call_str.result, ev->e_sandbox_call_str.len, ev->e_sandbox_call_str.userdata) ); break; case PKG_EVENT_PROGRESS_START: progressbar_start(ev->e_progress_start.msg); break; case PKG_EVENT_PROGRESS_TICK: progressbar_tick(ev->e_progress_tick.current, ev->e_progress_tick.total); break; case PKG_EVENT_BACKUP: sbuf_cat(msg_buf, "Backing up"); sbuf_finish(msg_buf); break; case PKG_EVENT_RESTORE: sbuf_cat(msg_buf, "Restoring"); sbuf_finish(msg_buf); break; default: break; } return 0; }
/* mtree_resolve() sets errno to indicate why NULL was returned. */ static char * mtree_resolve(const char *spec, int *istemp) { struct sbuf *sb; char *res, *var = NULL; const char *base, *p, *v; size_t len; int c, error, quoted, subst; len = strlen(spec); if (len == 0) { errno = EINVAL; return (NULL); } c = (len > 1) ? (spec[0] == spec[len - 1]) ? spec[0] : 0 : 0; *istemp = (c == '`') ? 1 : 0; subst = (c == '`' || c == '"') ? 1 : 0; quoted = (subst || c == '\'') ? 1 : 0; if (!subst) { res = strdup(spec + quoted); if (res != NULL && quoted) res[len - 2] = '\0'; return (res); } sb = sbuf_new_auto(); if (sb == NULL) { errno = ENOMEM; return (NULL); } base = spec + 1; len -= 2; error = 0; while (len > 0) { p = strchr(base, '$'); if (p == NULL) { sbuf_bcat(sb, base, len); base += len; len = 0; continue; } /* The following is safe. spec always starts with a quote. */ if (p[-1] == '\\') p--; if (base != p) { sbuf_bcat(sb, base, p - base); len -= p - base; base = p; } if (*p == '\\') { sbuf_putc(sb, '$'); base += 2; len -= 2; continue; } /* Skip the '$'. */ base++; len--; /* Handle ${X} vs $X. */ v = base; if (*base == '{') { p = strchr(v, '}'); if (p == NULL) p = v; } else p = v; len -= (p + 1) - base; base = p + 1; if (v == p) { sbuf_putc(sb, *v); continue; } error = ENOMEM; var = calloc(p - v, 1); if (var == NULL) break; memcpy(var, v + 1, p - v - 1); if (strcmp(var, ".CURDIR") == 0) { res = getcwd(NULL, 0); if (res == NULL) break; } else if (strcmp(var, ".PROG") == 0) { res = strdup(getprogname()); if (res == NULL) break; } else { v = getenv(var); if (v != NULL) { res = strdup(v); if (res == NULL) break; } else res = NULL; } error = 0; if (res != NULL) { sbuf_cat(sb, res); free(res); } free(var); var = NULL; } free(var); sbuf_finish(sb); res = (error == 0) ? strdup(sbuf_data(sb)) : NULL; sbuf_delete(sb); if (res == NULL) errno = ENOMEM; return (res); }
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); }
void vfs_mountroot(void) { struct mount *mp; struct sbuf *sb; struct thread *td; time_t timebase; int error; td = curthread; vfs_mountroot_wait(); sb = sbuf_new_auto(); vfs_mountroot_conf0(sb); sbuf_finish(sb); error = vfs_mountroot_devfs(td, &mp); while (!error) { error = vfs_mountroot_parse(sb, mp); if (!error) { error = vfs_mountroot_shuffle(td, mp); if (!error) { sbuf_clear(sb); error = vfs_mountroot_readconf(td, sb); sbuf_finish(sb); } } } sbuf_delete(sb); /* * Iterate over all currently mounted file systems and use * the time stamp found to check and/or initialize the RTC. * Call inittodr() only once and pass it the largest of the * timestamps we encounter. */ timebase = 0; mtx_lock(&mountlist_mtx); mp = TAILQ_FIRST(&mountlist); while (mp != NULL) { if (mp->mnt_time > timebase) timebase = mp->mnt_time; mp = TAILQ_NEXT(mp, mnt_list); } mtx_unlock(&mountlist_mtx); inittodr(timebase); /* Keep prison0's root in sync with the global rootvnode. */ mtx_lock(&prison0.pr_mtx); prison0.pr_root = rootvnode; vref(prison0.pr_root); mtx_unlock(&prison0.pr_mtx); mtx_lock(&root_holds_mtx); atomic_store_rel_int(&root_mount_complete, 1); wakeup(&root_mount_complete); mtx_unlock(&root_holds_mtx); EVENTHANDLER_INVOKE(mountroot); }
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; bool yes = true, yes_arg = false; bool dry_run = false; bool auto_update; int done = 0; nbactions = nbdone = 0; pkg_flags f = PKG_FLAG_NONE | PKG_FLAG_PKG_VERSION_TEST; yes_arg = pkg_object_bool(pkg_config_get("ASSUME_ALWAYS_YES")); auto_update = pkg_object_bool(pkg_config_get("REPO_AUTOUPDATE")); while ((ch = getopt(argc, argv, "fInqFr:Uy")) != -1) { switch (ch) { case 'f': f |= PKG_FLAG_FORCE; break; case 'I': f |= PKG_FLAG_NOSCRIPT; break; case 'U': auto_update = false; break; case 'n': f |= PKG_FLAG_DRY_RUN; lock_type = PKGDB_LOCK_READONLY; dry_run = true; break; case 'F': f |= PKG_FLAG_SKIP_INSTALL; lock_type = PKGDB_LOCK_READONLY; break; case 'q': quiet = true; break; case 'r': reponame = optarg; break; case 'y': yes_arg = true; break; default: usage_upgrade(); return (EX_USAGE); /* NOTREACHED */ } } argc -= optind; argv += optind; if (argc != 0) { usage_upgrade(); 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 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, 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, 0, 0) != 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 (pkg_jobs_solve(jobs) != EPKG_OK) goto cleanup; while ((nbactions = pkg_jobs_count(jobs)) > 0) { /* print a summary before applying the jobs */ yes = yes_arg; 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 (!yes && !dry_run) yes = query_yesno(false, "\nProceed with this action [y/N]: "); if (dry_run) yes = false; } if (yes) { retcode = pkg_jobs_apply(jobs); done = 1; if (retcode == EPKG_CONFLICT) { printf ("The conflicts with the existing packages have been found.\n" "We need to run one more solver iteration 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 && yes) 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 (!yes && newpkgversion) newpkgversion = false; return (retcode); }
int pkg_ini(const char *path, const char *reposdir, pkg_init_flags flags) { struct ucl_parser *p = NULL; size_t i; const char *val = NULL; const char *buf, *walk, *value, *key, *k; const char *evkey = NULL; const char *nsname = NULL; const char *useragent = NULL; const char *evpipe = NULL; const ucl_object_t *cur, *object; ucl_object_t *obj = NULL, *o, *ncfg; ucl_object_iter_t it = NULL; struct sbuf *ukey = NULL; bool fatal_errors = false; char *rootedpath = NULL; char *tmp = NULL; k = NULL; o = NULL; pkg_get_myarch(myabi, BUFSIZ); pkg_get_myarch_legacy(myabi_legacy, BUFSIZ); if (parsed != false) { pkg_emit_error("pkg_init() must only be called once"); return (EPKG_FATAL); } if (((flags & PKG_INIT_FLAG_USE_IPV4) == PKG_INIT_FLAG_USE_IPV4) && ((flags & PKG_INIT_FLAG_USE_IPV6) == PKG_INIT_FLAG_USE_IPV6)) { pkg_emit_error("Invalid flags for pkg_init()"); return (EPKG_FATAL); } config = ucl_object_typed_new(UCL_OBJECT); for (i = 0; i < c_size; i++) { switch (c[i].type) { case PKG_STRING: tmp = NULL; if (c[i].def != NULL && c[i].def[0] == '/' && pkg_rootdir != NULL) { asprintf(&tmp, "%s%s", pkg_rootdir, c[i].def); } obj = ucl_object_fromstring_common( c[i].def != NULL ? tmp != NULL ? tmp : c[i].def : "", 0, UCL_STRING_TRIM); free(tmp); ucl_object_insert_key(config, obj, c[i].key, strlen(c[i].key), false); break; case PKG_INT: ucl_object_insert_key(config, ucl_object_fromstring_common(c[i].def, 0, UCL_STRING_PARSE_INT), c[i].key, strlen(c[i].key), false); break; case PKG_BOOL: ucl_object_insert_key(config, ucl_object_fromstring_common(c[i].def, 0, UCL_STRING_PARSE_BOOLEAN), c[i].key, strlen(c[i].key), false); break; case PKG_OBJECT: obj = ucl_object_typed_new(UCL_OBJECT); if (c[i].def != NULL) { walk = buf = c[i].def; while ((buf = strchr(buf, ',')) != NULL) { key = walk; value = walk; while (*value != ',') { if (*value == '=') break; value++; } ucl_object_insert_key(obj, ucl_object_fromstring_common(value + 1, buf - value - 1, UCL_STRING_TRIM), key, value - key, false); buf++; walk = buf; } key = walk; value = walk; while (*value != ',') { if (*value == '=') break; value++; } if (o == NULL) o = ucl_object_typed_new(UCL_OBJECT); ucl_object_insert_key(o, ucl_object_fromstring_common(value + 1, strlen(value + 1), UCL_STRING_TRIM), key, value - key, false); } ucl_object_insert_key(config, obj, c[i].key, strlen(c[i].key), false); break; case PKG_ARRAY: obj = ucl_object_typed_new(UCL_ARRAY); if (c[i].def != NULL) { walk = buf = c[i].def; while ((buf = strchr(buf, ',')) != NULL) { ucl_array_append(obj, ucl_object_fromstring_common(walk, buf - walk, UCL_STRING_TRIM)); buf++; walk = buf; } ucl_array_append(obj, ucl_object_fromstring_common(walk, strlen(walk), UCL_STRING_TRIM)); } ucl_object_insert_key(config, obj, c[i].key, strlen(c[i].key), false); break; } } if (path == NULL) path = PREFIX"/etc/pkg.conf"; if (pkg_rootdir != NULL) asprintf(&rootedpath, "%s/%s", pkg_rootdir, path); p = ucl_parser_new(0); ucl_parser_register_variable (p, "ABI", myabi); ucl_parser_register_variable (p, "ALTABI", myabi_legacy); errno = 0; obj = NULL; if (!ucl_parser_add_file(p, rootedpath != NULL ? rootedpath : path)) { if (errno != ENOENT) pkg_emit_error("Invalid configuration file: %s", ucl_parser_get_error(p)); } else { obj = ucl_parser_get_object(p); } ncfg = NULL; while (obj != NULL && (cur = ucl_iterate_object(obj, &it, true))) { sbuf_init(&ukey); key = ucl_object_key(cur); for (i = 0; key[i] != '\0'; i++) sbuf_putc(ukey, toupper(key[i])); sbuf_finish(ukey); object = ucl_object_find_keyl(config, sbuf_data(ukey), sbuf_len(ukey)); if (strncasecmp(sbuf_data(ukey), "PACKAGESITE", sbuf_len(ukey)) == 0 || strncasecmp(sbuf_data(ukey), "PUBKEY", sbuf_len(ukey)) == 0 || strncasecmp(sbuf_data(ukey), "MIRROR_TYPE", sbuf_len(ukey)) == 0) { pkg_emit_error("%s in pkg.conf is no longer " "supported. Convert to the new repository style." " See pkg.conf(5)", sbuf_data(ukey)); fatal_errors = true; continue; } /* ignore unknown keys */ if (object == NULL) continue; if (object->type != cur->type) { pkg_emit_error("Malformed key %s, ignoring", key); continue; } if (ncfg == NULL) ncfg = ucl_object_typed_new(UCL_OBJECT); ucl_object_insert_key(ncfg, ucl_object_copy(cur), sbuf_data(ukey), sbuf_len(ukey), true); } if (fatal_errors) { ucl_object_unref(ncfg); ucl_parser_free(p); free(rootedpath); return (EPKG_FATAL); } if (ncfg != NULL) { it = NULL; while (( cur = ucl_iterate_object(ncfg, &it, true))) { key = ucl_object_key(cur); ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), true); } ucl_object_unref(ncfg); } ncfg = NULL; it = NULL; while ((cur = ucl_iterate_object(config, &it, true))) { o = NULL; key = ucl_object_key(cur); val = getenv(key); if (val == NULL) continue; switch (cur->type) { case UCL_STRING: o = ucl_object_fromstring_common(val, 0, UCL_STRING_TRIM); break; case UCL_INT: o = ucl_object_fromstring_common(val, 0, UCL_STRING_PARSE_INT); if (o->type != UCL_INT) { pkg_emit_error("Invalid type for environment " "variable %s, got %s, while expecting an integer", key, val); ucl_object_unref(o); continue; } break; case UCL_BOOLEAN: o = ucl_object_fromstring_common(val, 0, UCL_STRING_PARSE_BOOLEAN); if (o->type != UCL_BOOLEAN) { pkg_emit_error("Invalid type for environment " "variable %s, got %s, while expecting a boolean", key, val); ucl_object_unref(o); continue; } break; case UCL_OBJECT: o = ucl_object_typed_new(UCL_OBJECT); walk = buf = val; while ((buf = strchr(buf, ',')) != NULL) { k = walk; value = walk; while (*value != ',') { if (*value == '=') break; value++; } ucl_object_insert_key(o, ucl_object_fromstring_common(value + 1, buf - value - 1, UCL_STRING_TRIM), k, value - k, false); buf++; walk = buf; } k = walk; value = walk; while (*value != '\0') { if (*value == '=') break; value++; } ucl_object_insert_key(o, ucl_object_fromstring_common(value + 1, strlen(value + 1), UCL_STRING_TRIM), k, value - k, false); break; case UCL_ARRAY: o = ucl_object_typed_new(UCL_ARRAY); walk = buf = val; while ((buf = strchr(buf, ',')) != NULL) { ucl_array_append(o, ucl_object_fromstring_common(walk, buf - walk, UCL_STRING_TRIM)); buf++; walk = buf; } ucl_array_append(o, ucl_object_fromstring_common(walk, strlen(walk), UCL_STRING_TRIM)); break; default: /* ignore other types */ break; } if (o != NULL) { if (ncfg == NULL) ncfg = ucl_object_typed_new(UCL_OBJECT); ucl_object_insert_key(ncfg, o, key, strlen(key), true); } } if (ncfg != NULL) { it = NULL; while (( cur = ucl_iterate_object(ncfg, &it, true))) { key = ucl_object_key(cur); ucl_object_replace_key(config, ucl_object_ref(cur), key, strlen(key), true); } ucl_object_unref(ncfg); } disable_plugins_if_static(); parsed = true; ucl_object_unref(obj); ucl_parser_free(p); free(rootedpath); if (strcmp(pkg_object_string(pkg_config_get("ABI")), "unknown") == 0) { pkg_emit_error("Unable to determine ABI"); return (EPKG_FATAL); } pkg_debug(1, "%s", "pkg initialized"); /* Start the event pipe */ evpipe = pkg_object_string(pkg_config_get("EVENT_PIPE")); if (evpipe != NULL) connect_evpipe(evpipe); debug_level = pkg_object_int(pkg_config_get("DEBUG_LEVEL")); developer_mode = pkg_object_bool(pkg_config_get("DEVELOPER_MODE")); it = NULL; object = ucl_object_find_key(config, "PKG_ENV"); while ((cur = ucl_iterate_object(object, &it, true))) { evkey = ucl_object_key(cur); pkg_debug(1, "Setting env var: %s", evkey); if (evkey != NULL && evkey[0] != '\0') setenv(evkey, ucl_object_tostring_forced(cur), 1); } /* Set user-agent */ useragent = pkg_object_string(pkg_config_get("HTTP_USER_AGENT")); setenv("HTTP_USER_AGENT", useragent, 1); /* load the repositories */ load_repositories(reposdir, flags); /* bypass resolv.conf with specified NAMESERVER if any */ nsname = pkg_object_string(pkg_config_get("NAMESERVER")); if (nsname != NULL) { if (set_nameserver(ucl_object_tostring_forced(o)) != 0) { pkg_emit_error("Unable to set nameserver"); return (EPKG_FATAL); } } return (EPKG_OK); }
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); }
struct pkgdb_it * pkgdb_rquery(struct pkgdb *db, const char *pattern, match_t match, const char *repo) { sqlite3_stmt *stmt = NULL; struct sbuf *sql = NULL; const char *reponame = NULL; const char *comp = NULL; int ret; char basesql[BUFSIZ] = "" "SELECT id, origin, name, name || '~' || origin as uniqueid, version, comment, " "prefix, desc, arch, maintainer, www, " "licenselogic, flatsize, pkgsize, " "cksum, manifestdigest, path AS repopath, '%1$s' AS dbname " "FROM '%1$s'.packages p"; assert(db != NULL); assert(match == MATCH_ALL || (pattern != NULL && pattern[0] != '\0')); /* * If we have no remote repos loaded, we just return nothing instead of failing * an assert deep inside pkgdb_get_reponame */ if (db->type != PKGDB_REMOTE) return (NULL); reponame = pkgdb_get_reponame(db, repo); sql = sbuf_new_auto(); comp = pkgdb_get_pattern_query(pattern, match); if (comp && comp[0]) strlcat(basesql, comp, sizeof(basesql)); /* * Working on multiple remote repositories */ if (reponame == NULL) { /* duplicate the query via UNION for all the attached * databases */ ret = pkgdb_sql_all_attached(db->sqlite, sql, basesql, " UNION ALL "); if (ret != EPKG_OK) { sbuf_delete(sql); return (NULL); } } else sbuf_printf(sql, basesql, reponame, reponame); sbuf_cat(sql, " ORDER BY name;"); sbuf_finish(sql); pkg_debug(4, "Pkgdb: running '%s' query for %s", sbuf_get(sql), pattern); ret = sqlite3_prepare_v2(db->sqlite, sbuf_get(sql), sbuf_size(sql), &stmt, NULL); if (ret != SQLITE_OK) { ERROR_SQLITE(db->sqlite, sbuf_get(sql)); sbuf_delete(sql); return (NULL); } sbuf_delete(sql); if (match != MATCH_ALL && match != MATCH_CONDITION) sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_TRANSIENT); return (pkgdb_it_new(db, stmt, PKG_REMOTE, PKGDB_IT_FLAG_ONCE)); }
static int scan(FILE *fp, const char *name, bool quiet) { int c; bool hasid = false; bool subversion = false; analyzer_states state = INIT; struct sbuf *id = sbuf_new_auto(); locale_t l; l = newlocale(LC_ALL_MASK, "C", NULL); if (name != NULL) printf("%s:\n", name); while ((c = fgetc(fp)) != EOF) { switch (state) { case INIT: if (c == '$') { /* Transit to DELIM_SEEN if we see $ */ state = DELIM_SEEN; } else { /* Otherwise, stay in INIT state */ continue; } break; case DELIM_SEEN: if (isalpha_l(c, l)) { /* Transit to KEYWORD if we see letter */ sbuf_clear(id); sbuf_putc(id, '$'); sbuf_putc(id, c); state = KEYWORD; continue; } else if (c == '$') { /* Or, stay in DELIM_SEEN if more $ */ continue; } else { /* Otherwise, transit back to INIT */ state = INIT; } break; case KEYWORD: sbuf_putc(id, c); if (isalpha_l(c, l)) { /* * Stay in KEYWORD if additional letter is seen */ continue; } else if (c == ':') { /* * See ':' for the first time, transit to * PUNC_SEEN. */ state = PUNC_SEEN; subversion = false; } else if (c == '$') { /* * Incomplete ident. Go back to DELIM_SEEN * state because we see a '$' which could be * the beginning of a keyword. */ state = DELIM_SEEN; } else { /* * Go back to INIT state otherwise. */ state = INIT; } break; case PUNC_SEEN: case PUNC_SEEN_SVN: sbuf_putc(id, c); switch (c) { case ':': /* * If we see '::' (seen : in PUNC_SEEN), * activate subversion treatment and transit * to PUNC_SEEN_SVN state. * * If more than two :'s were seen, the ident * is invalid and we would therefore go back * to INIT state. */ if (state == PUNC_SEEN) { state = PUNC_SEEN_SVN; subversion = true; } else { state = INIT; } break; case ' ': /* * A space after ':' or '::' indicates we are at the * last component of potential ident. */ state = TEXT; break; default: /* All other characters are invalid */ state = INIT; break; } break; case TEXT: sbuf_putc(id, c); if (iscntrl_l(c, l)) { /* Control characters are not allowed in this state */ state = INIT; } else if (c == '$') { sbuf_finish(id); /* * valid ident should end with a space. * * subversion extension uses '#' to indicate that * the keyword expansion have exceeded the fixed * width, so it is also permitted if we are in * subversion mode. No length check is enforced * because GNU RCS ident(1) does not do it either. */ c = sbuf_data(id)[sbuf_len(id) - 2]; if (c == ' ' || (subversion && c == '#')) { printf(" %s\n", sbuf_data(id)); hasid = true; } state = INIT; } /* Other characters: stay in the state */ break; } } sbuf_delete(id); freelocale(l); if (!hasid) { if (!quiet) fprintf(stderr, "%s warning: no id keywords in %s\n", getprogname(), name ? name : "standard input"); return (EXIT_FAILURE); } return (EXIT_SUCCESS); }
static void attempt_to_merge(int rootfd, struct pkg_config_file *rcf, struct pkg *local, bool merge) { const struct pkg_file *lf = NULL; struct sbuf *newconf; struct pkg_config_file *lcf = NULL; char *localconf = NULL; off_t sz; char *localsum; if (rcf == NULL) { pkg_debug(3, "No remote config file"); return; } if (local == NULL) { pkg_debug(3, "No local package"); return; } if (!pkg_is_config_file(local, rcf->path, &lf, &lcf)) { pkg_debug(3, "No local package"); return; } if (lcf->content == NULL) { pkg_debug(3, "Empty configuration content for local package"); return; } pkg_debug(1, "Config file found %s", rcf->path); if (file_to_bufferat(rootfd, RELATIVE_PATH(rcf->path), &localconf, &sz) != EPKG_OK) return; pkg_debug(2, "size: %d vs %d", sz, strlen(lcf->content)); if (sz == strlen(lcf->content)) { pkg_debug(2, "Ancient vanilla and deployed conf are the same size testing checksum"); localsum = pkg_checksum_data(localconf, sz, PKG_HASH_TYPE_SHA256_HEX); if (localsum && strcmp(localsum, lf->sum) == 0) { pkg_debug(2, "Checksum are the same %d", strlen(localconf)); free(localconf); free(localsum); return; } free(localsum); pkg_debug(2, "Checksum are different %d", strlen(localconf)); } rcf->status = MERGE_FAILED; if (!merge) { free(localconf); return; } pkg_debug(1, "Attempting to merge %s", rcf->path); newconf = sbuf_new_auto(); if (merge_3way(lcf->content, localconf, rcf->content, newconf) != 0) { pkg_emit_error("Impossible to merge configuration file"); } else { sbuf_finish(newconf); rcf->newcontent = strdup(sbuf_data(newconf)); rcf->status = MERGE_SUCCESS; } sbuf_delete(newconf); free(localconf); }