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