diff options
author | Ian Moffett <ian@osmora.org> | 2025-08-06 13:44:16 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-08-06 13:44:16 -0400 |
commit | 5bcddc5da132eb0eed462580f5a29b42ea34737d (patch) | |
tree | 0a65aa82c6a0ff7f6c99019b5d8d1fca6284604f | |
parent | 7895cfcd1f902c036cdb7207637269af4aa6c02f (diff) |
usr.bin: Add 'sysctl' program
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r-- | usr.bin/Makefile | 1 | ||||
-rw-r--r-- | usr.bin/sysctl/Makefile | 6 | ||||
-rw-r--r-- | usr.bin/sysctl/sysctl.c | 139 |
3 files changed, 146 insertions, 0 deletions
diff --git a/usr.bin/Makefile b/usr.bin/Makefile index d8bf421..47ba752 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -26,3 +26,4 @@ all: make -C oasm/ $(ARGS) make -C oemu/ $(ARGS) make -C dmidump/ $(ARGS) + make -C sysctl/ $(ARGS) diff --git a/usr.bin/sysctl/Makefile b/usr.bin/sysctl/Makefile new file mode 100644 index 0000000..e32dbc4 --- /dev/null +++ b/usr.bin/sysctl/Makefile @@ -0,0 +1,6 @@ +include user.mk + +CFILES = $(shell find . -name "*.c") + +$(ROOT)/base/usr/bin/sysctl: + gcc $(CFILES) -o $@ $(INTERNAL_CFLAGS) diff --git a/usr.bin/sysctl/sysctl.c b/usr.bin/sysctl/sysctl.c new file mode 100644 index 0000000..a23bfe8 --- /dev/null +++ b/usr.bin/sysctl/sysctl.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * 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. + * 3. Neither the name of Hyra 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +#include <sys/sysctl.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#define NAME_OSTYPE "ostype" +#define NAME_OSRELEASE "osrelease" +#define NAME_VERSION "version" +#define NAME_VCACHE_TYPE "vcache_type" + +/* + * Convert string name to a sysctl name + * definition. + * + * @name: Name to convert + * + * Convert to int def + * / + * kern.ostype + * ^^ name + * + * -- + * Returns a less than zero value on failure + * (e.g., entry not found). + */ +static int +name_to_def(const char *name) +{ + switch (*name) { + case 'v': + if (strcmp(name, NAME_VERSION) == 0) { + return KERN_VERSION; + } + + if (strcmp(name, NAME_VCACHE_TYPE) == 0) { + return KERN_VCACHE_TYPE; + } + + return -1; + case 'o': + if (strcmp(name, NAME_OSTYPE) == 0) { + return KERN_OSTYPE; + } + + if (strcmp(name, NAME_OSRELEASE) == 0) { + return KERN_OSRELEASE; + } + + return -1; + } + + return -1; +} + +int +main(int argc, char **argv) +{ + struct sysctl_args args; + char *var, *p; + int type, name, error; + size_t oldlen; + char buf[128]; + + if (argc < 2) { + printf("sysctl: usage: sysctl <var>\n"); + return -1; + } + + var = argv[1]; + p = strtok(var, "."); + + if (p == NULL) { + printf("sysctl: bad var\n"); + return -1; + } + + /* TODO: Non kern.* vars */ + if (strcmp(p, "kern") != 0) { + printf("unknown var \"%s\"\n", p); + return -1; + } + + p = strtok(NULL, "."); + if (p == NULL) { + printf("sysctl: bad var \"%s\"\n", p); + return -1; + } + + if ((name = name_to_def(p)) < 0) { + printf("sysctl: bad var \"%s\"\n", p); + return name; + } + + name = name; + oldlen = sizeof(buf); + args.name = &name; + args.nlen = 1; + args.oldp = buf; + args.oldlenp = &oldlen; + args.newp = NULL; + args.newlen = 0; + + if ((error = sysctl(&args)) != 0) { + printf("sysctl returned %d\n", error); + return error; + } + + printf("%s\n", buf); + return 0; +} |