[shell] Tab completion, basic work on writing files
This commit is contained in:
parent
149225e097
commit
062e6fcd43
@ -2,7 +2,7 @@
|
||||
#include <ext2.h>
|
||||
#include <fs.h>
|
||||
|
||||
#define EXT2_DEBUG_BLOCK_DESCRIPTORS 1
|
||||
#define EXT2_DEBUG_BLOCK_DESCRIPTORS 0
|
||||
|
||||
#define BLOCKSIZE 1024
|
||||
#define SECTORSIZE 512
|
||||
@ -31,7 +31,9 @@ uint32_t ext2_disk_bg_descriptors = 0;
|
||||
#define RN ext2_root_fsnode
|
||||
#define DC ext2_disk_cache
|
||||
|
||||
#define BLOCKBIT(n) (bg_buffer[(n / 8)] & (1 << ((n % 8))))
|
||||
#define BLOCKBIT(n) (bg_buffer[((n) / 8)] & (1 << (((n) % 8))))
|
||||
#define BLOCKBYTE(n) (bg_buffer[((n) / 8)])
|
||||
#define SETBIT(n) (1 << (((n) % 8)))
|
||||
|
||||
static uint32_t btos(uint32_t block) {
|
||||
return block * (BLOCKSIZE / SECTORSIZE);
|
||||
@ -62,7 +64,9 @@ void ext2_disk_read_block(uint32_t block_no, uint8_t * buf) {
|
||||
void ext2_disk_write_block(uint32_t block_no, uint8_t * buf) {
|
||||
if (!block_no) return;
|
||||
ide_write_sector(DISK_PORT, 0, btos(block_no) + 0, (uint8_t *)((uint32_t)buf + 0));
|
||||
ide_write_sector(DISK_PORT, 0, btos(block_no) + 0, (uint8_t *)((uint32_t)buf + SECTORSIZE));
|
||||
timer_wait(10);
|
||||
ide_write_sector(DISK_PORT, 0, btos(block_no) + 1, (uint8_t *)((uint32_t)buf + SECTORSIZE));
|
||||
timer_wait(10);
|
||||
int oldest = -1;
|
||||
uint32_t oldest_age = UINT32_MAX;
|
||||
for (uint32_t i = 0; i < CACHEENTRIES; ++i) {
|
||||
@ -110,6 +114,56 @@ uint32_t ext2_disk_inode_block(ext2_inodetable_t * inode, uint32_t block, uint8_
|
||||
return 0;
|
||||
}
|
||||
|
||||
ext2_inodetable_t * ext2_disk_alloc_inode(ext2_inodetable_t * parent, char * name) {
|
||||
#if 0
|
||||
/* Allocate a new inode with parent as the parent directory node and name as the filename
|
||||
* within that parent directory. Returns a pointer to a memory-copy of the node which
|
||||
* the client can (and should) free. */
|
||||
ext2_inodetable_t * inode = (ext2_inodetable_t * )malloc(BLOCKSIZE);
|
||||
uint32_t node_no = 0, node_offset = 0, group = 0;
|
||||
char bg_buffer[BLOCKSIZE];
|
||||
/* Locate a block with an available inode. Will probably be the first block group. */
|
||||
for (uint32_t i = 0; i < BGDS; ++i) {
|
||||
if (BGD[i].free_inodes_count > 0) {
|
||||
kprintf("Group %d has %d free inodes!\n", i, BGD[i].free_inodes_count);
|
||||
ext2_disk_read_block(BGD[i].inode_bitmap, (uint8_t *)bg_buffer);
|
||||
node_offset = 0;
|
||||
while (BLOCKBIT(node_offset)) ++node_offset;
|
||||
node_no = node_offset + ext2_disk_inodes_per_group * i + 1;
|
||||
group = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!node_no) {
|
||||
free(inode);
|
||||
return NULL;
|
||||
}
|
||||
/* Alright, we found an inode (node_no), we need to mark it as in-use... */
|
||||
uint8_t b = BLOCKBYTE(node_offset);
|
||||
kprintf("Located an inode at #%d (%d), the byte for this block is currently set to %x\n", node_no, node_offset, (uint32_t)b);
|
||||
b |= SETBIT(node_offset);
|
||||
kprintf("We would want to set it to %x\n", (uint32_t)b);
|
||||
kprintf("Setting it in our temporary buffer...\n");
|
||||
BLOCKBYTE(node_offset) = b;
|
||||
for (uint32_t i = 0; i < BLOCKSIZE / 4; ++i) {
|
||||
kprintf("%x", ((uint32_t *)bg_buffer)[i]);
|
||||
}
|
||||
kprintf("\nWriting back out.\n");
|
||||
ext2_disk_write_block(BGD[group].inode_bitmap, (uint8_t * )bg_buffer);
|
||||
kprintf("Okay, now we need to update the available inodes count...\n");
|
||||
kprintf("it is %d, it should be %d\n", BGD[group].free_inodes_count, BGD[group].free_inodes_count - 1);
|
||||
BGD[group].free_inodes_count -= 1;
|
||||
for (uint32_t i = 0; i < BLOCKSIZE / 4; ++i) {
|
||||
kprintf("%x", ((uint32_t *)BGD)[i]);
|
||||
}
|
||||
kprintf("\nOkay, writing the block descriptors back to disk.\n");
|
||||
ext2_disk_write_block(2, (uint8_t *)BGD);
|
||||
kprintf("Alright, we have an inode (%d), time to write it out to disk and make the file in the directory.\n", node_no);
|
||||
free(inode);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ext2_dir_t * ext2_disk_direntry(ext2_inodetable_t * inode, uint32_t index) {
|
||||
uint8_t * block = malloc(BLOCKSIZE);
|
||||
ext2_disk_inode_block(inode,0,block);
|
||||
|
@ -163,6 +163,7 @@ int kgets_want = 0;
|
||||
int kgets_newline = 0;
|
||||
int kgets_cancel = 0;
|
||||
kgets_redraw_t kgets_redraw_func = NULL;
|
||||
kgets_tab_complete_t kgets_tab_complete_func = NULL;
|
||||
|
||||
static void
|
||||
kwrite(
|
||||
@ -196,7 +197,11 @@ kgets_handler(
|
||||
if (kgets_redraw_func) {
|
||||
kgets_redraw_func();
|
||||
}
|
||||
kprintf(kgets_buffer);
|
||||
kgets_redraw_buffer();
|
||||
return;
|
||||
} else if (ch == '\t' && kgets_tab_complete_func) {
|
||||
kgets_tab_complete_func(kgets_buffer);
|
||||
kgets_collected = strlen(kgets_buffer);
|
||||
return;
|
||||
} else if (ch == '\n') {
|
||||
/* Newline finishes off the kgets() */
|
||||
@ -211,6 +216,10 @@ kgets_handler(
|
||||
}
|
||||
}
|
||||
|
||||
void kgets_redraw_buffer() {
|
||||
kprintf(kgets_buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously get a string from the keyboard.
|
||||
*
|
||||
@ -239,6 +248,7 @@ kgets(
|
||||
/* Disable the buffer */
|
||||
keyboard_buffer_handler = NULL;
|
||||
kgets_redraw_func = NULL;
|
||||
kgets_tab_complete_func = NULL;
|
||||
/* Return the string */
|
||||
return kgets_collected;
|
||||
}
|
||||
|
@ -203,10 +203,13 @@ uint32_t shell_cmd_ls(int argc, char * argv[]) {
|
||||
struct dirent * entry = NULL;
|
||||
int i = 0;
|
||||
fs_node_t * ls_node;
|
||||
char * dir_path;
|
||||
if (argc < 2) {
|
||||
ls_node = shell.node;
|
||||
dir_path = shell.path;
|
||||
} else {
|
||||
ls_node = kopen(argv[1], 0);
|
||||
dir_path = argv[1];
|
||||
if (!ls_node) {
|
||||
kprintf("%s: Could not stat directory '%s'.\n", argv[0], argv[1]);
|
||||
return 1;
|
||||
@ -215,12 +218,12 @@ uint32_t shell_cmd_ls(int argc, char * argv[]) {
|
||||
entry = readdir_fs(ls_node, i);
|
||||
while (entry != NULL) {
|
||||
char * filename = malloc(sizeof(char) * 1024);
|
||||
memcpy(filename, shell.path, strlen(shell.path));
|
||||
if (!strcmp(shell.path,"/")) {
|
||||
memcpy((void *)((uintptr_t)filename + strlen(shell.path)),entry->name,strlen(entry->name)+1);
|
||||
memcpy(filename, dir_path, strlen(dir_path));
|
||||
if (!strcmp(dir_path,"/")) {
|
||||
memcpy((void *)((uintptr_t)filename + strlen(dir_path)),entry->name,strlen(entry->name)+1);
|
||||
} else {
|
||||
filename[strlen(shell.path)] = '/';
|
||||
memcpy((void *)((uintptr_t)filename + strlen(shell.path) + 1),entry->name,strlen(entry->name)+1);
|
||||
filename[strlen(dir_path)] = '/';
|
||||
memcpy((void *)((uintptr_t)filename + strlen(dir_path) + 1),entry->name,strlen(entry->name)+1);
|
||||
}
|
||||
fs_node_t * chd = kopen(filename, 0);
|
||||
if (chd) {
|
||||
@ -308,6 +311,14 @@ uint32_t shell_cmd_writedisk(int argc, char * argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <ext2.h>
|
||||
ext2_inodetable_t * ext2_disk_alloc_inode(ext2_inodetable_t * parent, char * name);
|
||||
|
||||
uint32_t shell_cmd_testing(int argc, char * argv[]) {
|
||||
ext2_inodetable_t * derp = ext2_disk_alloc_inode(NULL, "test");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void install_commands() {
|
||||
shell_install_command("cd", shell_cmd_cd);
|
||||
shell_install_command("ls", shell_cmd_ls);
|
||||
@ -319,12 +330,124 @@ void install_commands() {
|
||||
shell_install_command("read-sb", shell_cmd_readsb);
|
||||
shell_install_command("read-disk", shell_cmd_readdisk);
|
||||
shell_install_command("write-disk", shell_cmd_writedisk);
|
||||
shell_install_command("test-alloc-block", shell_cmd_testing);
|
||||
}
|
||||
|
||||
void add_path_contents() {
|
||||
struct dirent * entry = NULL;
|
||||
int i = 0;
|
||||
fs_node_t * ls_node;
|
||||
ls_node = kopen("/bin", 0);
|
||||
char * dir_path = "/bin";
|
||||
if (!ls_node) {
|
||||
kprintf("Failed to open /bin\n");
|
||||
return;
|
||||
}
|
||||
entry = readdir_fs(ls_node, i);
|
||||
while (entry != NULL) {
|
||||
char * filename = malloc(sizeof(char) * 1024);
|
||||
memcpy(filename, dir_path, strlen(dir_path));
|
||||
filename[strlen(dir_path)] = '/';
|
||||
memcpy((void *)((uintptr_t)filename + strlen(dir_path) + 1),entry->name,strlen(entry->name)+1);
|
||||
fs_node_t * chd = kopen(filename, 0);
|
||||
if (chd) {
|
||||
if (chd->flags & FS_DIRECTORY) {
|
||||
} else if ((chd->mask & 0x001) || (chd->mask & 0x008) || (chd->mask & 0x040)) {
|
||||
char * s = malloc(sizeof(char) * (strlen(entry->name) + 1));
|
||||
memcpy(s, entry->name, strlen(entry->name) + 1);
|
||||
shell_install_command(s, NULL);
|
||||
}
|
||||
close_fs(chd);
|
||||
}
|
||||
free(filename);
|
||||
free(entry);
|
||||
i++;
|
||||
entry = readdir_fs(ls_node, i);
|
||||
}
|
||||
if (ls_node != shell.node) {
|
||||
close_fs(ls_node);
|
||||
}
|
||||
}
|
||||
|
||||
void tab_complete_shell(char * buffer) {
|
||||
char buf[1024];
|
||||
memcpy(buf, buffer, 1024);
|
||||
char * pch;
|
||||
char * cmd;
|
||||
char * save;
|
||||
pch = strtok_r(buf," ",&save);
|
||||
cmd = pch;
|
||||
char * argv[1024]; /* Command tokens (space-separated elements) */
|
||||
int argc = 0;
|
||||
if (!cmd) {
|
||||
argv[0] = "";
|
||||
argc = 1;
|
||||
} else {
|
||||
while (pch != NULL) {
|
||||
argv[argc] = (char *)pch;
|
||||
++argc;
|
||||
pch = strtok_r(NULL," ",&save);
|
||||
}
|
||||
}
|
||||
argv[argc] = NULL;
|
||||
if (argc < 2) {
|
||||
if (buffer[strlen(buffer)-1] == ' ' || argc == 0) {
|
||||
kprintf("\n");
|
||||
for (uint32_t i = 0; i < shell_commands_len; ++i) {
|
||||
kprintf(shell_commands[i]);
|
||||
if (i < shell_commands_len - 1) {
|
||||
kprintf(", ");
|
||||
}
|
||||
}
|
||||
kprintf("\n");
|
||||
redraw_shell();
|
||||
kgets_redraw_buffer();
|
||||
return;
|
||||
} else {
|
||||
uint32_t count = 0, j = 0;
|
||||
for (uint32_t i = 0; i < shell_commands_len; ++i) {
|
||||
if (strspn(shell_commands[i], argv[0]) == strlen(argv[0])) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < shell_commands_len; ++i) {
|
||||
if (strspn(shell_commands[i], argv[0]) == strlen(argv[0])) {
|
||||
if (count == 1) {
|
||||
for (uint32_t j = 0; j < strlen(buffer); ++j) {
|
||||
kprintf("\x08 \x08");
|
||||
}
|
||||
kprintf(shell_commands[i]);
|
||||
memcpy(buffer, shell_commands[i], strlen(shell_commands[i]) + 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
kprintf("\n");
|
||||
for (uint32_t i = 0; i < shell_commands_len; ++i) {
|
||||
if (strspn(shell_commands[i], argv[0]) == strlen(argv[0])) {
|
||||
kprintf(shell_commands[i]);
|
||||
++j;
|
||||
if (j < count) {
|
||||
kprintf(", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
kprintf("\n");
|
||||
redraw_shell();
|
||||
kgets_redraw_buffer();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* Complete path names */
|
||||
kprintf("%d\n", argc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
start_shell() {
|
||||
init_shell();
|
||||
install_commands();
|
||||
add_path_contents();
|
||||
while (1) {
|
||||
/* Read buffer */
|
||||
shell_update_time();
|
||||
@ -333,6 +456,7 @@ start_shell() {
|
||||
int size;
|
||||
/* Read commands */
|
||||
kgets_redraw_func = redraw_shell;
|
||||
kgets_tab_complete_func = tab_complete_shell;
|
||||
size = kgets((char *)&buffer, 1023);
|
||||
if (size < 1) {
|
||||
continue;
|
||||
|
@ -127,6 +127,9 @@ extern int sprintf(char *buf, const char *fmt, ...);
|
||||
extern int kgets(char *buf, int size);
|
||||
typedef void (*kgets_redraw_t)();
|
||||
extern kgets_redraw_t kgets_redraw_func;
|
||||
typedef void (*kgets_tab_complete_t)(char *);
|
||||
extern kgets_tab_complete_t kgets_tab_complete_func;
|
||||
extern void kgets_redraw_buffer();
|
||||
|
||||
/* Memory Management */
|
||||
extern uintptr_t placement_pointer;
|
||||
|
Loading…
Reference in New Issue
Block a user