Home | History | Annotate | Line # | Download | only in info
      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 (at) 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