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