BarryServer : Git

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

// Related

OrionUserland

Barry Importing existing Orion Userland 19aefaa (2 years, 4 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;
+	}
+}