199 lines
3.7 KiB
C
199 lines
3.7 KiB
C
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
|
|
// Castor Only
|
|
#include <syscall.h>
|
|
#include <sys/dirent.h>
|
|
|
|
#define SHELL_MAX_ARGS 5
|
|
#define SHELL_MAX_LINE 256
|
|
|
|
void DispatchCommand(char *buf);
|
|
|
|
int
|
|
main(int argc, const char *argv[])
|
|
{
|
|
char buf[256];
|
|
|
|
printf("System Shell\n");
|
|
|
|
while (1) {
|
|
fputs("Shell> ", stdout);
|
|
fgets(buf, sizeof(buf), stdin);
|
|
|
|
DispatchCommand(buf);
|
|
}
|
|
}
|
|
|
|
void
|
|
Cmd_Help(int argc, const char *argv[])
|
|
{
|
|
printf("cat Print file\n");
|
|
printf("bkpt Trigger a kernel breakpoint\n");
|
|
printf("date Print current date and time\n");
|
|
printf("echo Echo arguments\n");
|
|
printf("exit Exit shell\n");
|
|
printf("help Display the list of commands\n");
|
|
printf("ls List files in a directory\n");
|
|
printf("spawn Spawn a process\n");
|
|
}
|
|
|
|
void
|
|
Cmd_Echo(int argc, const char *argv[])
|
|
{
|
|
int i;
|
|
|
|
for (i = 1; i < argc; i++)
|
|
{
|
|
printf("%s ", argv[i]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
void
|
|
Cmd_List(int argc, const char *argv[])
|
|
{
|
|
int fd;
|
|
int status;
|
|
uintptr_t offset = 0;
|
|
|
|
if (argc != 2) {
|
|
fputs("Requires an argument\n", stdout);
|
|
return;
|
|
}
|
|
|
|
fd = OSOpen(argv[1], 0);
|
|
if (fd < 0) {
|
|
fputs("Cannot open directory\n", stdout);
|
|
return;
|
|
}
|
|
|
|
while (1) {
|
|
struct dirent de;
|
|
|
|
status = OSReadDir(fd, (char *)&de, sizeof(de), &offset);
|
|
if (status == 0) {
|
|
break;
|
|
}
|
|
if (status < 0) {
|
|
fputs("Error\n", stdout);
|
|
break;
|
|
}
|
|
|
|
printf("%s\n", de.d_name);
|
|
}
|
|
}
|
|
|
|
void
|
|
Cmd_Cat(int argc, const char *argv[])
|
|
{
|
|
int i;
|
|
int status, fd;
|
|
struct stat sb;
|
|
char buf[256];
|
|
|
|
if (argc != 2) {
|
|
fputs("Requires an argument\n", stdout);
|
|
return;
|
|
}
|
|
|
|
status = OSStat(argv[1], &sb);
|
|
if (status != 0) {
|
|
fputs("Cannot stat file\n", stdout);
|
|
return;
|
|
}
|
|
fd = OSOpen(argv[1], 0);
|
|
for (i = 0; i < sb.st_size; i += 256) {
|
|
int len = (sb.st_size - i > 256) ? 256 : (sb.st_size - i);
|
|
|
|
OSRead(fd, &buf, i, len);
|
|
OSWrite(1, &buf, 0, len);
|
|
}
|
|
}
|
|
|
|
void
|
|
Cmd_Date(int argc, const char *argv[])
|
|
{
|
|
time_t t = time(NULL);
|
|
fputs(ctime(&t), stdout);
|
|
}
|
|
|
|
void
|
|
Cmd_Hexdump(int argc, const char *argv[])
|
|
{
|
|
}
|
|
|
|
void
|
|
Cmd_Spawn(int argc, const char *argv[])
|
|
{
|
|
int fd;
|
|
uint64_t status;
|
|
uintptr_t offset = 0;
|
|
|
|
if (argc != 2) {
|
|
fputs("Requires an argument\n", stdout);
|
|
return;
|
|
}
|
|
|
|
status = OSSpawn(argv[1]);
|
|
// XXX: check errors
|
|
OSWait(status);
|
|
}
|
|
|
|
void
|
|
DispatchCommand(char *buf)
|
|
{
|
|
int i;
|
|
int argc;
|
|
char *argv[SHELL_MAX_ARGS];
|
|
char *nextArg;
|
|
|
|
// Remove newline
|
|
for (i = 0; buf[i] != 0; i++) {
|
|
if (buf[i] == '\n') {
|
|
buf[i] = '\0';
|
|
break;
|
|
}
|
|
}
|
|
|
|
// parse input
|
|
argv[0] = buf;
|
|
for (argc = 1; argc < SHELL_MAX_ARGS; argc++) {
|
|
nextArg = strchr(argv[argc - 1], ' ');
|
|
if (nextArg == NULL)
|
|
{
|
|
break;
|
|
}
|
|
|
|
*nextArg = '\0';
|
|
argv[argc] = nextArg + 1;
|
|
}
|
|
|
|
// execute command
|
|
if (strcmp(argv[0], "help") == 0) {
|
|
Cmd_Help(argc, (const char **)argv);
|
|
} else if (strcmp(argv[0], "bkpt") == 0) {
|
|
asm volatile("int3");
|
|
} else if (strcmp(argv[0], "cat") == 0) {
|
|
Cmd_Cat(argc, (const char **)argv);
|
|
} else if (strcmp(argv[0], "date") == 0) {
|
|
Cmd_Date(argc, (const char **)argv);
|
|
} else if (strcmp(argv[0], "echo") == 0) {
|
|
Cmd_Echo(argc, (const char **)argv);
|
|
} else if (strcmp(argv[0], "exit") == 0) {
|
|
exit(0);
|
|
} else if (strcmp(argv[0], "ls") == 0) {
|
|
Cmd_List(argc, (const char **)argv);
|
|
} else if (strcmp(argv[0], "spawn") == 0) {
|
|
Cmd_Spawn(argc, (const char **)argv);
|
|
} else if (strcmp(argv[0], "#") == 0) {
|
|
// Ignore comments
|
|
} else if (buf[0] != '\0') {
|
|
printf("Unknown command '%s'\n", buf);
|
|
}
|
|
}
|
|
|