package.c

Go to the documentation of this file.
00001 /*
00002  *  package.c
00003  *
00004  *  Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org>
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018  */
00019 
00020 #include "config.h"
00021 
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <limits.h>
00026 #include <sys/stat.h>
00027 
00028 #include <alpm.h>
00029 #include <alpm_list.h>
00030 
00031 /* pacman */
00032 #include "package.h"
00033 #include "util.h"
00034 
00035 #define CLBUF_SIZE 4096
00036 
00037 /* Display the content of a package
00038  *
00039  * level: <0 - sync package [-Si]
00040  *        =0 - file query [-Qip]
00041  *         1 - localdb query, normal level [-Qi]
00042  *        >1 - localdb query, extra information (backup files) [-Qii]
00043  */
00044 void dump_pkg_full(pmpkg_t *pkg, int level)
00045 {
00046     const char *reason, *descheader;
00047     time_t bdate, idate;
00048     char bdatestr[50] = "", idatestr[50] = "";
00049     const alpm_list_t *i;
00050     alpm_list_t *requiredby = NULL, *depstrings = NULL;
00051 
00052     if(pkg == NULL) {
00053         return;
00054     }
00055 
00056     /* set variables here, do all output below */
00057     bdate = alpm_pkg_get_builddate(pkg);
00058     if(bdate) {
00059         strftime(bdatestr, 50, "%c", localtime(&bdate));
00060     }
00061     idate = alpm_pkg_get_installdate(pkg);
00062     if(idate) {
00063         strftime(idatestr, 50, "%c", localtime(&idate));
00064     }
00065 
00066     switch((long)alpm_pkg_get_reason(pkg)) {
00067         case PM_PKG_REASON_EXPLICIT:
00068             reason = _("Explicitly installed");
00069             break;
00070         case PM_PKG_REASON_DEPEND:
00071             reason = _("Installed as a dependency for another package");
00072             break;
00073         default:
00074             reason = _("Unknown");
00075             break;
00076     }
00077 
00078     /* turn depends list into a text list */
00079     for(i = alpm_pkg_get_depends(pkg); i; i = alpm_list_next(i)) {
00080         pmdepend_t *dep = (pmdepend_t*)alpm_list_getdata(i);
00081         depstrings = alpm_list_add(depstrings, alpm_dep_get_string(dep));
00082     }
00083 
00084     if(level>0) {
00085         /* compute this here so we don't get a puase in the middle of output */
00086         requiredby = alpm_pkg_compute_requiredby(pkg);
00087     }
00088 
00089     descheader = _("Description    : ");
00090 
00091     /* actual output */
00092     if(level == 0) {
00093         string_display(_("Filename       :"), alpm_pkg_get_filename(pkg));
00094     }
00095     string_display(_("Name           :"), alpm_pkg_get_name(pkg));
00096     string_display(_("Version        :"), alpm_pkg_get_version(pkg));
00097     string_display(_("URL            :"), alpm_pkg_get_url(pkg));
00098     list_display(_("Licenses       :"), alpm_pkg_get_licenses(pkg));
00099     list_display(_("Groups         :"), alpm_pkg_get_groups(pkg));
00100     list_display(_("Provides       :"), alpm_pkg_get_provides(pkg));
00101     list_display(_("Depends On     :"), depstrings);
00102     list_display(_("Optional Deps  :"), alpm_pkg_get_optdepends(pkg));
00103     /* Only applicable if installed */
00104     if(level > 0) {
00105         list_display(_("Required By    :"), requiredby);
00106         FREELIST(requiredby);
00107     }
00108     list_display(_("Conflicts With :"), alpm_pkg_get_conflicts(pkg));
00109     list_display(_("Replaces       :"), alpm_pkg_get_replaces(pkg));
00110     if(level < 0) {
00111         printf(_("Download Size  : %6.2f K\n"),
00112             (float)alpm_pkg_get_size(pkg) / 1024.0);
00113     }
00114     if(level == 0) {
00115         printf(_("Compressed Size: %6.2f K\n"),
00116             (float)alpm_pkg_get_size(pkg) / 1024.0);
00117     }
00118 
00119     printf(_("Installed Size : %6.2f K\n"),
00120             (float)alpm_pkg_get_isize(pkg) / 1024.0);
00121     string_display(_("Packager       :"), alpm_pkg_get_packager(pkg));
00122     string_display(_("Architecture   :"), alpm_pkg_get_arch(pkg));
00123     string_display(_("Build Date     :"), bdatestr);
00124     if(level > 0) {
00125         string_display(_("Install Date   :"), idatestr);
00126         string_display(_("Install Reason :"), reason);
00127     }
00128     if(level >= 0) {
00129         string_display(_("Install Script :"),
00130                 alpm_pkg_has_scriptlet(pkg) ?  _("Yes") : _("No"));
00131     }
00132 
00133     /* MD5 Sum for sync package */
00134     if(level < 0) {
00135         string_display(_("MD5 Sum        :"), alpm_pkg_get_md5sum(pkg));
00136     }
00137 
00138     /* printed using a variable to make i18n safe */
00139     printf("%s", descheader);
00140     indentprint(alpm_pkg_get_desc(pkg), mbstowcs(NULL, descheader, 0));
00141     printf("\n\n");
00142 
00143     /* Print additional package info if info flag passed more than once */
00144     if(level > 1) {
00145         dump_pkg_backups(pkg);
00146         printf("\n");
00147     }
00148 
00149     FREELIST(depstrings);
00150 }
00151 
00152 /* Display the content of a sync package
00153  */
00154 void dump_pkg_sync(pmpkg_t *pkg, const char *treename)
00155 {
00156     if(pkg == NULL) {
00157         return;
00158     }
00159     string_display(_("Repository     :"), treename);
00160     dump_pkg_full(pkg, -1);
00161 }
00162 
00163 /* Display list of backup files and their modification states
00164  */
00165 void dump_pkg_backups(pmpkg_t *pkg)
00166 {
00167     alpm_list_t *i;
00168     const char *root = alpm_option_get_root();
00169     printf(_("Backup Files:\n"));
00170     if(alpm_pkg_get_backup(pkg)) {
00171         /* package has backup files, so print them */
00172         for(i = alpm_pkg_get_backup(pkg); i; i = alpm_list_next(i)) {
00173             struct stat buf;
00174             char path[PATH_MAX];
00175             char *str = strdup(alpm_list_getdata(i));
00176             char *ptr = index(str, '\t');
00177             if(ptr == NULL) {
00178                 free(str);
00179                 continue;
00180             }
00181             *ptr = '\0';
00182             ptr++;
00183             snprintf(path, PATH_MAX-1, "%s%s", root, str);
00184             /* if we find the file, calculate checksums, otherwise it is missing */
00185             if(!stat(path, &buf)) {
00186                 char *md5sum = alpm_get_md5sum(path);
00187 
00188                 if(md5sum == NULL) {
00189                     fprintf(stderr, _("error: could not calculate checksums for %s\n"),
00190                             path);
00191                     free(str);
00192                     continue;
00193                 }
00194 
00195                 /* if checksums don't match, file has been modified */
00196                 if (strcmp(md5sum, ptr)) {
00197                     printf(_("MODIFIED\t%s\n"), path);
00198                 } else {
00199                     printf(_("Not Modified\t%s\n"), path);
00200                 }
00201                 free(md5sum);
00202             } else {
00203                 printf(_("MISSING\t\t%s\n"), path);
00204             }
00205             free(str);
00206         }
00207     } else {
00208         /* package had no backup files */
00209         printf(_("(none)\n"));
00210     }
00211 }
00212 
00213 /* List all files contained in a package
00214  */
00215 void dump_pkg_files(pmpkg_t *pkg)
00216 {
00217     const char *pkgname, *root, *filestr;
00218     alpm_list_t *i, *pkgfiles;
00219     char path[PATH_MAX];
00220 
00221     pkgname = alpm_pkg_get_name(pkg);
00222     pkgfiles = alpm_pkg_get_files(pkg);
00223     root = alpm_option_get_root();
00224 
00225     for(i = pkgfiles; i; i = alpm_list_next(i)) {
00226         filestr = (char*)alpm_list_getdata(i);
00227         /* build a path so we can stat the filename */
00228         snprintf(path, PATH_MAX-1, "%s%s", root, filestr);
00229         fprintf(stdout, "%s %s\n", pkgname, path);
00230     }
00231 
00232     fflush(stdout);
00233 }
00234 
00235 /* Display the changelog of a package
00236  */
00237 void dump_pkg_changelog(pmpkg_t *pkg)
00238 {
00239     void *fp = NULL;
00240 
00241     if((fp = alpm_pkg_changelog_open(pkg)) == NULL) {
00242         /* TODO after string freeze use pm_fprintf */
00243         fprintf(stderr, _("error: no changelog available for '%s'.\n"),
00244                 alpm_pkg_get_name(pkg));
00245         return;
00246     } else {
00247         /* allocate a buffer to get the changelog back in chunks */
00248         char buf[CLBUF_SIZE];
00249         int ret = 0;
00250         while((ret = alpm_pkg_changelog_read(buf, CLBUF_SIZE, pkg, fp))) {
00251             if(ret < CLBUF_SIZE) {
00252                 /* if we hit the end of the file, we need to add a null terminator */
00253                 *(buf + ret) = '\0';
00254             }
00255             printf("%s", buf);
00256         }
00257         alpm_pkg_changelog_close(pkg, fp);
00258         printf("\n");
00259     }
00260 }
00261 
00262 /* vim: set ts=2 sw=2 noet: */

Generated on Mon Jan 14 23:53:40 2008 for libalpm by  doxygen 1.5.4