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