1*5c51f124SMoriah Waterland /* 2*5c51f124SMoriah Waterland * CDDL HEADER START 3*5c51f124SMoriah Waterland * 4*5c51f124SMoriah Waterland * The contents of this file are subject to the terms of the 5*5c51f124SMoriah Waterland * Common Development and Distribution License (the "License"). 6*5c51f124SMoriah Waterland * You may not use this file except in compliance with the License. 7*5c51f124SMoriah Waterland * 8*5c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing. 10*5c51f124SMoriah Waterland * See the License for the specific language governing permissions 11*5c51f124SMoriah Waterland * and limitations under the License. 12*5c51f124SMoriah Waterland * 13*5c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each 14*5c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the 16*5c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying 17*5c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner] 18*5c51f124SMoriah Waterland * 19*5c51f124SMoriah Waterland * CDDL HEADER END 20*5c51f124SMoriah Waterland */ 21*5c51f124SMoriah Waterland 22*5c51f124SMoriah Waterland /* 23*5c51f124SMoriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*5c51f124SMoriah Waterland * Use is subject to license terms. 25*5c51f124SMoriah Waterland */ 26*5c51f124SMoriah Waterland 27*5c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*5c51f124SMoriah Waterland /* All Rights Reserved */ 29*5c51f124SMoriah Waterland 30*5c51f124SMoriah Waterland 31*5c51f124SMoriah Waterland #define __EXTENTIONS__ 32*5c51f124SMoriah Waterland 33*5c51f124SMoriah Waterland #include <stdio.h> 34*5c51f124SMoriah Waterland #include <limits.h> 35*5c51f124SMoriah Waterland #include <unistd.h> 36*5c51f124SMoriah Waterland #include <stdlib.h> 37*5c51f124SMoriah Waterland #include <locale.h> 38*5c51f124SMoriah Waterland #include <libintl.h> 39*5c51f124SMoriah Waterland #include <strings.h> 40*5c51f124SMoriah Waterland #include <string.h> 41*5c51f124SMoriah Waterland #include <dirent.h> 42*5c51f124SMoriah Waterland #include <sys/param.h> 43*5c51f124SMoriah Waterland #include <sys/stat.h> 44*5c51f124SMoriah Waterland #include <pkginfo.h> 45*5c51f124SMoriah Waterland #include <fcntl.h> 46*5c51f124SMoriah Waterland #include <sys/types.h> 47*5c51f124SMoriah Waterland #include <sys/stat.h> 48*5c51f124SMoriah Waterland #include <sys/param.h> 49*5c51f124SMoriah Waterland #include <sys/mman.h> 50*5c51f124SMoriah Waterland #include <pkgstrct.h> 51*5c51f124SMoriah Waterland #include <pkglocs.h> 52*5c51f124SMoriah Waterland #include <errno.h> 53*5c51f124SMoriah Waterland #include <ctype.h> 54*5c51f124SMoriah Waterland 55*5c51f124SMoriah Waterland #include <pkglib.h> 56*5c51f124SMoriah Waterland #include <instzones_api.h> 57*5c51f124SMoriah Waterland #include <libadm.h> 58*5c51f124SMoriah Waterland #include <libinst.h> 59*5c51f124SMoriah Waterland 60*5c51f124SMoriah Waterland extern char *pkgdir; 61*5c51f124SMoriah Waterland extern int pkginfofind(char *path, char *pkg_dir, char *pkginst); 62*5c51f124SMoriah Waterland 63*5c51f124SMoriah Waterland #define ERR_USAGE "usage:\n" \ 64*5c51f124SMoriah Waterland "%s [-q] [-pi] [-x|l] [options] [pkg ...]\n" \ 65*5c51f124SMoriah Waterland "%s -d device [-q] [-x|l] [options] [pkg ...]\n" \ 66*5c51f124SMoriah Waterland "where\n" \ 67*5c51f124SMoriah Waterland " -q #quiet mode\n" \ 68*5c51f124SMoriah Waterland " -p #select partially installed packages\n" \ 69*5c51f124SMoriah Waterland " -i #select completely installed packages\n" \ 70*5c51f124SMoriah Waterland " -x #extracted listing\n" \ 71*5c51f124SMoriah Waterland " -l #long listing\n" \ 72*5c51f124SMoriah Waterland " -r #relocation base \n" \ 73*5c51f124SMoriah Waterland "and options may include:\n" \ 74*5c51f124SMoriah Waterland " -c category, [category...]\n" \ 75*5c51f124SMoriah Waterland " -a architecture\n" \ 76*5c51f124SMoriah Waterland " -v version\n" 77*5c51f124SMoriah Waterland 78*5c51f124SMoriah Waterland #define ERR_INCOMP0 "-L and -l/-x/-r flags are incompatible" 79*5c51f124SMoriah Waterland #define ERR_INCOMP1 "-l and -x/-r flags are not compatible" 80*5c51f124SMoriah Waterland #define ERR_INCOMP2 "-x and -l/-r flags are not compatible" 81*5c51f124SMoriah Waterland #define ERR_INCOMP3 "-r and -x/-x flags are not compatible" 82*5c51f124SMoriah Waterland #define ERR_NOINFO "ERROR: information for \"%s\" was not found" 83*5c51f124SMoriah Waterland #define ERR_NOPINFO "ERROR: No partial information for \"%s\" was found" 84*5c51f124SMoriah Waterland #define ERR_BADINFO "pkginfo file is corrupt or missing" 85*5c51f124SMoriah Waterland #define ERR_ROOT_SET "Could not set install root from the environment." 86*5c51f124SMoriah Waterland #define ERR_ROOT_CMD "Command line install root contends with environment." 87*5c51f124SMoriah Waterland 88*5c51f124SMoriah Waterland /* Format for dumping package attributes in dumpinfo() */ 89*5c51f124SMoriah Waterland #define FMT "%10s: %s\n" 90*5c51f124SMoriah Waterland #define SFMT "%-11.11s %-*.*s %s\n" 91*5c51f124SMoriah Waterland #define CFMT "%*.*s " 92*5c51f124SMoriah Waterland #define XFMT "%-*.*s %s\n" 93*5c51f124SMoriah Waterland 94*5c51f124SMoriah Waterland #define nblock(size) ((size + (DEV_BSIZE - 1)) / DEV_BSIZE) 95*5c51f124SMoriah Waterland #define MAXCATG 64 96*5c51f124SMoriah Waterland 97*5c51f124SMoriah Waterland static char *device = NULL; 98*5c51f124SMoriah Waterland static char *parmlst[] = { 99*5c51f124SMoriah Waterland "DESC", "PSTAMP", "INSTDATE", "VSTOCK", "SERIALNUM", "HOTLINE", 100*5c51f124SMoriah Waterland "EMAIL", NULL 101*5c51f124SMoriah Waterland }; 102*5c51f124SMoriah Waterland 103*5c51f124SMoriah Waterland static char contents[PATH_MAX]; 104*5c51f124SMoriah Waterland static int errflg = 0; 105*5c51f124SMoriah Waterland static int qflag = 0; 106*5c51f124SMoriah Waterland static int iflag = -1; 107*5c51f124SMoriah Waterland static int pflag = -1; 108*5c51f124SMoriah Waterland static int lflag = 0; 109*5c51f124SMoriah Waterland static int Lflag = 0; 110*5c51f124SMoriah Waterland static int Nflag = 0; 111*5c51f124SMoriah Waterland static int xflag = 0; 112*5c51f124SMoriah Waterland static int rflag = 0; /* bug # 1081606 */ 113*5c51f124SMoriah Waterland static struct cfent entry; 114*5c51f124SMoriah Waterland static char **pkg = NULL; 115*5c51f124SMoriah Waterland static int pkgcnt = 0; 116*5c51f124SMoriah Waterland static char *ckcatg[MAXCATG] = {NULL}; 117*5c51f124SMoriah Waterland static int ncatg = 0; 118*5c51f124SMoriah Waterland static char *ckvers = NULL; 119*5c51f124SMoriah Waterland static char *ckarch = NULL; 120*5c51f124SMoriah Waterland 121*5c51f124SMoriah Waterland static struct cfstat { 122*5c51f124SMoriah Waterland char pkginst[32]; 123*5c51f124SMoriah Waterland short exec; 124*5c51f124SMoriah Waterland short dirs; 125*5c51f124SMoriah Waterland short link; 126*5c51f124SMoriah Waterland short partial; 127*5c51f124SMoriah Waterland long spooled; 128*5c51f124SMoriah Waterland long installed; 129*5c51f124SMoriah Waterland short info; 130*5c51f124SMoriah Waterland short shared; 131*5c51f124SMoriah Waterland short setuid; 132*5c51f124SMoriah Waterland long tblks; 133*5c51f124SMoriah Waterland struct cfstat *next; 134*5c51f124SMoriah Waterland } *data; 135*5c51f124SMoriah Waterland static struct pkginfo info; 136*5c51f124SMoriah Waterland 137*5c51f124SMoriah Waterland static struct cfstat *fpkg(char *pkginst); 138*5c51f124SMoriah Waterland static int iscatg(char *list); 139*5c51f124SMoriah Waterland static int selectp(char *p); 140*5c51f124SMoriah Waterland static void usage(void), look_for_installed(void), 141*5c51f124SMoriah Waterland report(void), rdcontents(void); 142*5c51f124SMoriah Waterland static void pkgusage(struct cfstat *dp, struct cfent *pentry); 143*5c51f124SMoriah Waterland static void getinfo(struct cfstat *dp); 144*5c51f124SMoriah Waterland static void dumpinfo(struct cfstat *dp, int pkgLngth); 145*5c51f124SMoriah Waterland 146*5c51f124SMoriah Waterland int 147*5c51f124SMoriah Waterland main(int argc, char **argv) 148*5c51f124SMoriah Waterland { 149*5c51f124SMoriah Waterland int c; 150*5c51f124SMoriah Waterland 151*5c51f124SMoriah Waterland pkgdir = NULL; 152*5c51f124SMoriah Waterland setErrstr(NULL); 153*5c51f124SMoriah Waterland 154*5c51f124SMoriah Waterland /* initialize locale mechanism */ 155*5c51f124SMoriah Waterland 156*5c51f124SMoriah Waterland (void) setlocale(LC_ALL, ""); 157*5c51f124SMoriah Waterland 158*5c51f124SMoriah Waterland #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 159*5c51f124SMoriah Waterland #define TEXT_DOMAIN "SYS_TEST" 160*5c51f124SMoriah Waterland #endif 161*5c51f124SMoriah Waterland (void) textdomain(TEXT_DOMAIN); 162*5c51f124SMoriah Waterland 163*5c51f124SMoriah Waterland /* determine program name */ 164*5c51f124SMoriah Waterland 165*5c51f124SMoriah Waterland (void) set_prog_name(argv[0]); 166*5c51f124SMoriah Waterland 167*5c51f124SMoriah Waterland /* tell spmi zones interface how to access package output functions */ 168*5c51f124SMoriah Waterland 169*5c51f124SMoriah Waterland z_set_output_functions(echo, echoDebug, progerr); 170*5c51f124SMoriah Waterland 171*5c51f124SMoriah Waterland /* establish installation root directory */ 172*5c51f124SMoriah Waterland 173*5c51f124SMoriah Waterland if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) { 174*5c51f124SMoriah Waterland progerr(gettext(ERR_ROOT_SET)); 175*5c51f124SMoriah Waterland exit(1); 176*5c51f124SMoriah Waterland } 177*5c51f124SMoriah Waterland 178*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, "LNR:xv:a:d:qrpilc:?")) != EOF) { 179*5c51f124SMoriah Waterland switch (c) { 180*5c51f124SMoriah Waterland case 'v': 181*5c51f124SMoriah Waterland ckvers = optarg; 182*5c51f124SMoriah Waterland break; 183*5c51f124SMoriah Waterland 184*5c51f124SMoriah Waterland case 'a': 185*5c51f124SMoriah Waterland ckarch = optarg; 186*5c51f124SMoriah Waterland break; 187*5c51f124SMoriah Waterland 188*5c51f124SMoriah Waterland case 'd': 189*5c51f124SMoriah Waterland /* -d could specify stream or mountable device */ 190*5c51f124SMoriah Waterland device = flex_device(optarg, 1); 191*5c51f124SMoriah Waterland break; 192*5c51f124SMoriah Waterland 193*5c51f124SMoriah Waterland case 'q': 194*5c51f124SMoriah Waterland qflag++; 195*5c51f124SMoriah Waterland break; 196*5c51f124SMoriah Waterland 197*5c51f124SMoriah Waterland case 'i': 198*5c51f124SMoriah Waterland iflag = 1; 199*5c51f124SMoriah Waterland if (pflag > 0) 200*5c51f124SMoriah Waterland usage(); 201*5c51f124SMoriah Waterland pflag = 0; 202*5c51f124SMoriah Waterland break; 203*5c51f124SMoriah Waterland 204*5c51f124SMoriah Waterland case 'p': 205*5c51f124SMoriah Waterland pflag = 1; 206*5c51f124SMoriah Waterland if (iflag > 0) 207*5c51f124SMoriah Waterland usage(); 208*5c51f124SMoriah Waterland iflag = 0; 209*5c51f124SMoriah Waterland break; 210*5c51f124SMoriah Waterland 211*5c51f124SMoriah Waterland case 'N': 212*5c51f124SMoriah Waterland Nflag++; 213*5c51f124SMoriah Waterland break; 214*5c51f124SMoriah Waterland 215*5c51f124SMoriah Waterland case 'L': 216*5c51f124SMoriah Waterland if (xflag || lflag || rflag) { 217*5c51f124SMoriah Waterland progerr(gettext(ERR_INCOMP0)); 218*5c51f124SMoriah Waterland usage(); 219*5c51f124SMoriah Waterland } 220*5c51f124SMoriah Waterland Lflag++; 221*5c51f124SMoriah Waterland break; 222*5c51f124SMoriah Waterland 223*5c51f124SMoriah Waterland case 'l': 224*5c51f124SMoriah Waterland if (xflag || rflag) { 225*5c51f124SMoriah Waterland progerr(gettext(ERR_INCOMP1)); 226*5c51f124SMoriah Waterland usage(); 227*5c51f124SMoriah Waterland } 228*5c51f124SMoriah Waterland lflag++; 229*5c51f124SMoriah Waterland break; 230*5c51f124SMoriah Waterland 231*5c51f124SMoriah Waterland case 'x': 232*5c51f124SMoriah Waterland /* bug # 1081606 */ 233*5c51f124SMoriah Waterland if (lflag || rflag) { 234*5c51f124SMoriah Waterland progerr(gettext(ERR_INCOMP2)); 235*5c51f124SMoriah Waterland usage(); 236*5c51f124SMoriah Waterland } 237*5c51f124SMoriah Waterland xflag++; 238*5c51f124SMoriah Waterland break; 239*5c51f124SMoriah Waterland 240*5c51f124SMoriah Waterland case 'r': 241*5c51f124SMoriah Waterland if (lflag || xflag || Lflag) { 242*5c51f124SMoriah Waterland progerr(gettext(ERR_INCOMP0)); 243*5c51f124SMoriah Waterland usage(); 244*5c51f124SMoriah Waterland } 245*5c51f124SMoriah Waterland rflag++; 246*5c51f124SMoriah Waterland break; 247*5c51f124SMoriah Waterland 248*5c51f124SMoriah Waterland case 'c': 249*5c51f124SMoriah Waterland ckcatg[ncatg++] = strtok(optarg, " \t\n, "); 250*5c51f124SMoriah Waterland while (ckcatg[ncatg] = strtok(NULL, " \t\n, ")) 251*5c51f124SMoriah Waterland ncatg++; 252*5c51f124SMoriah Waterland break; 253*5c51f124SMoriah Waterland 254*5c51f124SMoriah Waterland /* added for newroot functions */ 255*5c51f124SMoriah Waterland case 'R': 256*5c51f124SMoriah Waterland if (!set_inst_root(optarg)) { 257*5c51f124SMoriah Waterland progerr(gettext(ERR_ROOT_CMD)); 258*5c51f124SMoriah Waterland exit(1); 259*5c51f124SMoriah Waterland } 260*5c51f124SMoriah Waterland break; 261*5c51f124SMoriah Waterland 262*5c51f124SMoriah Waterland default: 263*5c51f124SMoriah Waterland usage(); 264*5c51f124SMoriah Waterland } 265*5c51f124SMoriah Waterland } 266*5c51f124SMoriah Waterland 267*5c51f124SMoriah Waterland /* 268*5c51f124SMoriah Waterland * implement the newroot option 269*5c51f124SMoriah Waterland */ 270*5c51f124SMoriah Waterland set_PKGpaths(get_inst_root()); /* set up /var... directories */ 271*5c51f124SMoriah Waterland 272*5c51f124SMoriah Waterland /* 273*5c51f124SMoriah Waterland * Open the install DB, if one exists. 274*5c51f124SMoriah Waterland */ 275*5c51f124SMoriah Waterland 276*5c51f124SMoriah Waterland pkg = &argv[optind]; 277*5c51f124SMoriah Waterland pkgcnt = (argc - optind); 278*5c51f124SMoriah Waterland 279*5c51f124SMoriah Waterland if (pkg[0] && strcmp(pkg[0], "all") == NULL) { 280*5c51f124SMoriah Waterland pkgcnt = 0; 281*5c51f124SMoriah Waterland pkg[0] = NULL; 282*5c51f124SMoriah Waterland } 283*5c51f124SMoriah Waterland 284*5c51f124SMoriah Waterland if (pkgdir == NULL) 285*5c51f124SMoriah Waterland pkgdir = get_PKGLOC(); /* we need this later */ 286*5c51f124SMoriah Waterland 287*5c51f124SMoriah Waterland /* convert device appropriately */ 288*5c51f124SMoriah Waterland if (pkghead(device)) 289*5c51f124SMoriah Waterland exit(1); 290*5c51f124SMoriah Waterland 291*5c51f124SMoriah Waterland /* 292*5c51f124SMoriah Waterland * If we are to inspect a spooled package we are only interested in 293*5c51f124SMoriah Waterland * the pkginfo file in the spooled pkg so we skip any Reg 4 DB 294*5c51f124SMoriah Waterland * lookups and use the old algorithm. We have a spooled pkg if 295*5c51f124SMoriah Waterland * device is not NULL. 296*5c51f124SMoriah Waterland */ 297*5c51f124SMoriah Waterland 298*5c51f124SMoriah Waterland 299*5c51f124SMoriah Waterland look_for_installed(); 300*5c51f124SMoriah Waterland 301*5c51f124SMoriah Waterland if (lflag && strcmp(pkgdir, get_PKGLOC()) == NULL) { 302*5c51f124SMoriah Waterland /* look at contents file */ 303*5c51f124SMoriah Waterland (void) snprintf(contents, sizeof (contents), 304*5c51f124SMoriah Waterland "%s/contents", get_PKGADM()); 305*5c51f124SMoriah Waterland rdcontents(); 306*5c51f124SMoriah Waterland 307*5c51f124SMoriah Waterland } 308*5c51f124SMoriah Waterland 309*5c51f124SMoriah Waterland /* 310*5c51f124SMoriah Waterland * If we are to inspect a spooled package we are only interested in 311*5c51f124SMoriah Waterland * the pkginfo file in the spooled pkg so we skip any Reg 4 DB 312*5c51f124SMoriah Waterland * lookups and use the old algorithm. We have a spooled pkg if 313*5c51f124SMoriah Waterland * device is not NULL. 314*5c51f124SMoriah Waterland */ 315*5c51f124SMoriah Waterland 316*5c51f124SMoriah Waterland report(); 317*5c51f124SMoriah Waterland 318*5c51f124SMoriah Waterland (void) pkghead(NULL); 319*5c51f124SMoriah Waterland 320*5c51f124SMoriah Waterland return (errflg ? 1 : 0); 321*5c51f124SMoriah Waterland } 322*5c51f124SMoriah Waterland 323*5c51f124SMoriah Waterland static void 324*5c51f124SMoriah Waterland report(void) 325*5c51f124SMoriah Waterland { 326*5c51f124SMoriah Waterland struct cfstat *dp, *choice; 327*5c51f124SMoriah Waterland int i; 328*5c51f124SMoriah Waterland int pkgLgth = 0; 329*5c51f124SMoriah Waterland int longestPkg = 0; 330*5c51f124SMoriah Waterland boolean_t output = B_FALSE; 331*5c51f124SMoriah Waterland 332*5c51f124SMoriah Waterland for (;;) { 333*5c51f124SMoriah Waterland choice = (struct cfstat *)0; 334*5c51f124SMoriah Waterland for (dp = data; dp; dp = dp->next) { 335*5c51f124SMoriah Waterland pkgLgth = strlen(dp->pkginst); 336*5c51f124SMoriah Waterland if (pkgLgth > longestPkg) 337*5c51f124SMoriah Waterland longestPkg = pkgLgth; 338*5c51f124SMoriah Waterland } 339*5c51f124SMoriah Waterland for (dp = data; dp; dp = dp->next) { 340*5c51f124SMoriah Waterland /* get information about this package */ 341*5c51f124SMoriah Waterland if (dp->installed < 0) 342*5c51f124SMoriah Waterland continue; /* already used */ 343*5c51f124SMoriah Waterland if (Lflag && pkgcnt) { 344*5c51f124SMoriah Waterland choice = dp; 345*5c51f124SMoriah Waterland break; 346*5c51f124SMoriah Waterland } else if (!choice || 347*5c51f124SMoriah Waterland (strcmp(choice->pkginst, dp->pkginst) > 0)) 348*5c51f124SMoriah Waterland choice = dp; 349*5c51f124SMoriah Waterland } 350*5c51f124SMoriah Waterland if (!choice) 351*5c51f124SMoriah Waterland break; /* no more packages */ 352*5c51f124SMoriah Waterland 353*5c51f124SMoriah Waterland if (pkginfo(&info, choice->pkginst, ckarch, ckvers)) { 354*5c51f124SMoriah Waterland choice->installed = (-1); 355*5c51f124SMoriah Waterland continue; 356*5c51f124SMoriah Waterland } 357*5c51f124SMoriah Waterland 358*5c51f124SMoriah Waterland /* 359*5c51f124SMoriah Waterland * Confirm that the pkginfo file contains the 360*5c51f124SMoriah Waterland * required information. 361*5c51f124SMoriah Waterland */ 362*5c51f124SMoriah Waterland if (info.name == NULL || *(info.name) == NULL || 363*5c51f124SMoriah Waterland info.arch == NULL || *(info.arch) == NULL || 364*5c51f124SMoriah Waterland info.version == NULL || *(info.version) == NULL || 365*5c51f124SMoriah Waterland info.catg == NULL || *(info.catg) == NULL) { 366*5c51f124SMoriah Waterland progerr(gettext(ERR_BADINFO)); 367*5c51f124SMoriah Waterland errflg++; 368*5c51f124SMoriah Waterland return; 369*5c51f124SMoriah Waterland } 370*5c51f124SMoriah Waterland 371*5c51f124SMoriah Waterland /* is it in an appropriate catgory? */ 372*5c51f124SMoriah Waterland if (iscatg(info.catg)) { 373*5c51f124SMoriah Waterland choice->installed = (-1); 374*5c51f124SMoriah Waterland continue; 375*5c51f124SMoriah Waterland } 376*5c51f124SMoriah Waterland 377*5c51f124SMoriah Waterland if (!pflag && 378*5c51f124SMoriah Waterland /* don't include partially installed packages */ 379*5c51f124SMoriah Waterland (choice->partial || (info.status == PI_PARTIAL) || 380*5c51f124SMoriah Waterland (info.status == PI_UNKNOWN))) { 381*5c51f124SMoriah Waterland choice->installed = (-1); 382*5c51f124SMoriah Waterland continue; 383*5c51f124SMoriah Waterland } 384*5c51f124SMoriah Waterland 385*5c51f124SMoriah Waterland if (Nflag && (info.status == PI_PRESVR4)) { 386*5c51f124SMoriah Waterland /* don't include preSVR4 packages */ 387*5c51f124SMoriah Waterland choice->installed = (-1); 388*5c51f124SMoriah Waterland continue; 389*5c51f124SMoriah Waterland } 390*5c51f124SMoriah Waterland 391*5c51f124SMoriah Waterland if (!iflag && ((info.status == PI_INSTALLED) || 392*5c51f124SMoriah Waterland (info.status == PI_PRESVR4))) { 393*5c51f124SMoriah Waterland /* don't include completely installed packages */ 394*5c51f124SMoriah Waterland choice->installed = (-1); 395*5c51f124SMoriah Waterland continue; 396*5c51f124SMoriah Waterland } 397*5c51f124SMoriah Waterland 398*5c51f124SMoriah Waterland output = B_TRUE; 399*5c51f124SMoriah Waterland dumpinfo(choice, longestPkg); 400*5c51f124SMoriah Waterland choice->installed = (-1); 401*5c51f124SMoriah Waterland if (pkgcnt) { 402*5c51f124SMoriah Waterland i = selectp(choice->pkginst); 403*5c51f124SMoriah Waterland if (i >= 0) 404*5c51f124SMoriah Waterland pkg[i] = NULL; 405*5c51f124SMoriah Waterland else { 406*5c51f124SMoriah Waterland if (qflag) { 407*5c51f124SMoriah Waterland errflg++; 408*5c51f124SMoriah Waterland return; 409*5c51f124SMoriah Waterland } 410*5c51f124SMoriah Waterland } 411*5c51f124SMoriah Waterland } 412*5c51f124SMoriah Waterland } 413*5c51f124SMoriah Waterland 414*5c51f124SMoriah Waterland /* If no package matched and no output produced set error flag */ 415*5c51f124SMoriah Waterland if (!output) 416*5c51f124SMoriah Waterland errflg++; 417*5c51f124SMoriah Waterland 418*5c51f124SMoriah Waterland /* verify that each package listed on command line was output */ 419*5c51f124SMoriah Waterland for (i = 0; i < pkgcnt; ++i) { 420*5c51f124SMoriah Waterland if (pkg[i]) { 421*5c51f124SMoriah Waterland errflg++; 422*5c51f124SMoriah Waterland if (!qflag) { 423*5c51f124SMoriah Waterland if (pflag == 1) 424*5c51f124SMoriah Waterland logerr(gettext(ERR_NOPINFO), pkg[i]); 425*5c51f124SMoriah Waterland else 426*5c51f124SMoriah Waterland logerr(gettext(ERR_NOINFO), pkg[i]); 427*5c51f124SMoriah Waterland } else 428*5c51f124SMoriah Waterland return; 429*5c51f124SMoriah Waterland } 430*5c51f124SMoriah Waterland } 431*5c51f124SMoriah Waterland (void) pkginfo(&info, NULL); /* free up all memory and open fds */ 432*5c51f124SMoriah Waterland } 433*5c51f124SMoriah Waterland 434*5c51f124SMoriah Waterland static void 435*5c51f124SMoriah Waterland dumpinfo(struct cfstat *dp, int pkgLngth) 436*5c51f124SMoriah Waterland { 437*5c51f124SMoriah Waterland register int i; 438*5c51f124SMoriah Waterland char *pt; 439*5c51f124SMoriah Waterland char category[128]; 440*5c51f124SMoriah Waterland 441*5c51f124SMoriah Waterland if (qflag) { 442*5c51f124SMoriah Waterland return; /* print nothing */ 443*5c51f124SMoriah Waterland } 444*5c51f124SMoriah Waterland 445*5c51f124SMoriah Waterland if (rflag) { 446*5c51f124SMoriah Waterland (void) puts((info.basedir) ? info.basedir : "none"); 447*5c51f124SMoriah Waterland return; 448*5c51f124SMoriah Waterland } 449*5c51f124SMoriah Waterland 450*5c51f124SMoriah Waterland if (Lflag) { 451*5c51f124SMoriah Waterland (void) puts(info.pkginst); 452*5c51f124SMoriah Waterland return; 453*5c51f124SMoriah Waterland } else if (xflag) { 454*5c51f124SMoriah Waterland (void) printf(XFMT, pkgLngth, pkgLngth, info.pkginst, 455*5c51f124SMoriah Waterland info.name); 456*5c51f124SMoriah Waterland 457*5c51f124SMoriah Waterland if (info.arch || info.version) { 458*5c51f124SMoriah Waterland (void) printf(CFMT, pkgLngth, pkgLngth, ""); 459*5c51f124SMoriah Waterland if (info.arch) 460*5c51f124SMoriah Waterland (void) printf("(%s) ", info.arch); 461*5c51f124SMoriah Waterland if (info.version) 462*5c51f124SMoriah Waterland (void) printf("%s", info.version); 463*5c51f124SMoriah Waterland (void) printf("\n"); 464*5c51f124SMoriah Waterland } 465*5c51f124SMoriah Waterland return; 466*5c51f124SMoriah Waterland } else if (!lflag) { 467*5c51f124SMoriah Waterland if (info.catg) { 468*5c51f124SMoriah Waterland (void) sscanf(info.catg, "%[^, \t\n]", category); 469*5c51f124SMoriah Waterland } else if (info.status == PI_PRESVR4) { 470*5c51f124SMoriah Waterland (void) strcpy(category, "preSVR4"); 471*5c51f124SMoriah Waterland } else { 472*5c51f124SMoriah Waterland (void) strcpy(category, "(unknown)"); 473*5c51f124SMoriah Waterland } 474*5c51f124SMoriah Waterland (void) printf(SFMT, category, pkgLngth, pkgLngth, info.pkginst, 475*5c51f124SMoriah Waterland info.name); 476*5c51f124SMoriah Waterland return; 477*5c51f124SMoriah Waterland } 478*5c51f124SMoriah Waterland if (info.pkginst) 479*5c51f124SMoriah Waterland (void) printf(FMT, "PKGINST", info.pkginst); 480*5c51f124SMoriah Waterland if (info.name) 481*5c51f124SMoriah Waterland (void) printf(FMT, "NAME", info.name); 482*5c51f124SMoriah Waterland if (lflag && info.catg) 483*5c51f124SMoriah Waterland (void) printf(FMT, "CATEGORY", info.catg); 484*5c51f124SMoriah Waterland if (lflag && info.arch) 485*5c51f124SMoriah Waterland (void) printf(FMT, "ARCH", info.arch); 486*5c51f124SMoriah Waterland if (info.version) 487*5c51f124SMoriah Waterland (void) printf(FMT, "VERSION", info.version); 488*5c51f124SMoriah Waterland if (info.basedir) 489*5c51f124SMoriah Waterland (void) printf(FMT, "BASEDIR", info.basedir); 490*5c51f124SMoriah Waterland if (info.vendor) 491*5c51f124SMoriah Waterland (void) printf(FMT, "VENDOR", info.vendor); 492*5c51f124SMoriah Waterland 493*5c51f124SMoriah Waterland if (info.status == PI_PRESVR4) 494*5c51f124SMoriah Waterland (void) printf(FMT, "STATUS", "preSVR4"); 495*5c51f124SMoriah Waterland else { 496*5c51f124SMoriah Waterland for (i = 0; parmlst[i]; ++i) { 497*5c51f124SMoriah Waterland if ((pt = pkgparam(info.pkginst, parmlst[i])) != NULL && 498*5c51f124SMoriah Waterland *pt) 499*5c51f124SMoriah Waterland (void) printf(FMT, parmlst[i], pt); 500*5c51f124SMoriah Waterland } 501*5c51f124SMoriah Waterland if (info.status == PI_SPOOLED) 502*5c51f124SMoriah Waterland (void) printf(FMT, "STATUS", gettext("spooled")); 503*5c51f124SMoriah Waterland else if (info.status == PI_PARTIAL) 504*5c51f124SMoriah Waterland (void) printf(FMT, "STATUS", 505*5c51f124SMoriah Waterland gettext("partially installed")); 506*5c51f124SMoriah Waterland else if (info.status == PI_INSTALLED) 507*5c51f124SMoriah Waterland (void) printf(FMT, "STATUS", 508*5c51f124SMoriah Waterland gettext("completely installed")); 509*5c51f124SMoriah Waterland else 510*5c51f124SMoriah Waterland (void) printf(FMT, "STATUS", gettext("(unknown)")); 511*5c51f124SMoriah Waterland } 512*5c51f124SMoriah Waterland (void) pkgparam(NULL, NULL); 513*5c51f124SMoriah Waterland 514*5c51f124SMoriah Waterland if (!lflag) { 515*5c51f124SMoriah Waterland (void) putchar('\n'); 516*5c51f124SMoriah Waterland return; 517*5c51f124SMoriah Waterland } 518*5c51f124SMoriah Waterland 519*5c51f124SMoriah Waterland if (info.status != PI_PRESVR4) { 520*5c51f124SMoriah Waterland if (strcmp(pkgdir, get_PKGLOC())) 521*5c51f124SMoriah Waterland getinfo(dp); 522*5c51f124SMoriah Waterland 523*5c51f124SMoriah Waterland if (dp->spooled) 524*5c51f124SMoriah Waterland (void) printf( 525*5c51f124SMoriah Waterland gettext("%10s: %7ld spooled pathnames\n"), 526*5c51f124SMoriah Waterland "FILES", dp->spooled); 527*5c51f124SMoriah Waterland if (dp->installed) 528*5c51f124SMoriah Waterland (void) printf( 529*5c51f124SMoriah Waterland gettext("%10s: %7ld installed pathnames\n"), 530*5c51f124SMoriah Waterland "FILES", dp->installed); 531*5c51f124SMoriah Waterland if (dp->partial) 532*5c51f124SMoriah Waterland (void) printf( 533*5c51f124SMoriah Waterland gettext("%20d partially installed pathnames\n"), 534*5c51f124SMoriah Waterland dp->partial); 535*5c51f124SMoriah Waterland if (dp->shared) 536*5c51f124SMoriah Waterland (void) printf(gettext("%20d shared pathnames\n"), 537*5c51f124SMoriah Waterland dp->shared); 538*5c51f124SMoriah Waterland if (dp->link) 539*5c51f124SMoriah Waterland (void) printf(gettext("%20d linked files\n"), dp->link); 540*5c51f124SMoriah Waterland if (dp->dirs) 541*5c51f124SMoriah Waterland (void) printf(gettext("%20d directories\n"), dp->dirs); 542*5c51f124SMoriah Waterland if (dp->exec) 543*5c51f124SMoriah Waterland (void) printf(gettext("%20d executables\n"), dp->exec); 544*5c51f124SMoriah Waterland if (dp->setuid) 545*5c51f124SMoriah Waterland (void) printf( 546*5c51f124SMoriah Waterland gettext("%20d setuid/setgid executables\n"), 547*5c51f124SMoriah Waterland dp->setuid); 548*5c51f124SMoriah Waterland if (dp->info) 549*5c51f124SMoriah Waterland (void) printf( 550*5c51f124SMoriah Waterland gettext("%20d package information files\n"), 551*5c51f124SMoriah Waterland dp->info+1); /* pkgmap counts! */ 552*5c51f124SMoriah Waterland 553*5c51f124SMoriah Waterland if (dp->tblks) 554*5c51f124SMoriah Waterland (void) printf(gettext("%20ld blocks used (approx)\n"), 555*5c51f124SMoriah Waterland dp->tblks); 556*5c51f124SMoriah Waterland } 557*5c51f124SMoriah Waterland (void) putchar('\n'); 558*5c51f124SMoriah Waterland } 559*5c51f124SMoriah Waterland 560*5c51f124SMoriah Waterland static struct cfstat * 561*5c51f124SMoriah Waterland fpkg(char *pkginst) 562*5c51f124SMoriah Waterland { 563*5c51f124SMoriah Waterland struct cfstat *dp, *last; 564*5c51f124SMoriah Waterland 565*5c51f124SMoriah Waterland dp = data; 566*5c51f124SMoriah Waterland last = (struct cfstat *)0; 567*5c51f124SMoriah Waterland while (dp) { 568*5c51f124SMoriah Waterland if (strcmp(dp->pkginst, pkginst) == NULL) 569*5c51f124SMoriah Waterland return (dp); 570*5c51f124SMoriah Waterland last = dp; 571*5c51f124SMoriah Waterland dp = dp->next; 572*5c51f124SMoriah Waterland } 573*5c51f124SMoriah Waterland dp = (struct cfstat *)calloc(1, sizeof (struct cfstat)); 574*5c51f124SMoriah Waterland if (!dp) { 575*5c51f124SMoriah Waterland progerr(gettext("no memory, malloc() failed")); 576*5c51f124SMoriah Waterland exit(1); 577*5c51f124SMoriah Waterland } 578*5c51f124SMoriah Waterland if (!last) 579*5c51f124SMoriah Waterland data = dp; 580*5c51f124SMoriah Waterland else 581*5c51f124SMoriah Waterland last->next = dp; /* link list */ 582*5c51f124SMoriah Waterland (void) strcpy(dp->pkginst, pkginst); 583*5c51f124SMoriah Waterland return (dp); 584*5c51f124SMoriah Waterland } 585*5c51f124SMoriah Waterland 586*5c51f124SMoriah Waterland #define SEPAR ',' 587*5c51f124SMoriah Waterland 588*5c51f124SMoriah Waterland static int 589*5c51f124SMoriah Waterland iscatg(char *list) 590*5c51f124SMoriah Waterland { 591*5c51f124SMoriah Waterland register int i; 592*5c51f124SMoriah Waterland register char *pt; 593*5c51f124SMoriah Waterland int match; 594*5c51f124SMoriah Waterland 595*5c51f124SMoriah Waterland if (!ckcatg[0]) 596*5c51f124SMoriah Waterland return (0); /* no specification implies all packages */ 597*5c51f124SMoriah Waterland if (info.status == PI_PRESVR4) { 598*5c51f124SMoriah Waterland for (i = 0; ckcatg[i]; /* void */) { 599*5c51f124SMoriah Waterland if (strcmp(ckcatg[i++], "preSVR4") == NULL) 600*5c51f124SMoriah Waterland return (0); 601*5c51f124SMoriah Waterland } 602*5c51f124SMoriah Waterland return (1); 603*5c51f124SMoriah Waterland } 604*5c51f124SMoriah Waterland if (!list) 605*5c51f124SMoriah Waterland return (1); /* no category specified in pkginfo is a bug */ 606*5c51f124SMoriah Waterland 607*5c51f124SMoriah Waterland match = 0; 608*5c51f124SMoriah Waterland do { 609*5c51f124SMoriah Waterland if (pt = strchr(list, ',')) 610*5c51f124SMoriah Waterland *pt = '\0'; 611*5c51f124SMoriah Waterland 612*5c51f124SMoriah Waterland for (i = 0; ckcatg[i]; /* void */) { 613*5c51f124SMoriah Waterland /* bug id 1081607 */ 614*5c51f124SMoriah Waterland if (!strcasecmp(list, ckcatg[i++])) { 615*5c51f124SMoriah Waterland match++; 616*5c51f124SMoriah Waterland break; 617*5c51f124SMoriah Waterland } 618*5c51f124SMoriah Waterland } 619*5c51f124SMoriah Waterland 620*5c51f124SMoriah Waterland if (pt) 621*5c51f124SMoriah Waterland *pt++ = ','; 622*5c51f124SMoriah Waterland if (match) 623*5c51f124SMoriah Waterland return (0); 624*5c51f124SMoriah Waterland list = pt; /* points to next one */ 625*5c51f124SMoriah Waterland } while (pt); 626*5c51f124SMoriah Waterland return (1); 627*5c51f124SMoriah Waterland } 628*5c51f124SMoriah Waterland 629*5c51f124SMoriah Waterland static void 630*5c51f124SMoriah Waterland look_for_installed(void) 631*5c51f124SMoriah Waterland { 632*5c51f124SMoriah Waterland struct dirent *drp; 633*5c51f124SMoriah Waterland struct stat status; 634*5c51f124SMoriah Waterland DIR *dirfp; 635*5c51f124SMoriah Waterland char path[PATH_MAX]; 636*5c51f124SMoriah Waterland int n; 637*5c51f124SMoriah Waterland 638*5c51f124SMoriah Waterland if (strcmp(pkgdir, get_PKGLOC()) == NULL && 639*5c51f124SMoriah Waterland (dirfp = opendir(get_PKGOLD()))) { 640*5c51f124SMoriah Waterland while (drp = readdir(dirfp)) { 641*5c51f124SMoriah Waterland if (drp->d_name[0] == '.') 642*5c51f124SMoriah Waterland continue; 643*5c51f124SMoriah Waterland n = strlen(drp->d_name); 644*5c51f124SMoriah Waterland if ((n > 5) && 645*5c51f124SMoriah Waterland strcmp(&drp->d_name[n-5], ".name") == NULL) { 646*5c51f124SMoriah Waterland (void) snprintf(path, sizeof (path), 647*5c51f124SMoriah Waterland "%s/%s", get_PKGOLD(), drp->d_name); 648*5c51f124SMoriah Waterland if (lstat(path, &status)) 649*5c51f124SMoriah Waterland continue; 650*5c51f124SMoriah Waterland if ((status.st_mode & S_IFMT) != S_IFREG) 651*5c51f124SMoriah Waterland continue; 652*5c51f124SMoriah Waterland drp->d_name[n-5] = '\0'; 653*5c51f124SMoriah Waterland if (!pkgcnt || (selectp(drp->d_name) >= 0)) 654*5c51f124SMoriah Waterland (void) fpkg(drp->d_name); 655*5c51f124SMoriah Waterland } 656*5c51f124SMoriah Waterland } 657*5c51f124SMoriah Waterland (void) closedir(dirfp); 658*5c51f124SMoriah Waterland } 659*5c51f124SMoriah Waterland 660*5c51f124SMoriah Waterland if ((dirfp = opendir(pkgdir)) == NULL) 661*5c51f124SMoriah Waterland return; 662*5c51f124SMoriah Waterland 663*5c51f124SMoriah Waterland while (drp = readdir(dirfp)) { 664*5c51f124SMoriah Waterland if (drp->d_name[0] == '.') 665*5c51f124SMoriah Waterland continue; 666*5c51f124SMoriah Waterland 667*5c51f124SMoriah Waterland if (pkgcnt && (selectp(drp->d_name) < 0)) 668*5c51f124SMoriah Waterland continue; 669*5c51f124SMoriah Waterland 670*5c51f124SMoriah Waterland if (!pkginfofind(path, pkgdir, drp->d_name)) 671*5c51f124SMoriah Waterland continue; /* doesn't appear to be a package */ 672*5c51f124SMoriah Waterland 673*5c51f124SMoriah Waterland (void) fpkg(drp->d_name); 674*5c51f124SMoriah Waterland } 675*5c51f124SMoriah Waterland (void) closedir(dirfp); 676*5c51f124SMoriah Waterland } 677*5c51f124SMoriah Waterland 678*5c51f124SMoriah Waterland static int 679*5c51f124SMoriah Waterland selectp(char *p) 680*5c51f124SMoriah Waterland { 681*5c51f124SMoriah Waterland register int i; 682*5c51f124SMoriah Waterland 683*5c51f124SMoriah Waterland for (i = 0; i < pkgcnt; ++i) { 684*5c51f124SMoriah Waterland if (pkg[i] && pkgnmchk(p, pkg[i], 1) == 0) 685*5c51f124SMoriah Waterland return (i); 686*5c51f124SMoriah Waterland } 687*5c51f124SMoriah Waterland return (-1); 688*5c51f124SMoriah Waterland } 689*5c51f124SMoriah Waterland 690*5c51f124SMoriah Waterland static void 691*5c51f124SMoriah Waterland rdcontents(void) 692*5c51f124SMoriah Waterland { 693*5c51f124SMoriah Waterland VFP_T *vfp; 694*5c51f124SMoriah Waterland struct cfstat *dp; 695*5c51f124SMoriah Waterland struct pinfo *pinfo; 696*5c51f124SMoriah Waterland int n; 697*5c51f124SMoriah Waterland 698*5c51f124SMoriah Waterland if (vfpOpen(&vfp, contents, "r", VFP_NEEDNOW) != 0) { 699*5c51f124SMoriah Waterland progerr(gettext("unable to open \"%s\" for reading"), contents); 700*5c51f124SMoriah Waterland exit(1); 701*5c51f124SMoriah Waterland } 702*5c51f124SMoriah Waterland 703*5c51f124SMoriah Waterland /* check the contents file to look for referenced packages */ 704*5c51f124SMoriah Waterland while ((n = srchcfile(&entry, "*", vfp, (VFP_T *)NULL)) > 0) { 705*5c51f124SMoriah Waterland for (pinfo = entry.pinfo; pinfo; pinfo = pinfo->next) { 706*5c51f124SMoriah Waterland /* see if entry is used by indicated packaged */ 707*5c51f124SMoriah Waterland if (pkgcnt && (selectp(pinfo->pkg) < 0)) 708*5c51f124SMoriah Waterland continue; 709*5c51f124SMoriah Waterland 710*5c51f124SMoriah Waterland dp = fpkg(pinfo->pkg); 711*5c51f124SMoriah Waterland pkgusage(dp, &entry); 712*5c51f124SMoriah Waterland 713*5c51f124SMoriah Waterland if (entry.npkgs > 1) 714*5c51f124SMoriah Waterland dp->shared++; 715*5c51f124SMoriah Waterland 716*5c51f124SMoriah Waterland /* 717*5c51f124SMoriah Waterland * Only objects specifically tagged with '!' event 718*5c51f124SMoriah Waterland * character are considered "partial", everything 719*5c51f124SMoriah Waterland * else is considered "installed" (even server 720*5c51f124SMoriah Waterland * objects). 721*5c51f124SMoriah Waterland */ 722*5c51f124SMoriah Waterland switch (pinfo->status) { 723*5c51f124SMoriah Waterland case '!' : 724*5c51f124SMoriah Waterland dp->partial++; 725*5c51f124SMoriah Waterland break; 726*5c51f124SMoriah Waterland default : 727*5c51f124SMoriah Waterland dp->installed++; 728*5c51f124SMoriah Waterland break; 729*5c51f124SMoriah Waterland } 730*5c51f124SMoriah Waterland } 731*5c51f124SMoriah Waterland } 732*5c51f124SMoriah Waterland if (n < 0) { 733*5c51f124SMoriah Waterland char *errstr = getErrstr(); 734*5c51f124SMoriah Waterland progerr(gettext("bad entry read in contents file")); 735*5c51f124SMoriah Waterland logerr(gettext("pathname: %s"), 736*5c51f124SMoriah Waterland (entry.path && *entry.path) ? entry.path : "Unknown"); 737*5c51f124SMoriah Waterland logerr(gettext("problem: %s"), 738*5c51f124SMoriah Waterland (errstr && *errstr) ? errstr : "Unknown"); 739*5c51f124SMoriah Waterland exit(1); 740*5c51f124SMoriah Waterland } 741*5c51f124SMoriah Waterland 742*5c51f124SMoriah Waterland (void) vfpClose(&vfp); 743*5c51f124SMoriah Waterland } 744*5c51f124SMoriah Waterland 745*5c51f124SMoriah Waterland static void 746*5c51f124SMoriah Waterland getinfo(struct cfstat *dp) 747*5c51f124SMoriah Waterland { 748*5c51f124SMoriah Waterland int n; 749*5c51f124SMoriah Waterland char pkgmap[MAXPATHLEN]; 750*5c51f124SMoriah Waterland VFP_T *vfp; 751*5c51f124SMoriah Waterland 752*5c51f124SMoriah Waterland (void) snprintf(pkgmap, sizeof (pkgmap), 753*5c51f124SMoriah Waterland "%s/%s/pkgmap", pkgdir, dp->pkginst); 754*5c51f124SMoriah Waterland 755*5c51f124SMoriah Waterland if (vfpOpen(&vfp, pkgmap, "r", VFP_NEEDNOW) != 0) { 756*5c51f124SMoriah Waterland progerr(gettext("unable open \"%s\" for reading"), pkgmap); 757*5c51f124SMoriah Waterland exit(1); 758*5c51f124SMoriah Waterland } 759*5c51f124SMoriah Waterland 760*5c51f124SMoriah Waterland dp->spooled = 1; /* pkgmap counts! */ 761*5c51f124SMoriah Waterland 762*5c51f124SMoriah Waterland while ((n = gpkgmapvfp(&entry, vfp)) > 0) { 763*5c51f124SMoriah Waterland dp->spooled++; 764*5c51f124SMoriah Waterland pkgusage(dp, &entry); 765*5c51f124SMoriah Waterland } 766*5c51f124SMoriah Waterland 767*5c51f124SMoriah Waterland if (n < 0) { 768*5c51f124SMoriah Waterland char *errstr = getErrstr(); 769*5c51f124SMoriah Waterland progerr(gettext("bad entry read in pkgmap file")); 770*5c51f124SMoriah Waterland logerr(gettext("pathname: %s"), 771*5c51f124SMoriah Waterland (entry.path && *entry.path) ? entry.path : "Unknown"); 772*5c51f124SMoriah Waterland logerr(gettext("problem: %s"), 773*5c51f124SMoriah Waterland (errstr && *errstr) ? errstr : "Unknown"); 774*5c51f124SMoriah Waterland exit(1); 775*5c51f124SMoriah Waterland } 776*5c51f124SMoriah Waterland 777*5c51f124SMoriah Waterland (void) vfpClose(&vfp); 778*5c51f124SMoriah Waterland } 779*5c51f124SMoriah Waterland 780*5c51f124SMoriah Waterland static void 781*5c51f124SMoriah Waterland pkgusage(struct cfstat *dp, struct cfent *pentry) 782*5c51f124SMoriah Waterland { 783*5c51f124SMoriah Waterland if (pentry->ftype == 'i') { 784*5c51f124SMoriah Waterland dp->info++; 785*5c51f124SMoriah Waterland return; 786*5c51f124SMoriah Waterland } else if (pentry->ftype == 'l') { 787*5c51f124SMoriah Waterland dp->link++; 788*5c51f124SMoriah Waterland } else { 789*5c51f124SMoriah Waterland if ((pentry->ftype == 'd') || (pentry->ftype == 'x')) 790*5c51f124SMoriah Waterland dp->dirs++; 791*5c51f124SMoriah Waterland 792*5c51f124SMoriah Waterland /* Only collect mode stats if they would be meaningful. */ 793*5c51f124SMoriah Waterland if (pentry->ainfo.mode != BADMODE) { 794*5c51f124SMoriah Waterland if (pentry->ainfo.mode & 06000) 795*5c51f124SMoriah Waterland dp->setuid++; 796*5c51f124SMoriah Waterland if (!strchr("dxcbp", pentry->ftype) && 797*5c51f124SMoriah Waterland (pentry->ainfo.mode & 0111)) 798*5c51f124SMoriah Waterland dp->exec++; 799*5c51f124SMoriah Waterland } 800*5c51f124SMoriah Waterland } 801*5c51f124SMoriah Waterland 802*5c51f124SMoriah Waterland if (strchr("ifve", pentry->ftype)) 803*5c51f124SMoriah Waterland dp->tblks += nblock(pentry->cinfo.size); 804*5c51f124SMoriah Waterland } 805*5c51f124SMoriah Waterland 806*5c51f124SMoriah Waterland static void 807*5c51f124SMoriah Waterland usage(void) 808*5c51f124SMoriah Waterland { 809*5c51f124SMoriah Waterland char *prog = get_prog_name(); 810*5c51f124SMoriah Waterland 811*5c51f124SMoriah Waterland /* bug # 1081606 */ 812*5c51f124SMoriah Waterland (void) fprintf(stderr, gettext(ERR_USAGE), prog, prog); 813*5c51f124SMoriah Waterland 814*5c51f124SMoriah Waterland exit(1); 815*5c51f124SMoriah Waterland } 816*5c51f124SMoriah Waterland 817*5c51f124SMoriah Waterland void 818*5c51f124SMoriah Waterland quit(int retval) 819*5c51f124SMoriah Waterland { 820*5c51f124SMoriah Waterland exit(retval); 821*5c51f124SMoriah Waterland } 822