1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __SCCSID("@(#)sysctl.c 8.2 (Berkeley) 1/4/94"); 34 #include <sys/param.h> 35 #include <sys/sysctl.h> 36 37 #include <errno.h> 38 #include <limits.h> 39 #include <paths.h> 40 #include <stdio.h> 41 #include <unistd.h> 42 #include <string.h> 43 44 extern int __sysctl(const int *name, u_int namelen, void *oldp, 45 size_t *oldlenp, const void *newp, size_t newlen); 46 47 static int 48 set_user_str(void *dstp, size_t *dstlenp, const char *src, size_t len, 49 size_t maxlen) 50 { 51 int retval; 52 53 retval = 0; 54 if (dstp != NULL) { 55 if (len > maxlen) { 56 len = maxlen; 57 errno = ENOMEM; 58 retval = -1; 59 } 60 memcpy(dstp, src, len); 61 } 62 *dstlenp = len; 63 return (retval); 64 } 65 66 int 67 sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp, 68 const void *newp, size_t newlen) 69 { 70 int retval; 71 size_t orig_oldlen; 72 73 orig_oldlen = oldlenp != NULL ? *oldlenp : 0; 74 retval = __sysctl(name, namelen, oldp, oldlenp, newp, newlen); 75 /* 76 * Valid names under CTL_USER except USER_LOCALBASE have a dummy entry 77 * in the sysctl tree (to support name lookups and enumerations) with 78 * an empty/zero value, and the true value is supplied by this routine. 79 * For all such names, __sysctl() is used solely to validate the name. 80 * 81 * Return here unless there was a successful lookup for a CTL_USER name. 82 */ 83 if (retval != 0 || name[0] != CTL_USER) 84 return (retval); 85 86 if (namelen != 2) { 87 errno = EINVAL; 88 return (-1); 89 } 90 91 /* Variables under CLT_USER that may be overridden by kernel values */ 92 switch (name[1]) { 93 case USER_LOCALBASE: 94 if (oldlenp == NULL || *oldlenp > sizeof("")) 95 return (0); 96 return (set_user_str(oldp, oldlenp, _PATH_LOCALBASE, 97 sizeof(_PATH_LOCALBASE), orig_oldlen)); 98 } 99 100 /* Variables under CLT_USER whose values are immutably defined below */ 101 if (newp != NULL) { 102 errno = EPERM; 103 return (-1); 104 } 105 106 switch (name[1]) { 107 case USER_CS_PATH: 108 return (set_user_str(oldp, oldlenp, _PATH_STDPATH, 109 sizeof(_PATH_STDPATH), orig_oldlen)); 110 } 111 112 if (oldp != NULL && *oldlenp < sizeof(int)) { 113 errno = ENOMEM; 114 return (-1); 115 } 116 *oldlenp = sizeof(int); 117 if (oldp == NULL) 118 return (0); 119 120 switch (name[1]) { 121 case USER_BC_BASE_MAX: 122 *(int *)oldp = BC_BASE_MAX; 123 return (0); 124 case USER_BC_DIM_MAX: 125 *(int *)oldp = BC_DIM_MAX; 126 return (0); 127 case USER_BC_SCALE_MAX: 128 *(int *)oldp = BC_SCALE_MAX; 129 return (0); 130 case USER_BC_STRING_MAX: 131 *(int *)oldp = BC_STRING_MAX; 132 return (0); 133 case USER_COLL_WEIGHTS_MAX: 134 *(int *)oldp = COLL_WEIGHTS_MAX; 135 return (0); 136 case USER_EXPR_NEST_MAX: 137 *(int *)oldp = EXPR_NEST_MAX; 138 return (0); 139 case USER_LINE_MAX: 140 *(int *)oldp = LINE_MAX; 141 return (0); 142 case USER_RE_DUP_MAX: 143 *(int *)oldp = RE_DUP_MAX; 144 return (0); 145 case USER_POSIX2_VERSION: 146 *(int *)oldp = _POSIX2_VERSION; 147 return (0); 148 case USER_POSIX2_C_BIND: 149 #ifdef POSIX2_C_BIND 150 *(int *)oldp = 1; 151 #else 152 *(int *)oldp = 0; 153 #endif 154 return (0); 155 case USER_POSIX2_C_DEV: 156 #ifdef POSIX2_C_DEV 157 *(int *)oldp = 1; 158 #else 159 *(int *)oldp = 0; 160 #endif 161 return (0); 162 case USER_POSIX2_CHAR_TERM: 163 #ifdef POSIX2_CHAR_TERM 164 *(int *)oldp = 1; 165 #else 166 *(int *)oldp = 0; 167 #endif 168 return (0); 169 case USER_POSIX2_FORT_DEV: 170 #ifdef POSIX2_FORT_DEV 171 *(int *)oldp = 1; 172 #else 173 *(int *)oldp = 0; 174 #endif 175 return (0); 176 case USER_POSIX2_FORT_RUN: 177 #ifdef POSIX2_FORT_RUN 178 *(int *)oldp = 1; 179 #else 180 *(int *)oldp = 0; 181 #endif 182 return (0); 183 case USER_POSIX2_LOCALEDEF: 184 #ifdef POSIX2_LOCALEDEF 185 *(int *)oldp = 1; 186 #else 187 *(int *)oldp = 0; 188 #endif 189 return (0); 190 case USER_POSIX2_SW_DEV: 191 #ifdef POSIX2_SW_DEV 192 *(int *)oldp = 1; 193 #else 194 *(int *)oldp = 0; 195 #endif 196 return (0); 197 case USER_POSIX2_UPE: 198 #ifdef POSIX2_UPE 199 *(int *)oldp = 1; 200 #else 201 *(int *)oldp = 0; 202 #endif 203 return (0); 204 case USER_STREAM_MAX: 205 *(int *)oldp = FOPEN_MAX; 206 return (0); 207 case USER_TZNAME_MAX: 208 *(int *)oldp = NAME_MAX; 209 return (0); 210 default: 211 errno = EINVAL; 212 return (-1); 213 } 214 /* NOTREACHED */ 215 } 216