summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--freebsd/lib/libc/stdlib/strtoimax.c165
-rw-r--r--freebsd/lib/libc/stdlib/strtoumax.c143
-rw-r--r--freebsd/sbin/sysctl/sysctl.c784
-rwxr-xr-xlibbsd.py3
-rw-r--r--libbsd_waf.py3
-rw-r--r--rtemsbsd/include/machine/rtems-bsd-commands.h2
-rw-r--r--rtemsbsd/include/rtems/netcmds-config.h2
-rw-r--r--rtemsbsd/rtems/rtems-bsd-shell-netcmds.c9
-rw-r--r--testsuite/include/rtems/bsd/test/default-network-init.h3
9 files changed, 1113 insertions, 1 deletions
diff --git a/freebsd/lib/libc/stdlib/strtoimax.c b/freebsd/lib/libc/stdlib/strtoimax.c
new file mode 100644
index 00000000..d7103b3a
--- /dev/null
+++ b/freebsd/lib/libc/stdlib/strtoimax.c
@@ -0,0 +1,165 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "from @(#)strtol.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#ifndef __rtems__
+#include "xlocale_private.h"
+#else
+#define locale_t void*
+#define isspace_l(_c, _l) isspace(_c)
+static void* __get_locale(void) { return NULL; }
+#endif /* __rtems__ */
+
+/*
+ * Convert a string to an intmax_t integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+intmax_t
+strtoimax_l(const char * __restrict nptr, char ** __restrict endptr, int base,
+ locale_t locale)
+{
+ const char *s;
+ uintmax_t acc;
+ char c;
+ uintmax_t cutoff;
+ int neg, any, cutlim;
+#ifndef __rtems__
+ FIX_LOCALE(locale);
+#else
+ locale = NULL;
+#endif /* __rtems__ */
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace_l((unsigned char)c, locale));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X') &&
+ ((s[1] >= '0' && s[1] <= '9') ||
+ (s[1] >= 'A' && s[1] <= 'F') ||
+ (s[1] >= 'a' && s[1] <= 'f'))) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ acc = any = 0;
+ if (base < 2 || base > 36)
+ goto noconv;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for intmax_t is
+ * [-9223372036854775808..9223372036854775807] and the input base
+ * is 10, cutoff will be set to 922337203685477580 and cutlim to
+ * either 7 (neg==0) or 8 (neg==1), meaning that if we have
+ * accumulated a value > 922337203685477580, or equal but the
+ * next digit is > 7 (or 8), the number is too big, and we will
+ * return a range error.
+ *
+ * Set 'any' if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ cutoff = neg ? (uintmax_t)-(INTMAX_MIN + INTMAX_MAX) + INTMAX_MAX
+ : INTMAX_MAX;
+ cutlim = cutoff % base;
+ cutoff /= base;
+ for ( ; ; c = *s++) {
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? INTMAX_MIN : INTMAX_MAX;
+ errno = ERANGE;
+ } else if (!any) {
+noconv:
+ errno = EINVAL;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != NULL)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
+intmax_t
+strtoimax(const char * __restrict nptr, char ** __restrict endptr, int base)
+{
+ return strtoimax_l(nptr, endptr, base, __get_locale());
+}
diff --git a/freebsd/lib/libc/stdlib/strtoumax.c b/freebsd/lib/libc/stdlib/strtoumax.c
new file mode 100644
index 00000000..4098ce81
--- /dev/null
+++ b/freebsd/lib/libc/stdlib/strtoumax.c
@@ -0,0 +1,143 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "from @(#)strtoul.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#ifndef __rtems__
+#include "xlocale_private.h"
+#else
+#define locale_t void*
+#define isspace_l(_c, _l) isspace(_c)
+static void* __get_locale(void) { return NULL; }
+#endif /* __rtems__ */
+
+/*
+ * Convert a string to a uintmax_t integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+uintmax_t
+strtoumax_l(const char * __restrict nptr, char ** __restrict endptr, int base,
+ locale_t locale)
+{
+ const char *s;
+ uintmax_t acc;
+ char c;
+ uintmax_t cutoff;
+ int neg, any, cutlim;
+#ifndef __rtems__
+ FIX_LOCALE(locale);
+#else
+ locale = NULL;
+#endif /* __rtems__ */
+
+ /*
+ * See strtoimax for comments as to the logic used.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace_l((unsigned char)c, locale));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X') &&
+ ((s[1] >= '0' && s[1] <= '9') ||
+ (s[1] >= 'A' && s[1] <= 'F') ||
+ (s[1] >= 'a' && s[1] <= 'f'))) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ acc = any = 0;
+ if (base < 2 || base > 36)
+ goto noconv;
+
+ cutoff = UINTMAX_MAX / base;
+ cutlim = UINTMAX_MAX % base;
+ for ( ; ; c = *s++) {
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = UINTMAX_MAX;
+ errno = ERANGE;
+ } else if (!any) {
+noconv:
+ errno = EINVAL;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != NULL)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
+uintmax_t
+strtoumax(const char * __restrict nptr, char ** __restrict endptr, int base)
+{
+ return strtoumax_l(nptr, endptr, base, __get_locale());
+}
diff --git a/freebsd/sbin/sysctl/sysctl.c b/freebsd/sbin/sysctl/sysctl.c
new file mode 100644
index 00000000..9d7a8692
--- /dev/null
+++ b/freebsd/sbin/sysctl/sysctl.c
@@ -0,0 +1,784 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)from: sysctl.c 8.1 (Berkeley) 6/6/93";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* not lint */
+#ifdef __rtems__
+#define __need_getopt_newlib
+#include <getopt.h>
+#include <machine/rtems-bsd-program.h>
+#include <machine/rtems-bsd-commands.h>
+#endif /* __rtems__ */
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/time.h>
+#include <rtems/bsd/sys/resource.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/vmmeter.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static int aflag, bflag, dflag, eflag, hflag, iflag;
+static int Nflag, nflag, oflag, qflag, xflag, warncount;
+
+static int oidfmt(int *, int, char *, u_int *);
+static void parse(const char *);
+static int show_var(int *, int);
+static int sysctl_all(int *oid, int len);
+static int name2oid(char *, int *);
+
+static int set_IK(const char *, int *);
+
+static void
+usage(void)
+{
+
+ (void)fprintf(stderr, "%s\n%s\n",
+ "usage: sysctl [-bdehiNnoqx] name[=value] ...",
+ " sysctl [-bdehNnoqx] -a");
+ exit(1);
+}
+
+#ifdef __rtems__
+static int main(int argc, char **argv);
+
+int rtems_bsd_command_sysctl(int argc, char *argv[])
+{
+ int exit_code;
+
+ rtems_bsd_program_lock();
+
+ aflag = bflag = dflag = eflag = hflag = iflag = 0;
+ Nflag = nflag = oflag = qflag = xflag = warncount = 0;
+
+ exit_code = rtems_bsd_program_call_main("sysctl", main, argc, argv);
+
+ rtems_bsd_program_unlock();
+
+ return exit_code;
+}
+#endif /* __rtems__ */
+
+int
+main(int argc, char **argv)
+{
+ int ch;
+
+#ifdef __rtems__
+ struct getopt_data getopt_data;
+ memset(&getopt_data, 0, sizeof(getopt_data));
+#define optind getopt_data.optind
+#define optarg getopt_data.optarg
+#define opterr getopt_data.opterr
+#define optopt getopt_data.optopt
+#define getopt(argc, argv, opt) getopt_r(argc, argv, "+" opt, &getopt_data)
+#endif /* __rtems__ */
+
+#ifndef __rtems__
+ setlocale(LC_NUMERIC, "");
+ setbuf(stdout,0);
+ setbuf(stderr,0);
+#endif /* __rtems__ */
+
+ while ((ch = getopt(argc, argv, "AabdehiNnoqwxX")) != -1) {
+ switch (ch) {
+ case 'A':
+ /* compatibility */
+ aflag = oflag = 1;
+ break;
+ case 'a':
+ aflag = 1;
+ break;
+ case 'b':
+ bflag = 1;
+ break;
+ case 'd':
+ dflag = 1;
+ break;
+ case 'e':
+ eflag = 1;
+ break;
+ case 'h':
+ hflag = 1;
+ break;
+ case 'i':
+ iflag = 1;
+ break;
+ case 'N':
+ Nflag = 1;
+ break;
+ case 'n':
+ nflag = 1;
+ break;
+ case 'o':
+ oflag = 1;
+ break;
+ case 'q':
+ qflag = 1;
+ break;
+ case 'w':
+ /* compatibility */
+ /* ignored */
+ break;
+ case 'X':
+ /* compatibility */
+ aflag = xflag = 1;
+ break;
+ case 'x':
+ xflag = 1;
+ break;
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (Nflag && nflag)
+ usage();
+ if (aflag && argc == 0)
+ exit(sysctl_all(0, 0));
+ if (argc == 0)
+ usage();
+
+ warncount = 0;
+ while (argc-- > 0)
+ parse(*argv++);
+ exit(warncount);
+}
+
+/*
+ * Parse a name into a MIB entry.
+ * Lookup and print out the MIB entry if it exists.
+ * Set a new value if requested.
+ */
+static void
+parse(const char *string)
+{
+ int len, i, j;
+ void *newval = 0;
+ int intval;
+ unsigned int uintval;
+ long longval;
+ unsigned long ulongval;
+ size_t newsize = 0;
+ int64_t i64val;
+ uint64_t u64val;
+ int mib[CTL_MAXNAME];
+ char *cp, *bufp, buf[BUFSIZ], *endptr, fmt[BUFSIZ];
+ u_int kind;
+
+ cp = buf;
+ if (snprintf(buf, BUFSIZ, "%s", string) >= BUFSIZ)
+ errx(1, "oid too long: '%s'", string);
+ bufp = strsep(&cp, "=");
+ if (cp != NULL) {
+ while (isspace(*cp))
+ cp++;
+ newval = cp;
+ newsize = strlen(cp);
+ }
+ len = name2oid(bufp, mib);
+
+ if (len < 0) {
+ if (iflag)
+ return;
+ if (qflag)
+ exit(1);
+ else
+ errx(1, "unknown oid '%s'", bufp);
+ }
+
+ if (oidfmt(mib, len, fmt, &kind))
+ err(1, "couldn't find format of oid '%s'", bufp);
+
+ if (newval == NULL || dflag) {
+ if ((kind & CTLTYPE) == CTLTYPE_NODE) {
+ if (dflag) {
+ i = show_var(mib, len);
+ if (!i && !bflag)
+ putchar('\n');
+ }
+ sysctl_all(mib, len);
+ } else {
+ i = show_var(mib, len);
+ if (!i && !bflag)
+ putchar('\n');
+ }
+ } else {
+ if ((kind & CTLTYPE) == CTLTYPE_NODE)
+ errx(1, "oid '%s' isn't a leaf node", bufp);
+
+ if (!(kind & CTLFLAG_WR)) {
+ if (kind & CTLFLAG_TUN) {
+ warnx("oid '%s' is a read only tunable", bufp);
+ errx(1, "Tunable values are set in /boot/loader.conf");
+ } else {
+ errx(1, "oid '%s' is read only", bufp);
+ }
+ }
+
+ if ((kind & CTLTYPE) == CTLTYPE_INT ||
+ (kind & CTLTYPE) == CTLTYPE_UINT ||
+ (kind & CTLTYPE) == CTLTYPE_LONG ||
+ (kind & CTLTYPE) == CTLTYPE_ULONG ||
+ (kind & CTLTYPE) == CTLTYPE_S64 ||
+ (kind & CTLTYPE) == CTLTYPE_U64) {
+ if (strlen(newval) == 0)
+ errx(1, "empty numeric value");
+ }
+
+ switch (kind & CTLTYPE) {
+ case CTLTYPE_INT:
+ if (strcmp(fmt, "IK") == 0) {
+ if (!set_IK(newval, &intval))
+ errx(1, "invalid value '%s'",
+ (char *)newval);
+ } else {
+ intval = (int)strtol(newval, &endptr,
+ 0);
+ if (endptr == newval || *endptr != '\0')
+ errx(1, "invalid integer '%s'",
+ (char *)newval);
+ }
+ newval = &intval;
+ newsize = sizeof(intval);
+ break;
+ case CTLTYPE_UINT:
+ uintval = (int) strtoul(newval, &endptr, 0);
+ if (endptr == newval || *endptr != '\0')
+ errx(1, "invalid unsigned integer '%s'",
+ (char *)newval);
+ newval = &uintval;
+ newsize = sizeof(uintval);
+ break;
+ case CTLTYPE_LONG:
+ longval = strtol(newval, &endptr, 0);
+ if (endptr == newval || *endptr != '\0')
+ errx(1, "invalid long integer '%s'",
+ (char *)newval);
+ newval = &longval;
+ newsize = sizeof(longval);
+ break;
+ case CTLTYPE_ULONG:
+ ulongval = strtoul(newval, &endptr, 0);
+ if (endptr == newval || *endptr != '\0')
+ errx(1, "invalid unsigned long integer"
+ " '%s'", (char *)newval);
+ newval = &ulongval;
+ newsize = sizeof(ulongval);
+ break;
+ case CTLTYPE_STRING:
+ break;
+ case CTLTYPE_S64:
+ i64val = strtoimax(newval, &endptr, 0);
+ if (endptr == newval || *endptr != '\0')
+ errx(1, "invalid int64_t '%s'",
+ (char *)newval);
+ newval = &i64val;
+ newsize = sizeof(i64val);
+ break;
+ case CTLTYPE_U64:
+ u64val = strtoumax(newval, &endptr, 0);
+ if (endptr == newval || *endptr != '\0')
+ errx(1, "invalid uint64_t '%s'",
+ (char *)newval);
+ newval = &u64val;
+ newsize = sizeof(u64val);
+ break;
+ case CTLTYPE_OPAQUE:
+ /* FALLTHROUGH */
+ default:
+ errx(1, "oid '%s' is type %d,"
+ " cannot set that", bufp,
+ kind & CTLTYPE);
+ }
+
+ i = show_var(mib, len);
+ if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
+ if (!i && !bflag)
+ putchar('\n');
+ switch (errno) {
+ case EOPNOTSUPP:
+ errx(1, "%s: value is not available",
+ string);
+ case ENOTDIR:
+ errx(1, "%s: specification is incomplete",
+ string);
+ case ENOMEM:
+ errx(1, "%s: type is unknown to this program",
+ string);
+ default:
+ warn("%s", string);
+ warncount++;
+ return;
+ }
+ }
+ if (!bflag)
+ printf(" -> ");
+ i = nflag;
+ nflag = 1;
+ j = show_var(mib, len);
+ if (!j && !bflag)
+ putchar('\n');
+ nflag = i;
+ }
+}
+
+/* These functions will dump out various interesting structures. */
+
+static int
+S_clockinfo(int l2, void *p)
+{
+#ifndef __rtems__
+ struct clockinfo *ci = (struct clockinfo*)p;
+
+ if (l2 != sizeof(*ci)) {
+ warnx("S_clockinfo %d != %zu", l2, sizeof(*ci));
+ return (1);
+ }
+ printf(hflag ? "{ hz = %'d, tick = %'d, profhz = %'d, stathz = %'d }" :
+ "{ hz = %d, tick = %d, profhz = %d, stathz = %d }",
+ ci->hz, ci->tick, ci->profhz, ci->stathz);
+#endif /* __rtems__ */
+ return (0);
+}
+
+static int
+S_loadavg(int l2, void *p)
+{
+ struct loadavg *tv = (struct loadavg*)p;
+
+ if (l2 != sizeof(*tv)) {
+ warnx("S_loadavg %d != %zu", l2, sizeof(*tv));
+ return (1);
+ }
+ printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }",
+ (double)tv->ldavg[0]/(double)tv->fscale,
+ (double)tv->ldavg[1]/(double)tv->fscale,
+ (double)tv->ldavg[2]/(double)tv->fscale);
+ return (0);
+}
+
+static int
+S_timeval(int l2, void *p)
+{
+ struct timeval *tv = (struct timeval*)p;
+ time_t tv_sec;
+ char *p1, *p2;
+
+ if (l2 != sizeof(*tv)) {
+ warnx("S_timeval %d != %zu", l2, sizeof(*tv));
+ return (1);
+ }
+ printf(hflag ? "{ sec = %'jd, usec = %'ld } " :
+ "{ sec = %jd, usec = %ld } ",
+ (intmax_t)tv->tv_sec, tv->tv_usec);
+ tv_sec = tv->tv_sec;
+ p1 = strdup(ctime(&tv_sec));
+ for (p2=p1; *p2 ; p2++)
+ if (*p2 == '\n')
+ *p2 = '\0';
+ fputs(p1, stdout);
+ free(p1);
+ return (0);
+}
+
+static int
+S_vmtotal(int l2, void *p)
+{
+ struct vmtotal *v = (struct vmtotal *)p;
+ int pageKilo = getpagesize() / 1024;
+
+ if (l2 != sizeof(*v)) {
+ warnx("S_vmtotal %d != %zu", l2, sizeof(*v));
+ return (1);
+ }
+
+ printf(
+ "\nSystem wide totals computed every five seconds:"
+ " (values in kilobytes)\n");
+ printf("===============================================\n");
+ printf(
+ "Processes:\t\t(RUNQ: %hd Disk Wait: %hd Page Wait: "
+ "%hd Sleep: %hd)\n",
+ v->t_rq, v->t_dw, v->t_pw, v->t_sl);
+ printf(
+ "Virtual Memory:\t\t(Total: %dK Active: %dK)\n",
+ v->t_vm * pageKilo, v->t_avm * pageKilo);
+ printf("Real Memory:\t\t(Total: %dK Active: %dK)\n",
+ v->t_rm * pageKilo, v->t_arm * pageKilo);
+ printf("Shared Virtual Memory:\t(Total: %dK Active: %dK)\n",
+ v->t_vmshr * pageKilo, v->t_avmshr * pageKilo);
+ printf("Shared Real Memory:\t(Total: %dK Active: %dK)\n",
+ v->t_rmshr * pageKilo, v->t_armshr * pageKilo);
+ printf("Free Memory:\t%dK\n", v->t_free * pageKilo);
+
+ return (0);
+}
+
+static int
+set_IK(const char *str, int *val)
+{
+ float temp;
+ int len, kelv;
+ const char *p;
+ char *endptr;
+
+ if ((len = strlen(str)) == 0)
+ return (0);
+ p = &str[len - 1];
+ if (*p == 'C' || *p == 'F') {
+ temp = strtof(str, &endptr);
+ if (endptr == str || endptr != p)
+ return (0);
+ if (*p == 'F')
+ temp = (temp - 32) * 5 / 9;
+ kelv = temp * 10 + 2732;
+ } else {
+ kelv = (int)strtol(str, &endptr, 10);
+ if (endptr == str || *endptr != '\0')
+ return (0);
+ }
+ *val = kelv;
+ return (1);
+}
+
+/*
+ * These functions uses a presently undocumented interface to the kernel
+ * to walk the tree and get the type so it can print the value.
+ * This interface is under work and consideration, and should probably
+ * be killed with a big axe by the first person who can find the time.
+ * (be aware though, that the proper interface isn't as obvious as it
+ * may seem, there are various conflicting requirements.
+ */
+
+static int
+name2oid(char *name, int *oidp)
+{
+ int oid[2];
+ int i;
+ size_t j;
+
+ oid[0] = 0;
+ oid[1] = 3;
+
+ j = CTL_MAXNAME * sizeof(int);
+ i = sysctl(oid, 2, oidp, &j, name, strlen(name));
+ if (i < 0)
+ return (i);
+ j /= sizeof(int);
+ return (j);
+}
+
+static int
+oidfmt(int *oid, int len, char *fmt, u_int *kind)
+{
+ int qoid[CTL_MAXNAME+2];
+ u_char buf[BUFSIZ];
+ int i;
+ size_t j;
+
+ qoid[0] = 0;
+ qoid[1] = 4;
+ memcpy(qoid + 2, oid, len * sizeof(int));
+
+ j = sizeof(buf);
+ i = sysctl(qoid, len + 2, buf, &j, 0, 0);
+ if (i)
+ err(1, "sysctl fmt %d %zu %d", i, j, errno);
+
+ if (kind)
+ *kind = *(u_int *)buf;
+
+ if (fmt)
+ strcpy(fmt, (char *)(buf + sizeof(u_int)));
+ return (0);
+}
+
+static int ctl_sign[CTLTYPE+1] = {
+ [CTLTYPE_INT] = 1,
+ [CTLTYPE_LONG] = 1,
+ [CTLTYPE_S64] = 1,
+};
+
+static int ctl_size[CTLTYPE+1] = {
+ [CTLTYPE_INT] = sizeof(int),
+ [CTLTYPE_UINT] = sizeof(u_int),
+ [CTLTYPE_LONG] = sizeof(long),
+ [CTLTYPE_ULONG] = sizeof(u_long),
+ [CTLTYPE_S64] = sizeof(int64_t),
+ [CTLTYPE_U64] = sizeof(int64_t),
+};
+
+/*
+ * This formats and outputs the value of one variable
+ *
+ * Returns zero if anything was actually output.
+ * Returns one if didn't know what to do with this.
+ * Return minus one if we had errors.
+ */
+static int
+show_var(int *oid, int nlen)
+{
+ u_char buf[BUFSIZ], *val, *oval, *p;
+ char name[BUFSIZ], *fmt;
+ const char *sep, *sep1;
+ int qoid[CTL_MAXNAME+2];
+ uintmax_t umv;
+ intmax_t mv;
+ int i, hexlen, sign, ctltype;
+ size_t intlen;
+ size_t j, len;
+ u_int kind;
+ int (*func)(int, void *);
+
+ /* Silence GCC. */
+ umv = mv = intlen = 0;
+
+ bzero(buf, BUFSIZ);
+ bzero(name, BUFSIZ);
+ qoid[0] = 0;
+ memcpy(qoid + 2, oid, nlen * sizeof(int));
+
+ qoid[1] = 1;
+ j = sizeof(name);
+ i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
+ if (i || !j)
+ err(1, "sysctl name %d %zu %d", i, j, errno);
+
+ if (Nflag) {
+ printf("%s", name);
+ return (0);
+ }
+
+ if (eflag)
+ sep = "=";
+ else
+ sep = ": ";
+
+ if (dflag) { /* just print description */
+ qoid[1] = 5;
+ j = sizeof(buf);
+ i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
+ if (!nflag)
+ printf("%s%s", name, sep);
+ printf("%s", buf);
+ return (0);
+ }
+ /* find an estimate of how much we need for this var */
+ j = 0;
+ i = sysctl(oid, nlen, 0, &j, 0, 0);
+ j += j; /* we want to be sure :-) */
+
+ val = oval = malloc(j + 1);
+ if (val == NULL) {
+ warnx("malloc failed");
+ return (1);
+ }
+ len = j;
+ i = sysctl(oid, nlen, val, &len, 0, 0);
+ if (i || !len) {
+ free(oval);
+ return (1);
+ }
+
+ if (bflag) {
+ fwrite(val, 1, len, stdout);
+ free(oval);
+ return (0);
+ }
+ val[len] = '\0';
+ fmt = buf;
+ oidfmt(oid, nlen, fmt, &kind);
+ p = val;
+ ctltype = (kind & CTLTYPE);
+ sign = ctl_sign[ctltype];
+ intlen = ctl_size[ctltype];
+
+ switch (ctltype) {
+ case CTLTYPE_STRING:
+ if (!nflag)
+ printf("%s%s", name, sep);
+ printf("%.*s", (int)len, p);
+ free(oval);
+ return (0);
+
+ case CTLTYPE_INT:
+ case CTLTYPE_UINT:
+ case CTLTYPE_LONG:
+ case CTLTYPE_ULONG:
+ case CTLTYPE_S64:
+ case CTLTYPE_U64:
+ if (!nflag)
+ printf("%s%s", name, sep);
+ hexlen = 2 + (intlen * CHAR_BIT + 3) / 4;
+ sep1 = "";
+ while (len >= intlen) {
+ switch (kind & CTLTYPE) {
+ case CTLTYPE_INT:
+ case CTLTYPE_UINT:
+ umv = *(u_int *)p;
+ mv = *(int *)p;
+ break;
+ case CTLTYPE_LONG:
+ case CTLTYPE_ULONG:
+ umv = *(u_long *)p;
+ mv = *(long *)p;
+ break;
+ case CTLTYPE_S64:
+ case CTLTYPE_U64:
+ umv = *(uint64_t *)p;
+ mv = *(int64_t *)p;
+ break;
+ }
+ fputs(sep1, stdout);
+ if (xflag)
+ printf("%#0*jx", hexlen, umv);
+ else if (!sign)
+ printf(hflag ? "%'ju" : "%ju", umv);
+ else if (fmt[1] == 'K') {
+ if (mv < 0)
+ printf("%jd", mv);
+ else
+ printf("%.1fC", (mv - 2732.0) / 10);
+ } else
+ printf(hflag ? "%'jd" : "%jd", mv);
+ sep1 = " ";
+ len -= intlen;
+ p += intlen;
+ }
+ free(oval);
+ return (0);
+
+ case CTLTYPE_OPAQUE:
+ i = 0;
+ if (strcmp(fmt, "S,clockinfo") == 0)
+ func = S_clockinfo;
+ else if (strcmp(fmt, "S,timeval") == 0)
+ func = S_timeval;
+ else if (strcmp(fmt, "S,loadavg") == 0)
+ func = S_loadavg;
+ else if (strcmp(fmt, "S,vmtotal") == 0)
+ func = S_vmtotal;
+ else
+ func = NULL;
+ if (func) {
+ if (!nflag)
+ printf("%s%s", name, sep);
+ i = (*func)(len, p);
+ free(oval);
+ return (i);
+ }
+ /* FALLTHROUGH */
+ default:
+ if (!oflag && !xflag) {
+ free(oval);
+ return (1);
+ }
+ if (!nflag)
+ printf("%s%s", name, sep);
+ printf("Format:%s Length:%zu Dump:0x", fmt, len);
+ while (len-- && (xflag || p < val + 16))
+ printf("%02x", *p++);
+ if (!xflag && len > 16)
+ printf("...");
+ free(oval);
+ return (0);
+ }
+ free(oval);
+ return (1);
+}
+
+static int
+sysctl_all(int *oid, int len)
+{
+ int name1[22], name2[22];
+ int i, j;
+ size_t l1, l2;
+
+ name1[0] = 0;
+ name1[1] = 2;
+ l1 = 2;
+ if (len) {
+ memcpy(name1+2, oid, len * sizeof(int));
+ l1 += len;
+ } else {
+ name1[2] = 1;
+ l1++;
+ }
+ for (;;) {
+ l2 = sizeof(name2);
+ j = sysctl(name1, l1, name2, &l2, 0, 0);
+ if (j < 0) {
+ if (errno == ENOENT)
+ return (0);
+ else
+ err(1, "sysctl(getnext) %d %zu", j, l2);
+ }
+
+ l2 /= sizeof(int);
+
+ if (len < 0 || l2 < (unsigned int)len)
+ return (0);
+
+ for (i = 0; i < len; i++)
+ if (name2[i] != oid[i])
+ return (0);
+
+ i = show_var(name2, l2);
+ if (!i && !bflag)
+ putchar('\n');
+
+ memcpy(name1+2, name2, l2 * sizeof(int));
+ l1 = 2 + l2;
+ }
+}
diff --git a/libbsd.py b/libbsd.py
index 75fb2ec3..b0ed161c 100755
--- a/libbsd.py
+++ b/libbsd.py
@@ -1952,7 +1952,9 @@ def user_space(mm):
'lib/libc/resolv/res_state.c',
'lib/libc/resolv/res_update.c',
'lib/libc/stdio/fgetln.c',
+ 'lib/libc/stdlib/strtoimax.c',
'lib/libc/stdlib/strtonum.c',
+ 'lib/libc/stdlib/strtoumax.c',
'lib/libc/string/strsep.c',
'lib/libipsec/ipsec_dump_policy.c',
'lib/libipsec/ipsec_get_policylen.c',
@@ -2002,6 +2004,7 @@ def user_space(mm):
'sbin/ping6/ping6.c',
'sbin/ping/ping.c',
'sbin/route/route.c',
+ 'sbin/sysctl/sysctl.c',
'usr.bin/netstat/atalk.c',
'usr.bin/netstat/bpf.c',
'usr.bin/netstat/if.c',
diff --git a/libbsd_waf.py b/libbsd_waf.py
index 93cf6062..1f50306b 100644
--- a/libbsd_waf.py
+++ b/libbsd_waf.py
@@ -283,7 +283,9 @@ def build(bld):
'freebsd/lib/libc/resolv/res_state.c',
'freebsd/lib/libc/resolv/res_update.c',
'freebsd/lib/libc/stdio/fgetln.c',
+ 'freebsd/lib/libc/stdlib/strtoimax.c',
'freebsd/lib/libc/stdlib/strtonum.c',
+ 'freebsd/lib/libc/stdlib/strtoumax.c',
'freebsd/lib/libc/string/strsep.c',
'freebsd/lib/libipsec/ipsec_dump_policy.c',
'freebsd/lib/libipsec/ipsec_get_policylen.c',
@@ -333,6 +335,7 @@ def build(bld):
'freebsd/sbin/ping/ping.c',
'freebsd/sbin/ping6/ping6.c',
'freebsd/sbin/route/route.c',
+ 'freebsd/sbin/sysctl/sysctl.c',
'freebsd/usr.bin/netstat/atalk.c',
'freebsd/usr.bin/netstat/bpf.c',
'freebsd/usr.bin/netstat/if.c',
diff --git a/rtemsbsd/include/machine/rtems-bsd-commands.h b/rtemsbsd/include/machine/rtems-bsd-commands.h
index df251787..8fd865e8 100644
--- a/rtemsbsd/include/machine/rtems-bsd-commands.h
+++ b/rtemsbsd/include/machine/rtems-bsd-commands.h
@@ -60,6 +60,8 @@ int rtems_bsd_command_dhcpcd(int argc, char **argv);
int rtems_bsd_command_tcpdump(int argc, char **argv);
+int rtems_bsd_command_sysctl(int argc, char **argv);
+
__END_DECLS
#endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_COMMANDS_H_ */
diff --git a/rtemsbsd/include/rtems/netcmds-config.h b/rtemsbsd/include/rtems/netcmds-config.h
index f69b17b5..d2d15ea2 100644
--- a/rtemsbsd/include/rtems/netcmds-config.h
+++ b/rtemsbsd/include/rtems/netcmds-config.h
@@ -37,6 +37,8 @@ extern rtems_shell_cmd_t rtems_shell_HOSTNAME_Command;
extern rtems_shell_cmd_t rtems_shell_TCPDUMP_Command;
+extern rtems_shell_cmd_t rtems_shell_SYSCTL_Command;
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/rtemsbsd/rtems/rtems-bsd-shell-netcmds.c b/rtemsbsd/rtems/rtems-bsd-shell-netcmds.c
index e6eea024..1271ff36 100644
--- a/rtemsbsd/rtems/rtems-bsd-shell-netcmds.c
+++ b/rtemsbsd/rtems/rtems-bsd-shell-netcmds.c
@@ -54,3 +54,12 @@ rtems_shell_cmd_t rtems_shell_TCPDUMP_Command = {
NULL, /* alias */
NULL /* next */
};
+
+rtems_shell_cmd_t rtems_shell_SYSCTL_Command = {
+ "sysctl", /* name */
+ "sysctl [-bdehiNnoRTqx] [-f filename] name[=value] ...", /* usage */
+ "net", /* topic */
+ rtems_bsd_command_sysctl, /* command */
+ NULL, /* alias */
+ NULL /* next */
+};
diff --git a/testsuite/include/rtems/bsd/test/default-network-init.h b/testsuite/include/rtems/bsd/test/default-network-init.h
index 380d5aaa..e93ee8e9 100644
--- a/testsuite/include/rtems/bsd/test/default-network-init.h
+++ b/testsuite/include/rtems/bsd/test/default-network-init.h
@@ -342,7 +342,8 @@ SYSINIT_NEED_NET_IF_VLAN;
&rtems_shell_ROUTE_Command, \
&rtems_shell_NETSTAT_Command, \
&rtems_shell_IFCONFIG_Command, \
- &rtems_shell_TCPDUMP_Command
+ &rtems_shell_TCPDUMP_Command, \
+ &rtems_shell_SYSCTL_Command
#define CONFIGURE_SHELL_COMMAND_CPUUSE
#define CONFIGURE_SHELL_COMMAND_PERIODUSE