show.c revision 93520
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 93520 2002-04-01 09:39:07Z obrien $");
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" : "\t%s\n", p->name);
154	    break;
155
156	case PLIST_MTREE:
157	    printf(Quiet ? "@mtree %s\n" : "\tPackage mtree file: %s\n", p->name);
158	    break;
159
160	case PLIST_DIR_RM:
161	    printf(Quiet ? "@dirrm %s\n" : "\tDeinstall directory remove: %s\n", p->name);
162	    break;
163
164	case PLIST_OPTION:
165	    printf(Quiet ? "@option %s\n" :
166		"\tOption \"%s\" controlling package installation behaviour\n",
167		p->name);
168	    break;
169
170	default:
171	    cleanup(0);
172	    errx(2, __FUNCTION__ ": unknown command type %d (%s)", p->type, p->name);
173	    break;
174	}
175	p = p->next;
176    }
177}
178
179/* Show all files in the packing list (except ignored ones) */
180void
181show_files(const char *title, Package *plist)
182{
183    PackingList p;
184    Boolean ign = FALSE;
185    const char *dir = ".";
186
187    if (!Quiet)
188	printf("%s%s", InfoPrefix, title);
189    p = plist->head;
190    while (p) {
191	switch(p->type) {
192	case PLIST_FILE:
193	    if (!ign)
194		printf("%s/%s\n", dir, p->name);
195	    ign = FALSE;
196	    break;
197
198	case PLIST_CWD:
199	    dir = p->name;
200	    break;
201
202	case PLIST_IGNORE:
203	    ign = TRUE;
204	    break;
205
206        /* Silence GCC in the -Wall mode */
207	default:
208	    break;
209	}
210	p = p->next;
211    }
212}
213
214/* Calculate and show size of all installed package files (except ignored ones) */
215void
216show_size(const char *title, Package *plist)
217{
218    PackingList p;
219    Boolean ign = FALSE;
220    const char *dir = ".";
221    struct stat sb;
222    char tmp[FILENAME_MAX];
223    unsigned long size = 0;
224    long blksize;
225    int headerlen;
226    char *descr;
227
228    descr = getbsize(&headerlen, &blksize);
229    if (!Quiet)
230	printf("%s%s", InfoPrefix, title);
231    for (p = plist->head; p != NULL; p = p->next) {
232	switch (p->type) {
233	case PLIST_FILE:
234	    if (!ign) {
235		snprintf(tmp, FILENAME_MAX, "%s/%s", dir, p->name);
236		if (!lstat(tmp, &sb)) {
237		    size += sb.st_size;
238		    if (Verbose)
239			printf("%lu\t%s\n", (unsigned long) howmany(sb.st_size, blksize), tmp);
240		}
241	    }
242	    ign = FALSE;
243	    break;
244
245	case PLIST_CWD:
246	    dir = p->name;
247	    break;
248
249	case PLIST_IGNORE:
250	    ign = TRUE;
251	    break;
252
253	/* Silence GCC in the -Wall mode */
254	default:
255	    break;
256	}
257    }
258    if (!Quiet)
259	printf("%lu\t(%s)\n", howmany(size, blksize), descr);
260    else
261	printf("%lu\n", size);
262}
263
264/* Show files that don't match the recorded checksum */
265void
266show_cksum(const char *title, Package *plist)
267{
268    PackingList p;
269    const char *dir = ".";
270    char tmp[FILENAME_MAX];
271
272    if (!Quiet)
273	printf("%s%s", InfoPrefix, title);
274
275    for (p = plist->head; p != NULL; p = p->next)
276	if (p->type == PLIST_CWD)
277	    dir = p->name;
278	else if (p->type == PLIST_FILE) {
279	    snprintf(tmp, FILENAME_MAX, "%s/%s", dir, p->name);
280	    if (!fexists(tmp))
281		warnx("%s doesn't exist\n", tmp);
282	    else if (p->next && p->next->type == PLIST_COMMENT && !strncmp(p->next->name, "MD5:", 4)) {
283		char *cp, buf[33];
284		if ((cp = MD5File(tmp, buf)) != NULL) {
285		    if (strcmp(cp, p->next->name + 4))
286			printf("%s fails the original MD5 checksum\n", tmp);
287		    else if (Verbose)
288			printf("%s matched the original MD5 checksum\n", tmp);
289		}
290	    }
291	}
292}
293
294/* Show an "origin" path (usually category/portname) */
295void
296show_origin(const char *title, Package *plist)
297{
298    PackingList p;
299
300    if (!Quiet)
301	printf("%s%s", InfoPrefix, title);
302    for (p = plist->head; p != NULL; p = p->next)
303	if (p->type == PLIST_COMMENT && !strncmp(p->name, "ORIGIN:", 7)) {
304	    printf("%s\n", p->name + 7);
305	    break;
306	}
307}
308
309/* Show revision number of the packing list */
310void
311show_fmtrev(const char *title, Package *plist)
312{
313    if (!Quiet)
314	printf("%s%s", InfoPrefix, title);
315    printf("%d.%d\n", plist->fmtver_maj, plist->fmtver_mnr);
316}
317