1 /* $NetBSD: show.c,v 1.5 2021/04/10 19:49:59 nia 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.5 2021/04/10 19:49:59 nia 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
show_file(const char * buf,const char * title,Boolean separator)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
show_var(const char * buf,const char * variable)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
show_index(const char * buf,const char * title)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
show_plist(const char * title,package_t * plist,pl_ent_t type)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
show_files(const char * title,package_t * plist)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
show_depends(const char * title,package_t * plist)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
show_bld_depends(const char * title,package_t * plist)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
show_summary(struct pkg_meta * meta,package_t * plist,const char * binpkgfile)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
print_string_as_var(const char * var,const char * str)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
show_list(lpkg_head_t * pkghead,const char * title)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