xref: /minix/external/bsd/pkg_install/dist/info/show.c (revision 0a6a1f1d)
1 /*	$NetBSD: show.c,v 1.3 2012/02/21 18:36:16 wiz Exp $	*/
2 
3 #if HAVE_CONFIG_H
4 #include "config.h"
5 #endif
6 #include <nbcompat.h>
7 #if HAVE_SYS_CDEFS_H
8 #include <sys/cdefs.h>
9 #endif
10 __RCSID("$NetBSD: show.c,v 1.3 2012/02/21 18:36:16 wiz Exp $");
11 
12 /*
13  * FreeBSD install - a package for the installation and maintainance
14  * of non-core utilities.
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
19  * 1. Redistributions of source code must retain the above copyright
20  *    notice, this list of conditions and the following disclaimer.
21  * 2. Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the
23  *    documentation and/or other materials provided with the distribution.
24  *
25  * Jordan K. Hubbard
26  * 23 Aug 1993
27  *
28  * Various display routines for the info module.
29  *
30  */
31 /*-
32  * Copyright (c) 1999-2008 The NetBSD Foundation, Inc.
33  * All rights reserved.
34  *
35  * This code is derived from software contributed to The NetBSD Foundation
36  * by Hubert Feyrer <hubert@feyrer.de>.
37  *
38  * Redistribution and use in source and binary forms, with or without
39  * modification, are permitted provided that the following conditions
40  * are met:
41  * 1. Redistributions of source code must retain the above copyright
42  *    notice, this list of conditions and the following disclaimer.
43  * 2. Redistributions in binary form must reproduce the above copyright
44  *    notice, this list of conditions and the following disclaimer in the
45  *    documentation and/or other materials provided with the distribution.
46  *
47  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
48  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
49  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
50  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
51  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
52  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
53  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
54  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
55  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
56  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
57  * POSSIBILITY OF SUCH DAMAGE.
58  */
59 
60 #if HAVE_ERR_H
61 #include <err.h>
62 #endif
63 
64 #include "defs.h"
65 #include "lib.h"
66 #include "info.h"
67 
68 /* Structure to define entries for the "show table" */
69 typedef struct show_t {
70 	pl_ent_t sh_type;	/* type of entry */
71 	const char *sh_quiet;	/* message when quiet */
72 	const char *sh_verbose;	/* message when verbose */
73 }       show_t;
74 
75 /*
76  * The entries in this table must be ordered the same as
77  * pl_ent_t constants
78  */
79 static const show_t showv[] = {
80 	{PLIST_FILE, "", "\tFile: "},
81 	{PLIST_CWD, "@cwd ", "\tCWD to: "},
82 	{PLIST_CMD, "@exec ", "\tEXEC ''"},
83 	{PLIST_CHMOD, "@chmod ", "\tCHMOD to "},
84 	{PLIST_CHOWN, "@chown ", "\tCHOWN to "},
85 	{PLIST_CHGRP, "@chgrp ", "\tCHGRP to "},
86 	{PLIST_COMMENT, "@comment ", "\tComment: "},
87 	{PLIST_IGNORE, "@ignore", "Ignore next file:"},
88 	{PLIST_NAME, "@name ", "\tPackage name: "},
89 	{PLIST_UNEXEC, "@unexec ", "\tUNEXEC ''"},
90 	{PLIST_SRC, "@src: ", "\tSRC to: "},
91 	{PLIST_DISPLAY, "@display ", "\tInstall message file: "},
92 	{PLIST_PKGDEP, "@pkgdep ", "\tPackage depends on: "},
93 	{PLIST_DIR_RM, "@dirrm ", "\tObsolete deinstall directory removal hint: "},
94 	{PLIST_OPTION, "@option ", "\tPackage has option: "},
95 	{PLIST_PKGCFL, "@pkgcfl ", "\tPackage conflicts with: "},
96 	{PLIST_BLDDEP, "@blddep ", "\tPackage depends exactly on: "},
97 	{PLIST_PKGDIR, "@pkgdir ", "\tManaged directory: "},
98 	{-1, NULL, NULL}
99 };
100 
101 static int print_string_as_var(const char *, const char *);
102 
103 void
104 show_file(const char *buf, const char *title, Boolean separator)
105 {
106 	size_t len;
107 
108 	if (!Quiet)
109 		printf("%s%s", InfoPrefix, title);
110 
111 	len = strlen(buf);
112 	if (len == 0 || buf[len - 1] != '\n')
113 		puts(buf);
114 	else
115 		fputs(buf, stdout);
116 
117 	if (!Quiet || separator)
118 		printf("\n");
119 }
120 
121 void
122 show_var(const char *buf, const char *variable)
123 {
124 	char   *value;
125 
126 	if (buf == NULL)
127 		return;
128 
129 	if ((value = var_get_memory(buf, variable)) != NULL) {
130 		(void) printf("%s\n", value);
131 		free(value);
132 	}
133 }
134 
135 void
136 show_index(const char *buf, const char *title)
137 {
138 	size_t len;
139 
140 	if (!Quiet)
141 		printf("%s%s", InfoPrefix, title);
142 
143 	len = strlen(buf);
144 	if (len == 0 || buf[len - 1] != '\n')
145 		puts(buf);
146 	else
147 		fputs(buf, stdout);
148 }
149 
150 /*
151  * Show a packing list item type.  If type is PLIST_SHOW_ALL, show all
152  */
153 void
154 show_plist(const char *title, package_t *plist, pl_ent_t type)
155 {
156 	plist_t *p;
157 	Boolean ign;
158 
159 	if (!Quiet) {
160 		printf("%s%s", InfoPrefix, title);
161 	}
162 	for (ign = FALSE, p = plist->head; p; p = p->next) {
163 		if (p->type == type || type == PLIST_SHOW_ALL) {
164 			switch (p->type) {
165 			case PLIST_FILE:
166 				printf("%s%s",
167 				    Quiet ? showv[p->type].sh_quiet :
168 				    showv[p->type].sh_verbose, p->name);
169 				if (ign) {
170 					if (!Quiet) {
171 						printf(" (ignored)");
172 					}
173 					ign = FALSE;
174 				}
175 				break;
176 			case PLIST_CHMOD:
177 			case PLIST_CHOWN:
178 			case PLIST_CHGRP:
179 				printf("%s%s",
180 				    Quiet ?  showv[p->type].sh_quiet :
181 				    showv[p->type].sh_verbose,
182 				    p->name ? p->name : "(clear default)");
183 				break;
184 			case PLIST_IGNORE:
185 				printf("%s", Quiet ? showv[p->type].sh_quiet :
186 				    showv[p->type].sh_verbose);
187 				ign = TRUE;
188 				break;
189 			case PLIST_CWD:
190 			case PLIST_CMD:
191 			case PLIST_SRC:
192 			case PLIST_UNEXEC:
193 			case PLIST_COMMENT:
194 			case PLIST_NAME:
195 			case PLIST_DISPLAY:
196 			case PLIST_PKGDEP:
197 			case PLIST_DIR_RM:
198 			case PLIST_OPTION:
199 			case PLIST_PKGCFL:
200 			case PLIST_BLDDEP:
201 			case PLIST_PKGDIR:
202 				printf("%s%s",
203 				    Quiet ? showv[p->type].sh_quiet :
204 				    showv[p->type].sh_verbose,
205 				    p->name ? p->name : "(null)");
206 				break;
207 			default:
208 				warnx("unknown command type %d (%s)", p->type, p->name);
209 			}
210 			(void) fputc('\n', stdout);
211 		}
212 	}
213 }
214 
215 /*
216  * Show all files in the packing list (except ignored ones)
217  */
218 void
219 show_files(const char *title, package_t *plist)
220 {
221 	plist_t *p;
222 	Boolean ign;
223 	const char *dir = ".";
224 
225 	if (!Quiet) {
226 		printf("%s%s", InfoPrefix, title);
227 	}
228 	for (ign = FALSE, p = plist->head; p; p = p->next) {
229 		switch (p->type) {
230 		case PLIST_FILE:
231 			if (!ign) {
232 				printf("%s%s%s\n", dir,
233 					(strcmp(dir, "/") == 0) ? "" : "/", p->name);
234 			}
235 			ign = FALSE;
236 			break;
237 		case PLIST_CWD:
238 			dir = p->name;
239 			break;
240 		case PLIST_IGNORE:
241 			ign = TRUE;
242 			break;
243 		default:
244 			break;
245 		}
246 	}
247 }
248 
249 /*
250  * Show dependencies (packages this pkg requires)
251  */
252 void
253 show_depends(const char *title, package_t *plist)
254 {
255 	plist_t *p;
256 	int     nodepends;
257 
258 	nodepends = 1;
259 	for (p = plist->head; p && nodepends; p = p->next) {
260 		switch (p->type) {
261 		case PLIST_PKGDEP:
262 			nodepends = 0;
263 			break;
264 		default:
265 			break;
266 		}
267 	}
268 	if (nodepends)
269 		return;
270 
271 	if (!Quiet) {
272 		printf("%s%s", InfoPrefix, title);
273 	}
274 	for (p = plist->head; p; p = p->next) {
275 		switch (p->type) {
276 		case PLIST_PKGDEP:
277 			printf("%s\n", p->name);
278 			break;
279 		default:
280 			break;
281 		}
282 	}
283 
284 	printf("\n");
285 }
286 
287 /*
288  * Show exact dependencies (packages this pkg was built with)
289  */
290 void
291 show_bld_depends(const char *title, package_t *plist)
292 {
293 	plist_t *p;
294 	int     nodepends;
295 
296 	nodepends = 1;
297 	for (p = plist->head; p && nodepends; p = p->next) {
298 		switch (p->type) {
299 		case PLIST_BLDDEP:
300 			nodepends = 0;
301 			break;
302 		default:
303 			break;
304 		}
305 	}
306 	if (nodepends)
307 		return;
308 
309 	if (!Quiet) {
310 		printf("%s%s", InfoPrefix, title);
311 	}
312 	for (p = plist->head; p; p = p->next) {
313 		switch (p->type) {
314 		case PLIST_BLDDEP:
315 			printf("%s\n", p->name);
316 			break;
317 		default:
318 			break;
319 		}
320 	}
321 
322 	printf("\n");
323 }
324 
325 
326 /*
327  * Show entry for pkg_summary.txt file.
328  */
329 void
330 show_summary(struct pkg_meta *meta, package_t *plist, const char *binpkgfile)
331 {
332 	static const char *bi_vars[] = {
333 		"PKGPATH",
334 		"CATEGORIES",
335 		"PROVIDES",
336 		"REQUIRES",
337 		"PKG_OPTIONS",
338 		"OPSYS",
339 		"OS_VERSION",
340 		"MACHINE_ARCH",
341 		"LICENSE",
342 		"HOMEPAGE",
343 		"PKGTOOLS_VERSION",
344 		"BUILD_DATE",
345 		"PREV_PKGPATH",
346 		"SUPERSEDES",
347 		NULL
348 	};
349 
350 	plist_t *p;
351 	struct stat st;
352 
353 	for (p = plist->head; p; p = p->next) {
354 		switch (p->type) {
355 		case PLIST_NAME:
356 			printf("PKGNAME=%s\n", p->name);
357 			break;
358 		case PLIST_PKGDEP:
359 			printf("DEPENDS=%s\n", p->name);
360 			break;
361 		case PLIST_PKGCFL:
362 			printf("CONFLICTS=%s\n", p->name);
363 			break;
364 
365 		default:
366 			break;
367 		}
368 	}
369 
370 	print_string_as_var("COMMENT", meta->meta_comment);
371 	if (meta->meta_size_pkg)
372 		print_string_as_var("SIZE_PKG", meta->meta_size_pkg);
373 
374 	if (meta->meta_build_info)
375 		var_copy_list(meta->meta_build_info, bi_vars);
376 	else
377 		warnx("Build information missing");
378 
379 	if (binpkgfile != NULL && stat(binpkgfile, &st) == 0) {
380 	    const char *base;
381 
382 	    base = strrchr(binpkgfile, '/');
383 	    if (base == NULL)
384 		base = binpkgfile;
385 	    else
386 		base++;
387 	    printf("FILE_NAME=%s\n", base);
388 	    printf("FILE_SIZE=%" MY_PRIu64 "\n", (uint64_t)st.st_size);
389 	    /* XXX: DIGETS */
390 	}
391 
392 	print_string_as_var("DESCRIPTION", meta->meta_desc);
393 	putc('\n', stdout);
394 }
395 
396 /*
397  * Print the contents of file fname as value of variable var to stdout.
398  */
399 static int
400 print_string_as_var(const char *var, const char *str)
401 {
402 	const char *eol;
403 
404 	while ((eol = strchr(str, '\n')) != NULL) {
405 		printf("%s=%.*s\n", var, (int)(eol - str), str);
406 		str = eol + 1;
407 	}
408 	if (*str)
409 		printf("%s=%s\n", var, str);
410 
411 	return 0;
412 }
413 
414 void
415 show_list(lpkg_head_t *pkghead, const char *title)
416 {
417 	lpkg_t *lpp;
418 
419 	if (!Quiet)
420 		printf("%s%s", InfoPrefix, title);
421 
422 	while ((lpp = TAILQ_FIRST(pkghead)) != NULL) {
423 		TAILQ_REMOVE(pkghead, lpp, lp_link);
424 		puts(lpp->lp_name);
425 		free_lpkg(lpp);
426 	}
427 
428 	if (!Quiet)
429 		printf("\n");
430 }
431