void pkg_emit_upgrade_finished(struct pkg *p) { struct pkg_event ev; bool syslog_enabled = false; char *name, *version, *newversion; ev.type = PKG_EVENT_UPGRADE_FINISHED; ev.e_upgrade_finished.pkg = p; pkg_config_bool(PKG_CONFIG_SYSLOG, &syslog_enabled); if (syslog_enabled) { const char *actions[] = { "upgraded", "reinstalled", "downgraded" }; int num_actions = sizeof(actions) / sizeof(*actions); int action; pkg_get(p, PKG_NAME, &name, PKG_VERSION, &version, PKG_NEWVERSION, &newversion); action = pkg_version_cmp(version, newversion) + 1; if (action >= 0 && action < num_actions) syslog(LOG_NOTICE, "%s %s: %s -> %s ", name, actions[action], version, newversion); } pkg_emit_event(&ev); }
static int maybe_delete_conflicting(const char *origin, const char *version, const char *pkg_path) { int ret; const char *oversion; if (run_prepared_statement(VERSION, origin) != SQLITE_ROW) return (EPKG_FATAL); /* sqlite error */ oversion = sqlite3_column_text(STMT(VERSION), 0); switch(pkg_version_cmp(oversion, version)) { case -1: pkg_emit_error("duplicate package origin: replacing older " "version %s in repo with package %s for " "origin %s", oversion, pkg_path, origin); if (run_prepared_statement(DELETE, origin) != SQLITE_DONE) return (EPKG_FATAL); /* sqlite error */ ret = EPKG_OK; /* conflict cleared */ break; case 0: case 1: pkg_emit_error("duplicate package origin: package %s is not " "newer than version %s already in repo for " "origin %s", pkg_path, oversion, origin); ret = EPKG_END; /* keep what is already in the repo */ break; } return (ret); }
static void pkgdb_pkgcmp(sqlite3_context *ctx, int argc, sqlite3_value **argv, int sign) { const unsigned char *version1 = NULL; const unsigned char *version2 = NULL; if (argc != 2 || (version1 = sqlite3_value_text(argv[0])) == NULL || (version2 = sqlite3_value_text(argv[1])) == NULL) { sqlite3_result_error(ctx, "Invalid comparison\n", -1); return; } sqlite3_result_int(ctx, (pkg_version_cmp(version1, version2) == sign)); }
static int pkg_conflicts_chain_cmp_cb(struct pkg_conflict_chain *a, struct pkg_conflict_chain *b) { const char *vera, *verb; if (a->req->skip || b->req->skip) { return (a->req->skip - b->req->skip); } vera = a->req->item->pkg->version; verb = b->req->item->pkg->version; /* Inverse sort to get the maximum version as the first element */ return (pkg_version_cmp(vera, verb)); }
static int pkg_conflicts_chain_cmp_cb(struct pkg_conflict_chain *a, struct pkg_conflict_chain *b) { const char *vera, *verb; if (a->req->skip || b->req->skip) { return (a->req->skip - b->req->skip); } pkg_get(a->req->item->pkg, PKG_VERSION, &vera); pkg_get(b->req->item->pkg, PKG_VERSION, &verb); /* Inverse sort to get the maximum version as the first element */ return (pkg_version_cmp(vera, verb)); }
static int pkg_repo_binary_delete_conflicting(const char *origin, const char *version, const char *pkg_path, bool forced) { int ret = EPKG_FATAL; const char *oversion; if (pkg_repo_binary_run_prstatement(VERSION, origin) != SQLITE_ROW) { ret = EPKG_FATAL; goto cleanup; } oversion = sqlite3_column_text(pkg_repo_binary_stmt_prstatement(VERSION), 0); if (!forced) { switch(pkg_version_cmp(oversion, version)) { case -1: pkg_emit_error("duplicate package origin: replacing older " "version %s in repo with package %s for " "origin %s", oversion, pkg_path, origin); if (pkg_repo_binary_run_prstatement(DELETE, origin, origin) != SQLITE_DONE) ret = EPKG_FATAL; else ret = EPKG_OK; /* conflict cleared */ break; case 0: case 1: pkg_emit_error("duplicate package origin: package %s is not " "newer than version %s already in repo for " "origin %s", pkg_path, oversion, origin); ret = EPKG_END; /* keep what is already in the repo */ break; } } else { if (pkg_repo_binary_run_prstatement(DELETE, origin, origin) != SQLITE_DONE) ret = EPKG_FATAL; ret = EPKG_OK; } cleanup: sqlite3_reset(pkg_repo_binary_stmt_prstatement(VERSION)); return (ret); }
static char * pkg_globmatch(char *pattern, const char *name) { glob_t g; int i; char *buf, *buf2; char *path = NULL; if (glob(pattern, 0, NULL, &g) == GLOB_NOMATCH) { globfree(&g); return (NULL); } for (i = 0; i < g.gl_pathc; i++) { /* the version starts here */ buf = strrchr(g.gl_pathv[i], '-'); if (buf == NULL) continue; buf2 = strchr(g.gl_pathv[i], '/'); if (buf2 == NULL) buf2 = g.gl_pathv[i]; else buf2++; /* ensure we have match the proper name */ if (strncmp(buf2, name, buf - buf2) != 0) continue; if (path == NULL) { path = g.gl_pathv[i]; continue; } if (pkg_version_cmp(path, g.gl_pathv[i]) == '>') path = g.gl_pathv[i]; } path = strdup(path); globfree(&g); return (path); }
void print_jobs_summary(struct pkg_jobs *jobs, const char *msg, ...) { struct pkg *pkg = NULL; char path[MAXPATHLEN]; struct stat st; const char *name, *version, *newversion, *pkgrepopath, *cachedir; int64_t dlsize, oldsize, newsize; int64_t flatsize, newflatsize, pkgsize; bool locked; 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 = newflatsize = pkgsize = 0; name = version = newversion = NULL; pkg_config_string(PKG_CONFIG_CACHEDIR, &cachedir); while (pkg_jobs(jobs, &pkg) == EPKG_OK) { pkg_get(pkg, PKG_NEWVERSION, &newversion, PKG_NAME, &name, PKG_VERSION, &version, PKG_FLATSIZE, &flatsize, PKG_NEW_FLATSIZE, &newflatsize, PKG_NEW_PKGSIZE, &pkgsize, PKG_REPOPATH, &pkgrepopath, PKG_LOCKED, &locked); if (locked) { printf("\tPackage %s-%s is locked ", name, version); switch (type) { case PKG_JOBS_INSTALL: case PKG_JOBS_UPGRADE: /* If it's a new install, then it * cannot have been locked yet. */ if (newversion != NULL) { switch(pkg_version_cmp(version, newversion)) { case -1: printf("and may not be upgraded to version %s\n", newversion); break; case 0: printf("and may not be reinstalled\n"); break; case 1: printf("and may not be downgraded to version %s\n", newversion); 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: snprintf(path, MAXPATHLEN, "%s/%s", cachedir, pkgrepopath); 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 (newversion != NULL) { switch (pkg_version_cmp(version, newversion)) { case 1: printf("\tDowngrading %s: %s -> %s\n", name, version, newversion); break; case 0: printf("\tReinstalling %s-%s\n", name, version); break; case -1: printf("\tUpgrading %s: %s -> %s\n", name, version, newversion); break; } oldsize += flatsize; newsize += newflatsize; } else { newsize += flatsize; printf("\tInstalling %s: %s\n", name, version); } break; case PKG_JOBS_DEINSTALL: case PKG_JOBS_AUTOREMOVE: oldsize += flatsize; newsize += newflatsize; printf("\t%s-%s\n", name, version); break; case PKG_JOBS_FETCH: dlsize += pkgsize; snprintf(path, MAXPATHLEN, "%s/%s", cachedir, pkgrepopath); if (stat(path, &st) != -1) oldsize = st.st_size; else oldsize = 0; dlsize -= oldsize; humanize_number(size, sizeof(size), pkgsize, "B", HN_AUTOSCALE, 0); printf("\t%s-%s (%" PRId64 "%% of %s)\n", name, newversion, 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); } }
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; }
int exec_info(int argc, char **argv) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; int query_flags; struct pkg *pkg = NULL; uint64_t opt = INFO_TAG_NAMEVER; match_t match = MATCH_GLOB; char *pkgname; char *pkgversion = NULL, *pkgversion2 = NULL; const char *file = NULL; int ch, fd; int ret = EPKG_OK; int retcode = 0; bool gotone = false; int i, j; int sign = 0; int sign2 = 0; int open_flags = 0; bool pkg_exists = false; bool origin_search = false; bool e_flag = false; struct pkg_manifest_key *keys = NULL; #ifdef HAVE_CAPSICUM cap_rights_t rights; #endif struct option longopts[] = { { "all", no_argument, NULL, 'a' }, { "annotations", no_argument, NULL, 'A' }, { "provided-shlibs", no_argument, NULL, 'b' }, { "required-shlibs", no_argument, NULL, 'B' }, { "case-sensitive", no_argument, NULL, 'C' }, { "dependencies", no_argument, NULL, 'd' }, { "pkg-message", no_argument, NULL, 'D' }, { "exists", no_argument, NULL, 'e' }, { "show-name-only", no_argument, NULL, 'E' }, { "full", no_argument, NULL, 'f' }, { "file", required_argument, NULL, 'F' }, { "glob", no_argument, NULL, 'g' }, { "case-insensitive", no_argument, NULL, 'i' }, { "comment", no_argument, NULL, 'I' }, { "locked", no_argument, NULL, 'k' }, { "list-files", no_argument, NULL, 'l' }, { "origin", no_argument, NULL, 'o' }, { "by-origin", no_argument, NULL, 'O' }, { "prefix", no_argument, NULL, 'p' }, { "quiet", no_argument, NULL, 'q' }, { "required-by", no_argument, NULL, 'r' }, { "raw", no_argument, NULL, 'R' }, { "size", no_argument, NULL, 's' }, { "regex", no_argument, NULL, 'x' }, { "raw-format", required_argument, NULL, 1 }, { NULL, 0, NULL, 0 }, }; /* TODO: exclusive opts ? */ while ((ch = getopt_long(argc, argv, "+aAbBCdDeEfF:giIkloOpqrRsx", longopts, NULL)) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'A': opt |= INFO_ANNOTATIONS; break; case 'b': opt |= INFO_SHLIBS_PROVIDED; break; case 'B': opt |= INFO_SHLIBS_REQUIRED; break; case 'C': pkgdb_set_case_sensitivity(true); break; case 'd': opt |= INFO_DEPS; break; case 'D': opt |= INFO_MESSAGE; break; case 'e': pkg_exists = true;; retcode = 1; break; case 'E': /* ports compatibility */ e_flag = true; break; case 'f': opt |= INFO_FULL; break; case 'F': file = optarg; break; case 'g': match = MATCH_GLOB; break; case 'i': pkgdb_set_case_sensitivity(false); break; case 'I': opt |= INFO_COMMENT; break; case 'k': opt |= INFO_LOCKED; break; case 'l': opt |= INFO_FILES; break; case 'o': opt |= INFO_ORIGIN; break; case 'O': origin_search = true; /* only for ports compat */ break; case 'p': opt |= INFO_PREFIX; break; case 'q': quiet = true; break; case 'r': opt |= INFO_RDEPS; break; case 'R': opt |= INFO_RAW; break; case 's': opt |= INFO_FLATSIZE; break; case 'x': match = MATCH_REGEX; break; case 1: if (strcasecmp(optarg, "json") == 0) opt |= INFO_RAW_JSON; else if (strcasecmp(optarg, "json-compact") == 0) opt |= INFO_RAW_JSON_COMPACT; else if (strcasecmp(optarg, "yaml") == 0) opt |= INFO_RAW_YAML; else if (strcasecmp(optarg, "ucl") == 0) opt |= INFO_RAW_UCL; else errx(EX_USAGE, "Invalid format '%s' for the " "raw output, expecting json, json-compact " "or yaml", optarg); break; default: usage_info(); return(EX_USAGE); } } if (argc == 1 || (argc == 2 && quiet)) match = MATCH_ALL; argc -= optind; argv += optind; if (argc == 0 && file == NULL && match != MATCH_ALL) { /* which -O bsd.*.mk always execpt clean output */ if (origin_search) return (EX_OK); usage_info(); return (EX_USAGE); } /* When no other data is requested, default is to print * 'name-ver comment' For -O, just print name-ver */ if (!origin_search && (opt & INFO_ALL) == 0 && match == MATCH_ALL && !quiet) opt |= INFO_COMMENT; /* Special compatibility: handle -O and -q -O */ if (origin_search) { if (quiet) { opt = INFO_TAG_NAMEVER; quiet = false; } else { opt = INFO_TAG_NAMEVER|INFO_COMMENT; } } if (match == MATCH_ALL && opt == INFO_TAG_NAMEVER) quiet = false; if (file != NULL) { if ((fd = open(file, O_RDONLY)) == -1) { warn("Unable to open %s", file); return (EX_IOERR); } #ifdef HAVE_CAPSICUM cap_rights_init(&rights, CAP_READ, CAP_FSTAT); if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS ) { warn("cap_rights_limit() failed"); close(fd); return (EX_SOFTWARE); } if (cap_enter() < 0 && errno != ENOSYS) { warn("cap_enter() failed"); close(fd); return (EX_SOFTWARE); } #endif if (opt == INFO_TAG_NAMEVER) opt |= INFO_FULL; pkg_manifest_keys_new(&keys); if (opt & INFO_RAW) { if ((opt & (INFO_RAW_JSON|INFO_RAW_JSON_COMPACT|INFO_RAW_UCL)) == 0) opt |= INFO_RAW_YAML; } if ((opt & (INFO_RAW | INFO_FILES | INFO_DIRS)) == 0) open_flags = PKG_OPEN_MANIFEST_COMPACT; if (pkg_open_fd(&pkg, fd, keys, open_flags) != EPKG_OK) { close(fd); return (1); } pkg_manifest_keys_free(keys); print_info(pkg, opt); close(fd); pkg_free(pkg); return (EX_OK); } ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL); if (ret == EPKG_ENOACCESS) { warnx("Insufficient privileges to query the package database"); return (EX_NOPERM); } else if (ret == EPKG_ENODB) { if (match == MATCH_ALL) return (EX_OK); if (origin_search) return (EX_OK); if (!quiet) warnx("No packages installed"); return (EX_UNAVAILABLE); } else if (ret != EPKG_OK) return (EX_IOERR); ret = pkgdb_open(&db, PKGDB_DEFAULT); if (ret != 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); } i = 0; do { gotone = false; pkgname = argv[i]; /* * allow to search for origin with a trailing / * likes audio/linux-vsound depending on ${PORTSDIR}/audio/sox/ */ if (argc > 0 && pkgname[strlen(pkgname) -1] == '/') pkgname[strlen(pkgname) -1] = '\0'; if (argc > 0) { j=0; while (pkgname[j] != '\0') { if (pkgname[j] == '<') { if (pkgversion) { pkgversion2 = pkgname + j; sign2 = LT; pkgversion2[0] = '\0'; pkgversion2++; if (pkgversion2[0] == '=') { pkgversion2++; sign=LE; j++; } } else { pkgversion = pkgname + j; sign = LT; pkgversion[0] = '\0'; pkgversion++; if (pkgversion[0] == '=') { pkgversion++; sign=LE; j++; } } } else if (pkgname[j] == '>') { if (pkgversion) { pkgversion2 = pkgname + j; sign2 = GT; pkgversion2[0] = '\0'; pkgversion2++; if (pkgversion2[0] == '=') { pkgversion2++; sign=GE; j++; } } else { pkgversion = pkgname + j; sign = GT; pkgversion[0] = '\0'; pkgversion++; if (pkgversion[0] == '=') { pkgversion++; sign=GE; j++; } } } else if (pkgname[j] == '=') { if (pkgversion) { pkgversion2 = pkgname + j; sign2 = EQ; pkgversion2[0] = '\0'; pkgversion2++; if (pkgversion2[0] == '=') { pkgversion2++; sign=EQ; j++; } } else { pkgversion = pkgname + j; sign = EQ; pkgversion[0] = '\0'; pkgversion++; if (pkgversion[0] == '=') { pkgversion++; sign=EQ; j++; } } } j++; } } if (match != MATCH_ALL && pkgname[0] == '\0') { fprintf(stderr, "Pattern must not be empty.\n"); i++; continue; } if ((it = pkgdb_query(db, pkgname, match)) == NULL) { goto cleanup; } /* this is place for compatibility hacks */ /* ports infrastructure expects pkg info -q -O to * always return 0 even if the ports doesn't exists */ if (origin_search) gotone = true; /* end of compatibility hacks */ /* * only show full version in case of match glob with a * single argument specified which does not contains * any glob pattern */ if (argc == 1 && !origin_search && !quiet && !e_flag && match == MATCH_GLOB && strcspn(pkgname, "*[]{}()") == strlen(pkgname) && opt == INFO_TAG_NAMEVER) opt |= INFO_FULL; query_flags = info_flags(opt, false); while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) { gotone = true; const char *version; pkg_get(pkg, PKG_VERSION, &version); if (pkgversion != NULL) { switch (pkg_version_cmp(version, pkgversion)) { case -1: if (sign != LT && sign != LE) { gotone = false; continue; } break; case 0: if (sign != LE && sign != GE && sign != EQ) { gotone = false; continue; } break; case 1: if (sign != GT && sign != GE) { gotone = false; continue; } break; } } if (pkgversion2 != NULL) { switch (pkg_version_cmp(version, pkgversion2)) { case -1: if (sign2 != LT && sign2 != LE) { gotone = false; continue; } break; case 0: if (sign2 != LE && sign2 != GE && sign2 != EQ) { gotone = false; continue; } break; case 1: if (sign2 != GT && sign2 != GE) { gotone = false; continue; } break; } } if (pkg_exists) retcode = EX_OK; else print_info(pkg, opt); } if (ret != EPKG_END) { retcode = EX_IOERR; } if (retcode == EX_OK && !gotone && match != MATCH_ALL) { if (!quiet) warnx("No package(s) matching %s", argv[i]); retcode = EX_SOFTWARE; } pkgdb_it_free(it); i++; } while (i < argc); cleanup: pkg_free(pkg); pkgdb_release_lock(db, PKGDB_LOCK_READONLY); pkgdb_close(db); return (retcode); }
int exec_info(int argc, char **argv) { struct pkgdb *db = NULL; struct pkgdb_it *it = NULL; int query_flags; struct pkg *pkg = NULL; unsigned int opt = INFO_TAG_NAMEVER; match_t match = MATCH_EXACT; char *pkgname; char *pkgversion = NULL, *pkgversion2 = NULL; const char *file = NULL; int ch; int ret = EPKG_OK; int retcode = 0; bool gotone = false; int i, j; int sign = 0; int sign2 = 0; bool pkg_exists = false; bool origin_search = false; /* TODO: exclusive opts ? */ while ((ch = getopt(argc, argv, "aDegxEIdrklBsqopOfF:R")) != -1) { switch (ch) { case 'a': match = MATCH_ALL; break; case 'O': origin_search = true; /* only for ports compat */ break; case 'e': pkg_exists = true;; retcode = 1; break; case 'g': match = MATCH_GLOB; break; case 'x': match = MATCH_REGEX; break; case 'D': opt |= INFO_MESSAGE; break; case 'd': opt |= INFO_DEPS; break; case 'I': opt |= INFO_COMMENT; break; case 'r': opt |= INFO_RDEPS; break; case 'k': opt |= INFO_LOCKED; break; case 'l': opt |= INFO_FILES; break; case 'B': opt |= INFO_SHLIBS; break; case 's': opt |= INFO_FLATSIZE; break; case 'E': /* ports compatibility */ /* FALLSTHROUGH */ case 'q': quiet = true; break; case 'o': opt |= INFO_ORIGIN; break; case 'p': opt |= INFO_PREFIX; break; case 'f': opt |= INFO_FULL; break; case 'F': file = optarg; break; case 'R': opt |= INFO_RAW; break; default: usage_info(); return(EX_USAGE); } } if (argc == 1) match = MATCH_ALL; argc -= optind; argv += optind; if (argc == 0 && file == NULL && match != MATCH_ALL) { /* which -O bsd.*.mk always execpt clean output */ if (origin_search) return (EX_OK); usage_info(); return (EX_USAGE); } /* When no other data is requested, default is to print * 'name-ver comment' For -O, just print name-ver */ if (!origin_search && (opt & INFO_ALL) == 0 && match == MATCH_ALL && !quiet) opt |= INFO_COMMENT; /* Special compatibility: handle -O and -q -O */ if (origin_search) { if (quiet) { opt = INFO_TAG_NAMEVER; quiet = false; } else { opt = INFO_TAG_NAMEVER|INFO_COMMENT; } } if (match == MATCH_ALL && opt == INFO_TAG_NAMEVER) quiet = false; if (file != NULL) { if (pkg_open(&pkg, file) != EPKG_OK) { return (1); } print_info(pkg, opt); pkg_free(pkg); return (0); } ret = pkgdb_open(&db, PKGDB_DEFAULT); if (ret == EPKG_ENODB) { if (geteuid() == 0) return (EX_IOERR); if (match == MATCH_ALL) return (EX_OK); if (!quiet) printf("No packages installed.\n"); return (EX_UNAVAILABLE); } if (ret != EPKG_OK) return (EX_IOERR); i = 0; do { gotone = false; pkgname = argv[i]; if (match != MATCH_ALL && pkgname[0] == '\0') { fprintf(stderr, "Pattern must not be empty.\n"); i++; continue; } /* * allow to search for origin with a trailing / * likes audio/linux-vsound depending on ${PORTSDIR}/audio/sox/ */ if (argc > 0 && pkgname[strlen(pkgname) -1] == '/') pkgname[strlen(pkgname) -1] = '\0'; if (argc > 0) { j=0; while (pkgname[j] != '\0') { if (pkgname[j] == '<') { if (pkgversion) { pkgversion2 = pkgname + j; sign2 = LT; pkgversion2[0] = '\0'; pkgversion2++; if (pkgversion2[0] == '=') { pkgversion2++; sign=LE; j++; } } else { pkgversion = pkgname + j; sign = LT; pkgversion[0] = '\0'; pkgversion++; if (pkgversion[0] == '=') { pkgversion++; sign=LE; j++; } } } else if (pkgname[j] == '>') { if (pkgversion) { pkgversion2 = pkgname + j; sign2 = GT; pkgversion2[0] = '\0'; pkgversion2++; if (pkgversion2[0] == '=') { pkgversion2++; sign=GE; j++; } } else { pkgversion = pkgname + j; sign = GT; pkgversion[0] = '\0'; pkgversion++; if (pkgversion[0] == '=') { pkgversion++; sign=GE; j++; } } } else if (pkgname[j] == '=') { if (pkgversion) { pkgversion2 = pkgname + j; sign2 = EQ; pkgversion2[0] = '\0'; pkgversion2++; if (pkgversion2[0] == '=') { pkgversion2++; sign=EQ; j++; } } else { pkgversion = pkgname + j; sign = EQ; pkgversion[0] = '\0'; pkgversion++; if (pkgversion[0] == '=') { pkgversion++; sign=EQ; j++; } } } j++; } } else pkgversion = NULL; if ((it = pkgdb_query(db, pkgname, match)) == NULL) { return (EX_IOERR); } /* this is place for compatibility hacks */ /* ports infrastructure expects pkg info -q -O to always return 0 even * if the ports doesn't exists */ if (origin_search) gotone = true; /* end of compatibility hacks */ query_flags = info_flags(opt); while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) { gotone = true; const char *version; pkg_get(pkg, PKG_VERSION, &version); if (pkgversion != NULL) { switch (pkg_version_cmp(version, pkgversion)) { case -1: if (sign != LT && sign != LE) { gotone = false; continue; } break; case 0: if (sign != LE && sign != GE && sign != EQ) { gotone = false; continue; } break; case 1: if (sign != GT && sign != GE) { gotone = false; continue; } break; } } if (pkgversion2 != NULL) { switch (pkg_version_cmp(version, pkgversion2)) { case -1: if (sign2 != LT && sign2 != LE) { gotone = false; continue; } break; case 0: if (sign2 != LE && sign2 != GE && sign2 != EQ) { gotone = false; continue; } break; case 1: if (sign2 != GT && sign2 != GE) { gotone = false; continue; } break; } } if (pkg_exists) retcode = EX_OK; else print_info(pkg, opt); } if (ret != EPKG_END) { retcode = EX_IOERR; } if (retcode == EX_OK && !gotone && match != MATCH_ALL) { if (!quiet) warnx("No package(s) matching %s", argv[i]); retcode = EX_SOFTWARE; } pkgdb_it_free(it); i++; } while (i < argc); pkg_free(pkg); pkgdb_close(db); return (retcode); }
int event_callback(void *data, struct pkg_event *ev) { struct pkg *pkg = NULL; struct pkg_dep *dep = NULL; const char *message; int *debug = data; (void) debug; const char *name, *version, *newversion; 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; pkg_get(ev->e_install_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version); nbdone++; if (nbactions > 0) printf("[%d/%d] ", nbdone, nbactions); printf("Installing %s-%s...", name, version); /* print to the terminal title*/ printf("%c]0;[%d/%d] Installing %s-%s%c", '\033', nbdone, nbactions, name, version, '\007'); break; case PKG_EVENT_INSTALL_FINISHED: if (quiet) break; printf(" done\n"); pkg_get(ev->e_install_finished.pkg, PKG_MESSAGE, &message); if (message != NULL && message[0] != '\0') { if (messages == NULL) messages = sbuf_new_auto(); sbuf_printf(messages, "%s\n", message); } 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; pkg_get(ev->e_deinstall_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version); nbdone++; if (nbactions > 0) printf("[%d/%d] ", nbdone, nbactions); printf("Deleting %s-%s...", name, version); printf("%c]0;[%d/%d] Deleting %s-%s%c", '\033', nbdone, nbactions, name, version, '\007'); break; case PKG_EVENT_DEINSTALL_FINISHED: if (quiet) break; printf(" done\n"); break; case PKG_EVENT_UPGRADE_BEGIN: if (quiet) break; pkg_get(ev->e_upgrade_begin.pkg, PKG_NAME, &name, PKG_VERSION, &newversion, PKG_OLD_VERSION, &version); nbdone++; if (nbactions > 0) printf("[%d/%d] ", nbdone, nbactions); switch (pkg_version_cmp(version, newversion)) { case 1: printf("Downgrading %s from %s to %s...", name, version, newversion); printf("%c]0;[%d/%d] Downgrading %s from %s to %s%c", '\033', nbdone, nbactions, name, version, newversion, '\007'); break; case 0: printf("Reinstalling %s-%s", name, version); printf("%c]0;[%d/%d] Reinstalling %s-%s%c", '\033', nbdone, nbactions, name, version, '\007'); break; case -1: printf("Upgrading %s from %s to %s...", name, version, newversion); printf("%c]0;[%d/%d] Upgrading %s from %s to %s%c", '\033', nbdone, nbactions, name, version, newversion, '\007'); break; } break; case PKG_EVENT_UPGRADE_FINISHED: if (quiet) break; printf(" done\n"); break; case PKG_EVENT_LOCKED: pkg = ev->e_locked.pkg; pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version); fprintf(stderr, "\n%s-%s is locked and may not be modified\n", name, version); break; case PKG_EVENT_REQUIRED: pkg = ev->e_required.pkg; pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version); fprintf(stderr, "\n%s-%s is required by:", name, version); while (pkg_rdeps(pkg, &dep) == EPKG_OK) fprintf(stderr, " %s-%s", pkg_dep_name(dep), pkg_dep_version(dep)); 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_get(ev->e_already_installed.pkg, PKG_NAME, &name, PKG_VERSION, &version); printf("%s-%s already installed\n", name, version); 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: printf("New version of pkg detected; it needs to be " "installed first.\nAfter this upgrade it is recommended " "that you do a full upgrade using: 'pkg upgrade'\n\n"); break; case PKG_EVENT_FILE_MISMATCH: pkg_get(ev->e_file_mismatch.pkg, PKG_NAME, &name, PKG_VERSION, &version); fprintf(stderr, "%s-%s: checksum mismatch for %s\n", name, version, 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; default: break; } return 0; }
int exec_version(int argc, char **argv) { unsigned int opt = 0; int ch; while ((ch = getopt(argc, argv, "hIoqvlLXsOtT")) != -1) { switch (ch) { case 'h': usage_version(); return (0); case 'I': opt |= VERSION_INDEX; break; case 'o': opt |= VERSION_ORIGIN; break; case 'q': opt |= VERSION_QUIET; break; case 'v': opt |= VERSION_VERBOSE; break; case 'l': opt |= VERSION_STATUS; break; case 'L': opt |= VERSION_NOSTATUS; break; case 'X': opt |= VERSION_EREGEX; break; case 's': opt |= VERSION_STRING; break; case 'O': opt |= VERSION_WITHORIGIN; break; case 't': opt |= VERSION_TESTVERSION; break; case 'T': opt |= VERSION_TESTPATTERN; break; } } argc -= optind; argv += optind; /* -t must be unique */ if (((opt & VERSION_TESTVERSION) && opt != VERSION_TESTVERSION) || (opt == VERSION_TESTVERSION && argc < 2)) { usage_version(); return (EX_USAGE); } else if (opt == VERSION_TESTVERSION) { switch (pkg_version_cmp(argv[0], argv[1])) { case -1: printf("<\n"); break; case 0: printf("=\n"); break; case 1: printf(">\n"); break; } } return 0; }
int event_callback(void *data, struct pkg_event *ev) { struct pkg *pkg = NULL; struct pkg_dep *dep = NULL; const char *message; int *debug = data; (void) debug; const char *name, *version, *newversion; const char *filename; switch(ev->type) { case PKG_EVENT_ERRNO: warn("%s(%s)", ev->e_errno.func, ev->e_errno.arg); break; case PKG_EVENT_ERROR: warnx("%s", ev->e_pkg_error.msg); break; case PKG_EVENT_FETCHING: if (quiet) 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; pkg_get(ev->e_install_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version); printf("Installing %s-%s...", name, version); break; case PKG_EVENT_INSTALL_FINISHED: if (quiet) break; printf(" done\n"); pkg_get(ev->e_install_finished.pkg, PKG_MESSAGE, &message); if (message != NULL && message[0] != '\0') { if (messages == NULL) messages = sbuf_new_auto(); sbuf_printf(messages, "%s\n", message); } 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_DEINSTALL_BEGIN: if (quiet) break; pkg_get(ev->e_deinstall_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version); printf("Deinstalling %s-%s...", name, version); break; case PKG_EVENT_DEINSTALL_FINISHED: if (quiet) break; printf(" done\n"); break; case PKG_EVENT_UPGRADE_BEGIN: if (quiet) break; pkg_get(ev->e_upgrade_finished.pkg, PKG_NAME, &name, PKG_VERSION, &version, PKG_NEWVERSION, &newversion); switch (pkg_version_cmp(version, newversion)) { case 1: printf("Downgrading %s from %s to %s...", name, version, newversion); break; case 0: printf("Reinstalling %s-%s", name, version); break; case -1: printf("Upgrading %s from %s to %s...", name, version, newversion); break; } break; case PKG_EVENT_UPGRADE_FINISHED: if (quiet) break; printf(" done\n"); break; case PKG_EVENT_REQUIRED: pkg = ev->e_required.pkg; pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version); fprintf(stderr, "%s-%s is required by:", name, version); while (pkg_rdeps(pkg, &dep) == EPKG_OK) fprintf(stderr, " %s-%s", pkg_dep_name(dep), pkg_dep_version(dep)); 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_get(ev->e_already_installed.pkg, PKG_NAME, &name, PKG_VERSION, &version); printf("%s-%s already installed\n", name, version); break; case PKG_EVENT_MISSING_DEP: fprintf(stderr, "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: /* only cares if run as root */ if (geteuid() == 0) fprintf(stderr, "Unable to create local database!\n"); break; case PKG_EVENT_NEWPKGVERSION: printf("New version of pkg detected; it needs to be " "installed first.\nAfter this upgrade it is recommended" "that you do a full upgrade using: 'pkg upgrade'\n\n"); break; case PKG_EVENT_FILE_MISMATCH: pkg_get(ev->e_file_mismatch.pkg, PKG_NAME, &name, PKG_VERSION, &version); fprintf(stderr, "%s-%s: checksum mismatch for %s\n", name, version, pkg_file_path(ev->e_file_mismatch.file)); default: break; } return 0; }