]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - usr.sbin/pkg_install/info/show.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / usr.sbin / pkg_install / info / show.c
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$");
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
32 void
33 show_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 == (FILE *) NULL)
43         printf("ERROR: show_file: Can't open '%s' for reading!\n", fname);
44     else {
45         int append_nl = 0;
46         while ((n = fread(line, 1, 1024, fp)) != 0)
47             fwrite(line, 1, n, stdout);
48         fclose(fp);
49         append_nl = (line[n - 1] != '\n');      /* Do we have a trailing \n ? */
50         if (append_nl)
51            printf("\n");
52     }
53     printf("\n");       /* just in case */
54 }
55
56 void
57 show_index(const char *title, const char *fname)
58 {
59     FILE *fp;
60     char line[MAXINDEXSIZE+2];
61
62     strlcpy(line, "???\n", sizeof(line));
63
64     if (!Quiet)
65         printf("%s%s", InfoPrefix, title);
66     fp = fopen(fname, "r");
67     if (fp == (FILE *) NULL) {
68         warnx("show_file: can't open '%s' for reading", fname);
69     } else {
70         if(fgets(line, MAXINDEXSIZE + 1, fp)) {
71                 size_t line_length = strlen(line);
72
73                 if (line[line_length - 1] != '\n') {    /* Do we have a trailing \n ? */
74                         line[line_length] = '\n';       /* Add a trailing \n */
75                         line[line_length + 1] = '\0';   /* Terminate string */
76                 }
77         }
78         fclose(fp);
79     }
80     fputs(line, stdout);
81 }
82
83 /* Show a packing list item type.  If showall is TRUE, show all */
84 void
85 show_plist(const char *title, Package *plist, plist_t type, Boolean showall)
86 {
87     PackingList p;
88     Boolean ign = FALSE;
89     char *prefix = NULL;
90
91     if (!Quiet)
92         printf("%s%s", InfoPrefix, title);
93     p = plist->head;
94     while (p) {
95         if (p->type != type && showall != TRUE) {
96             p = p->next;
97             continue;
98         }
99         switch(p->type) {
100         case PLIST_FILE:
101             if (ign) {
102                 printf(Quiet ? "%s\n" : "File: %s (ignored)\n", p->name);
103                 ign = FALSE;
104             }
105             else
106                 printf(Quiet ? "%s\n" : "File: %s\n", p->name);
107             break;
108
109         case PLIST_CWD:
110             if (!prefix)
111                 prefix = p->name;
112             printf(Quiet ? "@cwd %s\n" : "\tCWD to %s\n", (p->name == NULL) ? prefix : p->name);
113             break;
114
115         case PLIST_SRC:
116             printf(Quiet ? "@srcdir %s\n" : "\tSRCDIR to %s\n", p->name);
117             break;
118
119         case PLIST_CMD:
120             printf(Quiet ? "@exec %s\n" : "\tEXEC '%s'\n", p->name);
121             break;
122
123         case PLIST_UNEXEC:
124             printf(Quiet ? "@unexec %s\n" : "\tUNEXEC '%s'\n", p->name);
125             break;
126
127         case PLIST_CHMOD:
128             printf(Quiet ? "@chmod %s\n" : "\tCHMOD to %s\n",
129                    p->name ? p->name : "(clear default)");
130             break;
131
132         case PLIST_CHOWN:
133             printf(Quiet ? "@chown %s\n" : "\tCHOWN to %s\n",
134                    p->name ? p->name : "(clear default)");
135             break;
136
137         case PLIST_CHGRP:
138             printf(Quiet ? "@chgrp %s\n" : "\tCHGRP to %s\n",
139                    p->name ? p->name : "(clear default)");
140             break;
141
142         case PLIST_COMMENT:
143             printf(Quiet ? "@comment %s\n" : "\tComment: %s\n", p->name);
144             break;
145
146         case PLIST_NOINST:
147             printf(Quiet ? "@noinst %s\n" : "\tNot installed: %s\n", p->name);
148             break;
149
150         case PLIST_IGNORE:
151             ign = TRUE;
152             break;
153
154         case PLIST_IGNORE_INST:
155             printf(Quiet ? "@ignore_inst ??? doesn't belong here.\n" :
156                    "\tIgnore next file installation directive (doesn't belong)\n");
157             ign = TRUE;
158             break;
159
160         case PLIST_NAME:
161             printf(Quiet ? "@name %s\n" : "\tPackage name: %s\n", p->name);
162             break;
163
164         case PLIST_DISPLAY:
165             printf(Quiet ? "@display %s\n" : "\tInstall message file: %s\n", p->name);
166             break;
167
168         case PLIST_PKGDEP:
169             printf(Quiet ? "@pkgdep %s\n" : "Dependency: %s\n", p->name);
170             break;
171
172         case PLIST_DEPORIGIN:
173             printf(Quiet ? "@comment DEPORIGIN:%s\n" :
174                 "\tdependency origin: %s\n", p->name);
175             break;
176
177         case PLIST_CONFLICTS:
178             printf(Quiet ? "@conflicts %s\n" : "Conflicts: %s\n", p->name);
179             break;
180
181         case PLIST_MTREE:
182             printf(Quiet ? "@mtree %s\n" : "\tPackage mtree file: %s\n", p->name);
183             break;
184
185         case PLIST_DIR_RM:
186             printf(Quiet ? "@dirrm %s\n" : "\tDeinstall directory remove: %s\n", p->name);
187             break;
188
189         case PLIST_OPTION:
190             printf(Quiet ? "@option %s\n" :
191                 "\tOption \"%s\" controlling package installation behaviour\n",
192                 p->name);
193             break;
194
195         case PLIST_ORIGIN:
196             printf(Quiet ? "@comment ORIGIN:%s\n" :
197                 "\tPackage origin: %s\n", p->name); 
198             break;
199
200         default:
201             cleanup(0);
202             errx(2, "%s: unknown command type %d (%s)",
203                 __func__, p->type, p->name);
204             break;
205         }
206         p = p->next;
207     }
208 }
209
210 /* Show all files in the packing list (except ignored ones) */
211 void
212 show_files(const char *title, Package *plist)
213 {
214     PackingList p;
215     Boolean ign = FALSE;
216     char *prefix = NULL;
217     const char *dir = ".";
218
219     if (!Quiet)
220         printf("%s%s", InfoPrefix, title);
221     p = plist->head;
222     while (p) {
223         switch(p->type) {
224         case PLIST_FILE:
225             if (!ign)
226                 printf("%s/%s\n", dir, p->name);
227             ign = FALSE;
228             break;
229
230         case PLIST_CWD:
231             if (!prefix)
232                 prefix = p->name;
233             if (p->name == NULL)
234                 dir = prefix;
235             else
236                 dir = p->name;
237             break;
238
239         case PLIST_IGNORE:
240             ign = TRUE;
241             break;
242
243         /* Silence GCC in the -Wall mode */
244         default:
245             break;
246         }
247         p = p->next;
248     }
249 }
250
251 /* Calculate and show size of all installed package files (except ignored ones) */
252 void
253 show_size(const char *title, Package *plist)
254 {
255     PackingList p;
256     Boolean ign = FALSE;
257     const char *dir = ".";
258     struct stat sb;
259     char tmp[FILENAME_MAX];
260     unsigned long size = 0;
261     long blksize;
262     int headerlen;
263     char *descr;
264     char *prefix = NULL;
265
266     descr = getbsize(&headerlen, &blksize);
267     if (!Quiet)
268         printf("%s%s", InfoPrefix, title);
269     for (p = plist->head; p != NULL; p = p->next) {
270         switch (p->type) {
271         case PLIST_FILE:
272             if (!ign) {
273                 snprintf(tmp, FILENAME_MAX, "%s/%s", dir, p->name);
274                 if (!lstat(tmp, &sb)) {
275                     size += sb.st_size;
276                     if (Verbose)
277                         printf("%lu\t%s\n", (unsigned long) howmany(sb.st_size, blksize), tmp);
278                 }
279             }
280             ign = FALSE;
281             break;
282
283         case PLIST_CWD:
284             if (!prefix)
285                 prefix = p->name;
286             if (p->name == NULL)
287                 dir = prefix;
288             else
289                 dir = p->name;
290             break;
291
292         case PLIST_IGNORE:
293             ign = TRUE;
294             break;
295
296         /* Silence GCC in the -Wall mode */         
297         default:
298             break;
299         }
300     }
301     if (!Quiet)
302         printf("%lu\t(%s)\n", howmany(size, blksize), descr);
303     else
304         if (UseBlkSz)
305                 printf("%lu\n", howmany(size, blksize));
306         else
307                 printf("%lu\n", size);
308 }
309
310 /* Show files that don't match the recorded checksum */
311 void
312 show_cksum(const char *title, Package *plist)
313 {
314     PackingList p;
315     const char *dir = ".";
316     char *prefix = NULL;
317     char tmp[FILENAME_MAX];
318
319     if (!Quiet)
320         printf("%s%s", InfoPrefix, title);
321
322     for (p = plist->head; p != NULL; p = p->next)
323         if (p->type == PLIST_CWD) {
324             if (!prefix)
325                 prefix = p->name;
326             if (p->name == NULL)
327                 dir = prefix;
328             else
329                 dir = p->name;
330         } else if (p->type == PLIST_FILE) {
331             snprintf(tmp, FILENAME_MAX, "%s/%s", dir, p->name);
332             if (!fexists(tmp))
333                 warnx("%s doesn't exist", tmp);
334             else if (p->next && p->next->type == PLIST_COMMENT &&
335                      (strncmp(p->next->name, "MD5:", 4) == 0)) {
336                 char *cp = NULL, buf[33];
337
338                 /*
339                  * For packing lists whose version is 1.1 or greater, the md5
340                  * hash for a symlink is calculated on the string returned
341                  * by readlink().
342                  */
343                 if (issymlink(tmp) && verscmp(plist, 1, 0) > 0) {
344                     int len;
345                     char linkbuf[FILENAME_MAX];
346
347                     if ((len = readlink(tmp, linkbuf, FILENAME_MAX)) > 0)
348                         cp = MD5Data((unsigned char *)linkbuf, len, buf);
349                 } else if (isfile(tmp) || verscmp(plist, 1, 1) < 0)
350                     cp = MD5File(tmp, buf);
351
352                 if (cp != NULL) {
353                     /* Mismatch? */
354                     if (strcmp(cp, p->next->name + 4))
355                         printf("%s fails the original MD5 checksum\n", tmp);
356                     else if (Verbose)
357                         printf("%s matched the original MD5 checksum\n", tmp);
358                 }
359             }
360         }
361 }
362
363 /* Show an "origin" path (usually category/portname) */
364 void
365 show_origin(const char *title, Package *plist)
366 {
367
368     if (!Quiet)
369         printf("%s%s", InfoPrefix, title);
370     printf("%s\n", plist->origin != NULL ? plist->origin : "");
371 }
372
373 /* Show revision number of the packing list */
374 void
375 show_fmtrev(const char *title, Package *plist)
376 {
377
378     if (!Quiet)
379         printf("%s%s", InfoPrefix, title);
380     printf("%d.%d\n", plist->fmtver_maj, plist->fmtver_mnr);
381 }