BarryServer : Git

All the code for all my projects
// BarryServer : Git / OrionUserland / commit / 19aefaad8af9de8719ba1e5b5340e0a1b9c68853

// Related

OrionUserland

Barry Importing existing Orion Userland 19aefaa (2 years, 4 months ago)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5761abc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.o
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..85d9ce7
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,12 @@
+PROGS=$(shell basename -a $(shell find . -mindepth 1 -maxdepth 1 -type d -not -path '*/.*'))
+
+.PHONY: clean all install
+
+all:
+	@$(foreach prog,$(PROGS),$(MAKE) -s -C $(prog);)
+
+clean:
+	@$(foreach prog,$(PROGS),$(MAKE) -s -C $(prog) clean;)
+
+install:
+	@$(foreach prog,$(PROGS),$(MAKE) -s -C $(prog) install;)
diff --git a/cat/Makefile b/cat/Makefile
new file mode 100644
index 0000000..5254c7c
--- /dev/null
+++ b/cat/Makefile
@@ -0,0 +1,46 @@
+PRODUCT=$(notdir $(abspath $(CURDIR)))
+
+CC=i686-orion-gcc
+CFLAGS=
+
+AS=i686-orion-as
+AFLAGS=
+
+LD=i686-orion-gcc
+LFLAGS=
+
+AS_SOURCES := $(shell find . -name '*.S')
+OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES))))
+
+C_SOURCES := $(shell find . -name '*.c')
+OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES))))
+
+.PHONY: clean all install
+
+all: $(PRODUCT)
+
+clean:
+	@echo "REMOVING OBJECT FILES"
+	@mkdir -p build
+	@rm -rf build
+	@touch $(PRODUCT)
+	@rm $(PRODUCT)
+
+install: $(PRODUCT)
+	@echo "INSTALLING $^"
+	@mkdir -p ${SYSROOT}/bin/
+	@install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/
+
+$(PRODUCT): $(OBJS)
+	@echo "LINKING $@"
+	@$(LD) -o $@ $^ $(LFLAGS)
+
+build/%.o: %.c
+	@echo "COMPILING $<"
+	@mkdir -p $(@D)
+	@$(CC) -c $< -o $@ $(CFLAGS)
+
+build/%.o: %.S
+	@echo "ASSEMBLING $<"
+	@mkdir -p $(@D)
+	@$(AS) $< -o $@ $(AFLAGS)
diff --git a/cat/cat b/cat/cat
new file mode 100755
index 0000000..7b4fdb6
Binary files /dev/null and b/cat/cat differ
diff --git a/cat/main.c b/cat/main.c
new file mode 100644
index 0000000..f1570bc
--- /dev/null
+++ b/cat/main.c
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <dirent.h>
+
+/* Main function */
+int
+main(int argc, char *argv[])
+{
+	int fd, sz, i;
+	char *buf;
+	struct stat statbuf;
+
+	if (argc < 2) {
+		printf("Usage: %s <file> [<file>...]\n");
+		return 0;
+	}
+
+	for (i = 1; i < argc; i++) {
+		fd = open(argv[i], O_RDONLY);
+		if (fd < 0) {
+			printf("%s: %s: ", argv[0], argv[i]);
+			perror(NULL);
+			continue;
+		}
+
+		stat(argv[i], &statbuf);
+		if (S_ISREG(statbuf.mode)) {
+			sz = lseek(fd, 0, SEEK_END);
+			buf = malloc(sz + 1);
+			lseek(fd, 0, SEEK_SET);
+			read(fd, buf, sz);
+			printf("%s", buf);
+			free(buf);
+		}
+
+		close(fd);
+	}
+
+	return 0;
+}
diff --git a/clear/Makefile b/clear/Makefile
new file mode 100644
index 0000000..5254c7c
--- /dev/null
+++ b/clear/Makefile
@@ -0,0 +1,46 @@
+PRODUCT=$(notdir $(abspath $(CURDIR)))
+
+CC=i686-orion-gcc
+CFLAGS=
+
+AS=i686-orion-as
+AFLAGS=
+
+LD=i686-orion-gcc
+LFLAGS=
+
+AS_SOURCES := $(shell find . -name '*.S')
+OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES))))
+
+C_SOURCES := $(shell find . -name '*.c')
+OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES))))
+
+.PHONY: clean all install
+
+all: $(PRODUCT)
+
+clean:
+	@echo "REMOVING OBJECT FILES"
+	@mkdir -p build
+	@rm -rf build
+	@touch $(PRODUCT)
+	@rm $(PRODUCT)
+
+install: $(PRODUCT)
+	@echo "INSTALLING $^"
+	@mkdir -p ${SYSROOT}/bin/
+	@install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/
+
+$(PRODUCT): $(OBJS)
+	@echo "LINKING $@"
+	@$(LD) -o $@ $^ $(LFLAGS)
+
+build/%.o: %.c
+	@echo "COMPILING $<"
+	@mkdir -p $(@D)
+	@$(CC) -c $< -o $@ $(CFLAGS)
+
+build/%.o: %.S
+	@echo "ASSEMBLING $<"
+	@mkdir -p $(@D)
+	@$(AS) $< -o $@ $(AFLAGS)
diff --git a/clear/clear b/clear/clear
new file mode 100755
index 0000000..59b13f6
Binary files /dev/null and b/clear/clear differ
diff --git a/clear/main.c b/clear/main.c
new file mode 100644
index 0000000..fefc064
--- /dev/null
+++ b/clear/main.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+/* Main function */
+int
+main(int argc, char *argv[])
+{
+	printf("\033[H\033[2J");
+
+	return 0;
+}
diff --git a/date/Makefile b/date/Makefile
new file mode 100644
index 0000000..5254c7c
--- /dev/null
+++ b/date/Makefile
@@ -0,0 +1,46 @@
+PRODUCT=$(notdir $(abspath $(CURDIR)))
+
+CC=i686-orion-gcc
+CFLAGS=
+
+AS=i686-orion-as
+AFLAGS=
+
+LD=i686-orion-gcc
+LFLAGS=
+
+AS_SOURCES := $(shell find . -name '*.S')
+OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES))))
+
+C_SOURCES := $(shell find . -name '*.c')
+OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES))))
+
+.PHONY: clean all install
+
+all: $(PRODUCT)
+
+clean:
+	@echo "REMOVING OBJECT FILES"
+	@mkdir -p build
+	@rm -rf build
+	@touch $(PRODUCT)
+	@rm $(PRODUCT)
+
+install: $(PRODUCT)
+	@echo "INSTALLING $^"
+	@mkdir -p ${SYSROOT}/bin/
+	@install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/
+
+$(PRODUCT): $(OBJS)
+	@echo "LINKING $@"
+	@$(LD) -o $@ $^ $(LFLAGS)
+
+build/%.o: %.c
+	@echo "COMPILING $<"
+	@mkdir -p $(@D)
+	@$(CC) -c $< -o $@ $(CFLAGS)
+
+build/%.o: %.S
+	@echo "ASSEMBLING $<"
+	@mkdir -p $(@D)
+	@$(AS) $< -o $@ $(AFLAGS)
diff --git a/date/date b/date/date
new file mode 100755
index 0000000..0e0bee7
Binary files /dev/null and b/date/date differ
diff --git a/date/main.c b/date/main.c
new file mode 100644
index 0000000..2e35681
--- /dev/null
+++ b/date/main.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include <time.h>
+
+#define LEAP_YEAR(x) ((((x % 4) == 0) && ((x % 100) != 0)) || ((x % 400) == 0))
+
+/* Main function */
+int
+main(int argc, char *argv[])
+{
+	/* Length of months for normal and leap years */
+	const uint16_t monthLen[2][12] = {
+		{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+		{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
+	};
+
+	uint8_t second, minute, hour, day, month;
+	time_t now = time(NULL);
+	uint32_t year = 1970, dayclock = now % 86400, dayno = now / 86400;
+
+	second = dayclock % 60;
+	minute = (dayclock % 3600) / 60;
+	hour = dayclock / 3600;
+	while (dayno >= (LEAP_YEAR(year) ? 366 : 365)) {
+		dayno -= (LEAP_YEAR(year) ? 366 : 365);
+		year++;
+	}
+	year -= 1970;
+	month = 0;
+	while (dayno >= monthLen[LEAP_YEAR(year)][month]) {
+		dayno -= monthLen[LEAP_YEAR(year)][month];
+		month++;
+	}
+	day = dayno + 1;
+
+	printf("%.4d/%.2d/%.2d %.2d:%.2d:%.2d UTC\n",
+	       year+1970, month+1, day+1, hour, minute, second);
+
+	return 0;
+}
diff --git a/init/Makefile b/init/Makefile
new file mode 100644
index 0000000..5254c7c
--- /dev/null
+++ b/init/Makefile
@@ -0,0 +1,46 @@
+PRODUCT=$(notdir $(abspath $(CURDIR)))
+
+CC=i686-orion-gcc
+CFLAGS=
+
+AS=i686-orion-as
+AFLAGS=
+
+LD=i686-orion-gcc
+LFLAGS=
+
+AS_SOURCES := $(shell find . -name '*.S')
+OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES))))
+
+C_SOURCES := $(shell find . -name '*.c')
+OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES))))
+
+.PHONY: clean all install
+
+all: $(PRODUCT)
+
+clean:
+	@echo "REMOVING OBJECT FILES"
+	@mkdir -p build
+	@rm -rf build
+	@touch $(PRODUCT)
+	@rm $(PRODUCT)
+
+install: $(PRODUCT)
+	@echo "INSTALLING $^"
+	@mkdir -p ${SYSROOT}/bin/
+	@install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/
+
+$(PRODUCT): $(OBJS)
+	@echo "LINKING $@"
+	@$(LD) -o $@ $^ $(LFLAGS)
+
+build/%.o: %.c
+	@echo "COMPILING $<"
+	@mkdir -p $(@D)
+	@$(CC) -c $< -o $@ $(CFLAGS)
+
+build/%.o: %.S
+	@echo "ASSEMBLING $<"
+	@mkdir -p $(@D)
+	@$(AS) $< -o $@ $(AFLAGS)
diff --git a/init/init b/init/init
new file mode 100755
index 0000000..5b641ac
Binary files /dev/null and b/init/init differ
diff --git a/init/main.c b/init/main.c
new file mode 100644
index 0000000..0eb2b3b
--- /dev/null
+++ b/init/main.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+
+/* Main function */
+int
+main(int argc, char *argv[])
+{
+	if (getpid() != 1) {
+		printf("init will not run except as PID#1");
+		abort();
+	}
+
+	dbgprintf("Starting init");
+
+	/* Open standard descriptors */
+	open("/dev/tty", O_RDONLY);
+	open("/dev/tty", O_WRONLY);
+	dup(1);
+
+	printf("Welcome to \033[1;32mOrion\033[0m!\n");
+
+	int status;
+	pid_t child;
+	while (1) {
+		child = fork();
+		if (!child) {
+			char *v[] = { "login", NULL };
+			int err = execve("/bin/login", v, NULL);
+			if (err < 0) {
+				printf("init: %s: ", "/bin/login");
+				perror(NULL);
+				while (1);
+			}
+		} else {
+			waitpid(child, &status, 0);
+		}
+		printf("\033[H\033[2J"); /* Clear screen */
+	}
+}
diff --git a/login/Makefile b/login/Makefile
new file mode 100644
index 0000000..5254c7c
--- /dev/null
+++ b/login/Makefile
@@ -0,0 +1,46 @@
+PRODUCT=$(notdir $(abspath $(CURDIR)))
+
+CC=i686-orion-gcc
+CFLAGS=
+
+AS=i686-orion-as
+AFLAGS=
+
+LD=i686-orion-gcc
+LFLAGS=
+
+AS_SOURCES := $(shell find . -name '*.S')
+OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES))))
+
+C_SOURCES := $(shell find . -name '*.c')
+OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES))))
+
+.PHONY: clean all install
+
+all: $(PRODUCT)
+
+clean:
+	@echo "REMOVING OBJECT FILES"
+	@mkdir -p build
+	@rm -rf build
+	@touch $(PRODUCT)
+	@rm $(PRODUCT)
+
+install: $(PRODUCT)
+	@echo "INSTALLING $^"
+	@mkdir -p ${SYSROOT}/bin/
+	@install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/
+
+$(PRODUCT): $(OBJS)
+	@echo "LINKING $@"
+	@$(LD) -o $@ $^ $(LFLAGS)
+
+build/%.o: %.c
+	@echo "COMPILING $<"
+	@mkdir -p $(@D)
+	@$(CC) -c $< -o $@ $(CFLAGS)
+
+build/%.o: %.S
+	@echo "ASSEMBLING $<"
+	@mkdir -p $(@D)
+	@$(AS) $< -o $@ $(AFLAGS)
diff --git a/login/login b/login/login
new file mode 100755
index 0000000..b45884b
Binary files /dev/null and b/login/login differ
diff --git a/login/main.c b/login/main.c
new file mode 100644
index 0000000..d1bfd55
--- /dev/null
+++ b/login/main.c
@@ -0,0 +1,74 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <pwd.h>
+
+#define MANUAL_LOGIN
+
+/* Main function */
+int
+main(int argc, char *argv[])
+{
+	int fd, sz;
+	char *buf, *line, *input = malloc(1024);
+
+	Passwd *pwd;
+	Termios tcold, tcnew;
+
+	while (1) {
+		printf("\nUsername: ");
+		memset(input, 0, 1024);
+#ifdef MANUAL_LOGIN
+		sz = read(STDIN_FILENO, input, 1024);
+#else
+		printf("root\n");
+		sz = 5;
+		memcpy(input, "root", 5);
+#endif
+		input[--sz] = '\0';
+		if (sz < 1)
+			continue;
+
+		pwd = getpwname(input);
+		if (!pwd)
+			continue;
+
+		printf("Password: ");
+		memset(input, 0, 1024);
+		ioctl(STDIN_FILENO, TCGETS, &tcold);
+		memcpy(&tcnew, &tcold, sizeof(Termios));
+		tcnew.lflag &= ~ECHO;
+		ioctl(STDIN_FILENO, TCSETS, &tcnew);
+#ifdef MANUAL_LOGIN
+		sz = read(STDIN_FILENO, input, 1024);
+#else
+		printf("password\n");
+		sz = 9;
+		memcpy(input, "password", 9);
+#endif
+		input[--sz] = '\0';
+		if (sz < 1)
+			continue;
+		ioctl(STDIN_FILENO, TCSETS, &tcold);
+
+		if (!strcmp(input, pwd->password))
+			break;
+		printf("Login incorrect\n");
+	}
+	printf("\n");
+
+	dbgprintf("Authenticating \"%s\" (%d:%d) -> \"%s\" @ \"%s\"",
+	          pwd->username, pwd->uid, pwd->gid, pwd->shell, pwd->homedir);
+	chdir(pwd->homedir);
+	setuid(pwd->uid);
+	setgid(pwd->gid);
+	char *v[] = { "sh", NULL };
+	execve(pwd->shell, v, NULL);
+
+	return 0;
+}
diff --git a/ls/Makefile b/ls/Makefile
new file mode 100644
index 0000000..5254c7c
--- /dev/null
+++ b/ls/Makefile
@@ -0,0 +1,46 @@
+PRODUCT=$(notdir $(abspath $(CURDIR)))
+
+CC=i686-orion-gcc
+CFLAGS=
+
+AS=i686-orion-as
+AFLAGS=
+
+LD=i686-orion-gcc
+LFLAGS=
+
+AS_SOURCES := $(shell find . -name '*.S')
+OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES))))
+
+C_SOURCES := $(shell find . -name '*.c')
+OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES))))
+
+.PHONY: clean all install
+
+all: $(PRODUCT)
+
+clean:
+	@echo "REMOVING OBJECT FILES"
+	@mkdir -p build
+	@rm -rf build
+	@touch $(PRODUCT)
+	@rm $(PRODUCT)
+
+install: $(PRODUCT)
+	@echo "INSTALLING $^"
+	@mkdir -p ${SYSROOT}/bin/
+	@install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/
+
+$(PRODUCT): $(OBJS)
+	@echo "LINKING $@"
+	@$(LD) -o $@ $^ $(LFLAGS)
+
+build/%.o: %.c
+	@echo "COMPILING $<"
+	@mkdir -p $(@D)
+	@$(CC) -c $< -o $@ $(CFLAGS)
+
+build/%.o: %.S
+	@echo "ASSEMBLING $<"
+	@mkdir -p $(@D)
+	@$(AS) $< -o $@ $(AFLAGS)
diff --git a/ls/arg.h b/ls/arg.h
new file mode 100644
index 0000000..9022339
--- /dev/null
+++ b/ls/arg.h
@@ -0,0 +1,42 @@
+#ifndef ARG_H
+#define ARG_H
+
+extern char *progname;
+
+#define ARGBEGIN for (progname = *argv, argv++, argc--; \
+		      argc && argv[0] && argv[0][0] == '-' \
+		      && argv[0][1]; \
+		      argc--, argv++) { \
+			char argc_, **argv_; \
+			int brk_; \
+			if (argv[0][1] == '-' && argv[0][2] == '\0') { \
+				argv++; \
+				argc--; \
+				break; \
+			} \
+			int i_; \
+			for (i_ = 1, brk_ = 0, argv_ = argv; \
+			     argv[0][i_] && !brk_; \
+			     i_++) { \
+				if (argv_ != argv) \
+					break; \
+				argc_ = argv[0][i_]; \
+				switch (argc_)
+#define ARGEND 		} \
+		}
+
+#define ARGC() argc_
+
+#define EARGF(x) ((argv[0][i_+1] == '\0' && argv[1] == NULL) ? \
+		 	((x), abort(), (char *) 0) : \
+		 	(brk_ = 1, (argv[0][i_+1] != '\0') ? \
+		 		(&argv[0][i_+1]) : \
+		 		(argc--, argv++, argv[0])))
+
+#define ARGF() ((argv[0][i_+1] == '\0' && argv[1] == NULL) ? \
+			(char *) 0 : \
+			(brk_ = 1, (argv[0][i_+1] != '\0') ? \
+				(&argv[0][i_+1]) : \
+				(argc--, argv++, argv[0])))
+
+#endif
diff --git a/ls/ls b/ls/ls
new file mode 100755
index 0000000..0921d86
Binary files /dev/null and b/ls/ls differ
diff --git a/ls/main.c b/ls/main.c
new file mode 100644
index 0000000..27b754c
--- /dev/null
+++ b/ls/main.c
@@ -0,0 +1,320 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <dirent.h>
+#include <termios.h>
+#include <pwd.h>
+#include <grp.h>
+
+char *progname;
+#include "arg.h"
+
+Winsize termsz;
+int allFlag = 0;
+int longFlag = 0;
+
+/* Structure for a result */
+typedef struct Result Result;
+struct Result {
+	Result *next, *prev;
+	ino_t ino;
+	enum DirType type;
+	size_t namelen;
+	char name[255];
+	Stat stat;
+};
+
+/* Compare results by name */
+static int
+compare_name(Result *a, Result *b)
+{
+	return (strcmp(a->name, b->name) < 0);
+}
+
+/* Compare results by type */
+static int
+compare_type(Result *a, Result *b)
+{
+	return (a->type == DT_DIR && b->type != DT_DIR);
+}
+
+/* Sort a list of results */
+static Result *
+sort_results(Result *head, int (*compare)(Result *, Result *))
+{
+	Result *curr, *shead = NULL, *slast, *scurr;
+	int i, len = 0;
+	for (curr = head; curr; curr = curr->next)
+		len++;
+
+	/* Sort */
+	for (i = 0; i < len; i++) {
+		scurr = head;
+		for (curr = head->next; curr; curr = curr->next) {
+			if (compare(curr, scurr))
+				scurr = curr;
+		}
+
+		/* Unlink from old list */
+		if (scurr == head)
+			head = scurr->next;
+		if (scurr->next)
+			scurr->next->prev = scurr->prev;
+		if (scurr->prev)
+			scurr->prev->next = scurr->next;
+		scurr->prev = scurr->next = NULL;
+
+		/* Add to sorted list */
+		if (!shead) {
+			shead = scurr;
+		} else {
+			scurr->prev = slast;
+			slast->next = scurr;
+		}
+		slast = scurr;
+	}
+
+	return shead;
+}
+
+/* Print normal results */
+static void
+print_normal(Result *head)
+{
+	Result *curr, *next, *prev;
+	size_t printed = 0;
+
+	for (curr = head; curr; curr = next) {
+		prev = curr->prev;
+		next = curr->next;
+
+		int executable = 0;
+		if ((curr->stat.mode & S_IXUSR)
+		 || (curr->stat.mode & S_IXGRP)
+		 || (curr->stat.mode & S_IXOTH))
+			executable = 1;
+
+		if (curr->type == DT_DIR)
+			printf("\033[1;34m%s\033[0m  ", curr->name);
+		else if (curr->type == DT_CHR || curr->type == DT_BLK)
+			printf("\033[1;33m%s\033[0m  ", curr->name);
+		else if (curr->type == DT_LNK)
+			printf("\033[1;36m%s\033[0m  ", curr->name);
+		else if (curr->type == DT_REG && executable)
+			printf("\033[1;32m%s\033[0m  ", curr->name);
+		else
+			printf("%s  ", curr->name);
+		printed++;
+
+		/* Remove from list */
+		if (prev)
+			prev->next = next;
+		if (next)
+			next->prev = prev;
+		if (curr == head)
+			head = next;
+		free(curr);
+	}
+	if (printed)
+		putchar('\n');
+}
+
+/* Print long results */
+static void
+print_long(Result *head)
+{
+	Result *curr, *next, *prev;
+	size_t printed = 0;
+
+	/* Find max column widths */
+	size_t total = 0;
+	int linkWidth = 0, unameWidth = 0, groupWidth = 0, sizeWidth = 0;
+	for (curr = head; curr; curr = curr->next) {
+		int linkTmp = curr->stat.nlink, linkWidthTmp = 1;
+		while (linkTmp /= 10)
+			linkWidthTmp++;
+		if (linkWidthTmp > linkWidth)
+			linkWidth = linkWidthTmp;
+
+		Passwd *pwd = getpwuid(curr->stat.uid);
+		if (strlen(pwd->username) > unameWidth)
+			unameWidth = strlen(pwd->username);
+		Group *grp = getgrgid(curr->stat.gid);
+		if (strlen(grp->name) > groupWidth)
+			groupWidth = strlen(grp->name);
+
+		int sizeTmp = curr->stat.size, sizeWidthTmp = 1;
+		while (sizeTmp /= 10)
+			sizeWidthTmp++;
+		if (sizeWidthTmp > sizeWidth)
+			sizeWidth = sizeWidthTmp;
+
+		total += (curr->stat.size + (1024 - 1)) / 1024;
+	}
+
+	/* Print out */
+	printf("total %d\n", total);
+	for (curr = head; curr; curr = next) {
+		prev = curr->prev;
+		next = curr->next;
+
+		char perm[] = "----------";
+		char type[] = "?-dcbfsl";
+		char uname[33], group[33];
+		int executable = 0;
+		perm[0] = type[curr->type];
+		perm[1] = (curr->stat.mode & S_IRUSR) ? 'r' : '-';
+		perm[2] = (curr->stat.mode & S_IWUSR) ? 'w' : '-';
+		perm[3] = (curr->stat.mode & S_IXUSR) ? 'x' : '-';
+		perm[4] = (curr->stat.mode & S_IRGRP) ? 'r' : '-';
+		perm[5] = (curr->stat.mode & S_IWGRP) ? 'w' : '-';
+		perm[6] = (curr->stat.mode & S_IXGRP) ? 'x' : '-';
+		perm[7] = (curr->stat.mode & S_IROTH) ? 'r' : '-';
+		perm[8] = (curr->stat.mode & S_IWOTH) ? 'w' : '-';
+		perm[9] = (curr->stat.mode & S_IXOTH) ? 'x' : '-';
+		Passwd *pwd = getpwuid(curr->stat.uid);
+		Group *grp = getgrgid(curr->stat.gid);
+		if ((curr->stat.mode & S_IXUSR)
+		 || (curr->stat.mode & S_IXGRP)
+		 || (curr->stat.mode & S_IXOTH))
+			executable = 1;
+
+		printf("%s %*d %*s %*s %*d ", perm,
+		       linkWidth, curr->stat.nlink,
+		       -unameWidth, pwd->username,
+		       -groupWidth, grp->name,
+		       sizeWidth, curr->stat.size);
+
+		if (curr->type == DT_DIR)
+			printf("\033[1;34m%s\033[0m\n", curr->name);
+		else if (curr->type == DT_CHR || curr->type == DT_BLK)
+			printf("\033[1;33m%s\033[0m\n", curr->name);
+		else if (curr->type == DT_LNK)
+			printf("\033[1;36m%s\033[0m\n", curr->name);
+		else if (curr->type == DT_REG && executable)
+			printf("\033[1;32m%s\033[0m\n", curr->name);
+		else
+			printf("%s\n", curr->name);
+		printed++;
+
+		/* Remove from list */
+		if (prev)
+			prev->next = next;
+		if (next)
+			next->prev = prev;
+		if (curr == head)
+			head = next;
+		free(curr);
+	}
+}
+
+/* List files in a directory */
+static void
+ls(char *name)
+{
+	int fd, sz, i;
+	char *buf, cwd[1024];
+	struct stat statbuf;
+	struct dirent *de;
+
+	Result *head = NULL, *prev = NULL, *next, *curr;
+	size_t len = 0, longest = 0;
+
+	fd = open(name, O_RDONLY);
+	if (fd < 0) {
+		printf("%s: %s: ", progname, name);
+		perror(NULL);
+		return;
+	}
+
+	stat(name, &statbuf);
+	if (!S_ISDIR(statbuf.mode)) {
+		close(fd);
+		return;
+	}
+
+	getcwd(cwd, 1024);
+	chdir(name);
+
+	/* Get Directory Entries */
+	buf = malloc(512);
+	sz = getdents(fd, buf, 512);
+	for (de = (void *) buf;
+	     de < (struct dirent *) (buf + sz);
+	     de = (void *) de + de->namelen + sizeof(struct dirent)) {
+		if (de->name[0] == '.' && !allFlag)
+			continue;
+		curr = malloc(sizeof(Result));
+		curr->next = NULL;
+		curr->prev = prev;
+		curr->ino = de->ino;
+		curr->type = de->type;
+		curr->namelen = de->namelen;
+		memcpy(curr->name, de->name, de->namelen);
+		curr->name[de->namelen] = '\0';
+		stat(curr->name, &curr->stat);
+		if (prev)
+			prev->next = curr;
+		else
+			head = curr;
+		prev = curr;
+		len++;
+
+		if (longest < curr->namelen)
+			longest = curr->namelen;
+	}
+	free(buf);
+	close(fd);
+
+	head = sort_results(head, compare_name);
+	head = sort_results(head, compare_type);
+
+	if (longFlag)
+		print_long(head);
+	else
+		print_normal(head);
+
+	chdir(cwd);
+}
+
+/* Main function */
+int
+main(int argc, char *argv[])
+{
+	int i;
+	ioctl(STDOUT_FILENO, TCGWINSZ, &termsz);
+
+	ARGBEGIN {
+	case 'a':
+		allFlag = 1;
+		break;
+	case 'l':
+		longFlag = 1;
+		break;
+	default:
+		printf("Usage:\n");
+	} ARGEND;
+
+	if (argc == 0) {
+		ls(".");
+		return 0;
+	}
+
+	if (argc == 1) {
+		ls(argv[0]);
+		return 0;
+	}
+
+	for (i = 0; i < argc; i++) {
+		printf("%s:\n", argv[i]);
+		ls(argv[i]);
+		if (i < argc-1)
+			printf("\n");
+	}
+
+	return 0;
+}
diff --git a/pwd/Makefile b/pwd/Makefile
new file mode 100644
index 0000000..5254c7c
--- /dev/null
+++ b/pwd/Makefile
@@ -0,0 +1,46 @@
+PRODUCT=$(notdir $(abspath $(CURDIR)))
+
+CC=i686-orion-gcc
+CFLAGS=
+
+AS=i686-orion-as
+AFLAGS=
+
+LD=i686-orion-gcc
+LFLAGS=
+
+AS_SOURCES := $(shell find . -name '*.S')
+OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES))))
+
+C_SOURCES := $(shell find . -name '*.c')
+OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES))))
+
+.PHONY: clean all install
+
+all: $(PRODUCT)
+
+clean:
+	@echo "REMOVING OBJECT FILES"
+	@mkdir -p build
+	@rm -rf build
+	@touch $(PRODUCT)
+	@rm $(PRODUCT)
+
+install: $(PRODUCT)
+	@echo "INSTALLING $^"
+	@mkdir -p ${SYSROOT}/bin/
+	@install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/
+
+$(PRODUCT): $(OBJS)
+	@echo "LINKING $@"
+	@$(LD) -o $@ $^ $(LFLAGS)
+
+build/%.o: %.c
+	@echo "COMPILING $<"
+	@mkdir -p $(@D)
+	@$(CC) -c $< -o $@ $(CFLAGS)
+
+build/%.o: %.S
+	@echo "ASSEMBLING $<"
+	@mkdir -p $(@D)
+	@$(AS) $< -o $@ $(AFLAGS)
diff --git a/pwd/main.c b/pwd/main.c
new file mode 100644
index 0000000..be5c76f
--- /dev/null
+++ b/pwd/main.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/limits.h>
+
+/* Main function */
+int
+main(int argc, char *argv[])
+{
+	char cwd[PATH_MAX];
+	getcwd(cwd, PATH_MAX);
+	printf("%s\n", cwd);
+
+	return 0;
+}
diff --git a/pwd/pwd b/pwd/pwd
new file mode 100755
index 0000000..4cc5f35
Binary files /dev/null and b/pwd/pwd differ
diff --git a/sh/Makefile b/sh/Makefile
new file mode 100644
index 0000000..5254c7c
--- /dev/null
+++ b/sh/Makefile
@@ -0,0 +1,46 @@
+PRODUCT=$(notdir $(abspath $(CURDIR)))
+
+CC=i686-orion-gcc
+CFLAGS=
+
+AS=i686-orion-as
+AFLAGS=
+
+LD=i686-orion-gcc
+LFLAGS=
+
+AS_SOURCES := $(shell find . -name '*.S')
+OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES))))
+
+C_SOURCES := $(shell find . -name '*.c')
+OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES))))
+
+.PHONY: clean all install
+
+all: $(PRODUCT)
+
+clean:
+	@echo "REMOVING OBJECT FILES"
+	@mkdir -p build
+	@rm -rf build
+	@touch $(PRODUCT)
+	@rm $(PRODUCT)
+
+install: $(PRODUCT)
+	@echo "INSTALLING $^"
+	@mkdir -p ${SYSROOT}/bin/
+	@install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/
+
+$(PRODUCT): $(OBJS)
+	@echo "LINKING $@"
+	@$(LD) -o $@ $^ $(LFLAGS)
+
+build/%.o: %.c
+	@echo "COMPILING $<"
+	@mkdir -p $(@D)
+	@$(CC) -c $< -o $@ $(CFLAGS)
+
+build/%.o: %.S
+	@echo "ASSEMBLING $<"
+	@mkdir -p $(@D)
+	@$(AS) $< -o $@ $(AFLAGS)
diff --git a/sh/main.c b/sh/main.c
new file mode 100644
index 0000000..d1319ad
--- /dev/null
+++ b/sh/main.c
@@ -0,0 +1,131 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+#include <limits.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <dirent.h>
+#include <errno.h>
+#include <pwd.h>
+
+#define PS1 "\033[1;31m%s\033[0m@\033[1m%s\033[0m:\033[1;32m%s\033[0m$> "
+
+int argparser(char *str, char **res);
+
+/* Get the nice current working directory */
+static void
+shell_getcwd(char *cwd, char *homedir)
+{
+	getcwd(cwd, PATH_MAX);
+	/* Replace the homedir with "~" */
+	if (!strncmp(cwd, homedir, strlen(homedir))) {
+		strncpy(cwd + 1, cwd + strlen(homedir),
+		        PATH_MAX - strlen(homedir));
+		cwd[0] = '~';
+	}
+}
+
+/* Main function */
+int
+main(int argc, char *argv[])
+{
+	int fd, sz, i;
+	char *buf;
+	struct stat statbuf;
+	struct dirent *de;
+
+	/* Get username */
+	uid_t uid = getuid();
+	char *hostname, *username, *cwd, *homedir, *line, *ptr;
+	username = malloc(33);
+	homedir = malloc(PATH_MAX);
+	Passwd *pwd = getpwuid(uid);
+	strcpy(username, pwd->username);
+	strcpy(homedir, pwd->homedir);
+
+	/* Get hostname */
+	hostname = malloc(HOST_NAME_MAX + 1);
+	fd = open("/etc/hostname", O_RDONLY);
+	sz = lseek(fd, 0, SEEK_END);
+	lseek(fd, 0, SEEK_SET);
+	read(fd, hostname, sz - 1);
+	close(fd);
+
+	/* Get current working directory */
+	cwd = malloc(PATH_MAX);
+	shell_getcwd(cwd, homedir);
+
+	line = malloc(1024);
+	pid_t child;
+	int err, count, status;
+	char *v[256], filename[PATH_MAX] = {'/','b','i','n','/'};
+	while (1) {
+		printf(PS1, username, hostname, cwd);
+		memset(line, 0, 1024);
+		sz = read(STDIN_FILENO, line, 1024);
+
+		line[--sz] = '\0';
+		if (sz < 1)
+			continue;
+
+		count = argparser(line, v);
+
+		/* Change directory (built-in) */
+		if (!strcmp(v[0], "cd")) {
+			err = chdir(v[1]);
+			if (err < 0) {
+				printf("%s: cd: ", argv[0]);
+				perror(NULL);
+			} else {
+				shell_getcwd(cwd, homedir);
+			}
+			continue;
+		}
+		/* Exit (built-in) */
+		if (!strcmp(v[0], "exit"))
+			exit(0);
+
+		/* Check if program exists */
+		memcpy(filename+5, v[0], PATH_MAX-5);
+		err = stat(filename, NULL);
+		if (err < 0) {
+			if (errno == ENOENT) {
+				printf("%s: %s: Command not found\n",
+				       argv[0], v[0]);
+			} else {
+				printf("%s: %s: ", argv[0], v[0]);
+				perror(NULL);
+			}
+			continue;
+		}
+
+		/* Execute program */
+		child = fork();
+		if (!child) {
+			err = execv(filename, v);
+			if (err < 0) {
+				printf("%s: %s: ", argv[0], v[0]);
+				perror(NULL);
+			}
+			exit(EXIT_FAILURE);
+		} else {
+			if (waitpid(child, &status, 0) < 0)
+				perror("waitpid");
+			if (WIFEXITED(status) && WEXITSTATUS(status))
+				printf("Exited with status %d\n",
+				       WEXITSTATUS(status));
+			if (WIFSIGNALED(status) && WTERMSIG(status)) {
+				switch (WTERMSIG(status)) {
+				case SIGSEGV:
+					printf("Segmentation fault\n");
+					break;
+				}
+			}
+		}
+		child = 0;
+	}
+}
diff --git a/sh/parser.c b/sh/parser.c
new file mode 100644
index 0000000..6c0af04
--- /dev/null
+++ b/sh/parser.c
@@ -0,0 +1,24 @@
+#include <string.h>
+
+/* Split a string into separate strings */
+int
+argparser(char *str, char **res)
+{
+	int count = 0;
+	char *finder;
+
+	memset(res, 0, 1024);
+	finder = str;
+	while (*finder == ' ') finder++;
+	res[count++] = finder;
+	while (*finder) {
+		if (*finder == ' ') {
+			res[count++] = finder + 1;
+			*finder = '\0';
+		}
+		finder++;
+	}
+	res[count] = NULL;
+
+	return count;
+}
diff --git a/sh/sh b/sh/sh
new file mode 100755
index 0000000..6326a89
Binary files /dev/null and b/sh/sh differ
diff --git a/time/Makefile b/time/Makefile
new file mode 100644
index 0000000..5254c7c
--- /dev/null
+++ b/time/Makefile
@@ -0,0 +1,46 @@
+PRODUCT=$(notdir $(abspath $(CURDIR)))
+
+CC=i686-orion-gcc
+CFLAGS=
+
+AS=i686-orion-as
+AFLAGS=
+
+LD=i686-orion-gcc
+LFLAGS=
+
+AS_SOURCES := $(shell find . -name '*.S')
+OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES))))
+
+C_SOURCES := $(shell find . -name '*.c')
+OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES))))
+
+.PHONY: clean all install
+
+all: $(PRODUCT)
+
+clean:
+	@echo "REMOVING OBJECT FILES"
+	@mkdir -p build
+	@rm -rf build
+	@touch $(PRODUCT)
+	@rm $(PRODUCT)
+
+install: $(PRODUCT)
+	@echo "INSTALLING $^"
+	@mkdir -p ${SYSROOT}/bin/
+	@install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/
+
+$(PRODUCT): $(OBJS)
+	@echo "LINKING $@"
+	@$(LD) -o $@ $^ $(LFLAGS)
+
+build/%.o: %.c
+	@echo "COMPILING $<"
+	@mkdir -p $(@D)
+	@$(CC) -c $< -o $@ $(CFLAGS)
+
+build/%.o: %.S
+	@echo "ASSEMBLING $<"
+	@mkdir -p $(@D)
+	@$(AS) $< -o $@ $(AFLAGS)
diff --git a/time/main.c b/time/main.c
new file mode 100644
index 0000000..89ef9ab
--- /dev/null
+++ b/time/main.c
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/times.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+/* Main function */
+int
+main(int argc, char *argv[])
+{
+	pid_t pid;
+	Times tms;
+	clock_t r0, r1;
+	int status, ret = 0;
+
+	if (argc < 2)
+		return 0;
+
+	r0 = times(&tms);
+
+	pid = fork();
+	if (!pid) {
+		execv(argv[1], argv + 1);
+		printf("exec: %s: ", argv[1]);
+		perror(NULL);
+		exit(EXIT_FAILURE);
+	}
+	waitpid(pid, &status, 0);
+
+	if ((r1 = times(&tms)) == (clock_t) -1) {
+		perror("times");
+		exit(EXIT_FAILURE);
+	}
+
+	printf("\nreal %dms\nuser %dms\nsys  %dms\n",
+	       (r1 - r0), tms.cutime, tms.cstime);
+//	printf("\nreal %f\nuser %f\nsys %f\n",
+//	       (r1 - r0)  / (double) 1000,
+//	       tms.cutime / (double) 1000,
+//	       tms.cstime / (double) 1000);
+
+	return 0;
+}
diff --git a/time/time b/time/time
new file mode 100755
index 0000000..cf03725
Binary files /dev/null and b/time/time differ