Rename pmdepend_t to alpm_depend_t
[pacman-ng.git] / src / pacman / package.c
blob49d80ef0bc43eda0729f3993ebf7427cd8997b36
1 /*
2 * package.c
4 * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
5 * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "config.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <limits.h>
28 #include <errno.h>
30 #include <alpm.h>
31 #include <alpm_list.h>
33 /* pacman */
34 #include "package.h"
35 #include "util.h"
36 #include "conf.h"
38 #define CLBUF_SIZE 4096
40 /**
41 * Display the details of a package.
42 * Extra information entails 'required by' info for sync packages and backup
43 * files info for local packages.
44 * @param pkg package to display information for
45 * @param from the type of package we are dealing with
46 * @param extra should we show extra information
48 void dump_pkg_full(alpm_pkg_t *pkg, enum pkg_from from, int extra)
50 const char *reason;
51 time_t bdate, idate;
52 char bdatestr[50] = "", idatestr[50] = "";
53 const char *label;
54 double size;
55 const alpm_list_t *i;
56 alpm_list_t *requiredby = NULL, *depstrings = NULL;
58 if(pkg == NULL) {
59 return;
62 /* set variables here, do all output below */
63 bdate = alpm_pkg_get_builddate(pkg);
64 if(bdate) {
65 strftime(bdatestr, 50, "%c", localtime(&bdate));
67 idate = alpm_pkg_get_installdate(pkg);
68 if(idate) {
69 strftime(idatestr, 50, "%c", localtime(&idate));
72 switch((long)alpm_pkg_get_reason(pkg)) {
73 case PM_PKG_REASON_EXPLICIT:
74 reason = _("Explicitly installed");
75 break;
76 case PM_PKG_REASON_DEPEND:
77 reason = _("Installed as a dependency for another package");
78 break;
79 default:
80 reason = _("Unknown");
81 break;
84 /* turn depends list into a text list */
85 for(i = alpm_pkg_get_depends(pkg); i; i = alpm_list_next(i)) {
86 alpm_depend_t *dep = (alpm_depend_t *)alpm_list_getdata(i);
87 depstrings = alpm_list_add(depstrings, alpm_dep_compute_string(dep));
90 if(extra || from == PKG_FROM_LOCALDB) {
91 /* compute this here so we don't get a pause in the middle of output */
92 requiredby = alpm_pkg_compute_requiredby(pkg);
95 /* actual output */
96 if(from == PKG_FROM_SYNCDB) {
97 string_display(_("Repository :"),
98 alpm_db_get_name(alpm_pkg_get_db(pkg)));
100 string_display(_("Name :"), alpm_pkg_get_name(pkg));
101 string_display(_("Version :"), alpm_pkg_get_version(pkg));
102 string_display(_("URL :"), alpm_pkg_get_url(pkg));
103 list_display(_("Licenses :"), alpm_pkg_get_licenses(pkg));
104 list_display(_("Groups :"), alpm_pkg_get_groups(pkg));
105 list_display(_("Provides :"), alpm_pkg_get_provides(pkg));
106 list_display(_("Depends On :"), depstrings);
107 list_display_linebreak(_("Optional Deps :"), alpm_pkg_get_optdepends(pkg));
108 if(extra || from == PKG_FROM_LOCALDB) {
109 list_display(_("Required By :"), requiredby);
111 list_display(_("Conflicts With :"), alpm_pkg_get_conflicts(pkg));
112 list_display(_("Replaces :"), alpm_pkg_get_replaces(pkg));
114 size = humanize_size(alpm_pkg_get_size(pkg), 'K', 1, &label);
115 if(from == PKG_FROM_SYNCDB) {
116 printf(_("Download Size : %6.2f %s\n"), size, label);
117 } else if(from == PKG_FROM_FILE) {
118 printf(_("Compressed Size: %6.2f %s\n"), size, label);
121 size = humanize_size(alpm_pkg_get_isize(pkg), 'K', 1, &label);
122 printf(_("Installed Size : %6.2f %s\n"), size, label);
124 string_display(_("Packager :"), alpm_pkg_get_packager(pkg));
125 string_display(_("Architecture :"), alpm_pkg_get_arch(pkg));
126 string_display(_("Build Date :"), bdatestr);
127 if(from == PKG_FROM_LOCALDB) {
128 string_display(_("Install Date :"), idatestr);
129 string_display(_("Install Reason :"), reason);
131 if(from == PKG_FROM_FILE || from == PKG_FROM_LOCALDB) {
132 string_display(_("Install Script :"),
133 alpm_pkg_has_scriptlet(pkg) ? _("Yes") : _("No"));
136 if(from == PKG_FROM_SYNCDB) {
137 string_display(_("MD5 Sum :"), alpm_pkg_get_md5sum(pkg));
139 string_display(_("Description :"), alpm_pkg_get_desc(pkg));
141 /* Print additional package info if info flag passed more than once */
142 if(from == PKG_FROM_LOCALDB && extra) {
143 dump_pkg_backups(pkg);
146 /* final newline to separate packages */
147 printf("\n");
149 FREELIST(depstrings);
150 FREELIST(requiredby);
153 static const char *get_backup_file_status(const char *root,
154 const pmbackup_t *backup)
156 char path[PATH_MAX];
157 const char *ret;
159 snprintf(path, PATH_MAX, "%s%s", root, backup->name);
161 /* if we find the file, calculate checksums, otherwise it is missing */
162 if(access(path, R_OK) == 0) {
163 char *md5sum = alpm_compute_md5sum(path);
165 if(md5sum == NULL) {
166 pm_fprintf(stderr, PM_LOG_ERROR,
167 _("could not calculate checksums for %s\n"), path);
168 return NULL;
171 /* if checksums don't match, file has been modified */
172 if(strcmp(md5sum, backup->hash) != 0) {
173 ret = "MODIFIED";
174 } else {
175 ret = "UNMODIFIED";
177 free(md5sum);
178 } else {
179 switch(errno) {
180 case EACCES:
181 ret = "UNREADABLE";
182 break;
183 case ENOENT:
184 ret = "MISSING";
185 break;
186 default:
187 ret = "UNKNOWN";
190 return ret;
193 /* Display list of backup files and their modification states
195 void dump_pkg_backups(alpm_pkg_t *pkg)
197 alpm_list_t *i;
198 const char *root = alpm_option_get_root(config->handle);
199 printf(_("Backup Files:\n"));
200 if(alpm_pkg_get_backup(pkg)) {
201 /* package has backup files, so print them */
202 for(i = alpm_pkg_get_backup(pkg); i; i = alpm_list_next(i)) {
203 const pmbackup_t *backup = alpm_list_getdata(i);
204 const char *value;
205 if(!backup->hash) {
206 continue;
208 value = get_backup_file_status(root, backup);
209 printf("%s\t%s%s\n", value, root, backup->name);
211 } else {
212 /* package had no backup files */
213 printf(_("(none)\n"));
217 /* List all files contained in a package
219 void dump_pkg_files(alpm_pkg_t *pkg, int quiet)
221 const char *pkgname, *root, *filestr;
222 alpm_list_t *i, *pkgfiles;
224 pkgname = alpm_pkg_get_name(pkg);
225 pkgfiles = alpm_pkg_get_files(pkg);
226 root = alpm_option_get_root(config->handle);
228 for(i = pkgfiles; i; i = alpm_list_next(i)) {
229 filestr = alpm_list_getdata(i);
230 if(!quiet){
231 fprintf(stdout, "%s %s%s\n", pkgname, root, filestr);
232 } else {
233 fprintf(stdout, "%s%s\n", root, filestr);
237 fflush(stdout);
240 /* Display the changelog of a package
242 void dump_pkg_changelog(alpm_pkg_t *pkg)
244 void *fp = NULL;
246 if((fp = alpm_pkg_changelog_open(pkg)) == NULL) {
247 pm_fprintf(stderr, PM_LOG_ERROR, _("no changelog available for '%s'.\n"),
248 alpm_pkg_get_name(pkg));
249 return;
250 } else {
251 /* allocate a buffer to get the changelog back in chunks */
252 char buf[CLBUF_SIZE];
253 size_t ret = 0;
254 while((ret = alpm_pkg_changelog_read(buf, CLBUF_SIZE, pkg, fp))) {
255 if(ret < CLBUF_SIZE) {
256 /* if we hit the end of the file, we need to add a null terminator */
257 *(buf + ret) = '\0';
259 printf("%s", buf);
261 alpm_pkg_changelog_close(pkg, fp);
262 printf("\n");
266 /* vim: set ts=2 sw=2 noet: */