kern_environment.c revision 40116
1139823Simp/*- 21541Srgrimes * Copyright (c) 1998 Michael Smith 31541Srgrimes * All rights reserved. 4137668Smlaier * 51541Srgrimes * Redistribution and use in source and binary forms, with or without 61541Srgrimes * modification, are permitted provided that the following conditions 71541Srgrimes * are met: 81541Srgrimes * 1. Redistributions of source code must retain the above copyright 91541Srgrimes * notice, this list of conditions and the following disclaimer. 101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111541Srgrimes * notice, this list of conditions and the following disclaimer in the 121541Srgrimes * documentation and/or other materials provided with the distribution. 131541Srgrimes * 141541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 151541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 161541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 171541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 181541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 191541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 201541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 211541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 221541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 231541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 241541Srgrimes * SUCH DAMAGE. 251541Srgrimes * 261541Srgrimes * $Id: kern_environment.c,v 1.1 1998/10/09 00:31:29 msmith Exp $ 271541Srgrimes */ 281541Srgrimes 291541Srgrimes/* 3010939Swollman * The unified bootloader passes us a pointer to a preserved copy of 3150477Speter * bootstrap/kernel environment variables. 321541Srgrimes * We make these available using sysctl for both in-kernel and 331541Srgrimes * out-of-kernel consumers. 34143868Sglebius * 35143868Sglebius * Note that the current sysctl infrastructure doesn't allow 361541Srgrimes * dynamic insertion or traversal through handled spaces. Grr. 371549Srgrimes */ 3824204Sbde 391541Srgrimes#include <sys/param.h> 40164033Srwatson#include <sys/kernel.h> 411541Srgrimes#include <sys/systm.h> 4212704Sphk#include <sys/sysctl.h> 4312704Sphk#include <sys/libkern.h> 441541Srgrimes#include <machine/bootinfo.h> 451541Srgrimes 4655009Sshinchar *kern_envp; 471541Srgrimes 481541Srgrimesstatic char *kernenv_next(char *cp); 491541Srgrimes 501541Srgrimesstatic void 5181127Sumekernenv_init(void* arg) 52170613Sbms{ 531541Srgrimes if (bootinfo.bi_envp != 0) 5492723Salfred kern_envp = (char *)bootinfo.bi_envp; 5592723Salfred} 5692723Salfred 5792723SalfredSYSINIT(kernenv, SI_SUB_CONSOLE, SI_ORDER_FIRST, kernenv_init, 0); 5855009Sshin 59137628Smlaierchar * 60137628Smlaiergetenv(char *name) 6192723Salfred{ 6292723Salfred char *cp, *ep; 6392723Salfred int len; 64167729Sbms 651541Srgrimes for (cp = kern_envp; cp != NULL; cp = kernenv_next(cp)) { 6618193Swollman for (ep = cp; (*ep != '=') && (*ep != 0); ep++) 67133874Srwatson ; 68123998Sru len = ep - cp; 69149221Sglebius if (*ep = '=') 70149221Sglebius ep++; 71149221Sglebius if (!strncmp(name, cp, len)) 72149221Sglebius return(ep); 7321666Swollman } 7481127Sume return(NULL); 7581127Sume} 7681127Sume 771541Srgrimes 781541Srgrimesstatic int 791541Srgrimessysctl_kernenv SYSCTL_HANDLER_ARGS 801541Srgrimes{ 811541Srgrimes int *name = (int *)arg1; 821541Srgrimes u_int namelen = arg2; 831549Srgrimes char *cp; 84169454Srwatson int i, error; 851541Srgrimes 861541Srgrimes if (kern_envp == NULL) 871541Srgrimes return(ENOENT); 881541Srgrimes 891541Srgrimes name++; 9074362Sphk namelen--; 911541Srgrimes 921541Srgrimes if (namelen != 1) 931541Srgrimes return(EINVAL); 9472012Sphk 951541Srgrimes cp = kern_envp; 961541Srgrimes for (i = 0; i < name[0]; i++) { 971541Srgrimes cp = kernenv_next(cp); 981541Srgrimes if (cp == NULL) 991541Srgrimes break; 1001541Srgrimes } 1011541Srgrimes 102133486Sandre if (cp == NULL) 103133486Sandre return(ENOENT); 104133486Sandre 105133486Sandre error = SYSCTL_OUT(req, cp, strlen(cp) + 1); 106169454Srwatson return (error); 107133486Sandre} 108133486Sandre 109133486SandreSYSCTL_NODE(_kern, OID_AUTO, environment, CTLFLAG_RD, sysctl_kernenv, "kernel environment space"); 110133486Sandre 111133486Sandre/* 112133486Sandre * Find the next entry after the one which (cp) falls within, return a 113133486Sandre * pointer to its start or NULL if there are no more. 114133486Sandre */ 115133486Sandrestatic char * 116133486Sandrekernenv_next(char *cp) 117133486Sandre{ 1181541Srgrimes if (cp != NULL) { 1191541Srgrimes while (*cp != 0) 1201541Srgrimes cp++; 1211541Srgrimes cp++; 1221549Srgrimes if (*cp == 0) 123169454Srwatson cp = NULL; 1241541Srgrimes } 1251541Srgrimes return(cp); 1261541Srgrimes} 1271541Srgrimes 128166450Sbms