kern_environment.c revision 40090
1/*- 2 * Copyright (c) 1998 Michael Smith 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $Id$ 27 28/* 29 * The unified bootloader passes us a pointer to a preserved copy of 30 * bootstrap/kernel environment variables. 31 * We make these available using sysctl for both in-kernel and 32 * out-of-kernel consumers. 33 * 34 * Note that the current sysctl infrastructure doesn't allow 35 * dynamic insertion or traversal through handled spaces. Grr. 36 */ 37 38#include <sys/param.h> 39#include <sys/kernel.h> 40#include <sys/systm.h> 41#include <sys/sysctl.h> 42#include <sys/libkern.h> 43#include <machine/bootinfo.h> 44 45char *kern_envp; 46 47static char *kernenv_next(char *cp); 48 49static void 50kernenv_init(void* arg) 51{ 52 if (bootinfo.bi_envp != 0) 53 kern_envp = (char *)bootinfo.bi_envp; 54} 55 56SYSINIT(kernenv, SI_SUB_CONSOLE, SI_ORDER_FIRST, kernenv_init, 0); 57 58char * 59getenv(char *name) 60{ 61 char *cp, *ep; 62 int len; 63 64 for (cp = kern_envp; cp != NULL; cp = kernenv_next(cp)) { 65 for (ep = cp; (*ep != '=') && (*ep != 0); ep++) 66 ; 67 len = ep - cp; 68 if (*ep = '=') 69 ep++; 70 if (!strncmp(name, cp, len)) 71 return(ep); 72 } 73 return(NULL); 74} 75 76 77static int 78sysctl_kernenv SYSCTL_HANDLER_ARGS 79{ 80 int *name = (int *)arg1; 81 u_int namelen = arg2; 82 char *cp; 83 int i, error; 84 85 if (kern_envp == NULL) 86 return(ENOENT); 87 88 name++; 89 namelen--; 90 91 if (namelen != 1) 92 return(EINVAL); 93 94 cp = kern_envp; 95 for (i = 0; i < name[0]; i++) { 96 cp = kernenv_next(cp); 97 if (cp == NULL) 98 break; 99 } 100 101 if (cp == NULL) 102 return(ENOENT); 103 104 error = SYSCTL_OUT(req, cp, strlen(cp) + 1); 105 return (error); 106} 107 108SYSCTL_NODE(_kern, OID_AUTO, environment, CTLFLAG_RD, sysctl_kernenv, "kernel environment space"); 109 110/* 111 * Find the next entry after the one which (cp) falls within, return a 112 * pointer to its start or NULL if there are no more. 113 */ 114static char * 115kernenv_next(char *cp) 116{ 117 if (cp != NULL) { 118 while (*cp != 0) 119 cp++; 120 cp++; 121 if (*cp == 0) 122 cp = NULL; 123 } 124 return(cp); 125} 126 127