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