1*45916cd2Sjpk /* 2*45916cd2Sjpk * CDDL HEADER START 3*45916cd2Sjpk * 4*45916cd2Sjpk * The contents of this file are subject to the terms of the 5*45916cd2Sjpk * Common Development and Distribution License (the "License"). 6*45916cd2Sjpk * You may not use this file except in compliance with the License. 7*45916cd2Sjpk * 8*45916cd2Sjpk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*45916cd2Sjpk * or http://www.opensolaris.org/os/licensing. 10*45916cd2Sjpk * See the License for the specific language governing permissions 11*45916cd2Sjpk * and limitations under the License. 12*45916cd2Sjpk * 13*45916cd2Sjpk * When distributing Covered Code, include this CDDL HEADER in each 14*45916cd2Sjpk * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*45916cd2Sjpk * If applicable, add the following below this CDDL HEADER, with the 16*45916cd2Sjpk * fields enclosed by brackets "[]" replaced with your own identifying 17*45916cd2Sjpk * information: Portions Copyright [yyyy] [name of copyright owner] 18*45916cd2Sjpk * 19*45916cd2Sjpk * CDDL HEADER END 20*45916cd2Sjpk * 21*45916cd2Sjpk * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 22*45916cd2Sjpk * Use is subject to license terms. 23*45916cd2Sjpk */ 24*45916cd2Sjpk 25*45916cd2Sjpk #pragma ident "%Z%%M% %I% %E% SMI" 26*45916cd2Sjpk 27*45916cd2Sjpk #include <locale.h> 28*45916cd2Sjpk #include <stdio.h> 29*45916cd2Sjpk #include <stdlib.h> 30*45916cd2Sjpk #include <string.h> 31*45916cd2Sjpk #include <string.h> 32*45916cd2Sjpk #include <unistd.h> 33*45916cd2Sjpk #include <malloc.h> 34*45916cd2Sjpk #include <memory.h> 35*45916cd2Sjpk #include <sys/param.h> 36*45916cd2Sjpk #include <sys/types.h> 37*45916cd2Sjpk #include <sys/file.h> 38*45916cd2Sjpk #include <fcntl.h> 39*45916cd2Sjpk #include <bsm/devices.h> 40*45916cd2Sjpk #define DMPFILE "/etc/security/device_maps" 41*45916cd2Sjpk #define RETRY_SLEEP 6 42*45916cd2Sjpk #define RETRY_COUNT 10 43*45916cd2Sjpk #define EINVOKE 2 44*45916cd2Sjpk #define EFAIL 1 45*45916cd2Sjpk 46*45916cd2Sjpk #if !defined(TEXT_DOMAIN) 47*45916cd2Sjpk #define TEXT_DOMAIN "SUNW_BSM_DMINFO" 48*45916cd2Sjpk #endif 49*45916cd2Sjpk 50*45916cd2Sjpk extern off_t lseek(); 51*45916cd2Sjpk 52*45916cd2Sjpk char *getdmapfield(); 53*45916cd2Sjpk char *getdmapdfield(); 54*45916cd2Sjpk static void printdmapent(); 55*45916cd2Sjpk static void dmapi_err(); 56*45916cd2Sjpk 57*45916cd2Sjpk static char *prog_name; 58*45916cd2Sjpk 59*45916cd2Sjpk /* 60*45916cd2Sjpk * printdmapent(dmapp) prints a devmap_t structure pointed to by dmapp. 61*45916cd2Sjpk */ 62*45916cd2Sjpk static void 63*45916cd2Sjpk printdmapent(dmapp) 64*45916cd2Sjpk devmap_t *dmapp; 65*45916cd2Sjpk { 66*45916cd2Sjpk (void) printf("%s:", dmapp->dmap_devname); 67*45916cd2Sjpk (void) printf("%s:", dmapp->dmap_devtype); 68*45916cd2Sjpk (void) printf("%s", dmapp->dmap_devlist); 69*45916cd2Sjpk (void) printf("\n"); 70*45916cd2Sjpk } 71*45916cd2Sjpk 72*45916cd2Sjpk 73*45916cd2Sjpk /* 74*45916cd2Sjpk * dmapi_err(exit_code,err_msg) prints message pointed to by err_msg to 75*45916cd2Sjpk * stderr. Then prints usage message to stderr. Then exits program with 76*45916cd2Sjpk * exit_code. 77*45916cd2Sjpk * 78*45916cd2Sjpk */ 79*45916cd2Sjpk static void 80*45916cd2Sjpk dmapi_err(int exit_code, char *err_msg) 81*45916cd2Sjpk { 82*45916cd2Sjpk if (err_msg != NULL) { 83*45916cd2Sjpk (void) fprintf(stderr, "dmapinfo:%s\n", err_msg); 84*45916cd2Sjpk } 85*45916cd2Sjpk if (exit_code == EINVOKE) { 86*45916cd2Sjpk (void) fprintf(stderr, 87*45916cd2Sjpk "Usage: %s [-v] [-a] [-f filename] %s\n", 88*45916cd2Sjpk prog_name, 89*45916cd2Sjpk "[-d device ...]"); 90*45916cd2Sjpk (void) fprintf(stderr, 91*45916cd2Sjpk " %s [-v] [-a] [-f filename] %s\n", 92*45916cd2Sjpk prog_name, 93*45916cd2Sjpk "[-n name ...]"); 94*45916cd2Sjpk (void) fprintf(stderr, 95*45916cd2Sjpk " %s [-v] [-a] [-f filename] %s\n", 96*45916cd2Sjpk prog_name, 97*45916cd2Sjpk "[-t type ...]"); 98*45916cd2Sjpk (void) fprintf(stderr, 99*45916cd2Sjpk " %s [-v] [-a] [-f filename] %s\n", 100*45916cd2Sjpk prog_name, 101*45916cd2Sjpk "[-u Entry]"); 102*45916cd2Sjpk } 103*45916cd2Sjpk 104*45916cd2Sjpk exit(exit_code); 105*45916cd2Sjpk } 106*45916cd2Sjpk 107*45916cd2Sjpk int 108*45916cd2Sjpk main(int argc, char **argv) 109*45916cd2Sjpk { 110*45916cd2Sjpk devmap_t *dmapp; 111*45916cd2Sjpk devmap_t dmap; 112*45916cd2Sjpk char *mptr; 113*45916cd2Sjpk char *tptr; 114*45916cd2Sjpk char *nptr; 115*45916cd2Sjpk char *filename = DMPFILE; 116*45916cd2Sjpk int name = 0; 117*45916cd2Sjpk int device = 0; 118*45916cd2Sjpk int file = 0; 119*45916cd2Sjpk int verbose = 0; 120*45916cd2Sjpk int cntr = 0; 121*45916cd2Sjpk int any = 0; 122*45916cd2Sjpk int update = 0; 123*45916cd2Sjpk int tp = 0; 124*45916cd2Sjpk int des; 125*45916cd2Sjpk int status; 126*45916cd2Sjpk 127*45916cd2Sjpk /* Internationalization */ 128*45916cd2Sjpk (void) setlocale(LC_ALL, ""); 129*45916cd2Sjpk (void) textdomain(TEXT_DOMAIN); 130*45916cd2Sjpk 131*45916cd2Sjpk /* 132*45916cd2Sjpk * point prog_name to invocation name 133*45916cd2Sjpk */ 134*45916cd2Sjpk if ((tptr = strrchr(*argv, '/')) != NULL) 135*45916cd2Sjpk prog_name = ++tptr; 136*45916cd2Sjpk else 137*45916cd2Sjpk prog_name = *argv; 138*45916cd2Sjpk argc--; 139*45916cd2Sjpk argv++; 140*45916cd2Sjpk /* 141*45916cd2Sjpk * parse arguments 142*45916cd2Sjpk */ 143*45916cd2Sjpk while ((argc >= 1) && (argv[0][0] == '-')) { 144*45916cd2Sjpk switch (argv[0][1]) { 145*45916cd2Sjpk case 'a': 146*45916cd2Sjpk any++; 147*45916cd2Sjpk break; 148*45916cd2Sjpk case 'd': 149*45916cd2Sjpk if ((name) || (device) || (update) || (tp)) { 150*45916cd2Sjpk dmapi_err(EINVOKE, 151*45916cd2Sjpk gettext("option conflict")); 152*45916cd2Sjpk } 153*45916cd2Sjpk device++; 154*45916cd2Sjpk break; 155*45916cd2Sjpk case 'f': 156*45916cd2Sjpk argc--; 157*45916cd2Sjpk argv++; 158*45916cd2Sjpk if (argc <= 0) 159*45916cd2Sjpk dmapi_err(EINVOKE, 160*45916cd2Sjpk gettext("missing file name")); 161*45916cd2Sjpk filename = *argv; 162*45916cd2Sjpk file++; 163*45916cd2Sjpk break; 164*45916cd2Sjpk case 'n': 165*45916cd2Sjpk if ((name) || (device) || (update) || (tp)) { 166*45916cd2Sjpk dmapi_err(EINVOKE, 167*45916cd2Sjpk gettext("option conflict")); 168*45916cd2Sjpk } 169*45916cd2Sjpk name++; 170*45916cd2Sjpk break; 171*45916cd2Sjpk case 't': 172*45916cd2Sjpk if ((name) || (device) || (update) || (tp)) { 173*45916cd2Sjpk dmapi_err(EINVOKE, 174*45916cd2Sjpk gettext("option conflict")); 175*45916cd2Sjpk } 176*45916cd2Sjpk tp++; 177*45916cd2Sjpk break; 178*45916cd2Sjpk case 'u': 179*45916cd2Sjpk if ((name) || (device) || (update) || (tp)) { 180*45916cd2Sjpk dmapi_err(EINVOKE, 181*45916cd2Sjpk gettext("option conflict")); 182*45916cd2Sjpk } 183*45916cd2Sjpk update++; 184*45916cd2Sjpk break; 185*45916cd2Sjpk case 'v': 186*45916cd2Sjpk verbose++; 187*45916cd2Sjpk break; 188*45916cd2Sjpk default: 189*45916cd2Sjpk dmapi_err(EINVOKE, 190*45916cd2Sjpk gettext("bad option")); 191*45916cd2Sjpk break; 192*45916cd2Sjpk } 193*45916cd2Sjpk argc--; 194*45916cd2Sjpk argv++; 195*45916cd2Sjpk } 196*45916cd2Sjpk /* 197*45916cd2Sjpk * -d(device) -n(name) and -u(update) switches require at least one 198*45916cd2Sjpk * argument. 199*45916cd2Sjpk */ 200*45916cd2Sjpk if (file) 201*45916cd2Sjpk setdmapfile(filename); 202*45916cd2Sjpk if ((device) || (name) || (update) || (tp)) { 203*45916cd2Sjpk if (argc < 1) { 204*45916cd2Sjpk dmapi_err(EINVOKE, 205*45916cd2Sjpk gettext("insufficient args for this option")); 206*45916cd2Sjpk } 207*45916cd2Sjpk } 208*45916cd2Sjpk if (update) { 209*45916cd2Sjpk /* 210*45916cd2Sjpk * -u(update) switch requires only one argument 211*45916cd2Sjpk */ 212*45916cd2Sjpk if (argc != 1) { 213*45916cd2Sjpk dmapi_err(EINVOKE, 214*45916cd2Sjpk gettext("too many args for this option")); 215*45916cd2Sjpk } 216*45916cd2Sjpk /* 217*45916cd2Sjpk * read entry argument from stdin into a devmap_t known as dmap 218*45916cd2Sjpk */ 219*45916cd2Sjpk if ((dmap.dmap_devname = getdmapfield(*argv)) == NULL) { 220*45916cd2Sjpk dmapi_err(EINVOKE, 221*45916cd2Sjpk gettext("Bad dmap_devname in entry argument")); 222*45916cd2Sjpk } 223*45916cd2Sjpk if ((dmap.dmap_devtype = getdmapfield(NULL)) == 224*45916cd2Sjpk NULL) { 225*45916cd2Sjpk dmapi_err(EINVOKE, 226*45916cd2Sjpk gettext("Bad dmap_devtype in entry Argument")); 227*45916cd2Sjpk } 228*45916cd2Sjpk if ((dmap.dmap_devlist = getdmapfield(NULL)) == 229*45916cd2Sjpk NULL) { 230*45916cd2Sjpk dmapi_err(EINVOKE, 231*45916cd2Sjpk gettext("Bad dmap_devlist in entry argument")); 232*45916cd2Sjpk } 233*45916cd2Sjpk /* 234*45916cd2Sjpk * Find out how long device list is and create a buffer to 235*45916cd2Sjpk * hold it. Then copy it there. This is done since we do not 236*45916cd2Sjpk * want to corrupt the existing string. 237*45916cd2Sjpk */ 238*45916cd2Sjpk cntr = strlen(dmap.dmap_devlist) + 1; 239*45916cd2Sjpk mptr = calloc((unsigned)cntr, sizeof (char)); 240*45916cd2Sjpk if (mptr == NULL) { 241*45916cd2Sjpk if (verbose) { 242*45916cd2Sjpk (void) fprintf(stderr, 243*45916cd2Sjpk gettext( 244*45916cd2Sjpk "dmapinfo: Cannot calloc memory\n")); 245*45916cd2Sjpk } 246*45916cd2Sjpk exit(1); 247*45916cd2Sjpk } 248*45916cd2Sjpk (void) strcpy(mptr, dmap.dmap_devlist); 249*45916cd2Sjpk /* 250*45916cd2Sjpk * open the device maps file for read/ write. We are not 251*45916cd2Sjpk * sure we want to write to it yet but we may and this is a 252*45916cd2Sjpk * easy way to get the file descriptor. We want the file 253*45916cd2Sjpk * descriptor so we can lock the file. 254*45916cd2Sjpk */ 255*45916cd2Sjpk if ((des = open(filename, O_RDWR)) < 0) { 256*45916cd2Sjpk if (verbose) { 257*45916cd2Sjpk (void) fprintf(stderr, 258*45916cd2Sjpk gettext("dmapinfo: Cannot open %s\n"), 259*45916cd2Sjpk filename); 260*45916cd2Sjpk } 261*45916cd2Sjpk exit(1); 262*45916cd2Sjpk } 263*45916cd2Sjpk cntr = 0; 264*45916cd2Sjpk #ifdef CMW 265*45916cd2Sjpk while ((status = flock(des, LOCK_EX | LOCK_NB) == -1) && 266*45916cd2Sjpk (cntr++ < RETRY_COUNT)) { 267*45916cd2Sjpk (void) sleep(RETRY_SLEEP); 268*45916cd2Sjpk } 269*45916cd2Sjpk #else 270*45916cd2Sjpk while (((status = lockf(des, F_TLOCK, 0)) == -1) && 271*45916cd2Sjpk (cntr++ < RETRY_COUNT)) { 272*45916cd2Sjpk (void) sleep(RETRY_SLEEP); 273*45916cd2Sjpk } 274*45916cd2Sjpk #endif 275*45916cd2Sjpk if (status == -1) { 276*45916cd2Sjpk if (verbose) { 277*45916cd2Sjpk (void) fprintf(stderr, 278*45916cd2Sjpk gettext("dmapinfo: Cannot lock %s\n"), filename); 279*45916cd2Sjpk } 280*45916cd2Sjpk exit(1); 281*45916cd2Sjpk } 282*45916cd2Sjpk /* 283*45916cd2Sjpk * Now that we have the device_maps file then lets check 284*45916cd2Sjpk * for previous entrys with the same name. If it already 285*45916cd2Sjpk * exists then we will exit with status of 1. 286*45916cd2Sjpk */ 287*45916cd2Sjpk if (verbose) { 288*45916cd2Sjpk (void) fprintf(stderr, 289*45916cd2Sjpk gettext("dmapinfo: Checking %s for name (%s).\n"), 290*45916cd2Sjpk filename, dmap.dmap_devname); 291*45916cd2Sjpk } 292*45916cd2Sjpk if (getdmapnam(dmap.dmap_devname) != NULL) { 293*45916cd2Sjpk if (verbose) { 294*45916cd2Sjpk (void) fprintf(stderr, 295*45916cd2Sjpk gettext("dmapinfo: Device name (%s) found in %s.\n"), 296*45916cd2Sjpk dmap.dmap_devname, filename); 297*45916cd2Sjpk } 298*45916cd2Sjpk exit(1); 299*45916cd2Sjpk } 300*45916cd2Sjpk if (verbose) { 301*45916cd2Sjpk (void) fprintf(stderr, 302*45916cd2Sjpk gettext("dmapinfo: Device name (%s) not found in %s.\n"), 303*45916cd2Sjpk dmap.dmap_devname, filename); 304*45916cd2Sjpk } 305*45916cd2Sjpk /* 306*45916cd2Sjpk * We now Know name does not exist and now we need to check 307*45916cd2Sjpk * to see if any of the devices in the device list are in the 308*45916cd2Sjpk * device maps file. If the already exist then we will exit 309*45916cd2Sjpk * with a status of 1. 310*45916cd2Sjpk */ 311*45916cd2Sjpk nptr = mptr; 312*45916cd2Sjpk nptr = getdmapdfield(nptr); 313*45916cd2Sjpk while (nptr) { 314*45916cd2Sjpk if (verbose) { 315*45916cd2Sjpk (void) fprintf(stderr, 316*45916cd2Sjpk gettext("dmapinfo: " 317*45916cd2Sjpk "Check %s for device (%s).\n"), 318*45916cd2Sjpk filename, nptr); 319*45916cd2Sjpk } 320*45916cd2Sjpk if (getdmapdev(nptr) != NULL) { 321*45916cd2Sjpk if (verbose) { 322*45916cd2Sjpk (void) fprintf(stderr, 323*45916cd2Sjpk gettext("dmapinfo: " 324*45916cd2Sjpk "Device (%s) found in %s.\n"), 325*45916cd2Sjpk nptr, filename); 326*45916cd2Sjpk } 327*45916cd2Sjpk exit(1); 328*45916cd2Sjpk } 329*45916cd2Sjpk if (verbose) { 330*45916cd2Sjpk (void) fprintf(stderr, 331*45916cd2Sjpk gettext("dmapinfo: " 332*45916cd2Sjpk "Device (%s) not found in %s.\n"), 333*45916cd2Sjpk nptr, filename); 334*45916cd2Sjpk } 335*45916cd2Sjpk nptr = getdmapdfield(NULL); 336*45916cd2Sjpk } 337*45916cd2Sjpk /* 338*45916cd2Sjpk * Good the entry is uniq. So lets find out how long it is 339*45916cd2Sjpk * and add it to the end of device maps file in a pretty 340*45916cd2Sjpk * way. 341*45916cd2Sjpk */ 342*45916cd2Sjpk if (verbose) { 343*45916cd2Sjpk (void) fprintf(stderr, "dmapinfo: Adding entry to %s\n", 344*45916cd2Sjpk filename); 345*45916cd2Sjpk printdmapent(&dmap); 346*45916cd2Sjpk } 347*45916cd2Sjpk cntr = strlen(dmap.dmap_devname); 348*45916cd2Sjpk cntr += strlen(dmap.dmap_devtype); 349*45916cd2Sjpk cntr += strlen(dmap.dmap_devlist); 350*45916cd2Sjpk cntr += 15; 351*45916cd2Sjpk tptr = calloc((unsigned)cntr, sizeof (char)); 352*45916cd2Sjpk if (tptr == NULL) { 353*45916cd2Sjpk exit(1); 354*45916cd2Sjpk } 355*45916cd2Sjpk (void) strcat(tptr, dmap.dmap_devname); 356*45916cd2Sjpk (void) strcat(tptr, ":\\\n\t"); 357*45916cd2Sjpk (void) strcat(tptr, dmap.dmap_devtype); 358*45916cd2Sjpk (void) strcat(tptr, ":\\\n\t"); 359*45916cd2Sjpk (void) strcat(tptr, dmap.dmap_devlist); 360*45916cd2Sjpk (void) strcat(tptr, ":\\\n\t"); 361*45916cd2Sjpk (void) strcat(tptr, "\n"); 362*45916cd2Sjpk cntr = strlen(tptr); 363*45916cd2Sjpk #ifdef CMW 364*45916cd2Sjpk if (lseek(des, 0L, L_XTND) == -1L) { 365*45916cd2Sjpk exit(1); 366*45916cd2Sjpk } 367*45916cd2Sjpk #else 368*45916cd2Sjpk if (lseek(des, 0L, SEEK_END) == -1L) { 369*45916cd2Sjpk exit(1); 370*45916cd2Sjpk } 371*45916cd2Sjpk #endif 372*45916cd2Sjpk if (write(des, tptr, cntr) == -1) { 373*45916cd2Sjpk exit(1); 374*45916cd2Sjpk } 375*45916cd2Sjpk if (close(des) == -1) { 376*45916cd2Sjpk exit(1); 377*45916cd2Sjpk } 378*45916cd2Sjpk if (verbose) { 379*45916cd2Sjpk (void) fprintf(stderr, "dmapinfo: Entry added to %s\n", 380*45916cd2Sjpk filename); 381*45916cd2Sjpk } 382*45916cd2Sjpk exit(0); 383*45916cd2Sjpk } 384*45916cd2Sjpk /* 385*45916cd2Sjpk * Look for devices in device_maps file. If verbose switch is set 386*45916cd2Sjpk * then print entry(s) found. If "any" switch is set then, if any 387*45916cd2Sjpk * device is found will result in a exit status of 0. If "any" switch 388*45916cd2Sjpk * is not set then, if any device is not will result in a exit status 389*45916cd2Sjpk * of 1. 390*45916cd2Sjpk */ 391*45916cd2Sjpk if (device) { 392*45916cd2Sjpk setdmapent(); 393*45916cd2Sjpk while (argc >= 1) { 394*45916cd2Sjpk if ((dmapp = getdmapdev(*argv)) != NULL) { 395*45916cd2Sjpk if (verbose) { 396*45916cd2Sjpk printdmapent(dmapp); 397*45916cd2Sjpk } 398*45916cd2Sjpk cntr++; 399*45916cd2Sjpk } else if (any == 0) { 400*45916cd2Sjpk enddmapent(); 401*45916cd2Sjpk exit(1); 402*45916cd2Sjpk } 403*45916cd2Sjpk argc--; 404*45916cd2Sjpk argv++; 405*45916cd2Sjpk } 406*45916cd2Sjpk enddmapent(); 407*45916cd2Sjpk if (cntr != 0) 408*45916cd2Sjpk exit(0); 409*45916cd2Sjpk exit(1); 410*45916cd2Sjpk } 411*45916cd2Sjpk /* 412*45916cd2Sjpk * Look for names in device_maps file. If verbose switch is set 413*45916cd2Sjpk * then print entry(s) found. If "any" switch is set then, if any 414*45916cd2Sjpk * name is found will result in a exit status of 0. If "any" switch 415*45916cd2Sjpk * is not set then, if any name is not will result in a exit status 416*45916cd2Sjpk * of 1. 417*45916cd2Sjpk */ 418*45916cd2Sjpk if (name) { 419*45916cd2Sjpk setdmapent(); 420*45916cd2Sjpk while (argc >= 1) { 421*45916cd2Sjpk if ((dmapp = getdmapnam(*argv)) != NULL) { 422*45916cd2Sjpk if (verbose) { 423*45916cd2Sjpk printdmapent(dmapp); 424*45916cd2Sjpk } 425*45916cd2Sjpk cntr++; 426*45916cd2Sjpk } else if (any == 0) 427*45916cd2Sjpk exit(1); 428*45916cd2Sjpk argc--; 429*45916cd2Sjpk argv++; 430*45916cd2Sjpk } 431*45916cd2Sjpk enddmapent(); 432*45916cd2Sjpk if (cntr != 0) 433*45916cd2Sjpk exit(0); 434*45916cd2Sjpk exit(1); 435*45916cd2Sjpk } 436*45916cd2Sjpk /* 437*45916cd2Sjpk * Read all entrys from device maps file. If verbose flag is set 438*45916cd2Sjpk * then all the device maps files are printed. This is useful for 439*45916cd2Sjpk * piping to grep. Also this option used without the verbose option 440*45916cd2Sjpk * is useful to check for device maps file and for at least one 441*45916cd2Sjpk * entry. If the device maps file is found and there is one entry 442*45916cd2Sjpk * the return status is 0. 443*45916cd2Sjpk */ 444*45916cd2Sjpk if (tp) { 445*45916cd2Sjpk cntr = 0; 446*45916cd2Sjpk setdmapent(); 447*45916cd2Sjpk while (argc >= 1) { 448*45916cd2Sjpk while ((dmapp = getdmaptype(*argv)) != 0) { 449*45916cd2Sjpk cntr++; 450*45916cd2Sjpk if (verbose) { 451*45916cd2Sjpk printdmapent(dmapp); 452*45916cd2Sjpk } 453*45916cd2Sjpk } 454*45916cd2Sjpk if ((any == 0) && (cntr == 0)) { 455*45916cd2Sjpk enddmapent(); 456*45916cd2Sjpk exit(1); 457*45916cd2Sjpk } 458*45916cd2Sjpk argc--; 459*45916cd2Sjpk argv++; 460*45916cd2Sjpk } 461*45916cd2Sjpk enddmapent(); 462*45916cd2Sjpk if (cntr == 0) 463*45916cd2Sjpk exit(1); 464*45916cd2Sjpk exit(0); 465*45916cd2Sjpk } 466*45916cd2Sjpk /* 467*45916cd2Sjpk * Read all entrys from device maps file. If verbose flag is set 468*45916cd2Sjpk * then all the device maps files are printed. This is useful for 469*45916cd2Sjpk * piping to grep. Also this option used without the verbose option 470*45916cd2Sjpk * is useful to check for device maps file and for atleast one 471*45916cd2Sjpk * entry. If the device maps file is found and there is one entry 472*45916cd2Sjpk * the return status is 0. 473*45916cd2Sjpk */ 474*45916cd2Sjpk cntr = 0; 475*45916cd2Sjpk setdmapent(); 476*45916cd2Sjpk while ((dmapp = getdmapent()) != 0) { 477*45916cd2Sjpk cntr++; 478*45916cd2Sjpk if (verbose) { 479*45916cd2Sjpk printdmapent(dmapp); 480*45916cd2Sjpk } 481*45916cd2Sjpk } 482*45916cd2Sjpk enddmapent(); 483*45916cd2Sjpk if (cntr == 0) 484*45916cd2Sjpk exit(1); 485*45916cd2Sjpk return (0); 486*45916cd2Sjpk } 487