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_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); } }
int exec_install(int argc, char **argv) { struct pkg *pkg = NULL; struct pkgdb_it *it = NULL; struct pkgdb *db = NULL; struct pkg_jobs *jobs = NULL; const char *reponame = NULL; int retcode = 1; int ch; bool yes = false; int64_t dlsize = 0; int64_t oldsize = 0, newsize = 0; char size[7]; match_t match = MATCH_EXACT; while ((ch = getopt(argc, argv, "ygxXr:")) != -1) { switch (ch) { case 'y': yes = true; break; case 'g': match = MATCH_GLOB; break; case 'x': match = MATCH_REGEX; break; case 'X': match = MATCH_EREGEX; break; case 'r': reponame = optarg; break; default: usage_install(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc < 1) { usage_install(); return (EX_USAGE); } if (geteuid() != 0) { warnx("installing packages can only be done as root"); return (EX_NOPERM); } if (pkgdb_open(&db, PKGDB_REMOTE) != EPKG_OK) { return (EX_IOERR); } if (pkg_jobs_new(&jobs, PKG_JOBS_INSTALL, db) != EPKG_OK) { goto cleanup; } if ((it = pkgdb_query_installs(db, match, argc, argv, reponame)) == NULL) goto cleanup; while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC|PKG_LOAD_DEPS) == EPKG_OK) { pkg_jobs_add(jobs, pkg); pkg = NULL; } pkgdb_it_free(it); if (pkg_jobs_is_empty(jobs)) { printf("Nothing to do\n"); retcode = 0; goto cleanup; } /* print a summary before applying the jobs */ pkg = NULL; printf("The following packages will be installed:\n"); while (pkg_jobs(jobs, &pkg) == EPKG_OK) { const char *name, *version, *newversion; int64_t flatsize, newflatsize, pkgsize; pkg_get(pkg, PKG_NEWVERSION, &newversion, PKG_NAME, &name, PKG_VERSION, &version, PKG_FLATSIZE, &flatsize, PKG_NEW_FLATSIZE, &newflatsize, PKG_NEW_PKGSIZE, &pkgsize); dlsize += pkgsize; if (newversion != NULL) { printf("\tUpgrading %s: %s -> %s\n", name, version, newversion); oldsize += flatsize; newsize += flatsize; } else { newsize += flatsize; printf("\tInstalling %s: %s\n", name, version); } } if (oldsize > newsize) { newsize *= -1; humanize_number(size, sizeof(size), oldsize - newsize, "B", HN_AUTOSCALE, 0); printf("\nthe installation will save %s\n", size); } else { humanize_number(size, sizeof(size), newsize - oldsize, "B", HN_AUTOSCALE, 0); printf("\nthe installation will require %s more space\n", size); } humanize_number(size, sizeof(size), dlsize, "B", HN_AUTOSCALE, 0); printf("%s to be downloaded\n", size); if (yes == false) pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes); if (yes == false) yes = query_yesno("\nProceed with installing packages [y/N]: "); if (yes == true) if (pkg_jobs_apply(jobs, 0) != EPKG_OK) goto cleanup; retcode = 0; cleanup: pkg_jobs_free(jobs); pkgdb_close(db); return (retcode); }