summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md19
-rw-r--r--builddeps/limine.conf2
-rw-r--r--builddeps/wallpaper.jpgbin0 -> 203867 bytes
-rw-r--r--configure.ac2
-rwxr-xr-xhyra-build.sh2
-rw-r--r--sys/arch/amd64/isa/i8042.c6
-rw-r--r--sys/fs/initramfs.c6
-rw-r--r--sys/include/sys/limits.h1
-rw-r--r--sys/include/sys/vnode.h24
-rw-r--r--sys/kern/exec_elf64.c2
-rw-r--r--sys/kern/kern_descrip.c2
-rw-r--r--sys/kern/kern_sched.c19
-rw-r--r--sys/kern/vfs_lookup.c4
-rw-r--r--sys/kern/vfs_subr.c6
-rw-r--r--sys/kern/vfs_syscalls.c2
-rw-r--r--sys/vm/vm_vnode.c2
-rw-r--r--tools/omar/omar.c41
-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
23 files changed, 271 insertions, 51 deletions
diff --git a/README.md b/README.md
index 5592a0d..13bff62 100644
--- a/README.md
+++ b/README.md
@@ -29,6 +29,25 @@ Default User:
Upon booting, the `login` program will ask for user credentials. The default username is `root` and the default
password is also `root`.
+Programs:
+----------------
+The Hyra userspace provides the user various programs that they can run, examples of
+such programs include:
+
+- ``beep`` - Play a tone
+- ``cat`` - Print files to stdout
+- ``date`` - Get the current date or set system time
+- ``echo`` - Print a line of text
+- ``elfdump`` - Get information about an ELF binary
+- ``fetch`` - System fetch! A must have :~)
+- ``getconf`` - Get system configuration values
+- ``mex`` - OSMORA hexdump utility
+- ``sleep`` - Sleep for a number of seconds
+- ``kmsg`` - Read the kernel message buffer
+- ``readcore`` - Read coredump files
+
+And more! See ``usr.bin/*``
+
Documentation:
--------------
Documentation will be in the form of comments throughout the codebase and can also be found in the share/ directory within the project root.
diff --git a/builddeps/limine.conf b/builddeps/limine.conf
index d5ed978..1ad040c 100644
--- a/builddeps/limine.conf
+++ b/builddeps/limine.conf
@@ -1,5 +1,5 @@
timeout=10
-${WALLPAPER_PATH}=boot():/boot/tree.jpg
+${WALLPAPER_PATH}=boot():/boot/wallpaper.jpg
wallpaper: ${WALLPAPER_PATH}
interface_branding_color: 1
term_background: 40000000
diff --git a/builddeps/wallpaper.jpg b/builddeps/wallpaper.jpg
new file mode 100644
index 0000000..5d69f53
--- /dev/null
+++ b/builddeps/wallpaper.jpg
Binary files differ
diff --git a/configure.ac b/configure.ac
index 61f5b54..aec0464 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([Hyra], [2.2], [ian@osmora.org])
+AC_INIT([Hyra], [2.3], [ian@osmora.org])
TARGET="amd64"
QEMU="qemu-system-x86_64"
diff --git a/hyra-build.sh b/hyra-build.sh
index 68f415f..1ebc3bb 100755
--- a/hyra-build.sh
+++ b/hyra-build.sh
@@ -67,7 +67,7 @@ gen_iso_root() {
cp $RAMFS_NAME iso_root/boot/
cp builddeps/limine.conf stand/limine/limine-bios.sys \
stand/limine/limine-bios-cd.bin stand/limine/limine-uefi-cd.bin iso_root/
- cp builddeps/tree.jpg iso_root/boot/
+ cp builddeps/wallpaper.jpg iso_root/boot/
}
##################################
diff --git a/sys/arch/amd64/isa/i8042.c b/sys/arch/amd64/isa/i8042.c
index 69d9f92..cde70ff 100644
--- a/sys/arch/amd64/isa/i8042.c
+++ b/sys/arch/amd64/isa/i8042.c
@@ -33,6 +33,7 @@
#include <sys/syslog.h>
#include <sys/spinlock.h>
#include <sys/param.h>
+#include <sys/ascii.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/queue.h>
@@ -75,7 +76,7 @@ static int i8042_kb_getc(uint8_t sc, char *chr);
static void i8042_drain(void);
static char keytab[] = {
- '\0', '\0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
+ '\0', '\x1B', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
'-', '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
'o', 'p', '[', ']', '\n', '\0', 'a', 's', 'd', 'f', 'g', 'h',
'j', 'k', 'l', ';', '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v',
@@ -276,6 +277,9 @@ i8042_kb_getc(uint8_t sc, char *chr)
bool release = ISSET(sc, BIT(7));
switch (sc) {
+ case 0x76:
+ *chr = ASCII_ESC;
+ return 0;
/* Caps lock [press] */
case 0x3A:
/*
diff --git a/sys/fs/initramfs.c b/sys/fs/initramfs.c
index c41deb4..beb2e84 100644
--- a/sys/fs/initramfs.c
+++ b/sys/fs/initramfs.c
@@ -61,12 +61,16 @@ struct initramfs_node {
* @magic: Header magic ("OMAR")
* @len: Length of the file
* @namelen: Length of the filename
+ * @rev: OMAR revision
+ * @mode: File permissions
*/
struct __packed omar_hdr {
char magic[4];
uint8_t type;
uint8_t namelen;
uint32_t len;
+ uint8_t rev;
+ uint32_t mode;
};
static volatile struct limine_module_request mod_req = {
@@ -140,7 +144,7 @@ initramfs_get_file(const char *path, struct initramfs_node *res)
p += hdr->namelen;
if (strcmp(namebuf, path) == 0) {
- node.mode = 0700;
+ node.mode = hdr->mode;
node.size = hdr->len;
node.data = (void *)p;
*res = node;
diff --git a/sys/include/sys/limits.h b/sys/include/sys/limits.h
index f56958e..5b97b68 100644
--- a/sys/include/sys/limits.h
+++ b/sys/include/sys/limits.h
@@ -31,6 +31,7 @@
#define _SYS_LIMITS_H_
#define PATH_MAX 1024
+#define NAME_MAX 256
#define SSIZE_MAX 32767
#define ARG_MAX 4096
#define CHAR_BIT 8
diff --git a/sys/include/sys/vnode.h b/sys/include/sys/vnode.h
index b135433..3402b02 100644
--- a/sys/include/sys/vnode.h
+++ b/sys/include/sys/vnode.h
@@ -92,6 +92,16 @@ struct vop_create_args {
struct vnode **vpp; /* Result vnode */
};
+struct vop_getattr_args {
+ struct vnode *vp; /* Target vnode */
+ struct vattr *res; /* Result vattr */
+};
+
+struct vop_readdir_args {
+ struct vnode *vp; /* Target vnode */
+ struct sio_txn *sio; /* SIO data to read into */
+};
+
/*
* A field in this structure is unavailable
* if it has a value of VNOVAL.
@@ -101,14 +111,10 @@ struct vattr {
size_t size;
};
-struct vop_getattr_args {
- struct vnode *vp;
- struct vattr *res;
-};
-
struct vops {
int(*lookup)(struct vop_lookup_args *args);
int(*getattr)(struct vop_getattr_args *args);
+ int(*readdir)(struct vop_readdir_args *args);
int(*read)(struct vnode *vp, struct sio_txn *sio);
int(*write)(struct vnode *vp, struct sio_txn *sio);
int(*reclaim)(struct vnode *vp);
@@ -117,19 +123,21 @@ struct vops {
extern struct vnode *g_root_vnode;
+/* Vnode cache operations */
int vfs_vcache_type(void);
int vfs_vcache_migrate(int newtype);
-
int vfs_vcache_enter(struct vnode *vp);
struct vnode *vfs_recycle_vnode(void);
+/* Vnode operations */
int vfs_alloc_vnode(struct vnode **res, int type);
int vfs_release_vnode(struct vnode *vp);
-int vfs_vop_lookup(struct vnode *vp, struct vop_lookup_args *args);
+/* Vnode operation wrappers */
+int vfs_vop_lookup(struct vop_lookup_args *args);
+int vfs_vop_getattr(struct vop_getattr_args *args);
int vfs_vop_read(struct vnode *vp, struct sio_txn *sio);
int vfs_vop_write(struct vnode *vp, struct sio_txn *sio);
-int vfs_vop_getattr(struct vnode *vp, struct vop_getattr_args *args);
#endif /* _KERNEL */
#endif /* !_SYS_VNODE_H_ */
diff --git a/sys/kern/exec_elf64.c b/sys/kern/exec_elf64.c
index 9706e77..8dc87dc 100644
--- a/sys/kern/exec_elf64.c
+++ b/sys/kern/exec_elf64.c
@@ -112,7 +112,7 @@ elf_get_file(const char *pathname, struct elf_file *res)
getattr_args.res = &vattr;
getattr_args.vp = vp;
- status = vfs_vop_getattr(vp, &getattr_args);
+ status = vfs_vop_getattr(&getattr_args);
if (status != 0)
goto done;
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 0fb026f..b5ff144 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -351,7 +351,7 @@ fd_seek(int fildes, off_t offset, int whence)
getattr_args.vp = tmp->vp;
getattr_args.res = &attr;
- if ((vfs_vop_getattr(tmp->vp, &getattr_args)) < 0) {
+ if ((vfs_vop_getattr(&getattr_args)) < 0) {
return -EPIPE;
}
diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c
index 30036c0..774ba71 100644
--- a/sys/kern/kern_sched.c
+++ b/sys/kern/kern_sched.c
@@ -258,8 +258,27 @@ sched_enter(void)
void
sched_yield(void)
{
+ struct proc *td;
+ struct cpu_info *ci = this_cpu();
+
+ if ((td = ci->curtd) == NULL) {
+ return;
+ }
+
+ td->rested = true;
+
+ /* FIXME: Hang yielding when waited on */
+ if (ISSET(td->flags, PROC_WAITED)) {
+ return;
+ }
+
+ ci->curtd = NULL;
md_inton();
sched_oneshot(false);
+
+ md_hlt();
+ md_intoff();
+ ci->curtd = td;
}
void
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index d88c447..7320102 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -181,7 +181,7 @@ namei_mp_search(struct mount *mp, const char *path, struct nameidata *ndp)
lookup_args.dirvp = vp;
lookup_args.vpp = &vp;
- status = vfs_vop_lookup(vp, &lookup_args);
+ status = vfs_vop_lookup(&lookup_args);
dynfree(name);
if (status != 0) {
@@ -234,7 +234,7 @@ namei(struct nameidata *ndp)
lookup_args.name = path;
lookup_args.dirvp = g_root_vnode;
lookup_args.vpp = &vp;
- status = vfs_vop_lookup(lookup_args.dirvp, &lookup_args);
+ status = vfs_vop_lookup(&lookup_args);
/* Did we find it in the root */
if (status == 0) {
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index da0a4f9..69417d0 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -141,8 +141,9 @@ vfs_release_vnode(struct vnode *vp)
}
int
-vfs_vop_lookup(struct vnode *vp, struct vop_lookup_args *args)
+vfs_vop_lookup(struct vop_lookup_args *args)
{
+ const struct vnode *vp = args->dirvp;
const struct vops *vops = vp->vops;
if (vops == NULL)
@@ -180,8 +181,9 @@ vfs_vop_write(struct vnode *vp, struct sio_txn *sio)
}
int
-vfs_vop_getattr(struct vnode *vp, struct vop_getattr_args *args)
+vfs_vop_getattr(struct vop_getattr_args *args)
{
+ const struct vnode *vp = args->vp;
const struct vops *vops = vp->vops;
if (vops == NULL)
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 0d51331..d15ecf1 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -68,7 +68,7 @@ vfs_dostat(const char *path, struct stat *sbuf)
vp = nd.vp;
gattr.vp = vp;
gattr.res = &attr;
- error = vfs_vop_getattr(vp, &gattr);
+ error = vfs_vop_getattr(&gattr);
if (error != 0) {
return error;
diff --git a/sys/vm/vm_vnode.c b/sys/vm/vm_vnode.c
index 27defc9..777b382 100644
--- a/sys/vm/vm_vnode.c
+++ b/sys/vm/vm_vnode.c
@@ -73,7 +73,7 @@ vn_io(struct vnode *vp, struct vm_page **pgs, unsigned int npages, int rw)
args.res = &vattr;
c = MAX(vattr.size / DEFAULT_PAGESIZE, 1);
- if ((err = vfs_vop_getattr(vp, &args)) != 0) {
+ if ((err = vfs_vop_getattr(&args)) != 0) {
return err;
}
diff --git a/tools/omar/omar.c b/tools/omar/omar.c
index 129303e..a4c7ad6 100644
--- a/tools/omar/omar.c
+++ b/tools/omar/omar.c
@@ -53,6 +53,9 @@
#define OMAR_ARCHIVE 0
#define OMAR_EXTRACT 1
+/* Revision */
+#define OMAR_REV 2
+
#define ALIGN_UP(value, align) (((value) + (align)-1) & ~((align)-1))
#define BLOCK_SIZE 512
@@ -68,12 +71,16 @@ static const char *outpath = NULL;
* @magic: Header magic ("OMAR")
* @len: Length of the file
* @namelen: Length of the filename
+ * @rev: OMAR revision
+ * @mode: File permissions
*/
struct omar_hdr {
char magic[4];
uint8_t type;
uint8_t namelen;
uint32_t len;
+ uint8_t rev;
+ uint32_t mode;
} __attribute__((packed));
static inline void
@@ -112,7 +119,7 @@ strip_root(const char *path)
* Recursive mkdir
*/
static void
-mkpath(const char *path)
+mkpath(struct omar_hdr *hdr, const char *path)
{
size_t len;
char buf[256];
@@ -126,12 +133,12 @@ mkpath(const char *path)
for (p = (char *)buf + 1; *p != '\0'; ++p) {
if (*p == '/') {
*p = '\0';
- mkdir(buf, 0700);
+ mkdir(buf, hdr->mode);
*p = '/';
}
}
- mkdir(buf, 0700);
+ mkdir(buf, hdr->mode);
}
/*
@@ -166,9 +173,11 @@ file_push(const char *pathname, const char *name)
if (S_ISDIR(sb.st_mode)) {
hdr.type = OMAR_DIR;
}
+ hdr.mode = sb.st_mode;
}
hdr.len = (pathname == NULL) ? 0 : sb.st_size;
+ hdr.rev = OMAR_REV;
hdr.namelen = strlen(name);
/*
@@ -282,16 +291,17 @@ archive_create(const char *base, const char *dirname)
/*
* Extract a single file
*
+ * @hp: File header
* @data: Data to extract
* @len: Length of data
* @path: Path to output file
*/
static int
-extract_single(char *data, size_t len, const char *path)
+extract_single(struct omar_hdr *hp, char *data, size_t len, const char *path)
{
int fd;
- if ((fd = open(path, O_WRONLY | O_CREAT, 0700)) < 0) {
+ if ((fd = open(path, O_WRONLY | O_CREAT, hp->mode)) < 0) {
return fd;
}
@@ -312,8 +322,10 @@ archive_extract(void)
struct stat sb;
struct omar_hdr *hdr;
int fd, error;
+ size_t len;
off_t off;
char namebuf[256];
+ char pathbuf[256];
if ((fd = open(inpath, O_RDONLY)) < 0) {
perror("open");
@@ -351,20 +363,31 @@ archive_extract(void)
fprintf(stderr, "bad magic\n");
break;
}
+ if (hdr->rev != OMAR_REV) {
+ fprintf(stderr, "cannot extract rev %d archive\n", hdr->rev);
+ fprintf(stderr, "current OMAR revision: %d\n", OMAR_REV);
+ }
name = (char *)hdr + sizeof(struct omar_hdr);
memcpy(namebuf, name, hdr->namelen);
namebuf[hdr->namelen] = '\0';
- printf("unpacking %s\n", namebuf);
+
+ /* Get the full path */
+ len = snprintf(pathbuf, sizeof(pathbuf), "%s/%s", outpath, namebuf);
+ if (len < 0) {
+ free(buf);
+ return len;
+ }
+ printf("unpacking %s\n", pathbuf);
if (hdr->type == OMAR_DIR) {
off = 512;
- mkpath(namebuf);
+ mkpath(hdr, pathbuf);
} else {
- off = ALIGN_UP(sizeof(hdr) + hdr->namelen + hdr->len, BLOCK_SIZE);
+ off = ALIGN_UP(sizeof(*hdr) + hdr->namelen + hdr->len, BLOCK_SIZE);
p = (char *)hdr + sizeof(struct omar_hdr);
p += hdr->namelen;
- extract_single(p, hdr->len, namebuf);
+ extract_single(hdr, p, hdr->len, pathbuf);
}
hdr = (struct omar_hdr *)((char *)hdr + off);
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;
+}