summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/Makefile1
-rw-r--r--usr.bin/date/date.c51
-rw-r--r--usr.bin/fetch/fetch.c9
-rw-r--r--usr.bin/getconf/getconf.c5
-rw-r--r--usr.bin/login/login.c103
-rw-r--r--usr.bin/osh/osh.c4
-rw-r--r--usr.bin/sleep/Makefile6
-rw-r--r--usr.bin/sleep/sleep.c55
8 files changed, 200 insertions, 34 deletions
diff --git a/usr.bin/Makefile b/usr.bin/Makefile
index 4c17ddf..e84831a 100644
--- a/usr.bin/Makefile
+++ b/usr.bin/Makefile
@@ -19,3 +19,4 @@ all:
make -C echo/ $(ARGS)
make -C readcore/ $(ARGS)
make -C login/ $(ARGS)
+ make -C sleep/ $(ARGS)
diff --git a/usr.bin/date/date.c b/usr.bin/date/date.c
index a47e3eb..ab26c4c 100644
--- a/usr.bin/date/date.c
+++ b/usr.bin/date/date.c
@@ -32,6 +32,7 @@
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
+#include <string.h>
#define MONTHS_PER_YEAR 12
#define DAYS_PER_WEEK 7
@@ -51,19 +52,63 @@ static const char *daytab[] = {
"Fri"
};
+static int
+set_time(int clock_fd, struct date *dp, char *timestr)
+{
+ uint32_t hour, min, sec;
+ char *p;
+
+ /* Hour */
+ p = strtok(timestr, ":");
+ if (p == NULL)
+ return -1;
+ hour = atoi(p);
+
+ /* Minute */
+ p = strtok(NULL, ":");
+ if (p == NULL)
+ return -1;
+ min = atoi(p);
+
+ /* Second */
+ p = strtok(NULL, ":");
+ if (p == NULL)
+ return -1;
+ sec = atoi(p);
+
+ /* Set the time */
+ dp->hour = hour;
+ dp->min = min;
+ dp->sec = sec;
+ write(clock_fd, dp, sizeof(*dp));
+ return 0;
+}
+
int
-main(void)
+main(int argc, char **argv)
{
const char *day, *month;
char date_str[32];
struct date d;
- int rtc_fd;
+ int rtc_fd, error = 0;
- if ((rtc_fd = open("/dev/rtc", O_RDONLY)) < 0) {
+ if ((rtc_fd = open("/dev/rtc", O_RDWR)) < 0) {
return rtc_fd;
}
+
read(rtc_fd, &d, sizeof(d));
+
+ /*
+ * If a time was specified to be set in the
+ * 'hh:mm:ss' format, attempt to write it.
+ */
+ if (argc > 1) {
+ error = set_time(rtc_fd, &d, argv[1]);
+ if (error < 0)
+ printf("bad time specified, not set\n");
+ }
+
close(rtc_fd);
/* This should not happen */
diff --git a/usr.bin/fetch/fetch.c b/usr.bin/fetch/fetch.c
index 42c2825..175cd0e 100644
--- a/usr.bin/fetch/fetch.c
+++ b/usr.bin/fetch/fetch.c
@@ -32,18 +32,19 @@
#include <string.h>
#include <stdio.h>
+static const char *user = "unknown";
+
#define ASCII_ART \
" ____ \n" \
" | \\__\\ \n" \
- " | /\\ \\ user: root\n" \
+ " | /\\ \\ user: %s\n" \
" |/ \\ \\ OS: Hyra/amd64 v"_OSVER"\n" \
" \\ R. \\ \\ arch: "_OSARCH"\n" \
- " \\ I. \\ \\"
-
+ " \\ I. \\ \\\n"
int
main(void)
{
- puts(ASCII_ART);
+ printf(ASCII_ART, getlogin());
return 0;
}
diff --git a/usr.bin/getconf/getconf.c b/usr.bin/getconf/getconf.c
index c60bf5d..f028e76 100644
--- a/usr.bin/getconf/getconf.c
+++ b/usr.bin/getconf/getconf.c
@@ -37,12 +37,15 @@
struct sysvar {
const char *var;
uint8_t auxv : 1;
- uint8_t val;
+ uint32_t val;
};
static struct sysvar vartab[] = {
{ "PAGESIZE", 1, AT_PAGESIZE },
{ "CHAR_BIT", 0, CHAR_BIT },
+ { "NAME_MAX", 0, NAME_MAX },
+ { "PATH_MAX", 0, PATH_MAX },
+ { "SSIZE_MAX", 0, SSIZE_MAX },
{ NULL, 0, 0 }
};
diff --git a/usr.bin/login/login.c b/usr.bin/login/login.c
index c5af6c0..e9b5e88 100644
--- a/usr.bin/login/login.c
+++ b/usr.bin/login/login.c
@@ -30,6 +30,7 @@
#include <sys/spawn.h>
#include <sys/types.h>
#include <sys/errno.h>
+#include <crypto/sha256.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -46,11 +47,11 @@
#define is_ascii(C) ((C) >= 0 && (C) <= 128)
#define is_digit(C) ((C >= '0' && C <= '9'))
-#define USERNAME "root"
#define DEFAULT_SHELL "/usr/bin/osh"
static char buf[64];
static uint8_t buf_i;
+static short echo_chars = 1;
/*
* Verify a UID is valid
@@ -83,20 +84,25 @@ check_uid(const char *uid)
* (username)
*
* @alias: Alias to lookup
+ * @hash: Password hash
* @entry: /etc/passwd entry
*
* Returns -1 on failure
* Returns 0 if the entry matches
*/
static int
-check_user(char *alias, char *entry)
+check_user(char *alias, char *hash, char *entry)
{
- const char *p, *shell;
+ const char *p;
+ char shell_path[256];
char *shell_argv[] = { DEFAULT_SHELL, NULL };
char *envp[] = { NULL };
- size_t row = 0;
- short retval = -1;
+ size_t len, row = 0;
size_t line = 1;
+ short have_user = 0;
+ short have_pw = 0;
+ short have_uid = 0;
+ short have_shell = 0;
uid_t uid = -1;
if (alias == NULL || entry == NULL) {
@@ -115,9 +121,14 @@ check_user(char *alias, char *entry)
switch (row) {
case ROW_USERNAME:
if (strcmp(p, alias) == 0) {
- retval = 0;
+ have_user = 1;
}
break; /* UNREACHABLE */
+ case ROW_HASH:
+ if (strcmp(p, hash) == 0) {
+ have_pw = 1;
+ }
+ break;
case ROW_USERID:
if (check_uid(p) != 0) {
printf("bad uid @ line %d\n", line);
@@ -125,9 +136,18 @@ check_user(char *alias, char *entry)
}
uid = atoi(p);
+ have_uid = 1;
break;
case ROW_SHELL:
- /* TODO */
+ len = strlen(p) - 1;
+ if (len >= sizeof(shell_path) - 1) {
+ printf("bad shell path @ line %d\n", line);
+ return -1;
+ }
+
+ memcpy(shell_path, p, len);
+ shell_path[len] = '\0';
+ have_shell = 1;
break;
}
@@ -136,31 +156,34 @@ check_user(char *alias, char *entry)
++line;
}
- if (uid < 0) {
- printf("failed to set uid\n");
+ /*
+ * We need to have found the password hash,
+ * the username, AND the UID. If we have not,
+ * then this has failed.
+ */
+ if (!have_pw || !have_user || !have_uid) {
return -1;
}
- if (shell == NULL) {
- printf("failed to read shell path\n");
+
+ /* Do we have the shell path? */
+ if (!have_shell) {
return -1;
}
- if (retval == 0) {
- setuid(uid);
- spawn(shell_argv[0], shell_argv, envp, SPAWN_WAIT);
- }
- return retval;
+ setuid(uid);
+ shell_argv[0] = shell_path;
+ spawn(shell_argv[0], shell_argv, envp, SPAWN_WAIT);
+ return 0;
}
static char *
getstr(void)
{
- char c;
+ char c, printc;
int input;
buf_i = 0;
-
for (;;) {
if ((input = getchar()) < 0) {
continue;
@@ -171,6 +194,13 @@ getstr(void)
continue;
}
+ /*
+ * If we want to echo characters, 'printc' becomes
+ * exactly the character we got. Otherwise, just
+ * print little stars to redact it.
+ */
+ printc = echo_chars ? c : '*';
+
/* return on newline */
if (c == '\n') {
buf[buf_i] = '\0';
@@ -187,7 +217,7 @@ getstr(void)
} else if (is_ascii(c) && buf_i < sizeof(buf) - 1) {
/* write to fd and add to buffer */
buf[buf_i++] = c;
- putchar(c);
+ putchar(printc);
}
}
}
@@ -195,24 +225,50 @@ getstr(void)
static int
getuser(FILE *fp)
{
- char *alias;
+ char *pwtmp, *alias, *p;
char entry[256];
+ char pwhash[SHA256_HEX_SIZE];
int retval;
printf("username: ");
- alias = getstr();
+ p = getstr();
+ alias = strdup(p);
+
+ /* Grab the password now */
+ echo_chars = 0;
+ printf("password: ");
+ p = getstr();
+ pwtmp = strdup(p);
+ sha256_hex(pwtmp, strlen(pwtmp), pwhash);
+
+ /* Paranoia */
+ memset(pwtmp, 0, strlen(pwtmp));
+ buf_i = 0;
+ memset(buf, 0, sizeof(buf));
+
+ /* Clean up */
+ free(pwtmp);
+ pwtmp = NULL;
+
+ /* See if anything matches */
while (fgets(entry, sizeof(entry), fp) != NULL) {
- retval = check_user(alias, entry);
+ retval = check_user(alias, pwhash, entry);
if (retval == 0) {
printf("login: successful\n");
+ free(alias);
return 0;
}
}
- printf("bad username \"%s\"\n", alias);
+ /* If we reach this point, bad creds */
+ free(alias);
+ alias = NULL;
+
+ printf("bad username or password\n");
fseek(fp, 0, SEEK_SET);
memset(buf, 0, sizeof(buf));
buf_i = 0;
+ echo_chars = 1;
return -1;
}
@@ -228,7 +284,6 @@ main(void)
}
printf("- Please authenticate yourself -\n");
- printf("Default user 'root'\n");
for (;;) {
if (getuser(fp) == 0) {
break;
diff --git a/usr.bin/osh/osh.c b/usr.bin/osh/osh.c
index 0bce357..5bcd2e2 100644
--- a/usr.bin/osh/osh.c
+++ b/usr.bin/osh/osh.c
@@ -60,7 +60,7 @@
"clear - Clear the screen\n" \
"exit - Exit the shell"
-#define PROMPT "[root::osmora]~ "
+#define PROMPT "[%s::osmora]~ "
static char buf[64];
static uint8_t buf_i;
@@ -394,7 +394,7 @@ main(int argc, char **argv)
puts(WELCOME);
while (running) {
memset(prog_argv, 0, sizeof(prog_argv));
- fputs(PROMPT, stdout);
+ printf(PROMPT, getlogin());
input = getstr();
if (input[0] == '\0') {
diff --git a/usr.bin/sleep/Makefile b/usr.bin/sleep/Makefile
new file mode 100644
index 0000000..5bfd04f
--- /dev/null
+++ b/usr.bin/sleep/Makefile
@@ -0,0 +1,6 @@
+include user.mk
+
+CFILES = $(shell find . -name "*.c")
+
+$(ROOT)/base/usr/bin/sleep:
+ gcc $(CFILES) -o $@ $(INTERNAL_CFLAGS)
diff --git a/usr.bin/sleep/sleep.c b/usr.bin/sleep/sleep.c
new file mode 100644
index 0000000..f7d07f8
--- /dev/null
+++ b/usr.bin/sleep/sleep.c
@@ -0,0 +1,55 @@
+/*
+ * 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 <time.h>
+#include <string.h>
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+ struct timespec ts;
+ uint16_t nsec = 0;
+
+ if (argc < 2) {
+ printf("sleep: usage: sleep <seconds>\n");
+ return -1;
+ }
+
+ nsec = atoi(argv[1]);
+ if (nsec == 0) {
+ printf("sleep: bad argument\n");
+ return -1;
+ }
+
+ ts.tv_nsec = 0;
+ ts.tv_sec = nsec;
+ sleep(&ts, &ts);
+ return 0;
+}