BarryServer : Git

All the code for all my projects
// BarryServer : Git / OrionUserland / blob / f8ba6df5ab36d7554d045837b3f053ab6db75e5d / sh / main.c

// Related

OrionUserland

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