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
_setdgrptab(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
_enddgrptab(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 *
getfld(char * ptr,char * delims)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 *
getnextrec(void)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 *
_dgrptabpath(void)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
_opendgrptab(char * mode)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 *
_getdgrptabent(void)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
_freedgrptabent(struct dgrptabent * ent)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 *
_getdgrprec(char * dgroup)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