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/getconf/getconf.c5
-rw-r--r--usr.bin/login/login.c64
-rw-r--r--usr.bin/sleep/Makefile6
-rw-r--r--usr.bin/sleep/sleep.c55
6 files changed, 161 insertions, 21 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/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 5938d19..e9b5e88 100644
--- a/usr.bin/login/login.c
+++ b/usr.bin/login/login.c
@@ -47,7 +47,6 @@
#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];
@@ -95,11 +94,15 @@ static int
check_user(char *alias, char *hash, char *entry)
{
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) {
@@ -118,12 +121,12 @@ check_user(char *alias, char *hash, 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) {
- retval = 0;
+ have_pw = 1;
}
break;
case ROW_USERID:
@@ -133,9 +136,18 @@ check_user(char *alias, char *hash, 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;
}
@@ -144,16 +156,24 @@ check_user(char *alias, char *hash, 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 (retval == 0) {
- setuid(uid);
- spawn(shell_argv[0], shell_argv, envp, SPAWN_WAIT);
+ /* Do we have the shell path? */
+ if (!have_shell) {
+ return -1;
}
- return retval;
+
+ setuid(uid);
+ shell_argv[0] = shell_path;
+ spawn(shell_argv[0], shell_argv, envp, SPAWN_WAIT);
+ return 0;
}
static char *
@@ -205,35 +225,45 @@ getstr(void)
static int
getuser(FILE *fp)
{
- char *pwtmp;
- 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: ");
- pwtmp = getstr();
+ p = getstr();
+ pwtmp = strdup(p);
sha256_hex(pwtmp, strlen(pwtmp), pwhash);
/* Paranoia */
- pwtmp = NULL;
+ 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, pwhash, entry);
if (retval == 0) {
printf("login: successful\n");
+ free(alias);
return 0;
}
}
+ /* 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));
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;
+}