show.c revision 96392
1/* 2 * FreeBSD install - a package for the installation and maintainance 3 * of non-core utilities. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * Jordan K. Hubbard 15 * 23 Aug 1993 16 * 17 * Various display routines for the info module. 18 * 19 */ 20 21#include <sys/cdefs.h> 22__FBSDID("$FreeBSD: head/usr.sbin/pkg_install/info/show.c 96392 2002-05-11 04:17:55Z alfred $"); 23 24#include "lib.h" 25#include "info.h" 26#include <err.h> 27#include <stdlib.h> 28#include <sys/types.h> 29#include <sys/stat.h> 30#include <md5.h> 31 32void 33show_file(const char *title, const char *fname) 34{ 35 FILE *fp; 36 char line[1024]; 37 int n; 38 39 if (!Quiet) 40 printf("%s%s", InfoPrefix, title); 41 fp = fopen(fname, "r"); 42 if (!fp) 43 printf("ERROR: show_file: Can't open '%s' for reading!\n", fname); 44 else { 45 while ((n = fread(line, 1, 1024, fp)) != 0) 46 fwrite(line, 1, n, stdout); 47 fclose(fp); 48 } 49 printf("\n"); /* just in case */ 50} 51 52void 53show_index(const char *title, const char *fname) 54{ 55 FILE *fp; 56 char line[MAXINDEXSIZE+2]; 57 58 if (!Quiet) 59 printf("%s%s", InfoPrefix, title); 60 fp = fopen(fname, "r"); 61 if (!fp) { 62 warnx("show_file: can't open '%s' for reading", fname); 63 return; 64 } 65 if(fgets(line, MAXINDEXSIZE+1, fp)) { 66 if(line[MAXINDEXSIZE-1] != '\n') 67 line[MAXINDEXSIZE] = '\n'; 68 line[MAXINDEXSIZE+1] = 0; 69 fputs(line, stdout); 70 } 71 fclose(fp); 72} 73 74/* Show a packing list item type. If showall is TRUE, show all */ 75void 76show_plist(const char *title, Package *plist, plist_t type, Boolean showall) 77{ 78 PackingList p; 79 Boolean ign = FALSE; 80 81 if (!Quiet) 82 printf("%s%s", InfoPrefix, title); 83 p = plist->head; 84 while (p) { 85 if (p->type != type && showall != TRUE) { 86 p = p->next; 87 continue; 88 } 89 switch(p->type) { 90 case PLIST_FILE: 91 if (ign) { 92 printf(Quiet ? "%s\n" : "File: %s (ignored)\n", p->name); 93 ign = FALSE; 94 } 95 else 96 printf(Quiet ? "%s\n" : "File: %s\n", p->name); 97 break; 98 99 case PLIST_CWD: 100 printf(Quiet ? "@cwd %s\n" : "\tCWD to %s\n", p->name); 101 break; 102 103 case PLIST_SRC: 104 printf(Quiet ? "@srcdir %s\n" : "\tSRCDIR to %s\n", p->name); 105 break; 106 107 case PLIST_CMD: 108 printf(Quiet ? "@exec %s\n" : "\tEXEC '%s'\n", p->name); 109 break; 110 111 case PLIST_UNEXEC: 112 printf(Quiet ? "@unexec %s\n" : "\tUNEXEC '%s'\n", p->name); 113 break; 114 115 case PLIST_CHMOD: 116 printf(Quiet ? "@chmod %s\n" : "\tCHMOD to %s\n", 117 p->name ? p->name : "(clear default)"); 118 break; 119 120 case PLIST_CHOWN: 121 printf(Quiet ? "@chown %s\n" : "\tCHOWN to %s\n", 122 p->name ? p->name : "(clear default)"); 123 break; 124 125 case PLIST_CHGRP: 126 printf(Quiet ? "@chgrp %s\n" : "\tCHGRP to %s\n", 127 p->name ? p->name : "(clear default)"); 128 break; 129 130 case PLIST_COMMENT: 131 printf(Quiet ? "@comment %s\n" : "\tComment: %s\n", p->name); 132 break; 133 134 case PLIST_IGNORE: 135 ign = TRUE; 136 break; 137 138 case PLIST_IGNORE_INST: 139 printf(Quiet ? "@ignore_inst ??? doesn't belong here.\n" : 140 "\tIgnore next file installation directive (doesn't belong)\n"); 141 ign = TRUE; 142 break; 143 144 case PLIST_NAME: 145 printf(Quiet ? "@name %s\n" : "\tPackage name: %s\n", p->name); 146 break; 147 148 case PLIST_DISPLAY: 149 printf(Quiet ? "@display %s\n" : "\tInstall message file: %s\n", p->name); 150 break; 151 152 case PLIST_PKGDEP: 153 printf(Quiet ? "@pkgdep %s\n" : "Dependency: %s\n", p->name); 154 break; 155 156 case PLIST_DEPORIGIN: 157 printf(Quiet ? "@comment DEPORIGIN:%s\n" : 158 "\tdependency origin: %s\n", p->name); 159 break; 160 161 case PLIST_MTREE: 162 printf(Quiet ? "@mtree %s\n" : "\tPackage mtree file: %s\n", p->name); 163 break; 164 165 case PLIST_DIR_RM: 166 printf(Quiet ? "@dirrm %s\n" : "\tDeinstall directory remove: %s\n", p->name); 167 break; 168 169 case PLIST_OPTION: 170 printf(Quiet ? "@option %s\n" : 171 "\tOption \"%s\" controlling package installation behaviour\n", 172 p->name); 173 break; 174 175 case PLIST_ORIGIN: 176 printf(Quiet ? "@comment ORIGIN:%s\n" : 177 "\tPackage origin: %s\n", p->name); 178 break; 179 180 default: 181 cleanup(0); 182 errx(2, "%s: unknown command type %d (%s)", 183 __func__, p->type, p->name); 184 break; 185 } 186 p = p->next; 187 } 188} 189 190/* Show all files in the packing list (except ignored ones) */ 191void 192show_files(const char *title, Package *plist) 193{ 194 PackingList p; 195 Boolean ign = FALSE; 196 const char *dir = "."; 197 198 if (!Quiet) 199 printf("%s%s", InfoPrefix, title); 200 p = plist->head; 201 while (p) { 202 switch(p->type) { 203 case PLIST_FILE: 204 if (!ign) 205 printf("%s/%s\n", dir, p->name); 206 ign = FALSE; 207 break; 208 209 case PLIST_CWD: 210 dir = p->name; 211 break; 212 213 case PLIST_IGNORE: 214 ign = TRUE; 215 break; 216 217 /* Silence GCC in the -Wall mode */ 218 default: 219 break; 220 } 221 p = p->next; 222 } 223} 224 225/* Calculate and show size of all installed package files (except ignored ones) */ 226void 227show_size(const char *title, Package *plist) 228{ 229 PackingList p; 230 Boolean ign = FALSE; 231 const char *dir = "."; 232 struct stat sb; 233 char tmp[FILENAME_MAX]; 234 unsigned long size = 0; 235 long blksize; 236 int headerlen; 237 char *descr; 238 239 descr = getbsize(&headerlen, &blksize); 240 if (!Quiet) 241 printf("%s%s", InfoPrefix, title); 242 for (p = plist->head; p != NULL; p = p->next) { 243 switch (p->type) { 244 case PLIST_FILE: 245 if (!ign) { 246 snprintf(tmp, FILENAME_MAX, "%s/%s", dir, p->name); 247 if (!lstat(tmp, &sb)) { 248 size += sb.st_size; 249 if (Verbose) 250 printf("%lu\t%s\n", (unsigned long) howmany(sb.st_size, blksize), tmp); 251 } 252 } 253 ign = FALSE; 254 break; 255 256 case PLIST_CWD: 257 dir = p->name; 258 break; 259 260 case PLIST_IGNORE: 261 ign = TRUE; 262 break; 263 264 /* Silence GCC in the -Wall mode */ 265 default: 266 break; 267 } 268 } 269 if (!Quiet) 270 printf("%lu\t(%s)\n", howmany(size, blksize), descr); 271 else 272 printf("%lu\n", size); 273} 274 275/* Show files that don't match the recorded checksum */ 276void 277show_cksum(const char *title, Package *plist) 278{ 279 PackingList p; 280 const char *dir = "."; 281 char tmp[FILENAME_MAX]; 282 283 if (!Quiet) 284 printf("%s%s", InfoPrefix, title); 285 286 for (p = plist->head; p != NULL; p = p->next) 287 if (p->type == PLIST_CWD) 288 dir = p->name; 289 else if (p->type == PLIST_FILE) { 290 snprintf(tmp, FILENAME_MAX, "%s/%s", dir, p->name); 291 if (!fexists(tmp)) 292 warnx("%s doesn't exist\n", tmp); 293 else if (p->next && p->next->type == PLIST_COMMENT && 294 (strncmp(p->next->name, "MD5:", 4) == 0)) { 295 char *cp = NULL, buf[33]; 296 297 /* 298 * For packing lists whose version is 1.1 or greater, the md5 299 * hash for a symlink is calculated on the string returned 300 * by readlink(). 301 */ 302 if (issymlink(tmp) && verscmp(plist, 1, 0) > 0) { 303 int len; 304 char linkbuf[FILENAME_MAX]; 305 306 if ((len = readlink(tmp, linkbuf, FILENAME_MAX)) > 0) 307 cp = MD5Data((unsigned char *)linkbuf, len, buf); 308 } else if (isfile(tmp) || verscmp(plist, 1, 1) < 0) 309 cp = MD5File(tmp, buf); 310 311 if (cp != NULL) { 312 /* Mismatch? */ 313 if (strcmp(cp, p->next->name + 4)) 314 printf("%s fails the original MD5 checksum\n", tmp); 315 else if (Verbose) 316 printf("%s matched the original MD5 checksum\n", tmp); 317 } 318 } 319 } 320} 321 322/* Show an "origin" path (usually category/portname) */ 323void 324show_origin(const char *title, Package *plist) 325{ 326 327 if (!Quiet) 328 printf("%s%s", InfoPrefix, title); 329 printf("%s\n", plist->origin != NULL ? plist->origin : ""); 330} 331 332/* Show revision number of the packing list */ 333void 334show_fmtrev(const char *title, Package *plist) 335{ 336 337 if (!Quiet) 338 printf("%s%s", InfoPrefix, title); 339 printf("%d.%d\n", plist->fmtver_maj, plist->fmtver_mnr); 340} 341