1/*-
2 * Copyright (c) 1993
3 *	The Regents of the University of California.  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 * 4. Neither the name of the University nor the names of its contributors
14 *    may be used to endorse or promote products derived from this software
15 *    without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char sccsid[] = "@(#)sysctl.c	8.2 (Berkeley) 1/4/94";
32#endif /* LIBC_SCCS and not lint */
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: src/lib/libc/gen/sysctl.c,v 1.6 2007/01/09 00:27:55 imp Exp $");
35
36#include <sys/param.h>
37#include <sys/sysctl.h>
38
39#include <errno.h>
40#include <limits.h>
41#include <paths.h>
42#include <stdio.h>
43#include <unistd.h>
44#include <string.h>
45
46extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
47    void *newp, size_t newlen);
48
49int
50sysctl(name, namelen, oldp, oldlenp, newp, newlen)
51	int *name;
52	u_int namelen;
53	void *oldp, *newp;
54	size_t *oldlenp, newlen;
55{
56	if (name[0] != CTL_USER) {
57		if (namelen == 2 && name[0] == CTL_KERN && name[1] == KERN_EXEC) {
58			/*
59			 * 7723306: intercept kern.exec and fake a return of
60			 * a dummy string ("/" in this case)
61			 */
62			if (newp != NULL) {
63				errno = EPERM;
64				return -1;
65			}
66			if (oldp == NULL) {
67				if (oldlenp != NULL) *oldlenp = 2;
68				return 0;
69			}
70			if (oldlenp == NULL) {
71				errno = EFAULT;
72				return -1;
73			}
74			if (*oldlenp < 2) {
75				errno = ENOMEM;
76				return -1;
77			}
78			memmove(oldp, "/", 2);
79			*oldlenp = 2;
80			return 0;
81		}
82		return (__sysctl(name, namelen, oldp, oldlenp, newp, newlen));
83	}
84
85	if (newp != NULL) {
86		errno = EPERM;
87		return (-1);
88	}
89	if (namelen != 2) {
90		errno = EINVAL;
91		return (-1);
92	}
93
94	switch (name[1]) {
95	case USER_CS_PATH:
96		if (oldp && *oldlenp < sizeof(_PATH_STDPATH)) {
97			errno = ENOMEM;
98			return -1;
99		}
100		*oldlenp = sizeof(_PATH_STDPATH);
101		if (oldp != NULL)
102			memmove(oldp, _PATH_STDPATH, sizeof(_PATH_STDPATH));
103		return (0);
104	}
105
106	if (oldp && *oldlenp < sizeof(int)) {
107		errno = ENOMEM;
108		return (-1);
109	}
110	*oldlenp = sizeof(int);
111	if (oldp == NULL)
112		return (0);
113
114	switch (name[1]) {
115	case USER_BC_BASE_MAX:
116		*(int *)oldp = BC_BASE_MAX;
117		return (0);
118	case USER_BC_DIM_MAX:
119		*(int *)oldp = BC_DIM_MAX;
120		return (0);
121	case USER_BC_SCALE_MAX:
122		*(int *)oldp = BC_SCALE_MAX;
123		return (0);
124	case USER_BC_STRING_MAX:
125		*(int *)oldp = BC_STRING_MAX;
126		return (0);
127	case USER_COLL_WEIGHTS_MAX:
128		*(int *)oldp = COLL_WEIGHTS_MAX;
129		return (0);
130	case USER_EXPR_NEST_MAX:
131		*(int *)oldp = EXPR_NEST_MAX;
132		return (0);
133	case USER_LINE_MAX:
134		*(int *)oldp = LINE_MAX;
135		return (0);
136	case USER_RE_DUP_MAX:
137		*(int *)oldp = RE_DUP_MAX;
138		return (0);
139	case USER_POSIX2_VERSION:
140		*(int *)oldp = _POSIX2_VERSION;
141		return (0);
142	case USER_POSIX2_C_BIND:
143#ifdef POSIX2_C_BIND
144		*(int *)oldp = 1;
145#else
146		*(int *)oldp = 0;
147#endif
148		return (0);
149	case USER_POSIX2_C_DEV:
150#ifdef	POSIX2_C_DEV
151		*(int *)oldp = 1;
152#else
153		*(int *)oldp = 0;
154#endif
155		return (0);
156	case USER_POSIX2_CHAR_TERM:
157#ifdef	POSIX2_CHAR_TERM
158		*(int *)oldp = 1;
159#else
160		*(int *)oldp = 0;
161#endif
162		return (0);
163	case USER_POSIX2_FORT_DEV:
164#ifdef	POSIX2_FORT_DEV
165		*(int *)oldp = 1;
166#else
167		*(int *)oldp = 0;
168#endif
169		return (0);
170	case USER_POSIX2_FORT_RUN:
171#ifdef	POSIX2_FORT_RUN
172		*(int *)oldp = 1;
173#else
174		*(int *)oldp = 0;
175#endif
176		return (0);
177	case USER_POSIX2_LOCALEDEF:
178#ifdef	POSIX2_LOCALEDEF
179		*(int *)oldp = 1;
180#else
181		*(int *)oldp = 0;
182#endif
183		return (0);
184	case USER_POSIX2_SW_DEV:
185#ifdef	POSIX2_SW_DEV
186		*(int *)oldp = 1;
187#else
188		*(int *)oldp = 0;
189#endif
190		return (0);
191	case USER_POSIX2_UPE:
192#ifdef	POSIX2_UPE
193		*(int *)oldp = 1;
194#else
195		*(int *)oldp = 0;
196#endif
197		return (0);
198	case USER_STREAM_MAX:
199		*(int *)oldp = FOPEN_MAX;
200		return (0);
201	case USER_TZNAME_MAX:
202		*(int *)oldp = NAME_MAX;
203		return (0);
204	default:
205		errno = EINVAL;
206		return (-1);
207	}
208	/* NOTREACHED */
209}
210