BarryServer : Git

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

// Related

OrionUserland

Barry Importing existing Orion Userland 19aefaa (2 years, 4 months ago)
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