diff options
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/Makefile | 1 | ||||
-rw-r--r-- | usr.bin/date/date.c | 51 | ||||
-rw-r--r-- | usr.bin/getconf/getconf.c | 5 | ||||
-rw-r--r-- | usr.bin/login/login.c | 64 | ||||
-rw-r--r-- | usr.bin/sleep/Makefile | 6 | ||||
-rw-r--r-- | usr.bin/sleep/sleep.c | 55 |
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; +} |