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