static int check_deps(struct pkgdb *db, struct pkg *p, struct deps_head *dh, bool noinstall, struct sbuf *out) { struct pkg_dep *dep = NULL; int nbpkgs = 0; assert(db != NULL); assert(p != NULL); while (pkg_deps(p, &dep) == EPKG_OK) { /* do we have a missing dependency? */ if (pkg_is_installed(db, pkg_dep_name(dep)) != EPKG_OK) { if (quiet) pkg_sbuf_printf(out, "%n\t%sn\n", p, dep); else pkg_sbuf_printf(out, "%n has a missing dependency: %dn\n", p, dep); if (!noinstall) add_missing_dep(dep, dh, &nbpkgs); } } return (nbpkgs); }
static void format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, const 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; int *debug = data; (void) debug; const char *filename; struct pkg_event_conflict *cur_conflict; 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) warnx("%s", ev->e_pkg_notice.msg); break; case PKG_EVENT_DEVELOPER_MODE: warnx("DEVELOPER_MODE: %s", ev->e_pkg_error.msg); break; case PKG_EVENT_FETCHING: if (quiet || !isatty(fileno(stdin))) break; if (fetched == 0) { 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; } strlcpy(url, filename, sizeof(url)); start_progress_meter(url, ev->e_fetching.total, &fetched); } fetched = ev->e_fetching.done; if (ev->e_fetching.done == ev->e_fetching.total) { stop_progress_meter(); fetched = 0; } break; case PKG_EVENT_INSTALL_BEGIN: if (quiet) break; else { struct sbuf *msg; nbdone++; msg = sbuf_new_auto(); if (msg == NULL) { warn("sbuf_new_auto() failed"); break; } print_status_begin(msg); pkg = ev->e_install_begin.pkg; pkg_sbuf_printf(msg, "Installing %n-%v...", pkg, pkg); print_status_end(msg); } break; case PKG_EVENT_INSTALL_FINISHED: if (quiet) break; printf(" done\n"); if (pkg_has_message(ev->e_install_finished.pkg)) { if (messages == NULL) messages = sbuf_new_auto(); pkg_sbuf_printf(messages, "%M\n", ev->e_install_finished.pkg); } break; case PKG_EVENT_INTEGRITYCHECK_BEGIN: if (quiet) break; printf("Checking integrity..."); break; case PKG_EVENT_INTEGRITYCHECK_FINISHED: if (quiet) break; printf(" done\n"); break; case PKG_EVENT_INTEGRITYCHECK_CONFLICT: printf("\nConflict found on path %s between %s-%s(%s) and ", ev->e_integrity_conflict.pkg_path, ev->e_integrity_conflict.pkg_name, ev->e_integrity_conflict.pkg_version, ev->e_integrity_conflict.pkg_origin); cur_conflict = ev->e_integrity_conflict.conflicts; while (cur_conflict) { if (cur_conflict->next) printf("%s-%s(%s), ", cur_conflict->name, cur_conflict->version, cur_conflict->origin); else printf("%s-%s(%s)", cur_conflict->name, cur_conflict->version, cur_conflict->origin); cur_conflict = cur_conflict->next; } printf("\n"); break; case PKG_EVENT_DEINSTALL_BEGIN: if (quiet) break; else { struct sbuf *msg; nbdone++; msg = sbuf_new_auto(); if (msg == NULL) { warn("sbuf_new_auto() failed"); break; } print_status_begin(msg); pkg = ev->e_install_begin.pkg; pkg_sbuf_printf(msg, "Deleting %n-%v...", pkg, pkg); print_status_end(msg); } break; case PKG_EVENT_DEINSTALL_FINISHED: if (quiet) break; printf(" done\n"); break; case PKG_EVENT_UPGRADE_BEGIN: if (quiet) break; else { struct sbuf *msg; pkg = ev->e_upgrade_begin.pkg; nbdone++; msg = sbuf_new_auto(); if (msg == NULL) { warn("sbuf_new_auto() failed"); break; } print_status_begin(msg); switch (pkg_version_change(pkg)) { case PKG_DOWNGRADE: pkg_sbuf_printf(msg, "Downgrading %n from %V to %v...", pkg, pkg, pkg); break; case PKG_REINSTALL: pkg_sbuf_printf(msg, "Reinstalling %n-%V...", pkg, pkg); break; case PKG_UPGRADE: pkg_sbuf_printf(msg, "Upgrading %n from %V to %v...", pkg, pkg, pkg); break; } print_status_end(msg); } break; case PKG_EVENT_UPGRADE_FINISHED: if (quiet) break; printf(" done\n"); if (pkg_has_message(ev->e_upgrade_finished.pkg)) { if (messages == NULL) messages = sbuf_new_auto(); pkg_sbuf_printf(messages, "%M\n", ev->e_upgrade_finished.pkg); } break; case PKG_EVENT_LOCKED: pkg = ev->e_locked.pkg; pkg_fprintf(stderr, "\n%n-%v is locked and may not be modified\n", pkg, pkg); break; case PKG_EVENT_REQUIRED: pkg = ev->e_required.pkg; pkg_fprintf(stderr, "\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("%n-%v 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: fprintf(stderr, "missing dependency %s-%s\n", 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 %S\n", pkg, pkg, pkg_file_path(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("Incremental update completed, %d packages " "processed:\n" "%d packages updated, %d removed and %d added.\n", ev->e_incremental_update.processed, ev->e_incremental_update.updated, ev->e_incremental_update.removed, ev->e_incremental_update.added); break; case PKG_EVENT_DEBUG: fprintf(stderr, "DBG(%d)> %s\n", ev->e_debug.level, ev->e_debug.msg); break; default: break; } return 0; }
int pkg_old_emit_content(struct pkg *pkg, char **dest) { struct sbuf *content = sbuf_new_auto(); struct pkg_dep *dep = NULL; struct pkg_file *file = NULL; struct pkg_dir *dir = NULL; struct pkg_option *option = NULL; char option_type = 0; pkg_sbuf_printf(content, "@comment PKG_FORMAT_REVISION:1.1\n" "@name %n-%v\n" "@comment ORIGIN:%o\n" "@cwd %p\n" /* hack because we can recreate the prefix split or origin */ "@cwd /\n", pkg, pkg, pkg, pkg); while (pkg_deps(pkg, &dep) == EPKG_OK) { sbuf_printf(content, "@pkgdep %s-%s\n" "@comment DEPORIGIN:%s\n", pkg_dep_name(dep), pkg_dep_version(dep), pkg_dep_origin(dep)); } while (pkg_files(pkg, &file) == EPKG_OK) { sbuf_printf(content, "%s\n" "@comment MD5:%s\n", file->path + 1, file->sum); } while (pkg_dirs(pkg, &dir) == EPKG_OK) { sbuf_printf(content, "@unexec /sbin/rmdir \"%s\" 2>/dev/null\n", dir->path); } sbuf_printf(content, "@comment OPTIONS:"); while (pkg_options(pkg, &option) == EPKG_OK) { /* Add space for previous option, if not the first. */ if (option_type != 0) sbuf_cat(content, " "); if (strcmp(pkg_option_value(option), "on") == 0) option_type = '+'; else option_type = '-'; sbuf_printf(content, "%c%s", option_type, pkg_option_opt(option)); } sbuf_printf(content, "\n"); sbuf_finish(content); *dest = strdup(sbuf_get(content)); sbuf_delete(content); return (EPKG_OK); }
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); }
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; }
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); }