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" */ 69typedef 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 */ 79static 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 101static int print_string_as_var(const char *, const char *); 102 103void 104show_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 121void 122show_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 135void 136show_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 */ 153void 154show_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 */ 218void 219show_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 */ 252void 253show_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 */ 290void 291show_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 */ 329void 330show_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 */ 399static int 400print_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 414void 415show_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