]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/pkg_install/info/show.c
Upgrade our copy of llvm/clang to trunk r162107. With thanks to
[FreeBSD/FreeBSD.git] / usr.sbin / pkg_install / info / show.c
1 /*
2  * FreeBSD install - a package for the installation and maintenance
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 static const char *
211 elide_root(const char *dir)
212 {
213     if (strcmp(dir, "/") == 0)
214         return "";
215     return dir;
216 }
217
218 /* Show all files in the packing list (except ignored ones) */
219 void
220 show_files(const char *title, Package *plist)
221 {
222     PackingList p;
223     Boolean ign = FALSE;
224     char *prefix = NULL;
225     const char *dir = ".";
226
227     if (!Quiet)
228         printf("%s%s", InfoPrefix, title);
229     p = plist->head;
230     while (p) {
231         switch(p->type) {
232         case PLIST_FILE:
233             if (!ign)
234                 printf("%s/%s\n", elide_root(dir), p->name);
235             ign = FALSE;
236             break;
237
238         case PLIST_CWD:
239             if (!prefix)
240                 prefix = p->name;
241             if (p->name == NULL)
242                 dir = prefix;
243             else
244                 dir = p->name;
245             break;
246
247         case PLIST_IGNORE:
248             ign = TRUE;
249             break;
250
251         /* Silence GCC in the -Wall mode */
252         default:
253             break;
254         }
255         p = p->next;
256     }
257 }
258
259 /* Calculate and show size of all installed package files (except ignored ones) */
260 void
261 show_size(const char *title, Package *plist)
262 {
263     PackingList p;
264     Boolean ign = FALSE;
265     const char *dir = ".";
266     struct stat sb;
267     char tmp[FILENAME_MAX];
268     unsigned long size = 0;
269     long blksize;
270     int headerlen;
271     char *descr;
272     char *prefix = NULL;
273
274     descr = getbsize(&headerlen, &blksize);
275     if (!Quiet)
276         printf("%s%s", InfoPrefix, title);
277     for (p = plist->head; p != NULL; p = p->next) {
278         switch (p->type) {
279         case PLIST_FILE:
280             if (!ign) {
281                 snprintf(tmp, FILENAME_MAX, "%s/%s", elide_root(dir), p->name);
282                 if (!lstat(tmp, &sb)) {
283                     size += sb.st_size;
284                     if (Verbose)
285                         printf("%lu\t%s\n", (unsigned long) howmany(sb.st_size, blksize), tmp);
286                 }
287             }
288             ign = FALSE;
289             break;
290
291         case PLIST_CWD:
292             if (!prefix)
293                 prefix = p->name;
294             if (p->name == NULL)
295                 dir = prefix;
296             else
297                 dir = p->name;
298             break;
299
300         case PLIST_IGNORE:
301             ign = TRUE;
302             break;
303
304         /* Silence GCC in the -Wall mode */         
305         default:
306             break;
307         }
308     }
309     if (!Quiet)
310         printf("%lu\t(%s)\n", howmany(size, blksize), descr);
311     else
312         if (UseBlkSz)
313                 printf("%lu\n", howmany(size, blksize));
314         else
315                 printf("%lu\n", size);
316 }
317
318 /* Show files that don't match the recorded checksum */
319 void
320 show_cksum(const char *title, Package *plist)
321 {
322     PackingList p;
323     const char *dir = ".";
324     char *prefix = NULL;
325     char tmp[FILENAME_MAX];
326
327     if (!Quiet)
328         printf("%s%s", InfoPrefix, title);
329
330     for (p = plist->head; p != NULL; p = p->next)
331         if (p->type == PLIST_CWD) {
332             if (!prefix)
333                 prefix = p->name;
334             if (p->name == NULL)
335                 dir = prefix;
336             else
337                 dir = p->name;
338         } else if (p->type == PLIST_FILE) {
339             snprintf(tmp, FILENAME_MAX, "%s/%s", elide_root(dir), p->name);
340             if (!fexists(tmp))
341                 warnx("%s doesn't exist", tmp);
342             else if (p->next && p->next->type == PLIST_COMMENT &&
343                      (strncmp(p->next->name, "MD5:", 4) == 0)) {
344                 char *cp = NULL, buf[33];
345
346                 /*
347                  * For packing lists whose version is 1.1 or greater, the md5
348                  * hash for a symlink is calculated on the string returned
349                  * by readlink().
350                  */
351                 if (issymlink(tmp) && verscmp(plist, 1, 0) > 0) {
352                     int len;
353                     char linkbuf[FILENAME_MAX];
354
355                     if ((len = readlink(tmp, linkbuf, FILENAME_MAX)) > 0)
356                         cp = MD5Data((unsigned char *)linkbuf, len, buf);
357                 } else if (isfile(tmp) || verscmp(plist, 1, 1) < 0)
358                     cp = MD5File(tmp, buf);
359
360                 if (cp != NULL) {
361                     /* Mismatch? */
362                     if (strcmp(cp, p->next->name + 4))
363                         printf("%s fails the original MD5 checksum\n", tmp);
364                     else if (Verbose)
365                         printf("%s matched the original MD5 checksum\n", tmp);
366                 }
367             }
368         }
369 }
370
371 /* Show an "origin" path (usually category/portname) */
372 void
373 show_origin(const char *title, Package *plist)
374 {
375
376     if (!Quiet)
377         printf("%s%s", InfoPrefix, title);
378     printf("%s\n", plist->origin != NULL ? plist->origin : "");
379 }
380
381 /* Show revision number of the packing list */
382 void
383 show_fmtrev(const char *title, Package *plist)
384 {
385
386     if (!Quiet)
387         printf("%s%s", InfoPrefix, title);
388     printf("%d.%d\n", plist->fmtver_maj, plist->fmtver_mnr);
389 }