/* * Gets the PackageKit repository name for the package. */ const char * repo_of_package(struct pkg *package) { const char *repo; assert(package != NULL); /* * clang complains about this redundant assignment, but gcc complains * if it doesn't exist. */ #ifndef __clang__ repo = ""; #endif /* __clang */ switch (pkg_type(package)) { case PKG_OLD_FILE: case PKG_FILE: repo = "local"; break; case PKG_INSTALLED: repo = "installed"; break; case PKG_REMOTE: repo = repo_of_remote_package(package); break; case PKG_NONE: repo = "unknown"; break; } assert(repo != NULL); return repo; }
/* * Gets the PackageKit repository name for the (remote) package. * * Currently this is the pkgng repository name (not the ident as was previously * the case). * * This does not need to be freed (possibly, TODO: check). */ static const char * repo_of_remote_package(struct pkg *pkg) { const char *repo_name; assert(pkg != NULL); assert(pkg_type(pkg) == PKG_REMOTE); repo_name = NULL; pkg_get(pkg, PKG_REPONAME, &repo_name); return repo_name; }
void print_info(struct pkg * const pkg, unsigned int options) { struct pkg_category *cat = NULL; struct pkg_dep *dep = NULL; struct pkg_dir *dir = NULL; struct pkg_file *file = NULL; struct pkg_group *group = NULL; struct pkg_license *lic = NULL; struct pkg_option *option = NULL; struct pkg_shlib *shlib = NULL; struct pkg_user *user = NULL; bool multirepos_enabled = false; bool print_tag = false; bool show_locks = false; char size[7]; const char *name, *version, *prefix, *origin, *reponame, *repourl; const char *maintainer, *www, *comment, *desc, *message, *arch; const char *repopath; const char *tab; char *m; unsigned opt; int64_t flatsize, newflatsize, newpkgsize; lic_t licenselogic; bool locked; int cout = 0; /* Number of characters output */ int info_num; /* Number of different data items to print */ pkg_config_bool(PKG_CONFIG_MULTIREPOS, &multirepos_enabled); pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version, PKG_PREFIX, &prefix, PKG_ORIGIN, &origin, PKG_REPONAME, &reponame, PKG_REPOURL, &repourl, PKG_MAINTAINER, &maintainer, PKG_WWW, &www, PKG_COMMENT, &comment, PKG_DESC, &desc, PKG_FLATSIZE, &flatsize, PKG_NEW_FLATSIZE, &newflatsize, PKG_NEW_PKGSIZE, &newpkgsize, PKG_LICENSE_LOGIC, &licenselogic, PKG_MESSAGE, &message, PKG_ARCH, &arch, PKG_REPOPATH, &repopath, PKG_LOCKED, &locked); if (!multirepos_enabled) pkg_config_string(PKG_CONFIG_REPO, &repourl); if (options & INFO_RAW) { /* Not for remote packages */ if (pkg_type(pkg) != PKG_REMOTE) { pkg_emit_manifest(pkg, &m); printf("%s\n", m); free(m); } 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 = printf("%s-%s", name, version); else if (options & INFO_TAG_ORIGIN) cout = printf("%s", origin); else if (options & INFO_TAG_NAME) cout = printf("%s", name); } /* Don't display a tab if quiet, retains compatibility. */ tab = quiet ? "" : "\t"; /* 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"); printf("%s\n", name); break; case INFO_VERSION: if (print_tag) printf("%-15s: ", "Version"); printf("%s\n", version); break; case INFO_ORIGIN: if (print_tag) printf("%-15s: ", "Origin"); printf("%s\n", origin); break; case INFO_PREFIX: if (print_tag) printf("%-15s: ", "Prefix"); printf("%s\n", prefix); break; case INFO_REPOSITORY: if (pkg_type(pkg) == PKG_REMOTE && repourl != NULL && repourl[0] != '\0') { if (print_tag) printf("%-15s: ", "Repository"); printf("%s [%s]\n", reponame, 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"); if (pkg_categories(pkg, &cat) == EPKG_OK) printf("%s", pkg_category_name(cat)); while (pkg_categories(pkg, &cat) == EPKG_OK) printf(" %s", pkg_category_name(cat)); printf("\n"); } else if (!print_tag) printf("\n"); break; case INFO_LICENSES: if (pkg_list_count(pkg, PKG_LICENSES) > 0) { if (print_tag) printf("%-15s: ", "Licenses"); if (pkg_licenses(pkg, &lic) == EPKG_OK) printf("%s", pkg_license_name(lic)); while (pkg_licenses(pkg, &lic) == EPKG_OK) { if (licenselogic != 1) printf(" %c", licenselogic); printf(" %s", pkg_license_name(lic)); } printf("\n"); } else if (!print_tag) printf("\n"); break; case INFO_MAINTAINER: if (print_tag) printf("%-15s: ", "Maintainer"); printf("%s\n", maintainer); break; case INFO_WWW: if (print_tag) printf("%-15s: ", "WWW"); printf("%s\n", www); break; case INFO_COMMENT: if (print_tag) printf("%-15s: ", "Comment"); printf("%s\n", comment); break; case INFO_OPTIONS: if (pkg_list_count(pkg, PKG_OPTIONS) > 0) { if (print_tag) printf("%-15s:\n", "Options"); while (pkg_options(pkg, &option) == EPKG_OK) printf("%s%-15s: %s\n", tab, pkg_option_opt(option), pkg_option_value(option)); } break; case INFO_SHLIBS_REQUIRED: if (pkg_list_count(pkg, PKG_SHLIBS_REQUIRED) > 0) { if (print_tag) printf("%-15s:\n", "Shared Libs required"); while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) printf("%s%s\n", tab, pkg_shlib_name(shlib)); } break; case INFO_SHLIBS_PROVIDED: if (pkg_list_count(pkg, PKG_SHLIBS_PROVIDED) > 0) { if (print_tag) printf("%-15s:\n", "Shared Libs provided"); while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) printf("%s%s\n", tab, pkg_shlib_name(shlib)); } break; case INFO_FLATSIZE: if (pkg_type(pkg) == PKG_INSTALLED || pkg_type(pkg) == PKG_FILE) humanize_number(size, sizeof(size), flatsize,"B", HN_AUTOSCALE, 0); else humanize_number(size, sizeof(size), newflatsize,"B", HN_AUTOSCALE, 0); if (print_tag) printf("%-15s: ", "Flat size"); printf("%s\n", size); break; case INFO_PKGSIZE: /* Remote pkgs only */ if (pkg_type(pkg) == PKG_REMOTE) { humanize_number(size, sizeof(size), newpkgsize,"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"); printf("%s\n", desc); break; case INFO_MESSAGE: if (message) { if (print_tag) printf("%-15s:\n", "Message"); printf("%s\n", message); } break; case INFO_DEPS: if (pkg_list_count(pkg, PKG_DEPS) > 0) { if (print_tag) printf("%-15s:\n", "Depends on"); while (pkg_deps(pkg, &dep) == EPKG_OK) { printf("%s%s-%s", tab, pkg_dep_name(dep), pkg_dep_version(dep)); if (show_locks && pkg_dep_is_locked(dep)) printf(" (*)"); printf("\n"); } } break; case INFO_RDEPS: if (pkg_list_count(pkg, PKG_RDEPS) > 0) { if (print_tag) printf("%-15s:\n", "Required by"); while (pkg_rdeps(pkg, &dep) == EPKG_OK) { printf("%s%s-%s", tab, pkg_dep_name(dep), pkg_dep_version(dep)); if (show_locks && pkg_dep_is_locked(dep)) printf(" (*)"); printf("\n"); } } 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"); while (pkg_files(pkg, &file) == EPKG_OK) printf("%s%s\n", tab, pkg_file_path(file)); } 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"); while (pkg_dirs(pkg, &dir) == EPKG_OK) printf("%s%s\n", tab, pkg_dir_path(dir)); } 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"); if (pkg_users(pkg, &user) == EPKG_OK) printf("%s", pkg_user_name(user)); while (pkg_users(pkg, &user) == EPKG_OK) printf(" %s", pkg_user_name(user)); printf("\n"); } 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"); if (pkg_groups(pkg, &group) == EPKG_OK) printf("%s", pkg_group_name(group)); while (pkg_groups(pkg, &group) == EPKG_OK) printf(" %s", pkg_group_name(group)); printf("\n"); } break; case INFO_ARCH: if (print_tag) printf("%-15s: ", "Architecture"); printf("%s\n", arch); 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] == '/') printf("%s%s\n", repourl, repopath); else printf("%s/%s\n", repourl, repopath); } else if (!print_tag) printf("\n"); break; case INFO_LOCKED: if (print_tag) printf("%-15s: ", "Locked"); printf("%s\n", locked ? "yes" : "no"); break; } } }
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 print_info(struct pkg * const pkg, unsigned int opt) { struct pkg_dep *dep = NULL; struct pkg_file *file = NULL; struct pkg_category *cat = NULL; struct pkg_license *lic = NULL; struct pkg_option *option = NULL; bool multirepos_enabled = false; char *m; char size[7]; const char *name, *version, *prefix, *origin, *reponame, *repourl; const char *maintainer, *www, *comment, *desc; int64_t flatsize, newflatsize, newpkgsize; lic_t licenselogic; pkg_config_bool(PKG_CONFIG_MULTIREPOS, &multirepos_enabled); pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version, PKG_PREFIX, &prefix, PKG_ORIGIN, &origin, PKG_REPONAME, &reponame, PKG_REPOURL, &repourl, PKG_MAINTAINER, &maintainer, PKG_WWW, &www, PKG_COMMENT, &comment, PKG_DESC, &desc, PKG_FLATSIZE, &flatsize, PKG_NEW_FLATSIZE, &newflatsize, PKG_NEW_PKGSIZE, &newpkgsize, PKG_LICENSE_LOGIC, &licenselogic); if (opt & INFO_RAW) { pkg_emit_manifest(pkg, &m); printf("%s\n", m); free(m); } else if (opt & INFO_FULL) { printf("%-15s: %s\n", "Name", name); printf("%-15s: %s\n", "Version", version); printf("%-15s: %s\n", "Origin", origin); printf("%-15s: %s\n", "Prefix", prefix); if ((pkg_type(pkg) == PKG_REMOTE) && multirepos_enabled) printf("%-15s: %s [%s]\n", "Repository", reponame, repourl); if (!pkg_list_is_empty(pkg, PKG_CATEGORIES)) { printf("%-15s:", "Categories"); while (pkg_categories(pkg, &cat) == EPKG_OK) printf(" %s", pkg_category_name(cat)); printf("\n"); } if (!pkg_list_is_empty(pkg, PKG_LICENSES)) { printf("%-15s:", "Licenses"); while (pkg_licenses(pkg, &lic) == EPKG_OK) { printf(" %s", pkg_license_name(lic)); if (licenselogic != 1) printf(" %c", licenselogic); else printf(" "); } printf("\b \n"); } printf("%-15s: %s\n", "Maintainer", maintainer); printf("%-15s: %s\n", "WWW", www); printf("%-15s: %s\n", "Comment", comment); if (!pkg_list_is_empty(pkg, PKG_OPTIONS)) { printf("%-15s: \n", "Options"); while (pkg_options(pkg, &option) == EPKG_OK) printf("\t%s: %s\n", pkg_option_opt(option), pkg_option_value(option)); } if (pkg_type(pkg) == PKG_INSTALLED || pkg_type(pkg) == PKG_FILE) { humanize_number(size, sizeof(size), flatsize, "B", HN_AUTOSCALE, 0); printf("%-15s: %s\n", "Flat size", size); } else { humanize_number(size, sizeof(size), newflatsize, "B", HN_AUTOSCALE, 0); printf("%-15s: %s\n", "Flat size", size); humanize_number(size, sizeof(size), newpkgsize, "B", HN_AUTOSCALE, 0); printf("%-15s: %s\n", "Pkg size", size); } printf("%-15s: \n%s\n", "Description", desc); printf("\n"); } else if (opt & INFO_PRINT_DEP) { if (!(opt & INFO_QUIET)) printf("%s-%s depends on:\n", name, version); while (pkg_deps(pkg, &dep) == EPKG_OK) { printf("%s-%s\n", pkg_dep_get(dep, PKG_DEP_NAME), pkg_dep_get(dep, PKG_DEP_VERSION)); } if (!(opt & INFO_QUIET)) printf("\n"); } else if (opt & INFO_PRINT_RDEP) { if (!(opt & INFO_QUIET)) printf("%s-%s is required by:\n", name, version); while (pkg_rdeps(pkg, &dep) == EPKG_OK) { printf("%s-%s\n", pkg_dep_get(dep, PKG_DEP_NAME), pkg_dep_get(dep, PKG_DEP_VERSION)); } if (!(opt & INFO_QUIET)) printf("\n"); } else if (opt & INFO_LIST_FILES) { if (!(opt & INFO_QUIET)) printf("%s-%s owns the following files:\n", name, version); while (pkg_files(pkg, &file) == EPKG_OK) { printf("%s\n", pkg_file_get(file, PKG_FILE_PATH)); } if (!(opt & INFO_QUIET)) printf("\n"); } else if (opt & INFO_SIZE) { if (pkg_type(pkg) == PKG_INSTALLED) { humanize_number(size, sizeof(size), flatsize, "B", HN_AUTOSCALE, 0); printf("%s-%s size is: %s\n", name, version, size); } else { humanize_number(size, sizeof(size), newflatsize, "B", HN_AUTOSCALE, 0); printf("%s-%s flat size is: %s\n", name, version, size); humanize_number(size, sizeof(size), newpkgsize, "B", HN_AUTOSCALE, 0); printf("%s-%s package size is: %s\n", name, version, size); } } else if (opt & INFO_ORIGIN) { if (opt & INFO_QUIET) printf("%s\n", origin); else printf("%s-%s: %s\n", name, version, origin); } else if (opt & INFO_PREFIX) { if (opt & INFO_QUIET) printf("%s\n", prefix); else printf("%s-%s: %s\n", name, version, prefix); } else { if (opt & INFO_QUIET) printf("%s-%s\n", name, version); else { if ((pkg_type(pkg) == PKG_REMOTE) && multirepos_enabled) printf("%s-%s [repository: %s]: %s\n", name, version, reponame, comment); else printf("%s-%s: %s\n", name, version, comment); } } return (0); }
int pkg_add(struct pkgdb *db, const char *path, unsigned flags, struct pkg_manifest_key *keys) { const char *arch; const char *origin; const char *name; struct archive *a; struct archive_entry *ae; struct pkg *pkg = NULL; struct pkg_dep *dep = NULL; struct pkg *pkg_inst = NULL; bool extract = true; bool handle_rc = false; bool disable_mtree; char dpath[MAXPATHLEN]; const char *basedir; const char *ext; char *mtree; char *prefix; int retcode = EPKG_OK; int ret; assert(path != NULL); /* * Open the package archive file, read all the meta files and set the * current archive_entry to the first non-meta file. * If there is no non-meta files, EPKG_END is returned. */ ret = pkg_open2(&pkg, &a, &ae, path, keys, 0); if (ret == EPKG_END) extract = false; else if (ret != EPKG_OK) { retcode = ret; goto cleanup; } if ((flags & PKG_ADD_UPGRADE) == 0) pkg_emit_install_begin(pkg); if (pkg_is_valid(pkg) != EPKG_OK) { pkg_emit_error("the package is not valid"); return (EPKG_FATAL); } if (flags & PKG_ADD_AUTOMATIC) pkg_set(pkg, PKG_AUTOMATIC, (int64_t)true); /* * Check the architecture */ pkg_get(pkg, PKG_ARCH, &arch, PKG_ORIGIN, &origin, PKG_NAME, &name); if (!is_valid_abi(arch, true)) { if ((flags & PKG_ADD_FORCE) == 0) { retcode = EPKG_FATAL; goto cleanup; } } /* * Check if the package is already installed */ ret = pkg_try_installed(db, origin, &pkg_inst, PKG_LOAD_BASIC); if (ret == EPKG_OK) { if ((flags & PKG_FLAG_FORCE) == 0) { pkg_emit_already_installed(pkg_inst); retcode = EPKG_INSTALLED; pkg_free(pkg_inst); pkg_inst = NULL; goto cleanup; } else { pkg_emit_notice("package %s is already installed, forced install", name); pkg_free(pkg_inst); pkg_inst = NULL; } } else if (ret != EPKG_END) { retcode = ret; goto cleanup; } /* * Check for dependencies by searching the same directory as * the package archive we're reading. Of course, if we're * reading from a file descriptor or a unix domain socket or * somesuch, there's no valid directory to search. */ if (pkg_type(pkg) == PKG_FILE) { basedir = dirname(path); if ((ext = strrchr(path, '.')) == NULL) { pkg_emit_error("%s has no extension", path); retcode = EPKG_FATAL; goto cleanup; } } else { basedir = NULL; ext = NULL; } while (pkg_deps(pkg, &dep) == EPKG_OK) { if (pkg_is_installed(db, pkg_dep_origin(dep)) == EPKG_OK) continue; if (basedir != NULL) { const char *dep_name = pkg_dep_name(dep); const char *dep_ver = pkg_dep_version(dep); snprintf(dpath, sizeof(dpath), "%s/%s-%s%s", basedir, dep_name, dep_ver, ext); if ((flags & PKG_ADD_UPGRADE) == 0 && access(dpath, F_OK) == 0) { ret = pkg_add(db, dpath, PKG_ADD_AUTOMATIC, keys); if (ret != EPKG_OK) { retcode = EPKG_FATAL; goto cleanup; } } else { pkg_emit_error("Missing dependency matching '%s'", pkg_dep_get(dep, PKG_DEP_ORIGIN)); retcode = EPKG_FATAL; goto cleanup; } } else { retcode = EPKG_FATAL; pkg_emit_missing_dep(pkg, dep); goto cleanup; } } /* register the package before installing it in case there are * problems that could be caught here. */ retcode = pkgdb_register_pkg(db, pkg, flags & PKG_ADD_UPGRADE, flags & PKG_FLAG_FORCE); if (retcode != EPKG_OK) goto cleanup; /* MTREE replicates much of the standard functionality * inplicit in the way pkg works. It has to remain available * in the ports for compatibility with the old pkg_tools, but * ultimately, MTREE should be made redundant. Use this for * experimantal purposes and to develop MTREE-free versions of * packages. */ pkg_config_bool(PKG_CONFIG_DISABLE_MTREE, &disable_mtree); if (!disable_mtree) { pkg_get(pkg, PKG_PREFIX, &prefix, PKG_MTREE, &mtree); if ((retcode = do_extract_mtree(mtree, prefix)) != EPKG_OK) goto cleanup_reg; } /* * Execute pre-install scripts */ if ((flags & (PKG_ADD_NOSCRIPT | PKG_ADD_USE_UPGRADE_SCRIPTS)) == 0) pkg_script_run(pkg, PKG_SCRIPT_PRE_INSTALL); /* add the user and group if necessary */ /* pkg_add_user_group(pkg); */ /* * Extract the files on disk. */ if (extract && (retcode = do_extract(a, ae)) != EPKG_OK) { /* If the add failed, clean up (silently) */ pkg_delete_files(pkg, 2); pkg_delete_dirs(db, pkg, 1); goto cleanup_reg; } /* * Execute post install scripts */ if ((flags & PKG_ADD_NOSCRIPT) == 0) { if ((flags & PKG_ADD_USE_UPGRADE_SCRIPTS) == PKG_ADD_USE_UPGRADE_SCRIPTS) pkg_script_run(pkg, PKG_SCRIPT_POST_UPGRADE); else pkg_script_run(pkg, PKG_SCRIPT_POST_INSTALL); } /* * start the different related services if the users do want that * and that the service is running */ pkg_config_bool(PKG_CONFIG_HANDLE_RC_SCRIPTS, &handle_rc); if (handle_rc) pkg_start_stop_rc_scripts(pkg, PKG_RC_START); cleanup_reg: if ((flags & PKG_ADD_UPGRADE) == 0) pkgdb_register_finale(db, retcode); if (retcode == EPKG_OK && (flags & PKG_ADD_UPGRADE) == 0) pkg_emit_install_finished(pkg); cleanup: if (a != NULL) { archive_read_close(a); archive_read_free(a); } pkg_free(pkg); if (pkg_inst != NULL) pkg_free(pkg_inst); return (retcode); }