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