1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*0Sstevel@tonic-gate /* All Rights Reserved */ 24*0Sstevel@tonic-gate 25*0Sstevel@tonic-gate 26*0Sstevel@tonic-gate /* 27*0Sstevel@tonic-gate * Copyright (c) 1997,1998,2002 by Sun Microsystems, Inc. 28*0Sstevel@tonic-gate * All rights reserved. 29*0Sstevel@tonic-gate */ 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.1 */ 32*0Sstevel@tonic-gate /*LINTLIBRARY*/ 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate /* 35*0Sstevel@tonic-gate * dgrpent.c 36*0Sstevel@tonic-gate * 37*0Sstevel@tonic-gate * Contains functions that deal with the device-group table and are not for 38*0Sstevel@tonic-gate * consumption by the general user population. 39*0Sstevel@tonic-gate * 40*0Sstevel@tonic-gate * Functions defined: 41*0Sstevel@tonic-gate * _opendgrptab() Opens the device-group table for commands 42*0Sstevel@tonic-gate * _setdgrptab() Rewinds the open device table 43*0Sstevel@tonic-gate * _enddgrptab() Closes the open device table 44*0Sstevel@tonic-gate * _getdgrptabent() Gets the next entry in the device table 45*0Sstevel@tonic-gate * _freedgrptabent() Frees memory allocated to a device-table entry 46*0Sstevel@tonic-gate * _getdgrprec() Gets a specific record from the device table 47*0Sstevel@tonic-gate * _dgrptabpath() Gets the pathname of the device group file 48*0Sstevel@tonic-gate */ 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate /* 51*0Sstevel@tonic-gate * Header files 52*0Sstevel@tonic-gate * <sys/types.h> System data types 53*0Sstevel@tonic-gate * <unistd.h> Standard UNIX(r) definitions 54*0Sstevel@tonic-gate * <stdio.h> Standard I/O Definitions 55*0Sstevel@tonic-gate * <string.h> String handling definitions 56*0Sstevel@tonic-gate * <ctype.h> Character types and macros 57*0Sstevel@tonic-gate * <errno.h> Errorcode definitions 58*0Sstevel@tonic-gate * <sys/stat.h> File status information 59*0Sstevel@tonic-gate * <devmgmt.h> Global Device Management definitions 60*0Sstevel@tonic-gate * "devtab.h" Local device table definitions 61*0Sstevel@tonic-gate */ 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate #include <sys/types.h> 64*0Sstevel@tonic-gate #include <unistd.h> 65*0Sstevel@tonic-gate #include <stdio.h> 66*0Sstevel@tonic-gate #include <string.h> 67*0Sstevel@tonic-gate #include <ctype.h> 68*0Sstevel@tonic-gate #include <errno.h> 69*0Sstevel@tonic-gate #include <sys/stat.h> 70*0Sstevel@tonic-gate #include <devmgmt.h> 71*0Sstevel@tonic-gate #include "devtab.h" 72*0Sstevel@tonic-gate #include <stdlib.h> 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gate /* 75*0Sstevel@tonic-gate * Local definitions 76*0Sstevel@tonic-gate */ 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate /* 80*0Sstevel@tonic-gate * Static data definitions: 81*0Sstevel@tonic-gate * leftoff Addr of char to begin next parse using 82*0Sstevel@tonic-gate * getfld(), getattrval(), getquoted() 83*0Sstevel@tonic-gate * recbufsz The size of the buffer used for reading records 84*0Sstevel@tonic-gate * recbuf Addr of malloc() buffer for reading records 85*0Sstevel@tonic-gate * recnum Record number of next record to read 86*0Sstevel@tonic-gate * xtndcnt Number of times the buffer has been extended 87*0Sstevel@tonic-gate */ 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate static char *leftoff = NULL; 90*0Sstevel@tonic-gate static int recbufsz = 0; 91*0Sstevel@tonic-gate static char *recbuf = NULL; 92*0Sstevel@tonic-gate static int recnum = 0; 93*0Sstevel@tonic-gate static int xtndcnt = 0; 94*0Sstevel@tonic-gate 95*0Sstevel@tonic-gate /* 96*0Sstevel@tonic-gate * void _setdgrptab() 97*0Sstevel@tonic-gate * 98*0Sstevel@tonic-gate * This function rewinds the open device table so that the next 99*0Sstevel@tonic-gate * _getdgrptabent() returns the first record in the device table. 100*0Sstevel@tonic-gate * 101*0Sstevel@tonic-gate * Arguments: None 102*0Sstevel@tonic-gate * 103*0Sstevel@tonic-gate * Returns: Void 104*0Sstevel@tonic-gate */ 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate void 107*0Sstevel@tonic-gate _setdgrptab(void) 108*0Sstevel@tonic-gate { 109*0Sstevel@tonic-gate /* If the device table file is open, rewind the file */ 110*0Sstevel@tonic-gate if (oam_dgroup) { 111*0Sstevel@tonic-gate rewind(oam_dgroup); 112*0Sstevel@tonic-gate recnum = 0; 113*0Sstevel@tonic-gate } 114*0Sstevel@tonic-gate } 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate /* 117*0Sstevel@tonic-gate * void _enddgrptab() 118*0Sstevel@tonic-gate * 119*0Sstevel@tonic-gate * This function closes the open device table. It resets the 120*0Sstevel@tonic-gate * open device table external variable to NULL. 121*0Sstevel@tonic-gate * 122*0Sstevel@tonic-gate * Arguments: None 123*0Sstevel@tonic-gate * 124*0Sstevel@tonic-gate * Returns: Void 125*0Sstevel@tonic-gate */ 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gate void 128*0Sstevel@tonic-gate _enddgrptab(void) 129*0Sstevel@tonic-gate { 130*0Sstevel@tonic-gate /* If the device table file is open, close it */ 131*0Sstevel@tonic-gate if (oam_dgroup) { 132*0Sstevel@tonic-gate (void) fclose(oam_dgroup); 133*0Sstevel@tonic-gate recnum = 0; 134*0Sstevel@tonic-gate oam_dgroup = NULL; 135*0Sstevel@tonic-gate } 136*0Sstevel@tonic-gate } 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gate /* 139*0Sstevel@tonic-gate * char *getfld(ptr, delims) 140*0Sstevel@tonic-gate * char *ptr 141*0Sstevel@tonic-gate * char *delims 142*0Sstevel@tonic-gate * 143*0Sstevel@tonic-gate * Notes: 144*0Sstevel@tonic-gate * - Can't use "strtok()" because of its use of static data. The caller 145*0Sstevel@tonic-gate * may be using strtok() and we'll really mess them up. 146*0Sstevel@tonic-gate * - The function returns NULL if it didn't find any token -- '\0' can't 147*0Sstevel@tonic-gate * be a delimiter using this algorithm. 148*0Sstevel@tonic-gate */ 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate static char * 151*0Sstevel@tonic-gate getfld( 152*0Sstevel@tonic-gate char *ptr, /* String to parse */ 153*0Sstevel@tonic-gate char *delims) /* List of delimiters */ 154*0Sstevel@tonic-gate { 155*0Sstevel@tonic-gate char *p, *q; 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate /* 158*0Sstevel@tonic-gate * Figure out where to start. 159*0Sstevel@tonic-gate * If given a pointer, use that. 160*0Sstevel@tonic-gate * Otherwise, use where we left off. 161*0Sstevel@tonic-gate */ 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate p = ptr ? ptr : leftoff; 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gate /* 167*0Sstevel@tonic-gate * If there's anything to parse, search the string for the first 168*0Sstevel@tonic-gate * occurrence of any of the delimiters. If one is found, change it 169*0Sstevel@tonic-gate * to '\0' and remember the place to start for next time. If not 170*0Sstevel@tonic-gate * found, forget the restart address and prepare to return NULL 171*0Sstevel@tonic-gate */ 172*0Sstevel@tonic-gate 173*0Sstevel@tonic-gate if (p) { 174*0Sstevel@tonic-gate while (*p && isspace((unsigned char)*p)) p++; 175*0Sstevel@tonic-gate if (*p) { 176*0Sstevel@tonic-gate q = p; 177*0Sstevel@tonic-gate while (*q && !strchr(delims, *q)) q++; 178*0Sstevel@tonic-gate if (*q) { 179*0Sstevel@tonic-gate *q++ = '\0'; 180*0Sstevel@tonic-gate leftoff = q; 181*0Sstevel@tonic-gate } else leftoff = NULL; 182*0Sstevel@tonic-gate } else leftoff = p = NULL; 183*0Sstevel@tonic-gate } 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate /* Finished */ 186*0Sstevel@tonic-gate return (p); 187*0Sstevel@tonic-gate } 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate /* 190*0Sstevel@tonic-gate * char *getnextrec() 191*0Sstevel@tonic-gate * 192*0Sstevel@tonic-gate * This function gets the next record from the input stream "oam_dgroup" 193*0Sstevel@tonic-gate * and puts it in the device-group table record buffer (whose address is 194*0Sstevel@tonic-gate * in "recbuf"). If the buffer is not allocated or is too small to 195*0Sstevel@tonic-gate * accommodate the record, the function allocates more space to the 196*0Sstevel@tonic-gate * buffer. 197*0Sstevel@tonic-gate * 198*0Sstevel@tonic-gate * Arguments: None 199*0Sstevel@tonic-gate * 200*0Sstevel@tonic-gate * Returns: char * 201*0Sstevel@tonic-gate * The address of the buffer containing the record. 202*0Sstevel@tonic-gate * 203*0Sstevel@tonic-gate * Static Data Referenced: 204*0Sstevel@tonic-gate * recbuf Address of the buffer containing records read from the 205*0Sstevel@tonic-gate * device table file 206*0Sstevel@tonic-gate * recbufsz Current size of the record buffer 207*0Sstevel@tonic-gate * xtndcnt Number of times the record buffer has been extended 208*0Sstevel@tonic-gate * oam_dgroup Device-group table stream, expected to be open for (at 209*0Sstevel@tonic-gate * least) reading 210*0Sstevel@tonic-gate * 211*0Sstevel@tonic-gate * Notes: 212*0Sstevel@tonic-gate * - The string returned in the buffer <buf> ALWAYS end in a '\n' (newline) 213*0Sstevel@tonic-gate * character followed by a '\0' (null). 214*0Sstevel@tonic-gate */ 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate static char * 217*0Sstevel@tonic-gate getnextrec(void) 218*0Sstevel@tonic-gate { 219*0Sstevel@tonic-gate /* Automatic data */ 220*0Sstevel@tonic-gate char *recp; /* Value to return */ 221*0Sstevel@tonic-gate char *p; /* Temp pointer */ 222*0Sstevel@tonic-gate int done; /* TRUE if we're finished */ 223*0Sstevel@tonic-gate int reclen; /* Number of chars in record */ 224*0Sstevel@tonic-gate 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate /* If there's no buffer for records, try to get one */ 227*0Sstevel@tonic-gate if (!recbuf) { 228*0Sstevel@tonic-gate if (recbuf = malloc(DGRP_BUFSIZ)) { 229*0Sstevel@tonic-gate recbufsz = DGRP_BUFSIZ; 230*0Sstevel@tonic-gate xtndcnt = 0; 231*0Sstevel@tonic-gate } else return (NULL); 232*0Sstevel@tonic-gate } 233*0Sstevel@tonic-gate 234*0Sstevel@tonic-gate 235*0Sstevel@tonic-gate /* Get the next record */ 236*0Sstevel@tonic-gate recp = fgets(recbuf, recbufsz, oam_dgroup); 237*0Sstevel@tonic-gate done = FALSE; 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gate /* While we've something to return and we're not finished ... */ 240*0Sstevel@tonic-gate while (recp && !done) { 241*0Sstevel@tonic-gate 242*0Sstevel@tonic-gate /* If our return string isn't a null-string ... */ 243*0Sstevel@tonic-gate if ((reclen = (int)strlen(recp)) != 0) { 244*0Sstevel@tonic-gate 245*0Sstevel@tonic-gate /* If we have a complete record, we're finished */ 246*0Sstevel@tonic-gate if (*(recp+reclen-1) == '\n') done = TRUE; 247*0Sstevel@tonic-gate else while (!done) { 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate /* 250*0Sstevel@tonic-gate * Need to complete the record. A complete record is one 251*0Sstevel@tonic-gate * which is terminated by a new-line character 252*0Sstevel@tonic-gate */ 253*0Sstevel@tonic-gate 254*0Sstevel@tonic-gate /* If the buffer is full, expand it and continue reading */ 255*0Sstevel@tonic-gate if (reclen == recbufsz-1) { 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gate /* Have we reached our maximum extension count? */ 258*0Sstevel@tonic-gate if (xtndcnt < XTND_MAXCNT) { 259*0Sstevel@tonic-gate 260*0Sstevel@tonic-gate /* Expand the record buffer */ 261*0Sstevel@tonic-gate if (p = realloc(recbuf, 262*0Sstevel@tonic-gate (size_t)(recbufsz+DGRP_BUFINC))) { 263*0Sstevel@tonic-gate 264*0Sstevel@tonic-gate /* Update buffer information */ 265*0Sstevel@tonic-gate xtndcnt++; 266*0Sstevel@tonic-gate recbuf = p; 267*0Sstevel@tonic-gate recbufsz += DGRP_BUFINC; 268*0Sstevel@tonic-gate 269*0Sstevel@tonic-gate } else { 270*0Sstevel@tonic-gate 271*0Sstevel@tonic-gate /* Expansion failed */ 272*0Sstevel@tonic-gate recp = NULL; 273*0Sstevel@tonic-gate done = TRUE; 274*0Sstevel@tonic-gate } 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gate } else { 277*0Sstevel@tonic-gate 278*0Sstevel@tonic-gate /* Maximum extend count exceeded. Insane table */ 279*0Sstevel@tonic-gate recp = NULL; 280*0Sstevel@tonic-gate done = TRUE; 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate } 284*0Sstevel@tonic-gate 285*0Sstevel@tonic-gate /* Complete the record */ 286*0Sstevel@tonic-gate if (!done) { 287*0Sstevel@tonic-gate 288*0Sstevel@tonic-gate /* Read stuff into the expanded space */ 289*0Sstevel@tonic-gate if (fgets(recbuf+reclen, recbufsz-reclen, oam_dgroup)) { 290*0Sstevel@tonic-gate reclen = (int)strlen(recbuf); 291*0Sstevel@tonic-gate recp = recbuf; 292*0Sstevel@tonic-gate if (*(recp+reclen-1) == '\n') done = TRUE; 293*0Sstevel@tonic-gate } else { 294*0Sstevel@tonic-gate /* Read failed, corrupt record? */ 295*0Sstevel@tonic-gate recp = NULL; 296*0Sstevel@tonic-gate done = TRUE; 297*0Sstevel@tonic-gate } 298*0Sstevel@tonic-gate } 299*0Sstevel@tonic-gate 300*0Sstevel@tonic-gate } /* End incomplete record handling */ 301*0Sstevel@tonic-gate 302*0Sstevel@tonic-gate } else { 303*0Sstevel@tonic-gate 304*0Sstevel@tonic-gate /* Read a null string? (corrupt table) */ 305*0Sstevel@tonic-gate recp = NULL; 306*0Sstevel@tonic-gate done = TRUE; 307*0Sstevel@tonic-gate } 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gate } /* while (recp && !done) */ 310*0Sstevel@tonic-gate 311*0Sstevel@tonic-gate /* Return what we've got (if anything) */ 312*0Sstevel@tonic-gate return (recp); 313*0Sstevel@tonic-gate } 314*0Sstevel@tonic-gate 315*0Sstevel@tonic-gate /* 316*0Sstevel@tonic-gate * char *_dgrptabpath() 317*0Sstevel@tonic-gate * 318*0Sstevel@tonic-gate * Get the pathname of the device-group table file 319*0Sstevel@tonic-gate * 320*0Sstevel@tonic-gate * Arguments: None 321*0Sstevel@tonic-gate * 322*0Sstevel@tonic-gate * Returns: char * 323*0Sstevel@tonic-gate * Returns the pathname to the device group table of (char *) NULL if 324*0Sstevel@tonic-gate * there was a problem getting the memory needed to contain the 325*0Sstevel@tonic-gate * pathname. 326*0Sstevel@tonic-gate * 327*0Sstevel@tonic-gate * Algorithm: 328*0Sstevel@tonic-gate * 1. If OAM_DGRP is defined in the environment and is not 329*0Sstevel@tonic-gate * defined as "", it returns the value of that environment 330*0Sstevel@tonic-gate * variable. 331*0Sstevel@tonic-gate * 2. Otherwise, use the devault pathname (as defined by the 332*0Sstevel@tonic-gate * environment variable DGRP_PATH in <devmgmt.h>. 333*0Sstevel@tonic-gate */ 334*0Sstevel@tonic-gate 335*0Sstevel@tonic-gate 336*0Sstevel@tonic-gate char * 337*0Sstevel@tonic-gate _dgrptabpath(void) 338*0Sstevel@tonic-gate { 339*0Sstevel@tonic-gate 340*0Sstevel@tonic-gate /* Automatic data */ 341*0Sstevel@tonic-gate #ifdef DEBUG 342*0Sstevel@tonic-gate char *path; /* Ptr to path in environment */ 343*0Sstevel@tonic-gate #endif 344*0Sstevel@tonic-gate char *rtnval; /* Ptr to value to return */ 345*0Sstevel@tonic-gate 346*0Sstevel@tonic-gate 347*0Sstevel@tonic-gate /* 348*0Sstevel@tonic-gate * If compiled with -DDEBUG=1, 349*0Sstevel@tonic-gate * look for the pathname in the environment 350*0Sstevel@tonic-gate */ 351*0Sstevel@tonic-gate 352*0Sstevel@tonic-gate #ifdef DEBUG 353*0Sstevel@tonic-gate if (((path = getenv(OAM_DGROUP)) != NULL) && (*path)) { 354*0Sstevel@tonic-gate if (rtnval = malloc(strlen(path)+1)) 355*0Sstevel@tonic-gate (void) strcpy(rtnval, path); 356*0Sstevel@tonic-gate } else { 357*0Sstevel@tonic-gate #endif 358*0Sstevel@tonic-gate /* 359*0Sstevel@tonic-gate * Use the default name. 360*0Sstevel@tonic-gate */ 361*0Sstevel@tonic-gate 362*0Sstevel@tonic-gate if (rtnval = malloc(strlen(DGRP_PATH)+1)) 363*0Sstevel@tonic-gate (void) strcpy(rtnval, DGRP_PATH); 364*0Sstevel@tonic-gate 365*0Sstevel@tonic-gate #ifdef DEBUG 366*0Sstevel@tonic-gate } 367*0Sstevel@tonic-gate #endif 368*0Sstevel@tonic-gate 369*0Sstevel@tonic-gate /* Finished */ 370*0Sstevel@tonic-gate return (rtnval); 371*0Sstevel@tonic-gate } 372*0Sstevel@tonic-gate 373*0Sstevel@tonic-gate /* 374*0Sstevel@tonic-gate * int _opendgrptab(mode) 375*0Sstevel@tonic-gate * char *mode 376*0Sstevel@tonic-gate * 377*0Sstevel@tonic-gate * The _opendgrptab() function opens a device-group table for a command. 378*0Sstevel@tonic-gate * 379*0Sstevel@tonic-gate * Arguments: 380*0Sstevel@tonic-gate * mode The open mode to use to open the file. (i.e. "r" for 381*0Sstevel@tonic-gate * reading, "w" for writing. See FOPEN(BA_OS) in SVID.) 382*0Sstevel@tonic-gate * 383*0Sstevel@tonic-gate * Returns: int 384*0Sstevel@tonic-gate * TRUE if successful, FALSE otherwise 385*0Sstevel@tonic-gate */ 386*0Sstevel@tonic-gate 387*0Sstevel@tonic-gate int 388*0Sstevel@tonic-gate _opendgrptab(char *mode) 389*0Sstevel@tonic-gate { 390*0Sstevel@tonic-gate /* Automatic data */ 391*0Sstevel@tonic-gate char *dgrptabname; /* Ptr to the device-group table name */ 392*0Sstevel@tonic-gate int rtnval; /* Value to return */ 393*0Sstevel@tonic-gate 394*0Sstevel@tonic-gate rtnval = TRUE; 395*0Sstevel@tonic-gate if (dgrptabname = _dgrptabpath()) { 396*0Sstevel@tonic-gate if (oam_dgroup) (void) fclose(oam_dgroup); 397*0Sstevel@tonic-gate if (oam_dgroup = fopen(dgrptabname, mode)) { 398*0Sstevel@tonic-gate xtndcnt = 0; 399*0Sstevel@tonic-gate recnum = 0; 400*0Sstevel@tonic-gate } else rtnval = FALSE; /* :-( */ 401*0Sstevel@tonic-gate } else rtnval = FALSE; /* :-( */ 402*0Sstevel@tonic-gate return (rtnval); 403*0Sstevel@tonic-gate } 404*0Sstevel@tonic-gate 405*0Sstevel@tonic-gate /* 406*0Sstevel@tonic-gate * struct dgrptabent *_getdgrptabent() 407*0Sstevel@tonic-gate * 408*0Sstevel@tonic-gate * This function returns the next entry in the device-group table. 409*0Sstevel@tonic-gate * If no device-group table is open, it opens the standard device-group 410*0Sstevel@tonic-gate * table and returns the first record in the table. 411*0Sstevel@tonic-gate * 412*0Sstevel@tonic-gate * Arguments: None. 413*0Sstevel@tonic-gate * 414*0Sstevel@tonic-gate * Returns: struct dgrptabent * 415*0Sstevel@tonic-gate * Pointer to the next record in the device-group table, or 416*0Sstevel@tonic-gate * (struct dgrptabent *) NULL if it was unable to open the file or there 417*0Sstevel@tonic-gate * are no more records to read. "errno" reflects the situation. If 418*0Sstevel@tonic-gate * errno is not changed and the function returns NULL, there are no more 419*0Sstevel@tonic-gate * records to read. If errno is set, it indicates the error. 420*0Sstevel@tonic-gate * 421*0Sstevel@tonic-gate * Notes: 422*0Sstevel@tonic-gate * - The caller should set "errno" to 0 before calling this function. 423*0Sstevel@tonic-gate */ 424*0Sstevel@tonic-gate 425*0Sstevel@tonic-gate struct dgrptabent * 426*0Sstevel@tonic-gate _getdgrptabent(void) 427*0Sstevel@tonic-gate { 428*0Sstevel@tonic-gate /* Automatic data */ 429*0Sstevel@tonic-gate struct dgrptabent *ent; /* Dev table entry structure */ 430*0Sstevel@tonic-gate struct member *q, *r; /* Tmps for member structs */ 431*0Sstevel@tonic-gate char *record; /* Record just read */ 432*0Sstevel@tonic-gate char *p; /* Tmp char ptr */ 433*0Sstevel@tonic-gate int done; /* TRUE if built an entry */ 434*0Sstevel@tonic-gate 435*0Sstevel@tonic-gate 436*0Sstevel@tonic-gate /* Open the device-group table if it's not already open */ 437*0Sstevel@tonic-gate if (!oam_dgroup) 438*0Sstevel@tonic-gate if (!_opendgrptab("r")) 439*0Sstevel@tonic-gate return (NULL); 440*0Sstevel@tonic-gate 441*0Sstevel@tonic-gate 442*0Sstevel@tonic-gate /* Get space for the structure we're returning */ 443*0Sstevel@tonic-gate if (!(ent = malloc(sizeof (struct dgrptabent)))) { 444*0Sstevel@tonic-gate return (NULL); 445*0Sstevel@tonic-gate } 446*0Sstevel@tonic-gate 447*0Sstevel@tonic-gate done = FALSE; 448*0Sstevel@tonic-gate while (!done && (record = getnextrec())) { 449*0Sstevel@tonic-gate 450*0Sstevel@tonic-gate /* Is this a comment record or a data record */ 451*0Sstevel@tonic-gate if (strchr("#\n", *record) || 452*0Sstevel@tonic-gate isspace((unsigned char)*record)) { 453*0Sstevel@tonic-gate 454*0Sstevel@tonic-gate /* 455*0Sstevel@tonic-gate * Record is a comment record 456*0Sstevel@tonic-gate */ 457*0Sstevel@tonic-gate ent->comment = TRUE; 458*0Sstevel@tonic-gate ent->entryno = recnum++; 459*0Sstevel@tonic-gate 460*0Sstevel@tonic-gate /* Alloc space for the comment and save pointer in struct */ 461*0Sstevel@tonic-gate if (ent->dataspace = malloc(strlen(record)+1)) { 462*0Sstevel@tonic-gate (void) strcpy(ent->dataspace, record); 463*0Sstevel@tonic-gate } else { 464*0Sstevel@tonic-gate free(ent); 465*0Sstevel@tonic-gate ent = NULL; 466*0Sstevel@tonic-gate } 467*0Sstevel@tonic-gate done = TRUE; 468*0Sstevel@tonic-gate 469*0Sstevel@tonic-gate } else { 470*0Sstevel@tonic-gate 471*0Sstevel@tonic-gate /* 472*0Sstevel@tonic-gate * Record is a data record 473*0Sstevel@tonic-gate */ 474*0Sstevel@tonic-gate ent->comment = FALSE; 475*0Sstevel@tonic-gate 476*0Sstevel@tonic-gate /* Extract the device-group name */ 477*0Sstevel@tonic-gate if (p = getfld(record, ":")) { 478*0Sstevel@tonic-gate 479*0Sstevel@tonic-gate /* Record is a proper record */ 480*0Sstevel@tonic-gate done = TRUE; 481*0Sstevel@tonic-gate ent->entryno = recnum++; 482*0Sstevel@tonic-gate 483*0Sstevel@tonic-gate /* Copy device group name into malloc()ed space */ 484*0Sstevel@tonic-gate if (!(ent->name = malloc(strlen(p)+1))) { 485*0Sstevel@tonic-gate 486*0Sstevel@tonic-gate free(ent); 487*0Sstevel@tonic-gate return (NULL); 488*0Sstevel@tonic-gate } 489*0Sstevel@tonic-gate (void) strcpy(ent->name, p); 490*0Sstevel@tonic-gate 491*0Sstevel@tonic-gate /* 492*0Sstevel@tonic-gate * Extract the membership from the membership list 493*0Sstevel@tonic-gate */ 494*0Sstevel@tonic-gate 495*0Sstevel@tonic-gate /* Get the 1st member */ 496*0Sstevel@tonic-gate ent->dataspace = NULL; 497*0Sstevel@tonic-gate while (((p = getfld(NULL, ",\n")) != NULL) && !(*p)) 498*0Sstevel@tonic-gate ; 499*0Sstevel@tonic-gate if (p) { 500*0Sstevel@tonic-gate if (!(q = malloc(sizeof (struct member)))) { 501*0Sstevel@tonic-gate 502*0Sstevel@tonic-gate free(ent->name); 503*0Sstevel@tonic-gate free(ent); 504*0Sstevel@tonic-gate return (NULL); 505*0Sstevel@tonic-gate } 506*0Sstevel@tonic-gate if (!(q->name = malloc(strlen(p)+1))) { 507*0Sstevel@tonic-gate free(q); 508*0Sstevel@tonic-gate free(ent->name); 509*0Sstevel@tonic-gate free((char *)ent); 510*0Sstevel@tonic-gate return (NULL); 511*0Sstevel@tonic-gate } 512*0Sstevel@tonic-gate (void) strcpy(q->name, p); 513*0Sstevel@tonic-gate ent->membership = q; 514*0Sstevel@tonic-gate q->next = NULL; 515*0Sstevel@tonic-gate 516*0Sstevel@tonic-gate /* Get the rest of the members */ 517*0Sstevel@tonic-gate while (p = getfld(NULL, ",\n")) 518*0Sstevel@tonic-gate if (*p) { 519*0Sstevel@tonic-gate if (!(r = malloc(sizeof (struct member)))) { 520*0Sstevel@tonic-gate for (q = ent->membership; q; q = r) { 521*0Sstevel@tonic-gate free(q->name); 522*0Sstevel@tonic-gate r = q->next; 523*0Sstevel@tonic-gate free(q); 524*0Sstevel@tonic-gate } 525*0Sstevel@tonic-gate free(ent->name); 526*0Sstevel@tonic-gate free(ent); 527*0Sstevel@tonic-gate return (NULL); 528*0Sstevel@tonic-gate } 529*0Sstevel@tonic-gate if (!(r->name = malloc(strlen(p)+1))) { 530*0Sstevel@tonic-gate free(r); 531*0Sstevel@tonic-gate for (q = ent->membership; q; q = r) { 532*0Sstevel@tonic-gate free(q->name); 533*0Sstevel@tonic-gate r = q->next; 534*0Sstevel@tonic-gate free(q); 535*0Sstevel@tonic-gate } 536*0Sstevel@tonic-gate free(ent->name); 537*0Sstevel@tonic-gate free(ent); 538*0Sstevel@tonic-gate return (NULL); 539*0Sstevel@tonic-gate } 540*0Sstevel@tonic-gate 541*0Sstevel@tonic-gate q->next = r; 542*0Sstevel@tonic-gate (void) strcpy(r->name, p); 543*0Sstevel@tonic-gate r->next = NULL; 544*0Sstevel@tonic-gate q = r; 545*0Sstevel@tonic-gate } 546*0Sstevel@tonic-gate 547*0Sstevel@tonic-gate } else { 548*0Sstevel@tonic-gate /* No members */ 549*0Sstevel@tonic-gate ent->membership = NULL; 550*0Sstevel@tonic-gate } 551*0Sstevel@tonic-gate 552*0Sstevel@tonic-gate } /* record contains a group name */ 553*0Sstevel@tonic-gate 554*0Sstevel@tonic-gate } /* record is a data record */ 555*0Sstevel@tonic-gate 556*0Sstevel@tonic-gate } /* while (!done && there's more records) */ 557*0Sstevel@tonic-gate 558*0Sstevel@tonic-gate 559*0Sstevel@tonic-gate /* An entry read? If not, free alloc'd space and return NULL */ 560*0Sstevel@tonic-gate if (!done) { 561*0Sstevel@tonic-gate free(ent); 562*0Sstevel@tonic-gate ent = NULL; 563*0Sstevel@tonic-gate } 564*0Sstevel@tonic-gate 565*0Sstevel@tonic-gate /* Finis */ 566*0Sstevel@tonic-gate return (ent); 567*0Sstevel@tonic-gate } 568*0Sstevel@tonic-gate 569*0Sstevel@tonic-gate /* 570*0Sstevel@tonic-gate * void _freedgrptabent(dgrptabent) 571*0Sstevel@tonic-gate * struct dgrptabent *dgrptabent; 572*0Sstevel@tonic-gate * 573*0Sstevel@tonic-gate * This function frees space allocated to a device table entry. 574*0Sstevel@tonic-gate * 575*0Sstevel@tonic-gate * Arguments: 576*0Sstevel@tonic-gate * struct dgrptabent *dgrptabent The structure whose space is to be 577*0Sstevel@tonic-gate * freed. 578*0Sstevel@tonic-gate * 579*0Sstevel@tonic-gate * Returns: void 580*0Sstevel@tonic-gate */ 581*0Sstevel@tonic-gate 582*0Sstevel@tonic-gate void 583*0Sstevel@tonic-gate _freedgrptabent(struct dgrptabent *ent) /* Structure to free */ 584*0Sstevel@tonic-gate { 585*0Sstevel@tonic-gate /* 586*0Sstevel@tonic-gate * Automatic data 587*0Sstevel@tonic-gate */ 588*0Sstevel@tonic-gate 589*0Sstevel@tonic-gate struct member *p; /* Structure being freed */ 590*0Sstevel@tonic-gate struct member *q; /* Next structure to free */ 591*0Sstevel@tonic-gate 592*0Sstevel@tonic-gate /* 593*0Sstevel@tonic-gate * Free the space allocated to the membership structure. 594*0Sstevel@tonic-gate */ 595*0Sstevel@tonic-gate 596*0Sstevel@tonic-gate if (!ent->comment) { 597*0Sstevel@tonic-gate if ((q = ent->membership) != NULL) do { 598*0Sstevel@tonic-gate p = q; 599*0Sstevel@tonic-gate q = p->next; 600*0Sstevel@tonic-gate if (p->name) free(p->name); 601*0Sstevel@tonic-gate free(p); 602*0Sstevel@tonic-gate } while (q); 603*0Sstevel@tonic-gate 604*0Sstevel@tonic-gate /* Free the device group name */ 605*0Sstevel@tonic-gate if (ent->name) free(ent->name); 606*0Sstevel@tonic-gate } 607*0Sstevel@tonic-gate 608*0Sstevel@tonic-gate /* Free the membership string */ 609*0Sstevel@tonic-gate if (ent->dataspace) free(ent->dataspace); 610*0Sstevel@tonic-gate } 611*0Sstevel@tonic-gate 612*0Sstevel@tonic-gate /* 613*0Sstevel@tonic-gate * struct dgrptabent *_getdgrprec(dgroup) 614*0Sstevel@tonic-gate * char *dgroup 615*0Sstevel@tonic-gate * 616*0Sstevel@tonic-gate * Thie _getdgrprec() function returns a pointer to a structure that 617*0Sstevel@tonic-gate * contains the information in the device-group table entry that describes 618*0Sstevel@tonic-gate * the device-group <dgroup>. 619*0Sstevel@tonic-gate * 620*0Sstevel@tonic-gate * Arguments: 621*0Sstevel@tonic-gate * char *dgroup A character-string describing the device-group whose 622*0Sstevel@tonic-gate * record is to be retrieved from the device-group table. 623*0Sstevel@tonic-gate * 624*0Sstevel@tonic-gate * Returns: struct dgrptabent * 625*0Sstevel@tonic-gate * A pointer to a structure describing the device group. 626*0Sstevel@tonic-gate */ 627*0Sstevel@tonic-gate 628*0Sstevel@tonic-gate struct dgrptabent * 629*0Sstevel@tonic-gate _getdgrprec(char *dgroup) /* dgroup to search for */ 630*0Sstevel@tonic-gate { 631*0Sstevel@tonic-gate /* 632*0Sstevel@tonic-gate * Automatic data 633*0Sstevel@tonic-gate */ 634*0Sstevel@tonic-gate 635*0Sstevel@tonic-gate struct dgrptabent *dgrprec; /* Pointer to current record */ 636*0Sstevel@tonic-gate int found; /* FLAG, TRUE if found */ 637*0Sstevel@tonic-gate 638*0Sstevel@tonic-gate 639*0Sstevel@tonic-gate /* 640*0Sstevel@tonic-gate * Search the device-group table looking for the requested 641*0Sstevel@tonic-gate * device group 642*0Sstevel@tonic-gate */ 643*0Sstevel@tonic-gate 644*0Sstevel@tonic-gate _setdgrptab(); 645*0Sstevel@tonic-gate errno = 0; 646*0Sstevel@tonic-gate found = FALSE; 647*0Sstevel@tonic-gate while (!found && (dgrprec = _getdgrptabent())) { 648*0Sstevel@tonic-gate if (!dgrprec->comment && strcmp(dgroup, dgrprec->name) == 0) 649*0Sstevel@tonic-gate found = TRUE; 650*0Sstevel@tonic-gate else _freedgrptabent(dgrprec); 651*0Sstevel@tonic-gate } 652*0Sstevel@tonic-gate 653*0Sstevel@tonic-gate /* Set up return codes if we've failed */ 654*0Sstevel@tonic-gate if (!found) { 655*0Sstevel@tonic-gate if (errno == 0) errno = EINVAL; 656*0Sstevel@tonic-gate dgrprec = NULL; 657*0Sstevel@tonic-gate } 658*0Sstevel@tonic-gate 659*0Sstevel@tonic-gate /* Finis */ 660*0Sstevel@tonic-gate return (dgrprec); 661*0Sstevel@tonic-gate } 662