static void print_index(struct pkg *pkg, const char *portsdir) { const pkg_object *obj, *list; pkg_iter iter = NULL; pkg_printf("%n-%v|%S/%o|%p|%c|%S/%o/pkg-descr|%m|", pkg, pkg, portsdir, pkg, pkg, pkg, portsdir, pkg, pkg); pkg_get(pkg, PKG_CATEGORIES, &list); while ((obj = pkg_object_iterate(list, &iter))) pkg_printf("%Cn ", obj); printf("\n"); }
static int do_add(struct pkgdb *db, struct pkg *pkg, const char *tag, const char *value) { const char *pkgname, *pkgversion; int ret = EPKG_OK; if (yes || query_tty_yesno(false, "%n-%v: Add annotation tagged: %S with " "value: %S? [y/N]: ", pkg, pkg, tag, value)) { ret = pkgdb_add_annotation(db, pkg, tag, value); if (ret == EPKG_OK) { if (!quiet) pkg_printf("%n-%v: added annotation tagged:" " %S\n", pkg, pkg, tag); } else if (ret == EPKG_WARN) { if (!quiet) { pkg_get(pkg, PKG_NAME, &pkgname, PKG_VERSION, &pkgversion); warnx("%s-%s: Cannot add annotation tagged: " "%s -- already exists", pkgname, pkgversion, tag); } } else { pkg_get(pkg, PKG_NAME, &pkgname, PKG_VERSION, &pkgversion); warnx("%s-%s: Failed to add annotation tagged: %s", pkgname, pkgversion, tag); } } return (ret); }
static int do_delete(struct pkgdb *db, struct pkg *pkg, const char *tag) { const char *pkgname, *pkgversion; int ret = EPKG_OK; if (yes || query_tty_yesno(false, "%n-%v: Delete annotation tagged: %S? " "[y/N]: ", pkg, pkg, tag)) { ret = pkgdb_delete_annotation(db, pkg, tag); if (ret == EPKG_OK) { if (!quiet) pkg_printf("%n-%v: Deleted annotation " "tagged: %S\n", pkg, pkg, tag); } else if (ret == EPKG_WARN) { if (!quiet) { pkg_get(pkg, PKG_NAME, &pkgname, PKG_VERSION, &pkgversion); warnx("%s-%s: Cannot delete annotation " "tagged: %s -- because there is none", pkgname, pkgversion, tag); } } else { pkg_get(pkg, PKG_NAME, &pkgname, PKG_VERSION, &pkgversion); warnx("%s-%s: Failed to delete annotation tagged: %s", pkgname, pkgversion, tag); } } return (ret); }
static int do_unlock(struct pkgdb *db, struct pkg *pkg) { if (!pkg_is_locked(pkg)) { if (!quiet) pkg_printf("%n-%v: already unlocked\n", pkg, pkg); return (EPKG_OK); } if (!query_yesno(false, "%n-%v: unlock this package? [y/N]: ", pkg, pkg)) return (EPKG_OK); if (!quiet) pkg_printf("Unlocking %n-%v\n", pkg, pkg); return (pkgdb_set(db, pkg, PKG_SET_LOCKED, (int64_t)false)); }
static int list_locked(struct pkgdb *db) { struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; if ((it = pkgdb_query(db, " where locked=1", MATCH_CONDITION)) == NULL) { pkgdb_close(db); return (EX_UNAVAILABLE); } printf("Currently locked packages:\n"); while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) { pkg_printf("%n-%v\n", pkg, pkg); } return (EX_OK); }
static void print_index(struct pkg *pkg, const char *portsdir) { pkg_printf( "%n-%v|" /* PKGNAME */ "%S/%o|" /* PORTDIR */ "%p|" /* PREFIX */ "%c|" /* COMMENT */ "%S/%o/pkg-descr|" /* _DESCR */ "%m|" /* MAINTAINER */ "%C%{%Cn%| %}|" /* CATEGORIES */ "|" /* BUILD_DEPENDS */ "%d%{%dn-%dv%| %}|" /* RUN_DEPENDS */ "%w|" /* WWW */ "|" /* EXTRACT_DEPENDS */ "|" /* PATCH_DEPENDS */ "\n", /* FETCH_DEPENDS */ pkg, pkg, portsdir, pkg, pkg, pkg, portsdir, pkg, pkg, pkg, pkg, pkg); }
static int do_show(struct pkg *pkg, const char *tag) { const pkg_object *annotations, *note; pkg_iter it = NULL; int ret = EPKG_OK; pkg_get(pkg, PKG_ANNOTATIONS, &annotations); while ((note = pkg_object_iterate(annotations, &it)) != NULL) { if (strcmp(tag, pkg_object_key(note)) == 0) { if (quiet) printf("%s\n", pkg_object_string(note)); else pkg_printf("%n-%v: Tag: %S Value: %S\n", pkg, pkg, pkg_object_key(note), pkg_object_string(note)); } } return (ret); }
static int do_modify(struct pkgdb *db, struct pkg *pkg, const char *tag, const char *value) { const char *pkgname, *pkgversion; int ret = EPKG_OK; if (yes || query_tty_yesno(false, "%n-%v: Change annotation tagged: %S to " "new value: %S? [y/N]: ", pkg, pkg, tag, value)) { ret = pkgdb_modify_annotation(db, pkg, tag, value); if (ret == EPKG_OK || ret == EPKG_WARN) { if (!quiet) pkg_printf("%n-%v: Modified annotation " "tagged: %S\n", pkg, pkg, tag); } else { pkg_get(pkg, PKG_NAME, &pkgname, PKG_VERSION, &pkgversion); warnx("%s-%s: Failed to modify annotation tagged: %s", pkgname, pkgversion, tag); } } return (ret); }
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_jobs_summary(struct pkg_jobs *jobs, const char *msg, ...) { struct pkg *pkg = NULL; char path[MAXPATHLEN]; struct stat st; const char *oldversion, *cachedir, *why; int64_t dlsize, oldsize, newsize; int64_t flatsize, oldflatsize, pkgsize; char size[7]; va_list ap; pkg_jobs_t type; type = pkg_jobs_type(jobs); va_start(ap, msg); vprintf(msg, ap); va_end(ap); dlsize = oldsize = newsize = 0; flatsize = oldflatsize = pkgsize = 0; oldversion = NULL; pkg_config_string(PKG_CONFIG_CACHEDIR, &cachedir); while (pkg_jobs(jobs, &pkg) == EPKG_OK) { pkg_get(pkg, PKG_OLD_VERSION, &oldversion, PKG_FLATSIZE, &flatsize, PKG_OLD_FLATSIZE, &oldflatsize, PKG_PKGSIZE, &pkgsize, PKG_REASON, &why); if (pkg_is_locked(pkg)) { pkg_printf("\tPackage %n-%v is locked ", pkg, pkg); switch (type) { case PKG_JOBS_INSTALL: case PKG_JOBS_UPGRADE: /* If it's a new install, then it * cannot have been locked yet. */ if (oldversion != NULL) { switch(pkg_version_change(pkg)) { case PKG_UPGRADE: pkg_printf("and may not be upgraded to version %v\n", pkg); break; case PKG_REINSTALL: printf("and may not be reinstalled\n"); break; case PKG_DOWNGRADE: pkg_printf("and may not be downgraded to version %v\n", pkg); break; } continue; } break; case PKG_JOBS_DEINSTALL: case PKG_JOBS_AUTOREMOVE: printf("and may not be deinstalled\n"); continue; break; case PKG_JOBS_FETCH: printf("but a new package can still be fetched\n"); break; } } switch (type) { case PKG_JOBS_INSTALL: case PKG_JOBS_UPGRADE: pkg_snprintf(path, MAXPATHLEN, "%S/%R", cachedir, pkg); if (stat(path, &st) == -1 || pkgsize != st.st_size) /* file looks corrupted (wrong size), assume a checksum mismatch will occur later and the file will be fetched from remote again */ dlsize += pkgsize; if (oldversion != NULL) { switch (pkg_version_change(pkg)) { case PKG_DOWNGRADE: pkg_printf("\tDowngrading %n: %V -> %v", pkg, pkg, pkg); if (pkg_repos_count() > 1) pkg_printf(" [%N]", pkg); printf("\n"); break; case PKG_REINSTALL: pkg_printf("\tReinstalling %n-%v", pkg, pkg); if (pkg_repos_count() > 1) pkg_printf(" [%N]", pkg); if (why != NULL) printf(" (%s)", why); printf("\n"); break; case PKG_UPGRADE: pkg_printf("\tUpgrading %n: %V -> %v", pkg, pkg, pkg); if (pkg_repos_count() > 1) pkg_printf(" [%N]", pkg); printf("\n"); break; } oldsize += oldflatsize; newsize += flatsize; } else { newsize += flatsize; pkg_printf("\tInstalling %n: %v", pkg, pkg); if (pkg_repos_count() > 1) pkg_printf(" [%N]", pkg); printf("\n"); } break; case PKG_JOBS_DEINSTALL: case PKG_JOBS_AUTOREMOVE: oldsize += oldflatsize; newsize += flatsize; pkg_printf("\t%n-%v\n", pkg, pkg); break; case PKG_JOBS_FETCH: dlsize += pkgsize; pkg_snprintf(path, MAXPATHLEN, "%S/%R", cachedir, pkg); if (stat(path, &st) != -1) oldsize = st.st_size; else oldsize = 0; dlsize -= oldsize; humanize_number(size, sizeof(size), pkgsize, "B", HN_AUTOSCALE, 0); pkg_printf("\t%n-%v ", pkg, pkg); printf("(%" PRId64 "%% of %s)\n", 100 - (100 * oldsize)/pkgsize, size); break; } } if (oldsize > newsize) { humanize_number(size, sizeof(size), oldsize - newsize, "B", HN_AUTOSCALE, 0); switch (type) { case PKG_JOBS_INSTALL: printf("\nThe installation will free %s\n", size); break; case PKG_JOBS_UPGRADE: printf("\nThe upgrade will free %s\n", size); break; case PKG_JOBS_DEINSTALL: case PKG_JOBS_AUTOREMOVE: printf("\nThe deinstallation will free %s\n", size); break; case PKG_JOBS_FETCH: /* nothing to report here */ break; } } else if (newsize > oldsize) { humanize_number(size, sizeof(size), newsize - oldsize, "B", HN_AUTOSCALE, 0); switch (type) { case PKG_JOBS_INSTALL: printf("\nThe installation will require %s more space\n", size); break; case PKG_JOBS_UPGRADE: printf("\nThe upgrade will require %s more space\n", size); break; case PKG_JOBS_DEINSTALL: case PKG_JOBS_AUTOREMOVE: printf("\nThe deinstallation will require %s more space\n", size); break; case PKG_JOBS_FETCH: /* nothing to report here */ break; } } if ((type == PKG_JOBS_INSTALL) || (type == PKG_JOBS_FETCH) || (type == PKG_JOBS_UPGRADE)) { humanize_number(size, sizeof(size), dlsize, "B", HN_AUTOSCALE, 0); printf("\n%s to be downloaded\n", size); } }
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; }
static void print_version(struct pkg *pkg, const char *source, const char *ver, char limchar, unsigned int opt) { const char *key; const char *version; int cout; pkg_get(pkg, PKG_VERSION, &version); if (ver == NULL) { if (source == NULL) key = "!"; else key = "?"; } else { switch (pkg_version_cmp(version, ver)) { case -1: key = "<"; break; case 0: key = "="; break; case 1: key = ">"; break; default: key = "!"; break; } } if ((opt & VERSION_STATUS) && limchar != *key) return; if ((opt & VERSION_NOSTATUS) && limchar == *key) return; if (opt & VERSION_ORIGIN) pkg_printf("%-34o %S", pkg, key); else { cout = pkg_printf("%n-%v", pkg, pkg); cout = 35 - cout; if (cout < 1) cout = 1; printf("%*s%s", cout, " ", key); } if (opt & VERSION_VERBOSE) { switch (*key) { case '<': printf(" needs updating (%s has %s)", source, ver); break; case '=': printf(" up-to-date with %s", source); break; case '>': printf(" succeeds %s (%s has %s)", source, source, ver); break; case '?': pkg_printf(" orphaned: %o", pkg); break; case '!': printf(" Comparison failed"); break; } } printf("\n"); return; }
static int pkg_create_matches(int argc, char **argv, match_t match, pkg_formats fmt, const char * const outdir, bool overwrite) { int i, ret = EPKG_OK, retcode = EPKG_OK; struct pkg *pkg = NULL; struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; int query_flags = PKG_LOAD_DEPS | PKG_LOAD_FILES | PKG_LOAD_CATEGORIES | PKG_LOAD_DIRS | PKG_LOAD_SCRIPTS | PKG_LOAD_OPTIONS | PKG_LOAD_LICENSES | PKG_LOAD_USERS | PKG_LOAD_GROUPS | PKG_LOAD_SHLIBS_REQUIRED | PKG_LOAD_PROVIDES | PKG_LOAD_REQUIRES | PKG_LOAD_SHLIBS_PROVIDED | PKG_LOAD_ANNOTATIONS; struct pkg_entry *e = NULL, *etmp; char pkgpath[MAXPATHLEN]; const char *format = NULL; bool foundone; if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { pkgdb_close(db); return (EX_IOERR); } /* XXX: get rid of hardcoded timeouts */ if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) { pkgdb_close(db); warnx("Cannot get a read lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } switch (fmt) { case TXZ: format = "txz"; break; case TBZ: format = "tbz"; break; case TGZ: format = "tgz"; break; case TAR: format = "tar"; break; } for (i = 0; i < argc || match == MATCH_ALL; i++) { if (match == MATCH_ALL) { printf("Loading the package list...\n"); if ((it = pkgdb_query(db, NULL, match)) == NULL) goto cleanup; match = !MATCH_ALL; } else if ((it = pkgdb_query(db, argv[i], match)) == NULL) goto cleanup; foundone = false; while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) { if ((e = malloc(sizeof(struct pkg_entry))) == NULL) err(1, "malloc(pkg_entry)"); e->pkg = pkg; pkg = NULL; DL_APPEND(pkg_head, e); foundone = true; } if (!foundone) { warnx("No installed package matching \"%s\" found\n", argv[i]); retcode++; } pkgdb_it_free(it); if (ret != EPKG_END) retcode++; } DL_FOREACH_SAFE(pkg_head, e, etmp) { DL_DELETE(pkg_head, e); if (!overwrite) { pkg_snprintf(pkgpath, sizeof(pkgpath), "%S/%n-%v.%S", outdir, e->pkg, e->pkg, format); if (access(pkgpath, F_OK) == 0) { pkg_printf("%n-%v already packaged, skipping...\n", e->pkg, e->pkg); pkg_free(e->pkg); free(e); continue; } } pkg_printf("Creating package for %n-%v\n", e->pkg, e->pkg); if (pkg_create_installed(outdir, fmt, e->pkg) != EPKG_OK) retcode++; pkg_free(e->pkg); free(e); }
static void print_jobs_summary_pkg(struct pkg *pkg, pkg_jobs_t type, int64_t *oldsize, int64_t *newsize, int64_t *dlsize) { const char *oldversion, *cachedir, *why; char path[MAXPATHLEN]; struct stat st; int64_t flatsize, oldflatsize, pkgsize; char size[7]; flatsize = oldflatsize = pkgsize = 0; oldversion = NULL; pkg_config_string(PKG_CONFIG_CACHEDIR, &cachedir); pkg_get(pkg, PKG_OLD_VERSION, &oldversion, PKG_FLATSIZE, &flatsize, PKG_OLD_FLATSIZE, &oldflatsize, PKG_PKGSIZE, &pkgsize, PKG_REASON, &why); if (pkg_is_locked(pkg)) { pkg_printf("\tPackage %n-%v is locked ", pkg, pkg); switch (type) { case PKG_JOBS_INSTALL: case PKG_JOBS_UPGRADE: /* If it's a new install, then it * cannot have been locked yet. */ if (oldversion != NULL) { switch(pkg_version_change(pkg)) { case PKG_UPGRADE: pkg_printf("and may not be upgraded to version %v\n", pkg); break; case PKG_REINSTALL: printf("and may not be reinstalled\n"); break; case PKG_DOWNGRADE: pkg_printf("and may not be downgraded to version %v\n", pkg); break; } return; } break; case PKG_JOBS_DEINSTALL: case PKG_JOBS_AUTOREMOVE: printf("and may not be deinstalled\n"); return; break; case PKG_JOBS_FETCH: printf("but a new package can still be fetched\n"); break; } } switch (type) { case PKG_JOBS_INSTALL: case PKG_JOBS_UPGRADE: pkg_snprintf(path, MAXPATHLEN, "%S/%R", cachedir, pkg); if (stat(path, &st) == -1 || pkgsize != st.st_size) /* file looks corrupted (wrong size), assume a checksum mismatch will occur later and the file will be fetched from remote again */ *dlsize += pkgsize; if (oldversion != NULL) { switch (pkg_version_change(pkg)) { case PKG_DOWNGRADE: pkg_printf("\tDowngrading %n: %V -> %v", pkg, pkg, pkg); if (pkg_repos_total_count() > 1) pkg_printf(" [%N]", pkg); printf("\n"); break; case PKG_REINSTALL: pkg_printf("\tReinstalling %n-%v", pkg, pkg); if (pkg_repos_total_count() > 1) pkg_printf(" [%N]", pkg); if (why != NULL) printf(" (%s)", why); printf("\n"); break; case PKG_UPGRADE: pkg_printf("\tUpgrading %n: %V -> %v", pkg, pkg, pkg); if (pkg_repos_total_count() > 1) pkg_printf(" [%N]", pkg); printf("\n"); break; } *oldsize += oldflatsize; *newsize += flatsize; } else { *newsize += flatsize; pkg_printf("\tInstalling %n: %v", pkg, pkg); if (pkg_repos_total_count() > 1) pkg_printf(" [%N]", pkg); printf("\n"); } break; case PKG_JOBS_DEINSTALL: case PKG_JOBS_AUTOREMOVE: *oldsize += oldflatsize; *newsize += flatsize; pkg_printf("\tRemoving %n-%v\n", pkg, pkg); break; case PKG_JOBS_FETCH: *dlsize += pkgsize; pkg_snprintf(path, MAXPATHLEN, "%S/%R", cachedir, pkg); if (stat(path, &st) != -1) *oldsize = st.st_size; else *oldsize = 0; *dlsize -= *oldsize; humanize_number(size, sizeof(size), pkgsize, "B", HN_AUTOSCALE, 0); pkg_printf("\t%n-%v ", pkg, pkg); printf("(%" PRId64 "%% of %s)\n", 100 - (100 * (*oldsize))/pkgsize, size); break; } }
int exec_which(int argc, char **argv) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; char pathabs[MAXPATHLEN]; char *p, *path, *match, *savedpath; int ret = EPKG_OK, retcode = EX_SOFTWARE; int ch, i; int res, pathlen = 0; bool orig = false; bool glob = false; bool search = false; bool search_s = false; charlist patterns; struct option longopts[] = { { "glob", no_argument, NULL, 'g' }, { "origin", no_argument, NULL, 'o' }, { "path-search", no_argument, NULL, 'p' }, { "quiet", no_argument, NULL, 'q' }, { NULL, 0, NULL, 0 }, }; path = NULL; while ((ch = getopt_long(argc, argv, "+gopq", longopts, NULL)) != -1) { switch (ch) { case 'g': glob = true; break; case 'o': orig = true; break; case 'p': search_s = true; break; case 'q': quiet = true; break; default: usage_which(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc < 1) { usage_which(); return (EX_USAGE); } if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { return (EX_IOERR); } if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) { pkgdb_close(db); warnx("Cannot get a read lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } if (search_s) { if ((path = getenv("PATH")) == NULL) { printf("$PATH is not set, falling back to non-search behaviour\n"); search_s = false; } else { pathlen = strlen(path) + 1; } } while (argc >= 1) { kv_init(patterns); retcode = EX_SOFTWARE; if (search_s) { if ((argv[0][0] == '.') || (argv[0][0] == '/')) { search = false; } else { search = true; if (strlen(argv[0]) >= FILENAME_MAX) { retcode = EX_USAGE; goto cleanup; } p = malloc(pathlen); if (p == NULL) { retcode = EX_OSERR; goto cleanup; } strlcpy(p, path, pathlen); match = NULL; savedpath=p; for (;;) { res = get_match(&match, &p, argv[0]); if (p == NULL) break; if (res == (EX_USAGE)) { printf("%s was not found in PATH, falling back to non-search behaviour\n", argv[0]); search = false; } else if (res == (EX_OSERR)) { retcode = EX_OSERR; free(savedpath); goto cleanup; } else { pkg_absolutepath(match, pathabs, sizeof(pathabs)); /* ensure not not append twice an entry if PATH is messy */ if (already_in_list(&patterns, pathabs)) continue; kv_push(char *, patterns, strdup(pathabs)); free(match); } } free(savedpath); } } if (!glob && !search) { pkg_absolutepath(argv[0], pathabs, sizeof(pathabs)); kv_push(char *, patterns, strdup(pathabs)); } else if (!search) { if (strlcpy(pathabs, argv[0], sizeof(pathabs)) >= sizeof(pathabs)) { retcode = EX_USAGE; goto cleanup; } } for (i = 0; i < kv_size(patterns); i++) { if ((it = pkgdb_query_which(db, kv_A(patterns, i), glob)) == NULL) { retcode = EX_IOERR; goto cleanup; } pkg = NULL; while ((ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) { retcode = EX_OK; if (quiet && orig) pkg_printf("%o\n", pkg); else if (quiet && !orig) pkg_printf("%n-%v\n", pkg, pkg); else if (!quiet && orig) pkg_printf("%S was installed by package %o\n", kv_A(patterns, i), pkg); else if (!quiet && !orig) pkg_printf("%S was installed by package %n-%v\n", kv_A(patterns, i), pkg, pkg); } if (retcode != EX_OK && !quiet) printf("%s was not found in the database\n", kv_A(patterns, i)); pkg_free(pkg); pkgdb_it_free(it); } kv_destroy(patterns); argc--; argv++; } cleanup: pkgdb_release_lock(db, PKGDB_LOCK_READONLY); pkgdb_close(db); return (retcode); }
int exec_check(int argc, char **argv) { struct pkg *pkg = NULL; struct pkgdb_it *it = NULL; struct pkgdb *db = NULL; match_t match = MATCH_EXACT; int flags = PKG_LOAD_BASIC; int ret, rc = EX_OK; int ch; bool yes; bool dcheck = false; bool checksums = false; bool recompute = false; bool reanalyse_shlibs = false; bool noinstall = false; int nbpkgs = 0; int i; int verbose = 0; pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes); struct deps_head dh = STAILQ_HEAD_INITIALIZER(dh); while ((ch = getopt(argc, argv, "yagidnBxsrv")) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'B': reanalyse_shlibs = true; flags |= PKG_LOAD_FILES; break; case 'd': dcheck = true; flags |= PKG_LOAD_DEPS; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'n': noinstall = true; break; case 'r': recompute = true; flags |= PKG_LOAD_FILES; break; case 's': checksums = true; flags |= PKG_LOAD_FILES; break; case 'v': verbose = 1; break; case 'x': match = MATCH_REGEX; break; case 'y': yes = true; break; default: usage_check(); return (EX_USAGE); } } argc -= optind; argv += optind; /* Default to all packages if no pkg provided */ if (argc == 0 && (dcheck || checksums || recompute || reanalyse_shlibs)) { match = MATCH_ALL; } else if ((argc == 0 && match != MATCH_ALL) || !(dcheck || checksums || recompute || reanalyse_shlibs)) { usage_check(); return (EX_USAGE); } if (recompute || reanalyse_shlibs) ret = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE, PKGDB_DB_LOCAL); else ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL); if (ret == EPKG_ENODB) { warnx("No packages installed. Nothing to do!"); return (EX_OK); } else if (ret == EPKG_ENOACCESS) { warnx("Insufficient privileges to access the package database"); return (EX_NOPERM); } else if (ret != EPKG_OK) { warnx("Error accessing the package database"); return (EX_SOFTWARE); } ret = pkgdb_open(&db, PKGDB_DEFAULT); if (ret != EPKG_OK) return (EX_IOERR); i = 0; do { if ((it = pkgdb_query(db, argv[i], match)) == NULL) { pkgdb_close(db); return (EX_IOERR); } while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) { /* check for missing dependencies */ if (dcheck) { if (verbose) pkg_printf("Checking dependencies: %n\n", pkg); nbpkgs += check_deps(db, pkg, &dh, noinstall); if (noinstall && nbpkgs > 0) { rc = EX_UNAVAILABLE; } } if (checksums) { if (verbose) pkg_printf("Checking checksums: %n\n", pkg); if (pkg_test_filesum(pkg) != EPKG_OK) { rc = EX_DATAERR; } } if (recompute) { if (verbose) pkg_printf("Recomputing size and checksums: %n\n", pkg); if (pkg_recompute(db, pkg) != EPKG_OK) { rc = EX_DATAERR; } } if (reanalyse_shlibs) { if (verbose) pkg_printf("Reanalyzing files for shlibs: %n\n", pkg); if (pkgdb_reanalyse_shlibs(db, pkg) != EPKG_OK) { pkg_printf("Failed to reanalyse for shlibs: %n\n", pkg); rc = EX_UNAVAILABLE; } } } if (dcheck && nbpkgs > 0 && !noinstall) { printf("\n>>> Missing package dependencies were detected.\n"); printf(">>> Found %d issue(s) in the package database.\n\n", nbpkgs); ret = fix_deps(db, &dh, nbpkgs, yes); if (ret == EPKG_OK) check_summary(db, &dh); else if (ret == EPKG_ENODB) { db = NULL; return (EX_IOERR); } } pkgdb_it_free(it); i++; } while (i < argc); deps_free(&dh); pkg_free(pkg); pkgdb_close(db); return (rc); }
int exec_which(int argc, char **argv) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; struct pkg *pkg = NULL; char pathabs[MAXPATHLEN]; char *p, *path, *match; int ret = EPKG_OK, retcode = EX_SOFTWARE; int ch; int res, pathlen; bool orig = false; bool glob = false; bool search = false; bool search_s = false; while ((ch = getopt(argc, argv, "qgop")) != -1) { switch (ch) { case 'q': quiet = true; break; case 'g': glob = true; break; case 'o': orig = true; break; case 'p': search_s = true; break; default: usage_which(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc < 1) { usage_which(); return (EX_USAGE); } if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { return (EX_IOERR); } if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY, 0, 0) != EPKG_OK) { pkgdb_close(db); warnx("Cannot get a read lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } if (search_s) { if ((path = getenv("PATH")) == NULL) { printf("$PATH is not set, falling back to non-search behaviour\n"); search_s = false; } else { pathlen = strlen(path) + 1; } } while (argc >= 1) { retcode = EX_SOFTWARE; if (search_s) { if ((argv[0][0] == '.') || (argv[0][0] == '/')) { search = false; } else { search = true; if (strlen(argv[0]) >= FILENAME_MAX) { retcode = EX_USAGE; goto cleanup; } p = malloc(pathlen); if (p == NULL) { retcode = EX_OSERR; goto cleanup; } strlcpy(p, path, pathlen); match = NULL; res = get_match(&match, p, argv[0]); free(p); if (res == (EX_USAGE)) { printf("%s was not found in PATH, falling back to non-search behaviour\n", argv[0]); search = false; } else if (res == (EX_OSERR)) { retcode = EX_OSERR; goto cleanup; } else { absolutepath(match, pathabs, sizeof(pathabs)); free(match); } } } if (!glob && !search) absolutepath(argv[0], pathabs, sizeof(pathabs)); else if (!search) { if (strlcpy(pathabs, argv[0], sizeof(pathabs)) >= sizeof(pathabs)) retcode = EX_USAGE; goto cleanup; } if ((it = pkgdb_query_which(db, pathabs, glob)) == NULL) { retcode = EX_IOERR; goto cleanup; } pkg = NULL; while ((ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) { retcode = EX_OK; if (quiet && orig) pkg_printf("%o\n", pkg); else if (quiet && !orig) pkg_printf("%n-%v\n", pkg, pkg); else if (!quiet && orig) pkg_printf("%S was installed by package %o\n", pathabs, pkg); else if (!quiet && !orig) pkg_printf("%S was installed by package %n-%v\n", pathabs, pkg, pkg); } if (retcode != EX_OK && !quiet) printf("%s was not found in the database\n", pathabs); pkg_free(pkg); pkgdb_it_free(it); argc--; argv++; } cleanup: pkgdb_release_lock(db, PKGDB_LOCK_READONLY); pkgdb_close(db); return (retcode); }
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; }
void print_query(struct pkg *pkg, char *qstr, char multiline) { struct sbuf *output = sbuf_new_auto(); struct pkg_dep *dep = NULL; struct pkg_option *option = NULL; struct pkg_file *file = NULL; struct pkg_kv *kv; switch (multiline) { case 'd': while (pkg_deps(pkg, &dep) == EPKG_OK) { format_str(pkg, output, qstr, dep); printf("%s\n", sbuf_data(output)); } break; case 'r': while (pkg_rdeps(pkg, &dep) == EPKG_OK) { format_str(pkg, output, qstr, dep); printf("%s\n", sbuf_data(output)); } break; case 'C': pkg_printf("%C%{%Cn\n%|%}", pkg); break; case 'O': while (pkg_options(pkg, &option) == EPKG_OK) { format_str(pkg, output, qstr, option); printf("%s\n", sbuf_data(output)); } break; case 'F': while (pkg_files(pkg, &file) == EPKG_OK) { format_str(pkg, output, qstr, file); printf("%s\n", sbuf_data(output)); } break; case 'D': pkg_printf("%D", pkg); break; case 'L': pkg_printf("%L%{%Ln\n%|%}", pkg); break; case 'U': pkg_printf("%U", pkg); break; case 'G': pkg_printf("%G", pkg); break; case 'B': pkg_printf("%B", pkg); break; case 'b': pkg_printf("%b", pkg); break; case 'A': pkg_get(pkg, PKG_ANNOTATIONS, &kv); while (kv != NULL) { format_str(pkg, output, qstr, kv); printf("%s\n", sbuf_data(output)); kv = kv->next; } break; default: format_str(pkg, output, qstr, dep); printf("%s\n", sbuf_data(output)); break; } sbuf_delete(output); }