OrionUserland
Barry Importing existing Orion Userland 19aefaa (3 years, 3 months ago)
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;
+ }
+}