10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*1914Scasper * Common Development and Distribution License (the "License").
6*1914Scasper * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*1914Scasper * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23*1914Scasper * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
270Sstevel@tonic-gate
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate * Provides accessors to configuration properties.
300Sstevel@tonic-gate *
310Sstevel@tonic-gate * slp_readConfig: attempts to locate slp.conf, and reads in all
320Sstevel@tonic-gate * properties specified therein.
330Sstevel@tonic-gate * slp_get_mtu: returns the MTU
340Sstevel@tonic-gate * slp_get_next_onlist: parses a comma separated list of integers (in
350Sstevel@tonic-gate * string form), returning one at a time.
360Sstevel@tonic-gate * slp_parse_static_das: parses the list of DAs given in the DAAddresses
370Sstevel@tonic-gate * property.
380Sstevel@tonic-gate *
390Sstevel@tonic-gate * Also see the config wrapper macros in slp-internal.h.
400Sstevel@tonic-gate */
410Sstevel@tonic-gate
420Sstevel@tonic-gate #include <stdio.h>
430Sstevel@tonic-gate #include <syslog.h>
440Sstevel@tonic-gate #include <string.h>
450Sstevel@tonic-gate #include <stdlib.h>
460Sstevel@tonic-gate #include <ctype.h>
470Sstevel@tonic-gate #include <slp-internal.h>
480Sstevel@tonic-gate
490Sstevel@tonic-gate /*
500Sstevel@tonic-gate * Reads from fp and dynamically reallocates the buffer if necessary.
510Sstevel@tonic-gate * Returns 1 on success, 0 on read completion, and -1 on failure.
520Sstevel@tonic-gate */
super_fgets(char ** buf,size_t * bufsize,FILE * fp)530Sstevel@tonic-gate static int super_fgets(char **buf, size_t *bufsize, FILE *fp) {
540Sstevel@tonic-gate char *r, *p;
550Sstevel@tonic-gate size_t real_bufsize, readlen = 0;
560Sstevel@tonic-gate
570Sstevel@tonic-gate p = *buf;
580Sstevel@tonic-gate real_bufsize = *bufsize;
590Sstevel@tonic-gate for (;;) {
600Sstevel@tonic-gate r = fgets(p, (int)real_bufsize, fp);
610Sstevel@tonic-gate if (feof(fp) && !r)
620Sstevel@tonic-gate return (0);
630Sstevel@tonic-gate if (!r)
640Sstevel@tonic-gate return (-1);
650Sstevel@tonic-gate readlen += strlen(r);
660Sstevel@tonic-gate if ((*buf)[readlen - 1] == '\n')
670Sstevel@tonic-gate return (1);
680Sstevel@tonic-gate
690Sstevel@tonic-gate /* else buf is too small */
700Sstevel@tonic-gate *bufsize *= 2;
710Sstevel@tonic-gate if (!(*buf = realloc(*buf, *bufsize))) {
720Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "super_fgets", "out of memory");
730Sstevel@tonic-gate return (-1);
740Sstevel@tonic-gate }
750Sstevel@tonic-gate p = *buf + readlen;
760Sstevel@tonic-gate real_bufsize = *bufsize - readlen;
770Sstevel@tonic-gate }
780Sstevel@tonic-gate }
790Sstevel@tonic-gate
skip_space(char ** p)800Sstevel@tonic-gate static void skip_space(char **p) {
810Sstevel@tonic-gate while (*p && **p != '\n' && isspace(**p))
820Sstevel@tonic-gate (*p)++;
830Sstevel@tonic-gate }
840Sstevel@tonic-gate
null_space(char * p)850Sstevel@tonic-gate static void null_space(char *p) {
860Sstevel@tonic-gate for (; *p; p++)
870Sstevel@tonic-gate if (isspace(*p))
880Sstevel@tonic-gate *p = 0;
890Sstevel@tonic-gate }
900Sstevel@tonic-gate
910Sstevel@tonic-gate /*
920Sstevel@tonic-gate * Reads into the local property store all properties defined in
930Sstevel@tonic-gate * the config file.
940Sstevel@tonic-gate */
slp_readConfig()950Sstevel@tonic-gate void slp_readConfig() {
960Sstevel@tonic-gate char *cfile, *buf;
970Sstevel@tonic-gate FILE *fp;
980Sstevel@tonic-gate size_t buflen = 512;
990Sstevel@tonic-gate
1000Sstevel@tonic-gate /* check env for alternate config file */
1010Sstevel@tonic-gate fp = NULL;
1020Sstevel@tonic-gate if (cfile = getenv("SLP_CONF_FILE"))
103*1914Scasper fp = fopen(cfile, "rF");
1040Sstevel@tonic-gate if (!fp)
105*1914Scasper if (!(fp = fopen(SLP_DEFAULT_CONFIG_FILE, "rF"))) {
1060Sstevel@tonic-gate slp_err(LOG_INFO, 0, "readConfig",
1070Sstevel@tonic-gate "cannot open config file");
1080Sstevel@tonic-gate return;
1090Sstevel@tonic-gate }
1100Sstevel@tonic-gate
1110Sstevel@tonic-gate if (!(buf = malloc(buflen))) {
1120Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "readConfig", "out of memory");
1130Sstevel@tonic-gate (void) fclose(fp);
1140Sstevel@tonic-gate return;
1150Sstevel@tonic-gate }
1160Sstevel@tonic-gate
1170Sstevel@tonic-gate while (!feof(fp)) {
1180Sstevel@tonic-gate char *val, *p;
1190Sstevel@tonic-gate int err;
1200Sstevel@tonic-gate
1210Sstevel@tonic-gate /* read a line */
1220Sstevel@tonic-gate err = super_fgets(&buf, &buflen, fp);
1230Sstevel@tonic-gate if (err == 0) continue;
1240Sstevel@tonic-gate if (err == -1) {
1250Sstevel@tonic-gate slp_err(LOG_INFO, 0, "readConfig",
1260Sstevel@tonic-gate "error reading file: %d",
1270Sstevel@tonic-gate ferror(fp));
1280Sstevel@tonic-gate (void) fclose(fp);
1290Sstevel@tonic-gate free(buf);
1300Sstevel@tonic-gate return;
1310Sstevel@tonic-gate }
1320Sstevel@tonic-gate
1330Sstevel@tonic-gate /* skip comments and newlines */
1340Sstevel@tonic-gate p = buf;
1350Sstevel@tonic-gate skip_space(&p);
1360Sstevel@tonic-gate if (*p == '#' || *p == ';' || *p == '\n')
1370Sstevel@tonic-gate continue;
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate /* get property and value */
1400Sstevel@tonic-gate if (val = strchr(p, '=')) {
1410Sstevel@tonic-gate *val++ = 0;
1420Sstevel@tonic-gate skip_space(&val);
1430Sstevel@tonic-gate /* remove the trailing newline */
1440Sstevel@tonic-gate val[strlen(val) - 1] = 0;
1450Sstevel@tonic-gate }
1460Sstevel@tonic-gate null_space(p);
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate SLPSetProperty(p, val ? val : "");
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate
1510Sstevel@tonic-gate (void) fclose(fp);
1520Sstevel@tonic-gate free(buf);
1530Sstevel@tonic-gate }
1540Sstevel@tonic-gate
1550Sstevel@tonic-gate /*
1560Sstevel@tonic-gate * Config convenience wrappers
1570Sstevel@tonic-gate */
slp_get_mtu()1580Sstevel@tonic-gate size_t slp_get_mtu() {
1590Sstevel@tonic-gate size_t size;
1600Sstevel@tonic-gate size = atoi(SLPGetProperty(SLP_CONFIG_MTU));
1610Sstevel@tonic-gate size = size ? size : SLP_DEFAULT_SENDMTU;
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate return (size);
1640Sstevel@tonic-gate }
1650Sstevel@tonic-gate
1660Sstevel@tonic-gate /*
1670Sstevel@tonic-gate * On the first invocation, *state should == the value of the property
1680Sstevel@tonic-gate * to parse.
1690Sstevel@tonic-gate * If there are no more timeouts, returns -1, otherwise the timeout.
1700Sstevel@tonic-gate * If the value in the property is invalid, returns the default 2000.
1710Sstevel@tonic-gate */
slp_get_next_onlist(char ** state)1720Sstevel@tonic-gate int slp_get_next_onlist(char **state) {
1730Sstevel@tonic-gate char *p, buf[33];
1740Sstevel@tonic-gate size_t l;
1750Sstevel@tonic-gate int answer;
1760Sstevel@tonic-gate
1770Sstevel@tonic-gate if (!*state)
1780Sstevel@tonic-gate return (-1);
1790Sstevel@tonic-gate
1800Sstevel@tonic-gate if (**state == ',') {
1810Sstevel@tonic-gate (*state)++; /* skip the ',' */
1820Sstevel@tonic-gate }
1830Sstevel@tonic-gate p = *state;
1840Sstevel@tonic-gate *state = slp_utf_strchr(*state, ',');
1850Sstevel@tonic-gate if (!*state)
1860Sstevel@tonic-gate l = strlen(p);
1870Sstevel@tonic-gate else {
1880Sstevel@tonic-gate l = *state - p;
1890Sstevel@tonic-gate l = (l > 32 ? 32 : l);
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate (void) strncpy(buf, p, l);
1920Sstevel@tonic-gate buf[l] = 0;
1930Sstevel@tonic-gate answer = atoi(buf);
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate return (answer != 0 ? answer : 2000);
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate
slp_get_maxResults()1980Sstevel@tonic-gate int slp_get_maxResults() {
1990Sstevel@tonic-gate int num = atoi(SLPGetProperty(SLP_CONFIG_MAXRESULTS));
2000Sstevel@tonic-gate
2010Sstevel@tonic-gate return (num <= 0 ? -1 : num);
2020Sstevel@tonic-gate }
203