show.c revision 108455
1327Sjkh/* 2327Sjkh * FreeBSD install - a package for the installation and maintainance 3327Sjkh * of non-core utilities. 4327Sjkh * 5327Sjkh * Redistribution and use in source and binary forms, with or without 6327Sjkh * modification, are permitted provided that the following conditions 7327Sjkh * are met: 8327Sjkh * 1. Redistributions of source code must retain the above copyright 9327Sjkh * notice, this list of conditions and the following disclaimer. 10327Sjkh * 2. Redistributions in binary form must reproduce the above copyright 11327Sjkh * notice, this list of conditions and the following disclaimer in the 12327Sjkh * documentation and/or other materials provided with the distribution. 13327Sjkh * 14327Sjkh * Jordan K. Hubbard 15327Sjkh * 23 Aug 1993 16327Sjkh * 17327Sjkh * Various display routines for the info module. 18327Sjkh * 19327Sjkh */ 20327Sjkh 2193520Sobrien#include <sys/cdefs.h> 2293520Sobrien__FBSDID("$FreeBSD: head/usr.sbin/pkg_install/info/show.c 108455 2002-12-30 18:16:26Z mike $"); 2393520Sobrien 24327Sjkh#include "lib.h" 25327Sjkh#include "info.h" 2649637Sbillf#include <err.h> 2762775Ssobomax#include <stdlib.h> 2862775Ssobomax#include <sys/types.h> 2962775Ssobomax#include <sys/stat.h> 3071965Sjkh#include <md5.h> 3149637Sbillf 32327Sjkhvoid 3384745Ssobomaxshow_file(const char *title, const char *fname) 34327Sjkh{ 35327Sjkh FILE *fp; 36327Sjkh char line[1024]; 37327Sjkh int n; 38327Sjkh 39411Sjkh if (!Quiet) 40411Sjkh printf("%s%s", InfoPrefix, title); 41327Sjkh fp = fopen(fname, "r"); 429781Sache if (!fp) 439781Sache printf("ERROR: show_file: Can't open '%s' for reading!\n", fname); 449781Sache else { 4516549Sjkh while ((n = fread(line, 1, 1024, fp)) != 0) 469781Sache fwrite(line, 1, n, stdout); 479781Sache fclose(fp); 48327Sjkh } 49327Sjkh printf("\n"); /* just in case */ 50327Sjkh} 51327Sjkh 525399Sswallacevoid 5384745Ssobomaxshow_index(const char *title, const char *fname) 545399Sswallace{ 555399Sswallace FILE *fp; 565399Sswallace char line[MAXINDEXSIZE+2]; 578857Srgrimes 585399Sswallace if (!Quiet) 595399Sswallace printf("%s%s", InfoPrefix, title); 605399Sswallace fp = fopen(fname, "r"); 615399Sswallace if (!fp) { 6230221Scharnier warnx("show_file: can't open '%s' for reading", fname); 635399Sswallace return; 648857Srgrimes } 655399Sswallace if(fgets(line, MAXINDEXSIZE+1, fp)) { 665399Sswallace if(line[MAXINDEXSIZE-1] != '\n') 675399Sswallace line[MAXINDEXSIZE] = '\n'; 685399Sswallace line[MAXINDEXSIZE+1] = 0; 695399Sswallace fputs(line, stdout); 705399Sswallace } 715399Sswallace fclose(fp); 728857Srgrimes} 735399Sswallace 7484745Ssobomax/* Show a packing list item type. If showall is TRUE, show all */ 75327Sjkhvoid 7684745Ssobomaxshow_plist(const char *title, Package *plist, plist_t type, Boolean showall) 77327Sjkh{ 78327Sjkh PackingList p; 79327Sjkh Boolean ign = FALSE; 80327Sjkh 81411Sjkh if (!Quiet) 82411Sjkh printf("%s%s", InfoPrefix, title); 83327Sjkh p = plist->head; 84327Sjkh while (p) { 8584745Ssobomax if (p->type != type && showall != TRUE) { 86327Sjkh p = p->next; 87327Sjkh continue; 88327Sjkh } 89327Sjkh switch(p->type) { 90327Sjkh case PLIST_FILE: 91327Sjkh if (ign) { 92411Sjkh printf(Quiet ? "%s\n" : "File: %s (ignored)\n", p->name); 93327Sjkh ign = FALSE; 94327Sjkh } 95327Sjkh else 96411Sjkh printf(Quiet ? "%s\n" : "File: %s\n", p->name); 97327Sjkh break; 988857Srgrimes 99327Sjkh case PLIST_CWD: 100411Sjkh printf(Quiet ? "@cwd %s\n" : "\tCWD to %s\n", p->name); 101327Sjkh break; 102327Sjkh 1034996Sjkh case PLIST_SRC: 1044996Sjkh printf(Quiet ? "@srcdir %s\n" : "\tSRCDIR to %s\n", p->name); 1054996Sjkh break; 1064996Sjkh 107327Sjkh case PLIST_CMD: 108411Sjkh printf(Quiet ? "@exec %s\n" : "\tEXEC '%s'\n", p->name); 109327Sjkh break; 110327Sjkh 11130531Sjkh case PLIST_UNEXEC: 11230531Sjkh printf(Quiet ? "@unexec %s\n" : "\tUNEXEC '%s'\n", p->name); 11330531Sjkh break; 11430531Sjkh 115327Sjkh case PLIST_CHMOD: 116411Sjkh printf(Quiet ? "@chmod %s\n" : "\tCHMOD to %s\n", 117411Sjkh p->name ? p->name : "(clear default)"); 118327Sjkh break; 119327Sjkh 120327Sjkh case PLIST_CHOWN: 121411Sjkh printf(Quiet ? "@chown %s\n" : "\tCHOWN to %s\n", 122411Sjkh p->name ? p->name : "(clear default)"); 123327Sjkh break; 124327Sjkh 125327Sjkh case PLIST_CHGRP: 126411Sjkh printf(Quiet ? "@chgrp %s\n" : "\tCHGRP to %s\n", 127411Sjkh p->name ? p->name : "(clear default)"); 128327Sjkh break; 129327Sjkh 130327Sjkh case PLIST_COMMENT: 131411Sjkh printf(Quiet ? "@comment %s\n" : "\tComment: %s\n", p->name); 132327Sjkh break; 133327Sjkh 134327Sjkh case PLIST_IGNORE: 135327Sjkh ign = TRUE; 136327Sjkh break; 137327Sjkh 1384996Sjkh case PLIST_IGNORE_INST: 1394996Sjkh printf(Quiet ? "@ignore_inst ??? doesn't belong here.\n" : 1404996Sjkh "\tIgnore next file installation directive (doesn't belong)\n"); 1414996Sjkh ign = TRUE; 1424996Sjkh break; 1434996Sjkh 144327Sjkh case PLIST_NAME: 145411Sjkh printf(Quiet ? "@name %s\n" : "\tPackage name: %s\n", p->name); 146327Sjkh break; 147327Sjkh 1484996Sjkh case PLIST_DISPLAY: 1494996Sjkh printf(Quiet ? "@display %s\n" : "\tInstall message file: %s\n", p->name); 1504996Sjkh break; 1514996Sjkh 1524996Sjkh case PLIST_PKGDEP: 15396076Ssobomax printf(Quiet ? "@pkgdep %s\n" : "Dependency: %s\n", p->name); 1544996Sjkh break; 1554996Sjkh 15696076Ssobomax case PLIST_DEPORIGIN: 15796076Ssobomax printf(Quiet ? "@comment DEPORIGIN:%s\n" : 15896076Ssobomax "\tdependency origin: %s\n", p->name); 15996076Ssobomax break; 16096076Ssobomax 1614996Sjkh case PLIST_MTREE: 1624996Sjkh printf(Quiet ? "@mtree %s\n" : "\tPackage mtree file: %s\n", p->name); 1634996Sjkh break; 1644996Sjkh 1654996Sjkh case PLIST_DIR_RM: 1664996Sjkh printf(Quiet ? "@dirrm %s\n" : "\tDeinstall directory remove: %s\n", p->name); 1674996Sjkh break; 1684996Sjkh 16981218Skris case PLIST_OPTION: 17081218Skris printf(Quiet ? "@option %s\n" : 17181218Skris "\tOption \"%s\" controlling package installation behaviour\n", 17281218Skris p->name); 17381218Skris break; 17481218Skris 17596065Ssobomax case PLIST_ORIGIN: 17696065Ssobomax printf(Quiet ? "@comment ORIGIN:%s\n" : 17796065Ssobomax "\tPackage origin: %s\n", p->name); 17896065Ssobomax break; 17996065Ssobomax 180327Sjkh default: 18130221Scharnier cleanup(0); 18296388Salfred errx(2, "%s: unknown command type %d (%s)", 18396392Salfred __func__, p->type, p->name); 184327Sjkh break; 185327Sjkh } 186327Sjkh p = p->next; 187327Sjkh } 188327Sjkh} 189327Sjkh 190411Sjkh/* Show all files in the packing list (except ignored ones) */ 191411Sjkhvoid 19284745Ssobomaxshow_files(const char *title, Package *plist) 193411Sjkh{ 194411Sjkh PackingList p; 195411Sjkh Boolean ign = FALSE; 19684745Ssobomax const char *dir = "."; 197411Sjkh 198411Sjkh if (!Quiet) 199411Sjkh printf("%s%s", InfoPrefix, title); 200411Sjkh p = plist->head; 201411Sjkh while (p) { 202411Sjkh switch(p->type) { 203411Sjkh case PLIST_FILE: 204411Sjkh if (!ign) 205411Sjkh printf("%s/%s\n", dir, p->name); 206411Sjkh ign = FALSE; 207411Sjkh break; 2088857Srgrimes 209411Sjkh case PLIST_CWD: 210411Sjkh dir = p->name; 211411Sjkh break; 212411Sjkh 213411Sjkh case PLIST_IGNORE: 214411Sjkh ign = TRUE; 215411Sjkh break; 21662775Ssobomax 21762775Ssobomax /* Silence GCC in the -Wall mode */ 21862775Ssobomax default: 21962775Ssobomax break; 220411Sjkh } 221411Sjkh p = p->next; 222411Sjkh } 223411Sjkh} 22462775Ssobomax 22562775Ssobomax/* Calculate and show size of all installed package files (except ignored ones) */ 22662775Ssobomaxvoid 22784745Ssobomaxshow_size(const char *title, Package *plist) 22862775Ssobomax{ 22962775Ssobomax PackingList p; 23062775Ssobomax Boolean ign = FALSE; 23184745Ssobomax const char *dir = "."; 23262775Ssobomax struct stat sb; 23362775Ssobomax char tmp[FILENAME_MAX]; 23462775Ssobomax unsigned long size = 0; 23562775Ssobomax long blksize; 236108455Smike int headerlen; 23762775Ssobomax char *descr; 23862775Ssobomax 23962775Ssobomax descr = getbsize(&headerlen, &blksize); 24062775Ssobomax if (!Quiet) 24162775Ssobomax printf("%s%s", InfoPrefix, title); 24262775Ssobomax for (p = plist->head; p != NULL; p = p->next) { 24362775Ssobomax switch (p->type) { 24462775Ssobomax case PLIST_FILE: 24562775Ssobomax if (!ign) { 24662775Ssobomax snprintf(tmp, FILENAME_MAX, "%s/%s", dir, p->name); 24762775Ssobomax if (!lstat(tmp, &sb)) { 24862775Ssobomax size += sb.st_size; 24962775Ssobomax if (Verbose) 25062775Ssobomax printf("%lu\t%s\n", (unsigned long) howmany(sb.st_size, blksize), tmp); 25162775Ssobomax } 25262775Ssobomax } 25362775Ssobomax ign = FALSE; 25462775Ssobomax break; 25562775Ssobomax 25662775Ssobomax case PLIST_CWD: 25762775Ssobomax dir = p->name; 25862775Ssobomax break; 25962775Ssobomax 26062775Ssobomax case PLIST_IGNORE: 26162775Ssobomax ign = TRUE; 26262775Ssobomax break; 26362775Ssobomax 26462775Ssobomax /* Silence GCC in the -Wall mode */ 26562775Ssobomax default: 26662775Ssobomax break; 26762775Ssobomax } 26862775Ssobomax } 26962775Ssobomax if (!Quiet) 27062775Ssobomax printf("%lu\t(%s)\n", howmany(size, blksize), descr); 27162775Ssobomax else 27262775Ssobomax printf("%lu\n", size); 27362775Ssobomax} 27467454Ssobomax 27571965Sjkh/* Show files that don't match the recorded checksum */ 27671965Sjkhvoid 27784745Ssobomaxshow_cksum(const char *title, Package *plist) 27871965Sjkh{ 27971965Sjkh PackingList p; 28084745Ssobomax const char *dir = "."; 28171965Sjkh char tmp[FILENAME_MAX]; 28271965Sjkh 28371965Sjkh if (!Quiet) 28471965Sjkh printf("%s%s", InfoPrefix, title); 28571965Sjkh 28671965Sjkh for (p = plist->head; p != NULL; p = p->next) 28771965Sjkh if (p->type == PLIST_CWD) 28871965Sjkh dir = p->name; 28971965Sjkh else if (p->type == PLIST_FILE) { 29071965Sjkh snprintf(tmp, FILENAME_MAX, "%s/%s", dir, p->name); 29171965Sjkh if (!fexists(tmp)) 29271965Sjkh warnx("%s doesn't exist\n", tmp); 29395933Ssobomax else if (p->next && p->next->type == PLIST_COMMENT && 29495933Ssobomax (strncmp(p->next->name, "MD5:", 4) == 0)) { 29595933Ssobomax char *cp = NULL, buf[33]; 29695933Ssobomax 29795933Ssobomax /* 29895933Ssobomax * For packing lists whose version is 1.1 or greater, the md5 29995933Ssobomax * hash for a symlink is calculated on the string returned 30095933Ssobomax * by readlink(). 30195933Ssobomax */ 30295933Ssobomax if (issymlink(tmp) && verscmp(plist, 1, 0) > 0) { 30395933Ssobomax int len; 30495933Ssobomax char linkbuf[FILENAME_MAX]; 30595933Ssobomax 30695933Ssobomax if ((len = readlink(tmp, linkbuf, FILENAME_MAX)) > 0) 30795933Ssobomax cp = MD5Data((unsigned char *)linkbuf, len, buf); 30895933Ssobomax } else if (isfile(tmp) || verscmp(plist, 1, 1) < 0) 30995933Ssobomax cp = MD5File(tmp, buf); 31095933Ssobomax 31195933Ssobomax if (cp != NULL) { 31295933Ssobomax /* Mismatch? */ 31371965Sjkh if (strcmp(cp, p->next->name + 4)) 31471965Sjkh printf("%s fails the original MD5 checksum\n", tmp); 31571965Sjkh else if (Verbose) 31671965Sjkh printf("%s matched the original MD5 checksum\n", tmp); 31772034Ssobomax } 31871965Sjkh } 31971965Sjkh } 32071965Sjkh} 32171965Sjkh 32267454Ssobomax/* Show an "origin" path (usually category/portname) */ 32367454Ssobomaxvoid 32484745Ssobomaxshow_origin(const char *title, Package *plist) 32567454Ssobomax{ 32667454Ssobomax 32767454Ssobomax if (!Quiet) 32867454Ssobomax printf("%s%s", InfoPrefix, title); 32996030Ssobomax printf("%s\n", plist->origin != NULL ? plist->origin : ""); 33067454Ssobomax} 33184750Ssobomax 33284750Ssobomax/* Show revision number of the packing list */ 33384750Ssobomaxvoid 33484750Ssobomaxshow_fmtrev(const char *title, Package *plist) 33584750Ssobomax{ 33696030Ssobomax 33784750Ssobomax if (!Quiet) 33884750Ssobomax printf("%s%s", InfoPrefix, title); 33984750Ssobomax printf("%d.%d\n", plist->fmtver_maj, plist->fmtver_mnr); 34084750Ssobomax} 341