static int check_package_conflict(const char *pkgname, void *v) { struct package_conflict *conflict = v; package_t pkg; plist_t *p; FILE *f; int rv; if (conflict->skip_pkgname != NULL && strcmp(conflict->skip_pkgname, pkgname) == 0) return 0; rv = 0; f = fopen_contents(pkgname, "r"); read_plist(&pkg, f); (void)fclose(f); for (p = pkg.head; p; p = p->next) { if (p->type != PLIST_PKGCFL) continue; if (pkg_match(p->name, conflict->pkgname) == 1) { *(conflict->conflicting_pkgname) = xstrdup(pkgname); *(conflict->conflicting_pattern) = xstrdup(p->name); rv = 1 /* nonzero, stop iterating */; break; } } free_plist(&pkg); return rv; }
static int match_file_and_call(const char *filename, void *cookie) { struct call_matching_file_arg *arg = cookie; const char *active_filename; char *filtered_filename; int ret; if (arg->filter_suffix) { size_t len; len = strlen(filename); if (len < 5 || (memcmp(filename + len - 4, ".tgz", 4) != 0 && memcmp(filename + len - 4, ".tbz", 4) != 0)) { warnx("filename %s does not contain a recognized suffix", filename); return -1; } filtered_filename = xmalloc(len - 4 + 1); memcpy(filtered_filename, filename, len - 4); filtered_filename[len - 4] = '\0'; active_filename = filtered_filename; } else { filtered_filename = NULL; active_filename = filename; } ret = pkg_match(arg->pattern, active_filename); free(filtered_filename); if (ret == 1) return (*arg->call_fn)(filename, arg->cookie); else return 0; }
static int match_by_pattern(const char *pkg, void *cookie) { const char *pattern = cookie; return pkg_match(pattern, pkg); }
static int match_and_call(const char *pkg, void *cookie) { struct call_matching_arg *arg = cookie; if (pkg_match(arg->pattern, pkg) == 1) { return (*arg->call_fn)(pkg, arg->cookie); } else return 0; }
/** * \fn dep_present * * \brief check if a dependency is already recorded in the impact list */ static int dep_present(Plisthead *impacthead, char *depname) { Pkglist *pimpact; SLIST_FOREACH(pimpact, impacthead, next) if (pimpact->full != NULL && pkg_match(depname, pimpact->full)) return 1; return 0; }
int pkg_order(const char *pattern, const char *first_pkg, const char *second_pkg) { const char *first_version; const char *second_version; if (first_pkg == NULL && second_pkg == NULL) return 0; if (first_pkg == NULL) return pkg_match(pattern, second_pkg) ? 2 : 0; if (second_pkg == NULL) return pkg_match(pattern, first_pkg) ? 1 : 0; first_version = strrchr(first_pkg, '-'); second_version = strrchr(second_pkg, '-'); if (first_version == NULL || !pkg_match(pattern, first_pkg)) return pkg_match(pattern, second_pkg) ? 2 : 0; if (second_version == NULL || !pkg_match(pattern, second_pkg)) return pkg_match(pattern, first_pkg) ? 1 : 0; if (dewey_cmp(first_version + 1, DEWEY_GT, second_version + 1)) return 1; else if (dewey_cmp(first_version + 1, DEWEY_LT, second_version + 1)) return 2; else if (strcmp(first_pkg, second_pkg) < 0) return 1; else return 2; }
static int match_by_basename(const char *pkg, void *cookie) { const char *target = cookie; char *target_pattern; int match; target_pattern = addpkgwildcard(target); match = pkg_match(target_pattern, pkg); free(target_pattern); return match; }
int audit_package(struct pkg_vulnerabilities *pv, const char *pkgname, const char *limit_vul_types, int output_type) { FILE *output = output_type == 1 ? stdout : stderr; size_t i; int retval, do_eol; retval = 0; do_eol = (strcasecmp(check_eol, "yes") == 0); for (i = 0; i < pv->entries; ++i) { if (check_ignored_entry(pv, i)) continue; if (limit_vul_types != NULL && strcmp(limit_vul_types, pv->classification[i])) continue; if (!pkg_match(pv->vulnerability[i], pkgname)) continue; if (strcmp("eol", pv->classification[i]) == 0) { if (!do_eol) continue; retval = 1; if (output_type == 0) { puts(pkgname); continue; } fprintf(output, "Package %s has reached end-of-life (eol), " "see %s/eol-packages\n", pkgname, tnf_vulnerability_base); continue; } retval = 1; if (output_type == 0) { puts(pkgname); } else { fprintf(output, "Package %s has a %s vulnerability, see %s\n", pkgname, pv->classification[i], pv->advisory[i]); } } return retval; }
/* * Perform alternate match on "pkg" against "pattern", * calling pkg_match (recursively) to resolve any other patterns. * Return 1 on match, 0 otherwise */ static int alternate_match(const char *pattern, const char *pkg) { char *sep; char buf[MaxPathSize]; char *last; char *alt; char *cp; int cnt; int found; if ((sep = strchr(pattern, '{')) == (char *) NULL) { errx(EXIT_FAILURE, "alternate_match(): '{' expected in `%s'", pattern); } (void) strncpy(buf, pattern, (size_t) (sep - pattern)); alt = &buf[sep - pattern]; last = (char *) NULL; for (cnt = 0, cp = sep; *cp && last == (char *) NULL; cp++) { if (*cp == '{') { cnt++; } else if (*cp == '}' && --cnt == 0 && last == (char *) NULL) { last = cp + 1; } } if (cnt != 0) { errx(EXIT_FAILURE, "Malformed alternate `%s'", pattern); } for (found = 0, cp = sep + 1; *sep != '}'; cp = sep + 1) { for (cnt = 0, sep = cp; cnt > 0 || (cnt == 0 && *sep != '}' && *sep != ','); sep++) { if (*sep == '{') { cnt++; } else if (*sep == '}') { cnt--; } } (void) snprintf(alt, sizeof(buf) - (alt - buf), "%.*s%s", (int) (sep - cp), cp, last); if (pkg_match(buf, pkg) == 1) { found = 1; } } return found; }
int main(int argc, char *argv[]) { Boolean use_default_sfx = TRUE; Boolean show_basename_only = FALSE; char lsdir[MaxPathSize]; char sfx[MaxPathSize]; char *lsdirp = NULL; int ch; setprogname(argv[0]); if (argc < 2) usage(); while ((ch = getopt(argc, argv, Options)) != -1) switch (ch) { case 'C': config_file = optarg; break; case 'K': pkgdb_set_dir(optarg, 3); break; case 'S': sfx[0] = 0x0; use_default_sfx = FALSE; break; case 'V': show_version(); /* NOTREACHED */ case 'b': show_basename_only = TRUE; break; case 'd': (void) strlcpy(lsdir, optarg, sizeof(lsdir)); lsdirp = lsdir; break; case 'q': quiet = 1; break; case 's': (void) strlcpy(sfx, optarg, sizeof(sfx)); use_default_sfx = FALSE; break; case 'v': ++verbose; break; default: usage(); /* NOTREACHED */ } argc -= optind; argv += optind; if (argc <= 0) { usage(); } /* * config-var is reading the config file implicitly, * so skip it here. */ if (strcasecmp(argv[0], "config-var") != 0) pkg_install_config(); if (use_default_sfx) (void) strlcpy(sfx, DEFAULT_SFX, sizeof(sfx)); if (strcasecmp(argv[0], "pmatch") == 0) { char *pattern, *pkg; argv++; /* "pmatch" */ if (argv[0] == NULL || argv[1] == NULL) { usage(); } pattern = argv[0]; pkg = argv[1]; if (pkg_match(pattern, pkg)) { return 0; } else { return 1; } } else if (strcasecmp(argv[0], "rebuild") == 0) { rebuild(); printf("Done.\n"); } else if (strcasecmp(argv[0], "rebuild-tree") == 0) { rebuild_tree(); printf("Done.\n"); } else if (strcasecmp(argv[0], "check") == 0) { argv++; /* "check" */ check(argv); if (!quiet) { printf("Done.\n"); } } else if (strcasecmp(argv[0], "lsall") == 0) { argv++; /* "lsall" */ while (*argv != NULL) { /* args specified */ int rc; const char *basep, *dir; dir = lsdirp ? lsdirp : dirname_of(*argv); basep = basename_of(*argv); if (show_basename_only) rc = match_local_files(dir, use_default_sfx, 1, basep, lsbasepattern, NULL); else rc = match_local_files(dir, use_default_sfx, 1, basep, lspattern, __UNCONST(dir)); if (rc == -1) errx(EXIT_FAILURE, "Error from match_local_files(\"%s\", \"%s\", ...)", dir, basep); argv++; } } else if (strcasecmp(argv[0], "lsbest") == 0) { argv++; /* "lsbest" */ while (*argv != NULL) { /* args specified */ const char *basep, *dir; char *p; dir = lsdirp ? lsdirp : dirname_of(*argv); basep = basename_of(*argv); p = find_best_matching_file(dir, basep, use_default_sfx, 1); if (p) { if (show_basename_only) printf("%s\n", p); else printf("%s/%s\n", dir, p); free(p); } argv++; } } else if (strcasecmp(argv[0], "list") == 0 || strcasecmp(argv[0], "dump") == 0) { pkgdb_dump(); } else if (strcasecmp(argv[0], "add") == 0) { struct pkgdb_count count; count.files = 0; count.directories = 0; count.packages = 0; for (++argv; *argv != NULL; ++argv) add_pkg(*argv, &count); } else if (strcasecmp(argv[0], "set") == 0) { argv++; /* "set" */ set_unset_variable(argv, FALSE); } else if (strcasecmp(argv[0], "unset") == 0) { argv++; /* "unset" */ set_unset_variable(argv, TRUE); } else if (strcasecmp(argv[0], "config-var") == 0) { argv++; if (argv == NULL || argv[1] != NULL) errx(EXIT_FAILURE, "config-var takes exactly one argument"); pkg_install_show_variable(argv[0]); } else if (strcasecmp(argv[0], "check-license") == 0) { if (argv[1] == NULL) errx(EXIT_FAILURE, "check-license takes exactly one argument"); load_license_lists(); switch (acceptable_pkg_license(argv[1])) { case 0: puts("no"); return 0; case 1: puts("yes"); return 0; case -1: errx(EXIT_FAILURE, "invalid license condition"); } } else if (strcasecmp(argv[0], "check-single-license") == 0) { if (argv[1] == NULL) errx(EXIT_FAILURE, "check-license takes exactly one argument"); load_license_lists(); switch (acceptable_license(argv[1])) { case 0: puts("no"); return 0; case 1: puts("yes"); return 0; case -1: errx(EXIT_FAILURE, "invalid license"); } } #ifndef BOOTSTRAP else if (strcasecmp(argv[0], "findbest") == 0) { struct url *url; char *output; int rc; process_pkg_path(); rc = 0; for (++argv; *argv != NULL; ++argv) { url = find_best_package(NULL, *argv, 1); if (url == NULL) { rc = 1; continue; } output = fetchStringifyURL(url); puts(output); fetchFreeURL(url); free(output); } return rc; } else if (strcasecmp(argv[0], "fetch-pkg-vulnerabilities") == 0) { fetch_pkg_vulnerabilities(--argc, ++argv); } else if (strcasecmp(argv[0], "check-pkg-vulnerabilities") == 0) { check_pkg_vulnerabilities(--argc, ++argv); } else if (strcasecmp(argv[0], "audit") == 0) { audit_pkgdb(--argc, ++argv); } else if (strcasecmp(argv[0], "audit-pkg") == 0) { audit_pkg(--argc, ++argv); } else if (strcasecmp(argv[0], "audit-batch") == 0) { audit_batch(--argc, ++argv); } else if (strcasecmp(argv[0], "audit-history") == 0) { audit_history(--argc, ++argv); } else if (strcasecmp(argv[0], "check-signature") == 0) { struct archive *pkg; int rc; rc = 0; for (--argc, ++argv; argc > 0; --argc, ++argv) { char *archive_name; pkg = open_archive(*argv, &archive_name); if (pkg == NULL) { warnx("%s could not be opened", *argv); continue; } if (pkg_full_signature_check(archive_name, &pkg)) rc = 1; free(archive_name); if (!pkg) archive_read_finish(pkg); } return rc; } else if (strcasecmp(argv[0], "x509-sign-package") == 0) { #ifdef HAVE_SSL --argc; ++argv; if (argc != 4) errx(EXIT_FAILURE, "x509-sign-package takes exactly four arguments"); pkg_sign_x509(argv[0], argv[1], argv[2], argv[3]); #else errx(EXIT_FAILURE, "OpenSSL support is not included"); #endif } else if (strcasecmp(argv[0], "gpg-sign-package") == 0) { --argc; ++argv; if (argc != 2) errx(EXIT_FAILURE, "gpg-sign-package takes exactly two arguments"); pkg_sign_gpg(argv[0], argv[1]); } #endif else { usage(); } return 0; }
static void break_depends(Plisthead *impacthead) { Pkglist *rmimpact, *pimpact; Plisthead *rdphead, *fdphead; Pkglist *rdp, *fdp; char *pkgname, *rpkg; int dep_break, exists; SLIST_FOREACH(pimpact, impacthead, next) { if (pimpact->old == NULL) /* DONOTHING or TOINSTALL */ continue; rdphead = init_head(); XSTRDUP(pkgname, pimpact->old); trunc_str(pkgname, '-', STR_BACKWARD); /* fetch old package reverse dependencies */ full_dep_tree(pkgname, LOCAL_REVERSE_DEPS, rdphead); XFREE(pkgname); /* browse reverse dependencies */ SLIST_FOREACH(rdp, rdphead, next) { exists = 0; /* check if rdp was already on impact list */ SLIST_FOREACH(rmimpact, impacthead, next) if (strcmp(rmimpact->depend, rdp->depend) == 0) { exists = 1; break; } if (exists) continue; fdphead = init_head(); /* * reverse dependency is a full package name, * use it and strip it */ XSTRDUP(rpkg, rdp->depend); trunc_str(rpkg, '-', STR_BACKWARD); /* fetch dependencies for rdp */ full_dep_tree(rpkg, DIRECT_DEPS, fdphead); /* initialize to broken dependency */ dep_break = 1; /* empty full dep tree, this can't happen in normal situation. * If it does, that means that the reverse dependency we're * analyzing has no direct dependency. * Such a situation could occur if the reverse dependency is not on * the repository anymore, leading to no information regarding this * package. * So we will check if local package dependencies are satisfied by * our newly upgraded packages. */ if (SLIST_EMPTY(fdphead)) { free_pkglist(&fdphead, DEPTREE); fdphead = init_head(); full_dep_tree(rpkg, LOCAL_DIRECT_DEPS, fdphead); } XFREE(rpkg); /* * browse dependencies for rdp and see if * new package to be installed matches */ SLIST_FOREACH(fdp, fdphead, next) { if (pkg_match(fdp->depend, pimpact->full)) { dep_break = 0; break; } } free_pkglist(&fdphead, DEPTREE); if (!dep_break) continue; /* dependency break, insert rdp in remove-list */ rmimpact = malloc_pkglist(IMPACT); XSTRDUP(rmimpact->depend, rdp->depend); XSTRDUP(rmimpact->full, rdp->depend); XSTRDUP(rmimpact->old, rdp->depend); rmimpact->action = TOREMOVE; rmimpact->level = 0; SLIST_INSERT_HEAD(impacthead, rmimpact, next); } free_pkglist(&rdphead, DEPTREE); }
static int search(struct cmdctx *cmdctx) { struct poclidek_ctx *cctx = NULL; tn_array *pkgs = NULL; tn_array *matched_pkgs = NULL; int i, err = 0, display_bar = 0, bar_v; int term_height; struct pattern *pt; unsigned flags; if ((pt = cmdctx->_data) == NULL) { logn(LOGERR, _("search: no pattern given")); err++; goto l_end; } cmdctx->_data = NULL; /* we'll free pattern myself */ cctx = cmdctx->cctx; flags = cmdctx->_flags; flags &= ~OPT_NO_SEARCHSW; if (flags == 0) cmdctx->_flags |= OPT_SEARCH_DEFAULT; init_pcre(); if (!pattern_compile(pt, poldek_ts_get_arg_count(cmdctx->ts))) { err++; goto l_end; } poclidek_load_packages(cmdctx->cctx, POCLIDEK_LOAD_ALL); if (poldek_ts_get_arg_count(cmdctx->ts) == 0) { pkgs = poclidek_get_dent_packages(cctx, NULL); } else { pkgs = poclidek_resolve_packages(NULL, cctx, cmdctx->ts, 0); } if (pkgs == NULL) return 0; matched_pkgs = n_array_new(32, NULL, NULL); if (n_array_size(pkgs) > 5 && (cmdctx->_flags & OPT_SEARCH_HDD)) { display_bar = 1; msg(0, _("Searching packages...")); } bar_v = 0; for (i=0; i < n_array_size(pkgs); i++) { struct pkg *pkg = n_array_nth(pkgs, i); if (pkg_match(pkg, pt, cmdctx->_flags)) n_array_push(matched_pkgs, pkg); if (display_bar) { int v, j; v = i * 40 / n_array_size(pkgs); for (j = bar_v; j < v; j++) msg(0, "_."); bar_v = v; } if (sigint_reached()) { msgn(0, _("_interrupted.")); goto l_end; } } if (display_bar) msgn(0, _("_done.")); term_height = poldek_term_get_height(); if (n_array_size(matched_pkgs) == 0) cmdctx_printf_c(cmdctx, PRCOLOR_YELLOW, "!No package matches '%s'\n", pt->regexp); else if (n_array_size(matched_pkgs) < term_height) cmdctx_printf_c(cmdctx, PRCOLOR_YELLOW, "!%d package(s) found:\n", n_array_size(matched_pkgs)); for (i=0; i<n_array_size(matched_pkgs); i++) { struct pkg *pkg; pkg = n_array_nth(matched_pkgs, i); cmdctx_addtoresult(cmdctx, pkg); cmdctx_printf(cmdctx, "%s\n", pkg_id(pkg)); } if (n_array_size(matched_pkgs) >= term_height) cmdctx_printf_c(cmdctx, PRCOLOR_YELLOW, "!%d package(s) found.\n", n_array_size(matched_pkgs)); l_end: if (pkgs) n_array_free(pkgs); if (matched_pkgs) n_array_free(matched_pkgs); if (cmdctx->_data) cmdctx->_data = NULL; if (pt) pattern_free(pt); return 1; }