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 exec_register(int argc, char **argv) { struct pkg *pkg = NULL; struct pkgdb *db = NULL; struct pkg_manifest_key *keys = NULL; regex_t preg; regmatch_t pmatch[2]; char *arch = NULL; char myarch[BUFSIZ]; char *www = NULL; char fpath[MAXPATHLEN]; const char *plist = NULL; const char *mdir = NULL; const char *mfile = NULL; const char *input_path = NULL; const char *desc = NULL; const char *location = NULL; size_t size; bool developer; bool legacy = false; bool old = false; bool __unused metadata_only = false; bool testing_mode = false; int ch; int i; int ret = EPKG_OK; int retcode = EX_OK; /* options descriptor */ struct option longopts[] = { { "automatic", no_argument, NULL, 'A' }, { "plist", required_argument, NULL, 'f' }, { "root", required_argument, NULL, 'i' }, { "legacy", no_argument, NULL, 'l' }, { "manifest", required_argument, NULL, 'M' }, { "metadata", required_argument, NULL, 'm' }, { "old", no_argument, NULL, 'O' }, { "test", no_argument, NULL, 't' }, { "relocate", required_argument, NULL, 1 }, { NULL, 0, NULL, 0}, }; developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE")); if (pkg_new(&pkg, PKG_INSTALLED) != EPKG_OK) err(EX_OSERR, "malloc"); while ((ch = getopt_long(argc, argv, "Adf:i:lM:m:Ot", longopts, NULL)) != -1) { switch (ch) { case 'A': case 'd': pkg_set(pkg, PKG_AUTOMATIC, (bool)true); break; case 'f': plist = optarg; break; case 'i': input_path = optarg; break; case 'l': legacy = true; break; case 'M': metadata_only = true; mfile = optarg; break; case 'm': mdir = optarg; break; case 'O': old = true; break; case 't': testing_mode = true; break; case 1: location = optarg; break; default: warnx("Unrecognised option -%c\n", ch); usage_register(); return (EX_USAGE); } } if (!old) { retcode = pkgdb_access(PKGDB_MODE_READ | PKGDB_MODE_WRITE | PKGDB_MODE_CREATE, PKGDB_DB_LOCAL); if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privileges to register packages"); return (EX_NOPERM); } else if (retcode != EPKG_OK) return (EX_IOERR); else retcode = EX_OK; } /* * Ideally, the +MANIFEST should be all that is necessary, * since it can contain all of the meta-data supplied by the * other files mentioned below. These are here for backwards * compatibility with the way the ports tree works with * pkg_tools. * * The -M option specifies one manifest file to read the * meta-data from, and overrides the use of legacy meta-data * inputs. * * Dependencies, shlibs, files etc. may be derived by * analysing the package files (maybe discovered as the * content of the staging directory) unless -t (testing_mode) * is used. */ if (mfile != NULL && mdir != NULL) { warnx("Cannot use both -m and -M together"); usage_register(); return (EX_USAGE); } if (mfile == NULL && mdir == NULL) { warnx("One of either -m or -M flags is required"); usage_register(); return (EX_USAGE); } if (mfile != NULL && plist != NULL) { warnx("-M incompatible with -f option"); usage_register(); return (EX_USAGE); } if (testing_mode && input_path != NULL) { warnx("-i incompatible with -t option"); usage_register(); return (EX_USAGE); } pkg_manifest_keys_new(&keys); if (mfile != NULL) { ret = pkg_parse_manifest_file(pkg, mfile, keys); pkg_manifest_keys_free(keys); if (ret != EPKG_OK) return (EX_IOERR); } else { snprintf(fpath, sizeof(fpath), "%s/+MANIFEST", mdir); ret = pkg_parse_manifest_file(pkg, fpath, keys); pkg_manifest_keys_free(keys); if (ret != EPKG_OK) return (EX_IOERR); snprintf(fpath, sizeof(fpath), "%s/+DESC", mdir); pkg_set_from_file(pkg, PKG_DESC, fpath, false); snprintf(fpath, sizeof(fpath), "%s/+DISPLAY", mdir); if (access(fpath, F_OK) == 0) pkg_set_from_file(pkg, PKG_MESSAGE, fpath, false); snprintf(fpath, sizeof(fpath), "%s/+MTREE_DIRS", mdir); if (access(fpath, F_OK) == 0) pkg_set_from_file(pkg, PKG_MTREE, fpath, false); for (i = 0; scripts[i] != NULL; i++) { snprintf(fpath, sizeof(fpath), "%s/%s", mdir, scripts[i]); if (access(fpath, F_OK) == 0) pkg_addscript_file(pkg, fpath); } if (www != NULL) { pkg_set(pkg, PKG_WWW, www); free(www); } pkg_get(pkg, PKG_WWW, &www); /* * if www is not given then try to determine it from * description */ if (www == NULL) { pkg_get(pkg, PKG_DESC, &desc); regcomp(&preg, "^WWW:[[:space:]]*(.*)$", REG_EXTENDED|REG_ICASE|REG_NEWLINE); if (regexec(&preg, desc, 2, pmatch, 0) == 0) { size = pmatch[1].rm_eo - pmatch[1].rm_so; www = strndup(&desc[pmatch[1].rm_so], size); pkg_set(pkg, PKG_WWW, www); free(www); } else { pkg_set(pkg, PKG_WWW, "UNKNOWN"); } regfree(&preg); } if (plist != NULL) ret += ports_parse_plist(pkg, plist, input_path); } if (ret != EPKG_OK) { return (EX_IOERR); } if (!old) { if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) return (EX_IOERR); if (pkgdb_obtain_lock(db, PKGDB_LOCK_EXCLUSIVE) != EPKG_OK) { pkgdb_close(db); warnx("Cannot get an exclusive lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } } /* * testing_mode allows updating the local package database * without any check that the files etc. listed in the meta * data actually exist on the system. Inappropriate use of * testing_mode can really screw things up. */ if (!testing_mode) pkg_analyse_files(db, pkg, input_path); pkg_get(pkg, PKG_ARCH, &arch); if (arch == NULL) { /* * do not take the one from configuration on purpose * but the real abi of the package. */ pkg_get_myarch(myarch, BUFSIZ); if (developer) pkg_suggest_arch(pkg, myarch, true); pkg_set(pkg, PKG_ARCH, myarch); } else { if (developer) pkg_suggest_arch(pkg, arch, false); } if (!testing_mode && input_path != NULL) pkg_copy_tree(pkg, input_path, location ? location : "/"); if (location != NULL) pkg_addannotation(pkg, "relocated", location); if (old) { if (pkg_register_old(pkg) != EPKG_OK) retcode = EX_SOFTWARE; } else { if (pkgdb_register_ports(db, pkg) != EPKG_OK) retcode = EX_SOFTWARE; } if (!legacy && pkg_has_message(pkg)) pkg_printf("%M\n", pkg); if (!old) { pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE); pkgdb_close(db); } pkg_free(pkg); return (retcode); }
void print_info(struct pkg * const pkg, unsigned int options) { bool print_tag = false; bool show_locks = false; char size[7]; const char *repourl; unsigned opt; int64_t flatsize, oldflatsize, pkgsize; int cout = 0; /* Number of characters output */ int info_num; /* Number of different data items to print */ pkg_get(pkg, PKG_REPOURL, &repourl, PKG_FLATSIZE, &flatsize, PKG_OLD_FLATSIZE, &oldflatsize, PKG_PKGSIZE, &pkgsize); if (options & INFO_RAW) { if (pkg_type(pkg) != PKG_REMOTE) pkg_emit_manifest_file(pkg, stdout, PKG_MANIFEST_EMIT_PRETTY, NULL); else pkg_emit_manifest_file(pkg, stdout, PKG_MANIFEST_EMIT_COMPACT|PKG_MANIFEST_EMIT_PRETTY, NULL); return; } /* Show locking status when requested to display it and the package is locally installed */ if (pkg_type(pkg) == PKG_INSTALLED && (options & INFO_LOCKED) != 0) show_locks = true; if (!quiet) { /* Print a tag-line identifying the package -- either NAMEVER, ORIGIN or NAME (in that order of preference). This may be the only output from this function */ if (options & INFO_TAG_NAMEVER) cout = pkg_printf("%n-%v", pkg, pkg); else if (options & INFO_TAG_ORIGIN) cout = pkg_printf("%o", pkg); else if (options & INFO_TAG_NAME) cout = pkg_printf("%n", pkg); } /* If we printed a tag, and there are no other items to print, then just return now. If there's only one single-line item to print, show it at column 32 on the same line. If there's one multi-line item to print, start a new line. If there is more than one item to print per pkg, use 'key : value' style to show on a new line. */ info_num = 0; for (opt = 0x1U; opt <= INFO_LASTFIELD; opt <<= 1) if ((opt & options) != 0) info_num++; if (info_num == 0 && cout > 0) { printf("\n"); return; } if (info_num == 1) { /* Only one item to print */ print_tag = false; if (!quiet) { if (options & INFO_MULTILINE) printf(":\n"); else { if (cout < 31) cout = 31 - cout; else cout = 1; printf("%*s", cout, " "); } } } else { /* Several items to print */ print_tag = true; if (!quiet) printf("\n"); } for (opt = 0x1; opt <= INFO_LASTFIELD; opt <<= 1) { if ((opt & options) == 0) continue; switch (opt) { case INFO_NAME: if (print_tag) printf("%-15s: ", "Name"); pkg_printf("%n\n", pkg); break; case INFO_VERSION: if (print_tag) printf("%-15s: ", "Version"); pkg_printf("%v\n", pkg); break; case INFO_ORIGIN: if (print_tag) printf("%-15s: ", "Origin"); pkg_printf("%o\n", pkg); break; case INFO_PREFIX: if (print_tag) printf("%-15s: ", "Prefix"); pkg_printf("%p\n", pkg); break; case INFO_REPOSITORY: if (pkg_type(pkg) == PKG_REMOTE && repourl != NULL && repourl[0] != '\0') { if (print_tag) printf("%-15s: ", "Repository"); pkg_printf("%N [%S]\n", pkg, repourl); } else if (!print_tag) printf("\n"); break; case INFO_CATEGORIES: if (pkg_list_count(pkg, PKG_CATEGORIES) > 0) { if (print_tag) printf("%-15s: ", "Categories"); pkg_printf("%C%{%Cn%| %}\n", pkg); } else if (!print_tag) printf("\n"); break; case INFO_LICENSES: if (pkg_list_count(pkg, PKG_LICENSES) > 0) { if (print_tag) printf("%-15s: ", "Licenses"); pkg_printf("%L%{%Ln%| %l %}\n", pkg); } else if (!print_tag) printf("\n"); break; case INFO_MAINTAINER: if (print_tag) printf("%-15s: ", "Maintainer"); pkg_printf("%m\n", pkg); break; case INFO_WWW: if (print_tag) printf("%-15s: ", "WWW"); pkg_printf("%w\n", pkg); break; case INFO_COMMENT: if (print_tag) printf("%-15s: ", "Comment"); pkg_printf("%c\n", pkg); break; case INFO_OPTIONS: if (pkg_list_count(pkg, PKG_OPTIONS) > 0) { if (print_tag) printf("%-15s:\n", "Options"); if (quiet) pkg_printf("%O%{%-15On: %Ov\n%|%}", pkg); else pkg_printf("%O%{\t%-15On: %Ov\n%|%}", pkg); } break; case INFO_SHLIBS_REQUIRED: if (pkg_list_count(pkg, PKG_SHLIBS_REQUIRED) > 0) { if (print_tag) printf("%-15s:\n", "Shared Libs required"); if (quiet) pkg_printf("%B%{%Bn\n%|%}", pkg); else pkg_printf("%B%{\t%Bn\n%|%}", pkg); } break; case INFO_SHLIBS_PROVIDED: if (pkg_list_count(pkg, PKG_SHLIBS_PROVIDED) > 0) { if (print_tag) printf("%-15s:\n", "Shared Libs provided"); if (quiet) pkg_printf("%b%{%bn\n%|%}", pkg); else pkg_printf("%b%{\t%bn\n%|%}", pkg); } break; case INFO_ANNOTATIONS: if (pkg_list_count(pkg, PKG_ANNOTATIONS) > 0) { if (print_tag) printf("%-15s:\n", "Annotations"); if (quiet) pkg_printf("%A%{%-15An: %Av\n%|%}", pkg); else pkg_printf("%A%{\t%-15An: %Av\n%|%}", pkg); } break; case INFO_FLATSIZE: if (print_tag) printf("%-15s: ", "Flat size"); pkg_printf("%#sB\n", pkg); break; case INFO_PKGSIZE: /* Remote pkgs only */ if (pkg_type(pkg) == PKG_REMOTE) { humanize_number(size, sizeof(size), pkgsize,"B", HN_AUTOSCALE, 0); if (print_tag) printf("%-15s: ", "Pkg size"); printf("%s\n", size); } else if (!print_tag) printf("\n"); break; case INFO_DESCR: if (print_tag) printf("%-15s:\n", "Description"); pkg_printf("%e\n", pkg); break; case INFO_MESSAGE: if (print_tag) printf("%-15s:\n", "Message"); if (pkg_has_message(pkg)) pkg_printf("%M\n", pkg); break; case INFO_DEPS: if (pkg_list_count(pkg, PKG_DEPS) > 0) { if (print_tag) printf("%-15s:\n", "Depends on"); if (quiet) { if (show_locks) pkg_printf("%d%{%dn-%dv%#dk\n%|%}", pkg); else pkg_printf("%d%{%dn-%dv\n%|%}", pkg); } else { if (show_locks) pkg_printf("%d%{\t%dn-%dv%#dk\n%|%}", pkg); else pkg_printf("%d%{\t%dn-%dv\n%|%}", pkg); } } break; case INFO_RDEPS: if (pkg_list_count(pkg, PKG_RDEPS) > 0) { if (print_tag) printf("%-15s:\n", "Required by"); if (quiet) { if (show_locks) pkg_printf("%r%{%rn-%rv%#rk\n%|%}", pkg); else pkg_printf("%r%{%rn-%rv\n%|%}", pkg); } else { if (show_locks) pkg_printf("%r%{\t%rn-%rv%#rk\n%|%}", pkg); else pkg_printf("%r%{\t%rn-%rv\n%|%}", pkg); } } break; case INFO_FILES: /* Installed pkgs only */ if (pkg_type(pkg) != PKG_REMOTE && pkg_list_count(pkg, PKG_FILES) > 0) { if (print_tag) printf("%-15s:\n", "Files"); if (quiet) pkg_printf("%F%{%Fn\n%|%}", pkg); else pkg_printf("%F%{\t%Fn\n%|%}", pkg); } break; case INFO_DIRS: /* Installed pkgs only */ if (pkg_type(pkg) != PKG_REMOTE && pkg_list_count(pkg, PKG_DIRS) > 0) { if (print_tag) printf("%-15s:\n", "Directories"); if (quiet) pkg_printf("%D%{%Dn\n%|%}", pkg); else pkg_printf("%D%{\t%Dn\n%|%}", pkg); } break; case INFO_USERS: /* Installed pkgs only */ if (pkg_type(pkg) != PKG_REMOTE && pkg_list_count(pkg, PKG_USERS) > 0) { if (print_tag) printf("%-15s: ", "Users"); pkg_printf("%U%{%Un%| %}\n", pkg); } break; case INFO_GROUPS: /* Installed pkgs only */ if (pkg_type(pkg) != PKG_REMOTE && pkg_list_count(pkg, PKG_GROUPS) > 0) { if (print_tag) printf("%-15s: ", "Groups"); pkg_printf("%G%{%Gn%| %}\n", pkg); } break; case INFO_ARCH: if (print_tag) printf("%-15s: ", "Architecture"); pkg_printf("%q\n", pkg); break; case INFO_REPOURL: if (pkg_type(pkg) == PKG_REMOTE && repourl != NULL && repourl[0] != '\0') { if (print_tag) printf("%-15s: ", "Pkg URL"); if (repourl[strlen(repourl) -1] == '/') pkg_printf("%S%R\n", repourl, pkg); else pkg_printf("%S/%R\n", repourl, pkg); } else if (!print_tag) printf("\n"); break; case INFO_LOCKED: if (print_tag) printf("%-15s: ", "Locked"); pkg_printf("%?k\n", pkg); break; } } }
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_register_old(struct pkg *pkg) { FILE *fp; char *content; const char *pkgdbdir, *tmp; char path[MAXPATHLEN]; struct sbuf *install_script = sbuf_new_auto(); struct sbuf *deinstall_script = sbuf_new_auto(); struct pkg_dep *dep = NULL; pkg_to_old(pkg); pkg_old_emit_content(pkg, &content); pkgdbdir = pkg_object_string(pkg_config_get("PKG_DBDIR")); pkg_snprintf(path, sizeof(path), "%S/%n-%v", pkgdbdir, pkg, pkg); mkdir(path, 0755); pkg_snprintf(path, sizeof(path), "%S/%n-%v/+CONTENTS", pkgdbdir, pkg, pkg); fp = fopen(path, "w"); fputs(content, fp); fclose(fp); pkg_snprintf(path, sizeof(path), "%S/%n-%v/+DESC", pkgdbdir, pkg, pkg); fp = fopen(path, "w"); pkg_fprintf(fp, "%e", pkg); fclose(fp); pkg_snprintf(path, sizeof(path), "%s/%n-%v/+COMMENT", pkgdbdir, pkg, pkg); fp = fopen(path, "w"); pkg_fprintf(fp, "%c\n", pkg); fclose(fp); if (pkg_has_message(pkg)) { pkg_snprintf(path, sizeof(path), "%s/%n-%v/+DISPLAY", pkgdbdir, pkg, pkg); fp = fopen(path, "w"); pkg_fprintf(fp, "%M", pkg); fclose(fp); } sbuf_clear(install_script); tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_INSTALL); if (tmp != NULL && *tmp != '\0') { if (sbuf_len(install_script) == 0) sbuf_cat(install_script, "#!/bin/sh\n\n"); sbuf_printf(install_script, "if [ \"$2\" = \"PRE-INSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_INSTALL); if (tmp != NULL && *tmp != '\0') { if (sbuf_len(install_script) == 0) sbuf_cat(install_script, "#!/bin/sh\n\n"); sbuf_cat(install_script, tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_INSTALL); if (tmp != NULL && *tmp != '\0') { if (sbuf_len(install_script) == 0) sbuf_cat(install_script, "#!/bin/sh\n\n"); sbuf_printf(install_script, "if [ \"$2\" = \"POST-INSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } if (sbuf_len(install_script) > 0) { sbuf_finish(install_script); pkg_snprintf(path, sizeof(path), "%s/%n-%v/+INSTALL", pkgdbdir, pkg, pkg); fp = fopen(path, "w"); fputs(sbuf_data(install_script), fp); fclose(fp); } sbuf_clear(deinstall_script); tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_DEINSTALL); if (tmp != NULL && *tmp != '\0') { if (sbuf_len(deinstall_script) == 0) sbuf_cat(deinstall_script, "#!/bin/sh\n\n"); sbuf_printf(deinstall_script, "if [ \"$2\" = \"DEINSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_DEINSTALL); if (tmp != NULL && *tmp != '\0') { if (sbuf_len(deinstall_script) == 0) sbuf_cat(deinstall_script, "#!/bin/sh\n\n"); sbuf_cat(deinstall_script, tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_DEINSTALL); if (tmp != NULL && tmp[0] != '\0') { if (sbuf_len(deinstall_script) == 0) sbuf_cat(deinstall_script, "#!/bin/sh\n\n"); sbuf_printf(deinstall_script, "if [ \"$2\" = \"POST-DEINSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } if (sbuf_len(deinstall_script) > 0) { sbuf_finish(deinstall_script); pkg_snprintf(path, sizeof(path), "%s/%n-%v/+DEINSTALL", pkgdbdir, pkg, pkg); fp = fopen(path, "w"); fputs(sbuf_data(deinstall_script), fp); fclose(fp); } while (pkg_deps(pkg, &dep)) { snprintf(path, sizeof(path), "%s/%s-%s/+REQUIRED_BY", pkgdbdir, pkg_dep_name(dep), pkg_dep_version(dep)); fp = fopen(path, "a"); pkg_fprintf(fp, "%n-%v\n", pkg, pkg); fclose(fp); } return (EPKG_OK); }
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; }