quinn-os/shell.c
2015-08-24 16:50:16 +10:00

211 lines
4.4 KiB
C

#include <stdarg.h>
#include "vfs.h"
#include "syscalls.h"
char command[256];
struct vfs_device_t *curdrive = (struct vfs_device_t *)0;
unsigned char cmd_enter;
int cmd_at;
void task() {
int ret;
int i;
for (i=0;i<10000;i++) {
}
__asm__ volatile ("int $0x30" : "=a" (ret) : "0" (1));
kprintf("UH OH\n");
while (1);
}
void shell(void) {
kprintf("QUINN Kernel Shell.\n");
char **argv;
int argc;
char *ptr1;
char *ptr2;
char *newArg;
char *newPath;
int size;
int i;
int fno;
char buffer[256];
int read;
int ret;
int consolefd;
__asm__ volatile ("int $0x30" : "=a" (consolefd) : "0" (SYS_OPEN), "b" ("console:/"), "c" (O_RDWR), "d" (0));
while (1) {
memset(command, 0, 256);
if (curdrive) {
kprintf("\n%s:%s$ ", curdrive->name, curdrive->cwd);
} else {
kprintf("\nNoDevice$ ");
}
update_cursor();
cmd_at = 0;
cmd_enter = 0;
char c;
while (!cmd_enter) {
if (vfs_read_file(consolefd, &c, 1)) {
if (c == '\n') {
cmd_enter = 1;
} else {
command[cmd_at] = c;
cmd_at++;
}
}
}
ptr1 = command;
ptr2 = command;
argc = 0;
argv = (char **)0;
while (ptr2 != command + strlen(command)) {
while (*ptr1 == ' ') {
ptr1++;
}
ptr2 = ptr1;
while (*ptr2 != ' ' && *ptr2 != '\0') {
ptr2++;
}
size = ptr2 - ptr1 + 1;
newArg = (char *)malloc(sizeof(char) * size);
memset(newArg, 0, size);
memcpy(newArg, ptr1, size - 1);
if (argc == 0) {
argv = (char **)malloc(sizeof(char *));
} else {
argv = (char **)realloc(argv, sizeof(char *) * (argc + 1));
}
argv[argc] = newArg;
argc++;
ptr1 = ptr2;
}
// process command
kprintf("\n");
if (argc > 0) {
if (strcmp(argv[0], "cd") == 0) {
if (!curdrive) {
kprintf("No drive selected.\n");
} else {
if (argc == 2) {
if (strcmp(argv[1], ".") == 0) {
newPath = (char *)malloc(sizeof(char) * (strlen(curdrive->cwd) + 1));
strcpy(newPath, curdrive->cwd);
} else
if (strcmp(argv[1], "..") == 0) {
newPath = (char *)malloc(sizeof(char) * (strlen(curdrive->cwd) + 1));
strcpy(newPath, curdrive->cwd);
if (strcmp(curdrive->cwd, "/") != 0) {
for (i=strlen(newPath) - 1;i > 0;i--) {
if (newPath[i] == '/') {
newPath[i] = '\0';
break;
}
}
if (strlen(newPath) == 0) {
newPath[0] = '/';
newPath[1] = '\0';
}
}
} else {
if (argv[1][0] == '/') {
newPath = (char *)malloc(sizeof(char) * (strlen(argv[1]) + 1));
strcpy(newPath, argv[1]);
} else {
newPath = (char *)malloc(sizeof(char) * (strlen(argv[1]) + strlen(curdrive->cwd) + 2));
if (strcmp(curdrive->cwd, "/") == 0) {
strcpy(newPath, curdrive->cwd);
strcat(newPath, argv[1]);
} else {
strcpy(newPath, curdrive->cwd);
strcat(newPath, "/");
strcat(newPath, argv[1]);
}
}
// chop of any trailing / if not root
if (strlen(newPath) > 1) {
if (newPath[strlen(newPath) - 1] == '/') {
newPath[strlen(newPath) - 1] = '\0';
}
}
}
vfs_change_directory(curdrive, newPath);
kprintf("change directory to \"%s\"\n", newPath);
free(newPath);
} else {
kprintf("Usage cd directory\n");
}
}
} else
if (strcmp(argv[0], "dir") == 0) {
if (!curdrive) {
kprintf("No drive selected.\n");
} else {
vfs_list_directory_contents(curdrive);
}
} else
if (argv[0][strlen(argv[0]) - 1] == ':') {
argv[0][strlen(argv[0]) - 1] = '\0';
curdrive = vfs_select_device(argv[0]);
if (!curdrive) {
kprintf("Drive %s does not exist\n", command);
}
} else
if (strcmp(argv[0], "type") == 0) {
fno = vfs_open_file(argv[1], O_RDONLY, 0);
if (fno > -1) {
read = vfs_read_file(fno, buffer, 256);
//kprintf("Read %d\n", read);
while (read > 0) {
for (i=0;i<read;i++) {
putchar(buffer[i]);
}
read = vfs_read_file(fno, buffer, 256);
}
vfs_close_file(fno);
} else {
kprintf("Error Opening File.\n");
}
} else
if (strcmp(argv[0], "fork") == 0) {
} else {
kprintf("Unknown command!\n");
}
// free up arguments
for (i=0;i<argc;i++) {
free(argv[i]);
}
if (argv) {
free(argv);
argv = (char **)0;
}
argc = 0;
}
}
}