summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--etc/hostname1
-rw-r--r--lib/libc/include/ctype.h1
-rw-r--r--lib/libc/include/unistd.h3
-rw-r--r--lib/libc/src/hyra/sysctl.c38
-rw-r--r--lib/libc/src/unistd/hostname.c125
-rw-r--r--share/man/man1/cat.17
-rw-r--r--sys/arch/amd64/amd64/mp.c2
-rw-r--r--sys/include/sys/sysctl.h12
-rw-r--r--sys/include/sys/systm.h1
-rw-r--r--sys/kern/init_main.c3
-rw-r--r--sys/kern/kern_cpu.c61
-rw-r--r--sys/kern/kern_descrip.c2
-rw-r--r--sys/kern/kern_sysctl.c77
-rw-r--r--sys/kern/vfs_vcache.c2
-rw-r--r--usr.bin/Makefile1
-rw-r--r--usr.bin/fetch/fetch.c67
-rw-r--r--usr.bin/osh/osh.c6
-rw-r--r--usr.bin/sysctl/Makefile6
-rw-r--r--usr.bin/sysctl/sysctl.c279
-rw-r--r--usr.sbin/init/main.c42
21 files changed, 707 insertions, 31 deletions
diff --git a/configure.ac b/configure.ac
index 6db3a09..50c56b4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([Hyra], [2.5], [ian@osmora.org])
+AC_INIT([Hyra], [2.6], [ian@osmora.org])
TARGET="amd64"
QEMU="qemu-system-x86_64"
diff --git a/etc/hostname b/etc/hostname
new file mode 100644
index 0000000..c90b108
--- /dev/null
+++ b/etc/hostname
@@ -0,0 +1 @@
+osmora
diff --git a/lib/libc/include/ctype.h b/lib/libc/include/ctype.h
index 2348852..0ff9a43 100644
--- a/lib/libc/include/ctype.h
+++ b/lib/libc/include/ctype.h
@@ -72,6 +72,7 @@ __isspace(int c)
return 1;
return 0;
+ }
}
__END_DECLS
diff --git a/lib/libc/include/unistd.h b/lib/libc/include/unistd.h
index 8b03b81..21206ad 100644
--- a/lib/libc/include/unistd.h
+++ b/lib/libc/include/unistd.h
@@ -47,6 +47,9 @@ __BEGIN_DECLS
int sysconf(int name);
int setuid(uid_t new);
+int gethostname(char *name, size_t size);
+int sethostname(const char *name, size_t size);
+
uid_t getuid(void);
char *getlogin(void);
diff --git a/lib/libc/src/hyra/sysctl.c b/lib/libc/src/hyra/sysctl.c
new file mode 100644
index 0000000..2903e6f
--- /dev/null
+++ b/lib/libc/src/hyra/sysctl.c
@@ -0,0 +1,38 @@
+/*
+ * 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/types.h>
+#include <sys/syscall.h>
+#include <sys/sysctl.h>
+
+int
+sysctl(struct sysctl_args *args)
+{
+ return syscall(SYS_sysctl, (uintptr_t)args);
+}
diff --git a/lib/libc/src/unistd/hostname.c b/lib/libc/src/unistd/hostname.c
new file mode 100644
index 0000000..60df9a0
--- /dev/null
+++ b/lib/libc/src/unistd/hostname.c
@@ -0,0 +1,125 @@
+/*
+ * 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 <unistd.h>
+
+/*
+ * Internal helper to grab a sysctl
+ * variable.
+ *
+ * @name: Name definition of sysctl variable
+ * @buf: Buffer to read data in
+ * @buflen: Length of buffer
+ *
+ * Returns zero on success, otherwise a less than
+ * zero value.
+ */
+static int
+__sysctl_get(int name, char *buf, size_t buflen)
+{
+ struct sysctl_args args;
+ int error;
+
+ args.name = &name;
+ args.nlen = 1;
+ args.oldp = buf;
+ args.oldlenp = &buflen;
+ args.newp = NULL;
+ args.newlen = 0;
+
+ if ((error = sysctl(&args)) != 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Internal helper to set a sysctl
+ * variable.
+ *
+ * @name: Name definition of sysctl variable
+ * @buf: Buffer with data to set
+ * @buflen: Length of buffer
+ *
+ * Returns zero on success, otherwise a less than
+ * zero value.
+ */
+static int
+__sysctl_set(int name, const char *buf, size_t buflen)
+{
+ struct sysctl_args args;
+ int error;
+
+ args.name = &name;
+ args.nlen = 1;
+ args.oldp = NULL;
+ args.oldlenp = NULL;
+ args.newp = (void *)buf;
+ args.newlen = buflen;
+
+ if ((error = sysctl(&args)) != 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Get the system hostname
+ *
+ * @name: Buffer to read name into
+ * @size: Length of name to read
+ */
+int
+gethostname(char *name, size_t size)
+{
+ if (name == NULL || size == 0) {
+ return -1;
+ }
+
+ return __sysctl_get(KERN_HOSTNAME, name, size);
+}
+
+/*
+ * Set the system hostname
+ *
+ * @name: Name to set
+ * @size: Size of name to set
+ */
+int
+sethostname(const char *name, size_t size)
+{
+ if (name == NULL || size == 0) {
+ return -1;
+ }
+
+ return __sysctl_set(KERN_HOSTNAME, name, size);
+}
diff --git a/share/man/man1/cat.1 b/share/man/man1/cat.1
index 8214724..1759407 100644
--- a/share/man/man1/cat.1
+++ b/share/man/man1/cat.1
@@ -24,7 +24,7 @@
.\" 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.
-.Dd Jul 17 2025
+.Dd Aug 6 2025
.Dt CAT 1
.Os HYRA
.Sh NAME
@@ -39,6 +39,11 @@ The
command can be used concatenate files or simply write their contents
to standard output.
+.Bd -literal
+[-n]: Number each line
+[-b]: Number each non-blank line
+.Ed
+
.Sh SEE ALSO
mex(1)
diff --git a/sys/arch/amd64/amd64/mp.c b/sys/arch/amd64/amd64/mp.c
index 20f550f..43830ba 100644
--- a/sys/arch/amd64/amd64/mp.c
+++ b/sys/arch/amd64/amd64/mp.c
@@ -30,6 +30,7 @@
#include <sys/types.h>
#include <sys/limine.h>
#include <sys/limits.h>
+#include <sys/systm.h>
#include <sys/syslog.h>
#include <sys/proc.h>
#include <sys/spinlock.h>
@@ -149,4 +150,5 @@ mp_bootstrap_aps(struct cpu_info *ci)
/* Wait for all cores to be ready */
while ((ncpu_up - 1) < cpu_init_counter);
+ cpu_report_count(ncpu_up);
}
diff --git a/sys/include/sys/sysctl.h b/sys/include/sys/sysctl.h
index d13b0f8..3b8d3c7 100644
--- a/sys/include/sys/sysctl.h
+++ b/sys/include/sys/sysctl.h
@@ -39,10 +39,21 @@
#endif
#include <sys/param.h>
+/*
+ * List of 'kern.* ' identifiers
+ */
#define KERN_OSTYPE 0
#define KERN_OSRELEASE 1
#define KERN_VERSION 2
#define KERN_VCACHE_TYPE 3
+#define KERN_HOSTNAME 4
+
+/*
+ * List of 'hw.* ' identifiers
+ */
+#define HW_PAGESIZE 5
+#define HW_NCPU 6
+#define HW_MACHINE 7
/*
* Option types (i.e., int, string, etc) for
@@ -64,6 +75,7 @@ struct sysctl_entry {
};
scret_t sys_sysctl(struct syscall_args *scargs);
+int sysctl_clearstr(int name);
#endif /* _KERNEL */
/*
diff --git a/sys/include/sys/systm.h b/sys/include/sys/systm.h
index 42e1723..2f69175 100644
--- a/sys/include/sys/systm.h
+++ b/sys/include/sys/systm.h
@@ -39,6 +39,7 @@
int copyin(const void *uaddr, void *kaddr, size_t len);
int copyout(const void *kaddr, void *uaddr, size_t len);
int copyinstr(const void *uaddr, char *kaddr, size_t len);
+int cpu_report_count(uint32_t count);
__always_inline static inline void
__sigraise(int signo)
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index e8255bd..541355a 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -35,6 +35,7 @@
#include <sys/exec.h>
#include <sys/driver.h>
#include <sys/panic.h>
+#include <sys/sysctl.h>
#include <sys/systm.h>
#include <dev/acpi/uacpi.h>
#include <dev/cons/cons.h>
@@ -113,13 +114,13 @@ main(void)
sched_init();
memset(&g_proc0, 0, sizeof(g_proc0));
+ sysctl_clearstr(KERN_HOSTNAME);
/* Startup pid 1 */
spawn(&g_proc0, start_init, NULL, 0, &g_init);
md_inton();
/* Load all early drivers */
- driver_blacklist("ahci");
DRIVERS_INIT();
/* Only log to kmsg from here */
diff --git a/sys/kern/kern_cpu.c b/sys/kern/kern_cpu.c
new file mode 100644
index 0000000..69d44c4
--- /dev/null
+++ b/sys/kern/kern_cpu.c
@@ -0,0 +1,61 @@
+/*
+ * 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/systm.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+
+/*
+ * Report the number of processors that are online
+ * in the machine.
+ *
+ * @count: Number of processors active
+ *
+ * Returns zero on success, otherwise a less
+ * than zero value is returned.
+ */
+int
+cpu_report_count(uint32_t count)
+{
+ struct sysctl_args args;
+ int error, name = HW_NCPU;
+
+ args.name = &name;
+ args.nlen = 1;
+ args.oldlenp = 0;
+ args.oldp = NULL;
+ args.newp = &count;
+ args.newlen = sizeof(count);
+
+ if ((error = sysctl(&args)) != 0) {
+ return error;
+ }
+
+ return 0;
+}
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index c8f8357..83845f6 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -241,7 +241,7 @@ fd_rw(unsigned int fd, void *buf, size_t count, uint8_t write)
/* Increment the offset per read */
filedes->offset += n;
- retval = count;
+ retval = n;
done:
if (kbuf != NULL) {
dynfree(kbuf);
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 7679aa1..a4c16bb 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -33,12 +33,15 @@
#include <sys/errno.h>
#include <sys/systm.h>
#include <vm/dynalloc.h>
+#include <vm/vm.h>
#include <string.h>
#define HYRA_RELEASE "Hyra/" HYRA_ARCH " " \
HYRA_VERSION " " \
HYRA_BUILDDATE
+static uint32_t pagesize = DEFAULT_PAGESIZE;
+static char machine[] = HYRA_ARCH;
static char hyra[] = "Hyra";
static char hyra_version[] = HYRA_VERSION;
static char osrelease[] = HYRA_RELEASE;
@@ -49,10 +52,17 @@ static char osrelease[] = HYRA_RELEASE;
* allocated through dynalloc(9).
*/
static struct sysctl_entry common_optab[] = {
+ /* 'kern.*' */
[KERN_OSTYPE] = { KERN_OSTYPE, SYSCTL_OPTYPE_STR_RO, hyra },
[KERN_OSRELEASE] = { KERN_OSRELEASE, SYSCTL_OPTYPE_STR_RO, &osrelease },
[KERN_VERSION] = { KERN_VERSION, SYSCTL_OPTYPE_STR_RO, &hyra_version },
- [KERN_VCACHE_TYPE] = { KERN_VCACHE_TYPE, SYSCTL_OPTYPE_STR, NULL }
+ [KERN_VCACHE_TYPE] = { KERN_VCACHE_TYPE, SYSCTL_OPTYPE_STR, NULL },
+ [KERN_HOSTNAME] = { KERN_HOSTNAME, SYSCTL_OPTYPE_STR, NULL },
+
+ /* 'hw.*' */
+ [HW_PAGESIZE] = { HW_PAGESIZE, SYSCTL_OPTYPE_INT_RO, &pagesize },
+ [HW_NCPU] = { HW_NCPU, SYSCTL_OPTYPE_INT, NULL },
+ [HW_MACHINE] = {HW_MACHINE, SYSCTL_OPTYPE_STR_RO, &machine }
};
static int
@@ -91,19 +101,18 @@ static int
do_sysctl(struct sysctl_args *args)
{
struct sysctl_args new_args;
- size_t name_len, oldlenp;
+ size_t name_len = 1, oldlenp = 0;
int *name = NULL;
void *oldp = NULL, *newp = NULL;
- int retval = 0;
-
- if (args->oldlenp == NULL) {
- return -EINVAL;
- }
-
- name_len = args->nlen;
- retval = copyin(args->oldlenp, &oldlenp, sizeof(oldlenp));
- if (retval != 0) {
- goto done;
+ int retval = 0, have_oldlen = 0;
+
+ if (args->oldlenp != NULL) {
+ have_oldlen = 1;
+ name_len = args->nlen;
+ retval = copyin(args->oldlenp, &oldlenp, sizeof(oldlenp));
+ if (retval != 0) {
+ goto done;
+ }
}
/* Copy in newp if it is set */
@@ -124,25 +133,30 @@ do_sysctl(struct sysctl_args *args)
return retval;
}
- oldp = dynalloc(oldlenp);
- retval = copyin(args->oldp, oldp, oldlenp);
- if (retval != 0) {
- return retval;
+ if (oldlenp != 0) {
+ oldp = dynalloc(oldlenp);
+ retval = copyin(args->oldp, oldp, oldlenp);
+ if (retval != 0) {
+ return retval;
+ }
}
/* Prepare the arguments for the sysctl call */
new_args.name = name;
new_args.nlen = name_len;
new_args.oldp = oldp;
- new_args.oldlenp = &oldlenp;
+ new_args.oldlenp = (have_oldlen) ? &oldlenp : NULL;
new_args.newp = newp;
+ new_args.newlen = args->newlen;
retval = sysctl(&new_args);
if (retval != 0) {
goto done;
}
- copyout(oldp, args->oldp, oldlenp);
+ if (oldlenp != 0) {
+ copyout(oldp, args->oldp, oldlenp);
+ }
done:
if (name != NULL)
dynfree(name);
@@ -154,6 +168,33 @@ done:
return retval;
}
+/*
+ * Clear a writable sysctl string variable to the
+ * value of "(undef)"
+ *
+ * @name: Name to clear
+ */
+int
+sysctl_clearstr(int name)
+{
+ struct sysctl_args args;
+ char val[] = "(undef)";
+ int error;
+
+ args.name = &name;
+ args.nlen = 1;
+ args.oldlenp = 0;
+ args.oldp = NULL;
+ args.newp = val;
+ args.newlen = sizeof(val);
+
+ if ((error = sysctl(&args)) != 0) {
+ return error;
+ }
+
+ return 0;
+}
+
int
sysctl(struct sysctl_args *args)
{
diff --git a/sys/kern/vfs_vcache.c b/sys/kern/vfs_vcache.c
index 25e244c..6c08caf 100644
--- a/sys/kern/vfs_vcache.c
+++ b/sys/kern/vfs_vcache.c
@@ -161,7 +161,7 @@ vfs_vcache_migrate(int newtype)
args.oldp = NULL;
args.oldlenp = NULL;
args.newp = sysctl_val;
- args.newlen = strlen(sysctl_val);
+ args.newlen = strlen(sysctl_val) + 1;
if ((retval = sysctl(&args)) != 0) {
return retval;
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/fetch/fetch.c b/usr.bin/fetch/fetch.c
index 175cd0e..1e8ef92 100644
--- a/usr.bin/fetch/fetch.c
+++ b/usr.bin/fetch/fetch.c
@@ -30,21 +30,76 @@
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
+#include <stdlib.h>
#include <stdio.h>
-static const char *user = "unknown";
+#define CPUID(level, a, b, c, d) \
+ __ASMV("cpuid\n\t" \
+ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
+ : "0" (level))
#define ASCII_ART \
" ____ \n" \
- " | \\__\\ \n" \
- " | /\\ \\ user: %s\n" \
- " |/ \\ \\ OS: Hyra/amd64 v"_OSVER"\n" \
- " \\ R. \\ \\ arch: "_OSARCH"\n" \
+ " | \\__\\ user: %s\n" \
+ " | /\\ \\ OS: Hyra/amd64 v"_OSVER"\n" \
+ " |/ \\ \\ arch: "_OSARCH"\n" \
+ " \\ R. \\ \\ cpu: %s\n" \
" \\ I. \\ \\\n"
+
+/*
+ * Get the processor brand string
+ *
+ * @buffer: Buffer to copy branch string
+ *
+ * Returns a pointer to newly allocated memory
+ * containing the vendor string. One must ensure
+ * to call free() after use.
+ */
+static char *
+get_brand(void)
+{
+ uint32_t eax, ebx, ecx, edx;
+ uint32_t regs[12];
+ char buf[sizeof(regs) + 1];
+ char *p = buf;
+
+ /* Can we even get the brand? */
+ CPUID(0x80000000, eax, ebx, ecx, edx);
+ if (eax < 0x80000004) {
+ return NULL;
+ }
+
+ CPUID(0x80000002, regs[0], regs[1], regs[2], regs[3]);
+ CPUID(0x80000003, regs[4], regs[5], regs[6], regs[7]);
+ CPUID(0x80000004, regs[8], regs[9], regs[10], regs[11]);
+
+ /* Log it */
+ memcpy(p, regs, sizeof(regs));
+ buf[sizeof(regs)] = '\0';
+
+ /* Strip away leading whitespaces */
+ for (int i = 0; i < sizeof(buf); ++i) {
+ if (buf[i] == ' ') {
+ ++p;
+ } else {
+ break;
+ }
+ }
+
+ return strdup(p);
+}
+
int
main(void)
{
- printf(ASCII_ART, getlogin());
+ char *brand = get_brand();
+
+ if (brand == NULL) {
+ brand = strdup("unknown");
+ }
+
+ printf(ASCII_ART, getlogin(), brand);
+ free(brand);
return 0;
}
diff --git a/usr.bin/osh/osh.c b/usr.bin/osh/osh.c
index 545f95a..5062e64 100644
--- a/usr.bin/osh/osh.c
+++ b/usr.bin/osh/osh.c
@@ -67,7 +67,7 @@
"clear - Clear the screen\n" \
"exit - Exit the shell"
-#define PROMPT "[%s::osmora]~ "
+#define PROMPT "[%s::%s]~ "
static char last_command[INPUT_SIZE];
static char buf[INPUT_SIZE];
@@ -466,6 +466,7 @@ main(int argc, char **argv)
{
int found, prog_argc;
int stdout_fd;
+ char hostname[128] = "osmora";
uint8_t buf_i;
char *p;
char c;
@@ -478,9 +479,10 @@ main(int argc, char **argv)
running = 1;
bell_fd = open("/dev/beep", O_WRONLY);
dump_file("/etc/motd");
+ gethostname(hostname, sizeof(hostname));
while (running) {
- printf(PROMPT, getlogin());
+ printf(PROMPT, getlogin(), hostname);
buf_i = getstr();
if (buf[0] == '\0') {
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..d4275a7
--- /dev/null
+++ b/usr.bin/sysctl/sysctl.c
@@ -0,0 +1,279 @@
+/*
+ * 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>
+#include <stdbool.h>
+
+#define BUF_SIZE 128
+
+/* Kern var string constants */
+#define NAME_OSTYPE "ostype"
+#define NAME_OSRELEASE "osrelease"
+#define NAME_VERSION "version"
+#define NAME_VCACHE_TYPE "vcache_type"
+
+/* Hw var string constants */
+#define NAME_PAGESIZE "pagesize"
+#define NAME_NCPU "ncpu"
+#define NAME_MACHINE "machine"
+
+/* Name start string constants */
+#define NAME_KERN "kern"
+#define NAME_HW "hw"
+
+/* Name start int constants */
+#define NAME_DEF_KERN 0
+#define NAME_DEF_HW 1
+
+/*
+ * Print the contents read from a sysctl
+ * variable depending on its type.
+ *
+ * @data: Data to print
+ * @is_str: True if a string
+ */
+static inline void
+varbuf_print(char data[BUF_SIZE], bool is_str)
+{
+ uint32_t *val;
+
+ if (is_str) {
+ printf("%s\n", data);
+ } else {
+ val = (uint32_t *)data;
+ printf("%d\n", *val);
+ }
+}
+
+/*
+ * Convert string name to a internal name
+ * definition.
+ *
+ * @name: Name to convert
+ *
+ * Convert to int def
+ * /
+ * kern.ostype
+ * ^^
+ *
+ * --
+ * Returns a less than zero value on failure
+ * (e.g., entry not found).
+ */
+static int
+name_to_def(const char *name)
+{
+ switch (*name) {
+ case 'k':
+ if (strcmp(name, NAME_KERN) == 0) {
+ return NAME_DEF_KERN;
+ }
+
+ return -1;
+ case 'h':
+ if (strcmp(name, NAME_HW) == 0) {
+ return NAME_DEF_HW;
+ }
+
+ return -1;
+ }
+
+ return -1;
+}
+
+/*
+ * Handle parsing of 'kern.*' node names
+ *
+ * @node: Node name to parse
+ * @is_str: Set to true if string
+ */
+static int
+kern_node(const char *node, bool *is_str)
+{
+ switch (*node) {
+ case 'v':
+ if (strcmp(node, NAME_VERSION) == 0) {
+ return KERN_VERSION;
+ }
+
+ if (strcmp(node, NAME_VCACHE_TYPE) == 0) {
+ return KERN_VCACHE_TYPE;
+ }
+ return -1;
+ case 'o':
+ if (strcmp(node, NAME_OSTYPE) == 0) {
+ return KERN_OSTYPE;
+ }
+
+ if (strcmp(node, NAME_OSRELEASE) == 0) {
+ return KERN_OSRELEASE;
+ }
+ return -1;
+ }
+
+ return -1;
+}
+
+/*
+ * Handle parsing of 'hw.*' node names
+ *
+ * @node: Node name to parse
+ * @is_str: Set to true if string
+ */
+static int
+hw_node(const char *node, bool *is_str)
+{
+ switch (*node) {
+ case 'p':
+ if (strcmp(node, NAME_PAGESIZE) == 0) {
+ *is_str = false;
+ return HW_PAGESIZE;
+ }
+
+ return -1;
+ case 'n':
+ if (strcmp(node, NAME_NCPU) == 0) {
+ *is_str = false;
+ return HW_NCPU;
+ }
+
+ return -1;
+ case 'm':
+ if (strcmp(node, NAME_MACHINE) == 0) {
+ return HW_MACHINE;
+ }
+ return -1;
+ }
+
+ return -1;
+}
+
+/*
+ * Convert string node to a sysctl name
+ * definition.
+ *
+ * @name: Name to convert
+ * @is_str: Set to true if string
+ *
+ * Convert to int def
+ * /
+ * kern.ostype
+ * ^^ name
+ *
+ * --
+ * Returns a less than zero value on failure
+ * (e.g., entry not found).
+ */
+static int
+node_to_def(int name, const char *node, bool *is_str)
+{
+ int retval;
+ bool dmmy;
+
+ /*
+ * If the caller did not set `is_str' just
+ * set it to a dummy value. Otherwise, we will
+ * make it *default* to a 'true' value.
+ */
+ if (is_str == NULL) {
+ is_str = &dmmy;
+ } else {
+ *is_str = true;
+ }
+
+ switch (name) {
+ case NAME_DEF_KERN:
+ return kern_node(node, is_str);
+ case NAME_DEF_HW:
+ return hw_node(node, is_str);
+ }
+
+ return -1;
+}
+
+int
+main(int argc, char **argv)
+{
+ struct sysctl_args args;
+ char *var, *p;
+ int type, error;
+ int root, name;
+ size_t oldlen;
+ bool is_str;
+ char buf[BUF_SIZE];
+
+ 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;
+ }
+
+ if ((root = name_to_def(p)) < 0) {
+ printf("sysctl: bad var \"%s\"", p);
+ return root;
+ }
+
+ p = strtok(NULL, ".");
+ if (p == NULL) {
+ printf("sysctl: bad var \"%s\"\n", p);
+ return -1;
+ }
+
+ if ((name = node_to_def(root, p, &is_str)) < 0) {
+ printf("sysctl: bad var \"%s\"\n", p);
+ return name;
+ }
+
+ memset(buf, 0, sizeof(buf));
+ 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;
+ }
+
+ varbuf_print(buf, is_str);
+ return 0;
+}
diff --git a/usr.sbin/init/main.c b/usr.sbin/init/main.c
index e1ee4d8..12bb98c 100644
--- a/usr.sbin/init/main.c
+++ b/usr.sbin/init/main.c
@@ -29,11 +29,49 @@
#include <sys/spawn.h>
#include <stddef.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#define log_trace(fmt, ...) printf("[init]: " fmt, ##__VA_ARGS__)
+#define log_error(fmt, ...) printf("[error]: " fmt, ##__VA_ARGS__)
#define SHELL_PATH "/usr/bin/osh"
#define LOGIN_PATH "/usr/bin/login"
#define INIT_RC_PATH "/usr/rc/init.rc"
+static void
+init_hostname(void)
+{
+ char hostname[128];
+ size_t len;
+ FILE *fp;
+
+ fp = fopen("/etc/hostname", "r");
+ if (fp == NULL) {
+ log_error("[init]: error opening /etc/hostname\n");
+ return;
+ }
+
+ len = fread(hostname, sizeof(char), sizeof(hostname), fp);
+ if (len == 0) {
+ log_error("[init]: error reading /etc/hostname\n");
+ fclose(fp);
+ return;
+ }
+
+ hostname[len - 1] = '\0';
+ if (sethostname(hostname, len) < 0) {
+ log_error("[init]: error setting hostname\n");
+ log_error("[init]: tried to set %s (len=%d)\n", hostname, len);
+ fclose(fp);
+ return;
+ }
+
+ log_trace("hostname -> %s\n", hostname);
+ fclose(fp);
+}
+
int
main(int argc, char **argv)
{
@@ -41,7 +79,11 @@ main(int argc, char **argv)
char *start_argv[] = { SHELL_PATH, INIT_RC_PATH, NULL };
char *envp[] = { NULL };
+ /* Initialize the system hostname */
+ init_hostname();
+
/* Start the init.rc */
+ log_trace("init.rc up\n");
spawn(SHELL_PATH, start_argv, envp, 0);
start_argv[1] = NULL;