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; + } +}