dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libbsm / common / getdaent.c
blob40a133673a6834b1faf63a2edd5695a4cb5b6b2d
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <ctype.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <bsm/devices.h>
30 #include <bsm/devalloc.h>
32 extern char *_strdup_null(char *);
34 static struct _dabuff {
35 FILE *_daf; /* pointer into /etc/security/device_allocate */
36 devalloc_t _interpdevalloc;
37 char _interpdaline[DA_BUFSIZE + 1];
38 char *_DEVALLOC;
39 } *__dabuff;
41 #define daf (_da->_daf)
42 #define interpdevalloc (_da->_interpdevalloc)
43 #define interpdaline (_da->_interpdaline)
44 #define DEVALLOC_FILE (_da->_DEVALLOC)
45 static devalloc_t *da_interpret(char *);
47 int da_matchname(devalloc_t *, char *);
48 int da_matchtype(devalloc_t *, char *);
51 * trim_white -
52 * trims off leading and trailing white space from input string.
53 * The leading white space is skipped by moving the pointer forward.
54 * The trailing white space is removed by nulling the white space
55 * characters.
56 * returns pointer to non-white string, else returns NULL if input string
57 * is null or if the resulting string has zero length.
59 char *
60 trim_white(char *ptr)
62 char *tptr;
64 if (ptr == NULL)
65 return (NULL);
66 while (isspace(*ptr))
67 ptr++;
68 tptr = ptr + strlen(ptr);
69 while (tptr != ptr && isspace(tptr[-1]))
70 --tptr;
71 *tptr = '\0';
72 if (*ptr == '\0')
73 return (NULL);
75 return (ptr);
79 * pack_white -
80 * trims off multiple occurrences of white space from input string.
81 * returns the number of spaces retained
83 int
84 pack_white(char *ptr)
86 int cnt = 0;
87 char *tptr, ch;
89 if (ptr == NULL)
90 return (0);
91 tptr = ptr;
92 while (isspace(*tptr))
93 tptr++;
94 for (;;) {
95 while ((ch = *tptr) != '\0' && !isspace(ch)) {
96 *ptr++ = ch;
97 tptr++;
99 while (isspace(*tptr))
100 tptr++;
101 if (*tptr == '\0')
102 break;
103 *ptr++ = ' ';
104 cnt++;
106 *ptr = '\0';
108 return (cnt);
112 * getdadmline -
113 * reads one device_alloc/device_maps line from stream into buff of len
114 * bytes. Continued lines from stream are concatenated into one line in
115 * buff. Comments are removed from buff.
116 * returns the number of characters in buff, else returns 0 if no
117 * characters are read or an error occurred.
120 getdadmline(char *buff, int len, FILE *stream)
122 int tmpcnt;
123 int charcnt = 0;
124 int fileerr = 0;
125 int contline = 0;
126 char *cp;
127 char *ccp;
129 do {
130 cp = buff;
131 *cp = '\0';
132 do {
133 contline = 0;
134 if (fgets(cp, len - charcnt, stream) == NULL) {
135 fileerr = 1;
136 break;
138 ccp = strchr(cp, '\n');
139 if (ccp != NULL) {
140 if (ccp != cp && ccp[-1] == '\\') {
141 ccp--;
142 contline = 1;
144 else
145 contline = 0;
146 *ccp = '\0';
148 tmpcnt = strlen(cp);
149 cp += tmpcnt;
150 charcnt += tmpcnt;
151 } while ((contline) || (charcnt == 0));
152 ccp = strpbrk(buff, "#");
153 if (ccp != NULL)
154 *ccp = '\0';
155 charcnt = strlen(buff);
156 } while ((fileerr == 0) && (charcnt == 0));
158 if (fileerr && !charcnt)
159 return (0);
160 else
161 return (charcnt);
165 * _daalloc -
166 * allocates common buffers and structures.
167 * returns pointer to the new structure, else returns NULL on error.
169 static struct _dabuff *
170 _daalloc(void)
172 struct _dabuff *_da = __dabuff;
174 if (_da == NULL) {
175 _da = (struct _dabuff *)calloc((unsigned)1,
176 (unsigned)sizeof (*__dabuff));
177 if (_da == NULL)
178 return (NULL);
179 DEVALLOC_FILE = "/etc/security/device_allocate";
180 daf = NULL;
181 __dabuff = _da;
184 return (__dabuff);
188 * getdadmfield -
189 * gets individual fields separated by skip in ptr.
191 char *
192 getdadmfield(char *ptr, char *skip)
194 static char *tptr = NULL;
195 char *pend;
197 /* check for a continuing search */
198 if (ptr == NULL)
199 ptr = tptr;
200 /* check for source end */
201 if (ptr == NULL || *ptr == '\0')
202 return (NULL);
203 /* find terminator */
204 pend = strpbrk(ptr, skip);
205 /* terminate and set continuation pointer */
206 if (pend != NULL) {
207 *pend++ = '\0';
208 tptr = pend;
209 } else
210 tptr = NULL;
212 * trim off any surrounding white space, return what's left
215 return (trim_white(ptr));
219 * setdaent -
220 * rewinds the device_allocate file to the begining.
223 void
224 setdaent(void)
226 struct _dabuff *_da = _daalloc();
228 if (_da == NULL)
229 return;
230 if (daf == NULL)
231 daf = fopen(DEVALLOC_FILE, "rF");
232 else
233 rewind(daf);
237 * enddaent -
238 * closes device_allocate file.
241 void
242 enddaent(void)
244 struct _dabuff *_da = _daalloc();
246 if (_da == NULL)
247 return;
248 if (daf != NULL) {
249 (void) fclose(daf);
250 daf = NULL;
255 * setdafile -
256 * changes the default device_allocate file to the one specified.
257 * It does not close the previous file. If this is desired, enddaent
258 * should be called prior to setdafile.
260 void
261 setdafile(char *file)
263 struct _dabuff *_da = _daalloc();
265 if (_da == NULL)
266 return;
267 if (daf != NULL) {
268 (void) fclose(daf);
269 daf = NULL;
271 DEVALLOC_FILE = file;
274 void
275 freedaent(devalloc_t *dap)
277 if (dap == NULL)
278 return;
279 _kva_free(dap->da_devopts);
280 dap->da_devopts = NULL;
284 * getdaon -
285 * checks if device_allocate has string DEVICE_ALLOCATION=ON or
286 * DEVICE_ALLOCATION=OFF string in it.
287 * returns 1 if the string is DEVICE_ALLOCATION=ON, 0 if it is
288 * DEVICE_ALLOCATION=OFF, -1 if neither string present.
291 getdaon()
293 int is_on = -1;
294 char line1[DA_BUFSIZE + 1];
295 struct _dabuff *_da = _daalloc();
297 setdaent();
298 if ((_da == NULL) || (daf == NULL)) {
299 enddaent();
300 return (is_on);
302 while (getdadmline(line1, (int)sizeof (line1), daf) != 0) {
303 if (strncmp(line1, DA_ON_STR, (strlen(DA_ON_STR) - 1)) == 0) {
304 is_on = 1;
305 break;
306 } else if (strncmp(line1, DA_OFF_STR,
307 (strlen(DA_OFF_STR) - 1)) == 0) {
308 is_on = 0;
309 break;
312 enddaent();
314 return (is_on);
318 * getdaent -
319 * When first called, returns a pointer to the first devalloc_t
320 * structure in device_allocate; thereafter, it returns a pointer to the
321 * next devalloc_t structure in the file. Thus, successive calls can be
322 * used to search the entire file.
323 * call to getdaent should be bracketed by setdaent and enddaent.
324 * returns NULL on error.
326 devalloc_t *
327 getdaent(void)
329 char line1[DA_BUFSIZE + 1];
330 devalloc_t *da;
331 struct _dabuff *_da = _daalloc();
333 if ((_da == 0) || (daf == NULL))
334 return (NULL);
336 while (getdadmline(line1, (int)sizeof (line1), daf) != 0) {
337 if ((strncmp(line1, DA_ON_STR, (strlen(DA_ON_STR) - 1)) == 0) ||
338 (strncmp(line1, DA_OFF_STR, (strlen(DA_OFF_STR) - 1)) == 0))
339 continue;
340 if ((da = da_interpret(line1)) == NULL)
341 continue;
342 return (da);
345 return (NULL);
349 * getdanam
350 * searches from the beginning of device_allocate for the device specified
351 * by its name.
352 * call to getdanam should be bracketed by setdaent and enddaent.
353 * returns pointer to devalloc_t for the device if it is found, else
354 * returns NULL if device not found or in case of error.
356 devalloc_t *
357 getdanam(char *name)
359 char line[DA_BUFSIZE + 1];
360 devalloc_t *da;
361 struct _dabuff *_da = _daalloc();
363 if ((name == NULL) || (_da == 0) || (daf == NULL))
364 return (NULL);
366 while (getdadmline(line, (int)sizeof (line), daf) != 0) {
367 if (strstr(line, name) == NULL)
368 continue;
369 if ((da = da_interpret(line)) == NULL)
370 continue;
371 if (da_matchname(da, name)) {
372 enddaent();
373 return (da);
375 freedaent(da);
378 return (NULL);
382 * getdatype -
383 * searches from the beginning of device_allocate for the device specified
384 * by its type.
385 * call to getdatype should be bracketed by setdaent and enddaent.
386 * returns pointer to devalloc_t for the device if it is found, else
387 * returns NULL if device not found or in case of error.
389 devalloc_t *
390 getdatype(char *type)
392 char line1[DA_BUFSIZE + 1];
393 devalloc_t *da;
394 struct _dabuff *_da = _daalloc();
396 if ((type == NULL) || (_da == NULL) || (daf == NULL))
397 return (NULL);
399 while (getdadmline(line1, (int)sizeof (line1), daf) != 0) {
400 if (strstr(line1, type) == NULL)
401 continue;
402 if ((da = da_interpret(line1)) == NULL)
403 continue;
404 if (da_matchtype(da, type))
405 return (da);
406 freedaent(da);
409 return (NULL);
413 * da_matchname -
414 * checks if the specified devalloc_t is for the device specified.
415 * returns 1 if it is, else returns 0.
418 da_matchname(devalloc_t *dap, char *name)
420 if (dap->da_devname == NULL)
421 return (0);
423 return ((strcmp(dap->da_devname, name) == 0));
427 * da_matchtype -
428 * checks if the specified devalloc_t is for the device type specified.
429 * returns 1 if match found, else, returns 0.
432 da_matchtype(devalloc_t *da, char *type)
434 if (da->da_devtype == NULL)
435 return (0);
437 return ((strcmp(da->da_devtype, type) == 0));
441 * da_match -
442 * calls da_matchname or da_matchdev as appropriate.
445 da_match(devalloc_t *dap, da_args *dargs)
447 if (dargs->devinfo->devname)
448 return (da_matchname(dap, dargs->devinfo->devname));
449 else if (dargs->devinfo->devtype)
450 return (da_matchtype(dap, dargs->devinfo->devtype));
452 return (0);
456 * da_interpret -
457 * parses val and initializes pointers in devalloc_t.
458 * returns pointer to parsed devalloc_t entry, else returns NULL on error.
460 static devalloc_t *
461 da_interpret(char *val)
463 struct _dabuff *_da = _daalloc();
464 char *opts;
465 int i;
466 kva_t *kvap;
467 kv_t *kvp;
469 if (_da == NULL)
470 return (NULL);
472 (void) strcpy(interpdaline, val);
473 interpdevalloc.da_devname = getdadmfield(interpdaline, KV_DELIMITER);
474 interpdevalloc.da_devtype = getdadmfield(NULL, KV_DELIMITER);
475 opts = getdadmfield(NULL, KV_DELIMITER);
476 (void) getdadmfield(NULL, KV_DELIMITER); /* reserved field */
477 interpdevalloc.da_devauth = getdadmfield(NULL, KV_DELIMITER);
478 interpdevalloc.da_devexec = getdadmfield(NULL, KV_DELIMITER);
479 interpdevalloc.da_devopts = NULL;
480 if (interpdevalloc.da_devname == NULL ||
481 interpdevalloc.da_devtype == NULL)
482 return (NULL);
483 if ((opts != NULL) &&
484 (strncmp(opts, DA_RESERVED, strlen(DA_RESERVED)) != 0)) {
485 interpdevalloc.da_devopts =
486 _str2kva(opts, KV_ASSIGN, KV_TOKEN_DELIMIT);
488 /* remove any extraneous whitespace in the options */
489 if ((kvap = interpdevalloc.da_devopts) != NULL) {
490 for (i = 0, kvp = kvap->data; i < kvap->length; i++, kvp++) {
491 (void) pack_white(kvp->key);
492 (void) pack_white(kvp->value);
496 return (&interpdevalloc);