kern_environment.c revision 78247
140090Smsmith/*-
240090Smsmith * Copyright (c) 1998 Michael Smith
340090Smsmith * All rights reserved.
440090Smsmith *
540090Smsmith * Redistribution and use in source and binary forms, with or without
640090Smsmith * modification, are permitted provided that the following conditions
740090Smsmith * are met:
840090Smsmith * 1. Redistributions of source code must retain the above copyright
940090Smsmith *    notice, this list of conditions and the following disclaimer.
1040090Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1140090Smsmith *    notice, this list of conditions and the following disclaimer in the
1240090Smsmith *    documentation and/or other materials provided with the distribution.
1340090Smsmith *
1440090Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1540090Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1640090Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1740090Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1840090Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1940090Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2040090Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2140090Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2240090Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2340090Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2440090Smsmith * SUCH DAMAGE.
2540090Smsmith *
2650477Speter * $FreeBSD: head/sys/kern/kern_environment.c 78247 2001-06-15 07:29:17Z peter $
2740116Sjkh */
2840090Smsmith
2940090Smsmith/*
3040090Smsmith * The unified bootloader passes us a pointer to a preserved copy of
3140090Smsmith * bootstrap/kernel environment variables.
3240090Smsmith * We make these available using sysctl for both in-kernel and
3340090Smsmith * out-of-kernel consumers.
3440090Smsmith *
3540090Smsmith * Note that the current sysctl infrastructure doesn't allow
3640090Smsmith * dynamic insertion or traversal through handled spaces.  Grr.
3740090Smsmith */
3840090Smsmith
3940090Smsmith#include <sys/param.h>
4040090Smsmith#include <sys/kernel.h>
4140090Smsmith#include <sys/systm.h>
4240090Smsmith#include <sys/sysctl.h>
4340090Smsmith#include <sys/libkern.h>
4440090Smsmith
4540090Smsmithchar	*kern_envp;
4640090Smsmith
4740090Smsmithstatic char	*kernenv_next(char *cp);
4840090Smsmith
4940090Smsmithchar *
5078247Spetergetenv(const char *name)
5140090Smsmith{
5240090Smsmith    char	*cp, *ep;
5340090Smsmith    int		len;
5440090Smsmith
5540090Smsmith    for (cp = kern_envp; cp != NULL; cp = kernenv_next(cp)) {
5640090Smsmith	for (ep = cp; (*ep != '=') && (*ep != 0); ep++)
5740090Smsmith	    ;
5840090Smsmith	len = ep - cp;
5943299Sdillon	if (*ep == '=')
6040090Smsmith	    ep++;
6140090Smsmith	if (!strncmp(name, cp, len))
6240090Smsmith	    return(ep);
6340090Smsmith    }
6440090Smsmith    return(NULL);
6540090Smsmith}
6640090Smsmith
6742706Smsmith/*
6842706Smsmith * Return an integer value from an environment variable.
6942706Smsmith */
7042706Smsmithint
7178247Spetergetenv_int(const char *name, int *data)
7242706Smsmith{
7352947Smjacob    quad_t tmp;
7452947Smjacob    int rval;
7552947Smjacob
7652947Smjacob    rval = getenv_quad(name, &tmp);
7752947Smjacob    if (rval) {
7852947Smjacob	*data = (int) tmp;
7952947Smjacob    }
8052947Smjacob    return (rval);
8152947Smjacob}
8252947Smjacob
8352947Smjacob/*
8452947Smjacob * Return a quad_t value from an environment variable.
8552947Smjacob */
8652947Smjacobquad_t
8778247Spetergetenv_quad(const char *name, quad_t *data)
8852947Smjacob{
8953648Sarchie    const char	*value;
9053648Sarchie    char	*vtp;
9142706Smsmith    quad_t	iv;
9242706Smsmith
9342706Smsmith    if ((value = getenv(name)) == NULL)
9442706Smsmith	return(0);
9542706Smsmith
9642706Smsmith    iv = strtoq(value, &vtp, 0);
9753648Sarchie    if ((vtp == value) || (*vtp != '\0'))
9842706Smsmith	return(0);
9942706Smsmith
10052947Smjacob    *data = iv;
10142706Smsmith    return(1);
10242706Smsmith}
10340090Smsmith
10440090Smsmithstatic int
10562573Sphksysctl_kernenv(SYSCTL_HANDLER_ARGS)
10640090Smsmith{
10740090Smsmith    int		*name = (int *)arg1;
10840090Smsmith    u_int	namelen = arg2;
10940090Smsmith    char	*cp;
11040090Smsmith    int		i, error;
11140090Smsmith
11240090Smsmith    if (kern_envp == NULL)
11340090Smsmith	return(ENOENT);
11440090Smsmith
11540090Smsmith    name++;
11640090Smsmith    namelen--;
11740090Smsmith
11840090Smsmith    if (namelen != 1)
11940090Smsmith	return(EINVAL);
12040090Smsmith
12140090Smsmith    cp = kern_envp;
12240090Smsmith    for (i = 0; i < name[0]; i++) {
12340090Smsmith	cp = kernenv_next(cp);
12440090Smsmith	if (cp == NULL)
12540090Smsmith	    break;
12640090Smsmith    }
12740090Smsmith
12840090Smsmith    if (cp == NULL)
12940090Smsmith	return(ENOENT);
13040090Smsmith
13140090Smsmith    error = SYSCTL_OUT(req, cp, strlen(cp) + 1);
13240090Smsmith    return (error);
13340090Smsmith}
13440090Smsmith
13540090SmsmithSYSCTL_NODE(_kern, OID_AUTO, environment, CTLFLAG_RD, sysctl_kernenv, "kernel environment space");
13640090Smsmith
13740090Smsmith/*
13840090Smsmith * Find the next entry after the one which (cp) falls within, return a
13940090Smsmith * pointer to its start or NULL if there are no more.
14040090Smsmith */
14140090Smsmithstatic char *
14240090Smsmithkernenv_next(char *cp)
14340090Smsmith{
14440090Smsmith    if (cp != NULL) {
14540090Smsmith	while (*cp != 0)
14640090Smsmith	    cp++;
14740090Smsmith	cp++;
14840090Smsmith	if (*cp == 0)
14940090Smsmith	    cp = NULL;
15040090Smsmith    }
15140090Smsmith    return(cp);
15240090Smsmith}
15340090Smsmith
15477900Spetervoid
15577900Spetertunable_int_init(void *data)
15677900Speter{
15777900Speter	struct tunable_int *d = (struct tunable_int *)data;
15877900Speter
15977900Speter	TUNABLE_INT_FETCH(d->path, d->var);
16077900Speter}
16177900Speter
16277900Spetervoid
16377900Spetertunable_str_init(void *data)
16477900Speter{
16577900Speter	struct tunable_str *d = (struct tunable_str *)data;
16677900Speter
16777900Speter	TUNABLE_STR_FETCH(d->path, d->var, d->size);
16877900Speter}
169