2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A/*
2N/A * Provides accessors to configuration properties.
2N/A *
2N/A * slp_readConfig: attempts to locate slp.conf, and reads in all
2N/A * properties specified therein.
2N/A * slp_get_mtu: returns the MTU
2N/A * slp_get_next_onlist: parses a comma separated list of integers (in
2N/A * string form), returning one at a time.
2N/A * slp_parse_static_das: parses the list of DAs given in the DAAddresses
2N/A * property.
2N/A *
2N/A * Also see the config wrapper macros in slp-internal.h.
2N/A */
2N/A
2N/A#include <stdio.h>
2N/A#include <syslog.h>
2N/A#include <string.h>
2N/A#include <stdlib.h>
2N/A#include <ctype.h>
2N/A#include <slp-internal.h>
2N/A
2N/A/*
2N/A * Reads from fp and dynamically reallocates the buffer if necessary.
2N/A * Returns 1 on success, 0 on read completion, and -1 on failure.
2N/A */
2N/Astatic int super_fgets(char **buf, size_t *bufsize, FILE *fp) {
2N/A char *r, *p;
2N/A size_t real_bufsize, readlen = 0;
2N/A
2N/A p = *buf;
2N/A real_bufsize = *bufsize;
2N/A for (;;) {
2N/A r = fgets(p, (int)real_bufsize, fp);
2N/A if (feof(fp) && !r)
2N/A return (0);
2N/A if (!r)
2N/A return (-1);
2N/A readlen += strlen(r);
2N/A if ((*buf)[readlen - 1] == '\n')
2N/A return (1);
2N/A
2N/A /* else buf is too small */
2N/A *bufsize *= 2;
2N/A if (!(*buf = realloc(*buf, *bufsize))) {
2N/A slp_err(LOG_CRIT, 0, "super_fgets", "out of memory");
2N/A return (-1);
2N/A }
2N/A p = *buf + readlen;
2N/A real_bufsize = *bufsize - readlen;
2N/A }
2N/A}
2N/A
2N/Astatic void skip_space(char **p) {
2N/A while (*p && **p != '\n' && isspace(**p))
2N/A (*p)++;
2N/A}
2N/A
2N/Astatic void null_space(char *p) {
2N/A for (; *p; p++)
2N/A if (isspace(*p))
2N/A *p = 0;
2N/A}
2N/A
2N/A/*
2N/A * Reads into the local property store all properties defined in
2N/A * the config file.
2N/A */
2N/Avoid slp_readConfig() {
2N/A char *cfile, *buf;
2N/A FILE *fp;
2N/A size_t buflen = 512;
2N/A
2N/A /* check env for alternate config file */
2N/A fp = NULL;
2N/A if (cfile = getenv("SLP_CONF_FILE"))
2N/A fp = fopen(cfile, "rF");
2N/A if (!fp)
2N/A if (!(fp = fopen(SLP_DEFAULT_CONFIG_FILE, "rF"))) {
2N/A slp_err(LOG_INFO, 0, "readConfig",
2N/A "cannot open config file");
2N/A return;
2N/A }
2N/A
2N/A if (!(buf = malloc(buflen))) {
2N/A slp_err(LOG_CRIT, 0, "readConfig", "out of memory");
2N/A (void) fclose(fp);
2N/A return;
2N/A }
2N/A
2N/A while (!feof(fp)) {
2N/A char *val, *p;
2N/A int err;
2N/A
2N/A /* read a line */
2N/A err = super_fgets(&buf, &buflen, fp);
2N/A if (err == 0) continue;
2N/A if (err == -1) {
2N/A slp_err(LOG_INFO, 0, "readConfig",
2N/A "error reading file: %d",
2N/A ferror(fp));
2N/A (void) fclose(fp);
2N/A free(buf);
2N/A return;
2N/A }
2N/A
2N/A /* skip comments and newlines */
2N/A p = buf;
2N/A skip_space(&p);
2N/A if (*p == '#' || *p == ';' || *p == '\n')
2N/A continue;
2N/A
2N/A /* get property and value */
2N/A if (val = strchr(p, '=')) {
2N/A *val++ = 0;
2N/A skip_space(&val);
2N/A /* remove the trailing newline */
2N/A val[strlen(val) - 1] = 0;
2N/A }
2N/A null_space(p);
2N/A
2N/A SLPSetProperty(p, val ? val : "");
2N/A }
2N/A
2N/A (void) fclose(fp);
2N/A free(buf);
2N/A}
2N/A
2N/A/*
2N/A * Config convenience wrappers
2N/A */
2N/Asize_t slp_get_mtu() {
2N/A size_t size;
2N/A size = atoi(SLPGetProperty(SLP_CONFIG_MTU));
2N/A size = size ? size : SLP_DEFAULT_SENDMTU;
2N/A
2N/A return (size);
2N/A}
2N/A
2N/A/*
2N/A * On the first invocation, *state should == the value of the property
2N/A * to parse.
2N/A * If there are no more timeouts, returns -1, otherwise the timeout.
2N/A * If the value in the property is invalid, returns the default 2000.
2N/A */
2N/Aint slp_get_next_onlist(char **state) {
2N/A char *p, buf[33];
2N/A size_t l;
2N/A int answer;
2N/A
2N/A if (!*state)
2N/A return (-1);
2N/A
2N/A if (**state == ',') {
2N/A (*state)++; /* skip the ',' */
2N/A }
2N/A p = *state;
2N/A *state = slp_utf_strchr(*state, ',');
2N/A if (!*state)
2N/A l = strlen(p);
2N/A else {
2N/A l = *state - p;
2N/A l = (l > 32 ? 32 : l);
2N/A }
2N/A (void) strncpy(buf, p, l);
2N/A buf[l] = 0;
2N/A answer = atoi(buf);
2N/A
2N/A return (answer != 0 ? answer : 2000);
2N/A}
2N/A
2N/Aint slp_get_maxResults() {
2N/A int num = atoi(SLPGetProperty(SLP_CONFIG_MAXRESULTS));
2N/A
2N/A return (num <= 0 ? -1 : num);
2N/A}