diff --git a/Makefile b/Makefile index 5944011..50008c9 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ NAME := seyshell DRIVE := disk CC := gcc -CFLAGS := +CFLAGS := -Wall -Wextra -Werror -g OBJ_DIR := obj SRC_DIR := src diff --git a/src/const.h b/src/const.h index 1ae30ed..af896c5 100644 --- a/src/const.h +++ b/src/const.h @@ -7,6 +7,5 @@ #define TYPE_NULL 0 #define TYPE_FILE 1 -#define TYPE_BINARY 2 #define TYPE_DIRECTORY 3 #define TYPE_SYMBOLIC_LINK 4 \ No newline at end of file diff --git a/src/disk.c b/src/disk.c index a50b21e..64bcea4 100644 --- a/src/disk.c +++ b/src/disk.c @@ -1,5 +1,6 @@ /** @file */ #include "disk.h" +#include "env.h" #include "struct.h" #include #include @@ -48,15 +49,12 @@ int find_offset_in_parent_bloc(bloc *parent_bloc) { return -1; } -int create_directory(disk *disk, inode *parent, char *dirname) {} - -int create_file(disk *disk, inode *parent, char *filename) { +int allocate_node(disk *disk, inode *parent, char *name, char type) { int inode_index = 0; while (inode_index < MAX_INODE && disk->inodes[inode_index].filetype != TYPE_NULL) { inode_index++; } - if (inode_index >= MAX_INODE) { dprintf(STDERR_FILENO, "No free inodes\n"); return -1; @@ -70,46 +68,42 @@ int create_file(disk *disk, inode *parent, char *filename) { int p_bloc_idx = parent->blocs[0]; int offset = find_offset_in_parent_bloc(&disk->blocs[p_bloc_idx]); - if (offset == -1) { dprintf(STDERR_FILENO, "Parent directory full\n"); return -1; } - strncpy(&disk->blocs[p_bloc_idx].datas[offset], filename, MAX_INODE_NAME); + strncpy(&disk->blocs[p_bloc_idx].datas[offset], name, MAX_INODE_NAME); memcpy(&disk->blocs[p_bloc_idx].datas[offset + MAX_INODE_NAME], &inode_index, sizeof(int)); - init_inode_in_disk(disk, inode_index, TYPE_FILE, 0b111111111, new_bloc_idx); + init_inode_in_disk(disk, inode_index, type, 0b111111111, new_bloc_idx); + return inode_index; } -int create_inode(disk *disk, inode *parent, char inode_type, char *name) { - if (strlen(name) > MAX_INODE_NAME) { - dprintf(STDERR_FILENO, "A inode name must be < %d\n", MAX_INODE_NAME); - return -1; - } - if (parent->filetype != TYPE_DIRECTORY) { - dprintf(STDERR_FILENO, "A parent's inode must be a directory!\n"); - return -1; - } +int create_file(disk *disk, inode *parent, char *filename) { + return allocate_node(disk, parent, filename, TYPE_FILE); +} - switch (inode_type) { - case TYPE_DIRECTORY: - return create_directory(disk, parent, name); - break; - case TYPE_FILE: - return create_file(disk, parent, name); - case TYPE_BINARY: - // TODO plus tard - break; - case TYPE_SYMBOLIC_LINK: - // TODO plus tard - break; - default: - break; - } - return -1; +int create_directory(disk *disk, inode *parent, char *dirname) { + int new_idx = allocate_node(disk, parent, dirname, TYPE_DIRECTORY); + + if (new_idx == -1) + return -1; + + int bloc_idx = disk->inodes[new_idx].blocs[0]; + int entry_size = MAX_INODE_NAME + sizeof(int); + int p_idx = (int)(parent - disk->inodes); + + strncpy(&disk->blocs[bloc_idx].datas[0], ".", MAX_INODE_NAME); + memcpy(&disk->blocs[bloc_idx].datas[MAX_INODE_NAME], &new_idx, sizeof(int)); + + strncpy(&disk->blocs[bloc_idx].datas[entry_size], "..", MAX_INODE_NAME); + memcpy(&disk->blocs[bloc_idx].datas[entry_size + MAX_INODE_NAME], &p_idx, + sizeof(int)); + + return new_idx; } void write_in_file(disk *d, int file_index, char *data /*, char mode*/) { @@ -133,15 +127,60 @@ void write_in_file(disk *d, int file_index, char *data /*, char mode*/) { strncpy(&d->blocs[bloc_index_to_overwrite].datas[0], data, strlen(data)); } -void do_ls(disk *d, int dir_index) { - inode dir = d->inodes[dir_index]; - if (dir.filetype != TYPE_DIRECTORY) { - dprintf(STDERR_FILENO, "ls: Can only list in directories\n"); - return; +int find_dir_inode_by_name(char *name, int dir_index, disk *d) { + + int bloc = d->inodes[dir_index].blocs[0]; + + for (int i = 0; i < MAX_BYTES_PER_BLOC; i += MAX_INODE_NAME + sizeof(int)) { + char inode_name[MAX_INODE_NAME]; + strncpy(inode_name, &d->blocs[bloc].datas[i], MAX_INODE_NAME); + if (strcmp(name, inode_name) == 0) { + int inode_id; + memcpy(&inode_id, &d->blocs[bloc].datas[i + MAX_INODE_NAME], sizeof(int)); + return inode_id; + } } - // TODO: chercher sur tous les blocs possédés - int bloc = dir.blocs[0]; + return -1; +} + +int do_ls(disk *d, char *path) { + char *path_to_process; + + if (path == NULL) { + path_to_process = strdup(get_env_value("PWD")); + } else { + path_to_process = strdup(path); + } + + int dir_index = 0; + char *token = strtok(path_to_process, "/"); + + while (token != NULL) { + dir_index = find_dir_inode_by_name(token, dir_index, d); + + if (dir_index == -1) { + dprintf(STDERR_FILENO, "ls: This directory does not exist\n"); + free(path_to_process); + return -1; + } + + if (d->inodes[dir_index].filetype != TYPE_DIRECTORY) { + dprintf(STDERR_FILENO, "ls: '%s' is not a directory\n", token); + free(path_to_process); + return -1; + } + + token = strtok(NULL, "/"); + } + + inode dir_to_list = d->inodes[dir_index]; + int bloc = dir_to_list.blocs[0]; + + if (bloc == -1) { + free(path_to_process); + return 1; + } for (int i = 0; i < MAX_BYTES_PER_BLOC; i += MAX_INODE_NAME + sizeof(int)) { if (d->blocs[bloc].datas[i] != '\0') { @@ -150,6 +189,9 @@ void do_ls(disk *d, int dir_index) { dprintf(STDOUT_FILENO, "%-16s %d\n", &d->blocs[bloc].datas[i], inode_id); } } + + free(path_to_process); + return 1; } char *read_in_file(disk *d, int file_index) { @@ -163,7 +205,8 @@ char *read_in_file(disk *d, int file_index) { int bloc = file.blocs[0]; char *out; int c_index = 0; - while (d->blocs[bloc].datas[c_index] != '\0' || c_index < MAX_BYTES_PER_BLOC) { + while (d->blocs[bloc].datas[c_index] != '\0' || + c_index < MAX_BYTES_PER_BLOC) { c_index++; } @@ -178,9 +221,11 @@ char *read_in_file(disk *d, int file_index) { return out; } -void init_env_var_file(disk *d) { - int inode_idx = create_inode(d, &d->inodes[0], TYPE_FILE, "env"); - write_in_file(d, inode_idx, "PWD=/\nUSER=user"); +void init_test_files(disk *d) { + int inode_idx = create_file(d, &d->inodes[0], "test"); + write_in_file(d, inode_idx, "Contenu du fichier :)\n"); + int dir_idx = create_directory(d, &d->inodes[0], "dir"); + create_file(d, &d->inodes[dir_idx], "test1"); } /** @@ -211,7 +256,7 @@ disk create_disk() { d.inodes[0].blocs[0] = 0; // utilise le bloc 0 d.owned_blocs[0] = 1; // le bloc 1 est maintenant occupé - init_env_var_file(&d); + init_test_files(&d); int n = fwrite(&d, sizeof(disk), 1, fptr); if (n == 1) { diff --git a/src/disk.h b/src/disk.h index 424aaf5..2b49efe 100644 --- a/src/disk.h +++ b/src/disk.h @@ -5,7 +5,8 @@ #include "const.h" #include "struct.h" #include +#include "env.h" disk create_disk(); disk open_disk(char* filename); -void do_ls(disk *d, int dir_index); \ No newline at end of file +int do_ls(disk *d, char* path); \ No newline at end of file diff --git a/src/env.c b/src/env.c new file mode 100644 index 0000000..516793b --- /dev/null +++ b/src/env.c @@ -0,0 +1,47 @@ +#include "env.h" + +env *init_envs() { + env *envs = malloc(sizeof(env) * 3); + + if (envs == NULL) + return NULL; + + envs[0].key = "PWD"; + envs[0].value = "/"; + + envs[1].key = "USER"; + envs[1].value = "guams"; + + envs[2].key = "HOST"; + envs[2].value = "tartempion"; + + return envs; +} + +env *get_instance() { + static env *instance = NULL; + + if (instance == NULL) { + instance = init_envs(); + } + + return instance; +} + +int get_env_len(env *envs) { + int i = 0; + while (envs[i].key != NULL) { + i++; + } + return i; +} + +char *get_env_value(char *key) { + env *envs = get_instance(); + for (int i = 0; i < get_env_len(envs); i++) { + if (strcmp(envs[i].key, key) == 0) { + return envs[i].value; + } + } + return NULL; +} \ No newline at end of file diff --git a/src/env.h b/src/env.h new file mode 100644 index 0000000..b644a6d --- /dev/null +++ b/src/env.h @@ -0,0 +1,8 @@ +#pragma once +#include "struct.h" +#include +#include + +char* get_env_value(char* key); +int get_env_len(env *envs); +env* init_envs(); \ No newline at end of file diff --git a/src/exec.c b/src/exec.c index f8982d6..c418a21 100644 --- a/src/exec.c +++ b/src/exec.c @@ -1,18 +1,13 @@ /** @file */ #include "exec.h" +#include "disk.h" #include +#include #include -// TODO : Tout ce fichier est à changer je pense - -int is_builtin_cmd(char *executable) { - (void)executable; - return 0; -} - // à changer parce que je veux pas chercher dans le PATH, je veux juste executer // les futures primitives qui seront implémentées -int execute_cmd(char **args) { +/*int execute_cmd(char **args) { if (!is_builtin_cmd(args[0])) { int pid = fork(); if (pid == -1) @@ -30,4 +25,28 @@ int execute_cmd(char **args) { } } return 1; +} +*/ + +int child_process_job(disk *d, char **args) { + if (strcmp("ls", args[0]) == 0) { + do_ls(d, args[1]); + } + return 1; +} + +int execute_cmd(disk *d, char **args) { + int pid = fork(); + + if (pid == 1) { + return -1; + } + + if (pid == 0) { + child_process_job(d, args); + } else { + int status; + waitpid(pid, &status, WUNTRACED); + } + return 1; } \ No newline at end of file diff --git a/src/exec.h b/src/exec.h index c99313a..975f668 100644 --- a/src/exec.h +++ b/src/exec.h @@ -1,7 +1,8 @@ /** @file */ #pragma once +#include "disk.h" #include #include int is_builtin_cmd(char *executable); -int execute_cmd(char **args); \ No newline at end of file +int execute_cmd(disk *d, char **args); \ No newline at end of file diff --git a/src/main.c b/src/main.c index 185b985..23a0361 100644 --- a/src/main.c +++ b/src/main.c @@ -1,24 +1,17 @@ /** @file */ #include "disk.h" #include "parsing.h" -#include #include -int main(int argc, char *argv[], char *envp[]) { - (void)argc; - (void)argv; - (void)envp; - - // shell_loop(); +int main() { disk drive; if (access("disk", F_OK) == 0) { drive = open_disk("disk"); - do_ls(&drive, 0); } else drive = create_disk(); - (void)drive; + open_seyshell(&drive); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/src/parsing.c b/src/parsing.c index 04e4bec..6962677 100644 --- a/src/parsing.c +++ b/src/parsing.c @@ -1,6 +1,7 @@ /** @file */ #include "parsing.h" #include "const.h" +#include "env.h" #include "exec.h" #include #include @@ -15,6 +16,8 @@ char *read_line() { char c; int i = 0; + + // buffer overflow attention char *buffer = malloc(BUFSIZE * sizeof(char)); if (buffer == NULL) { dprintf(STDERR_FILENO, "Line read buffer allocation error !"); @@ -70,15 +73,14 @@ char **split_line(char *line) { * @see char** split_line(char *line) * @see int execute_cmd(char **args) */ -void shell_loop(void) { - char *user = getenv("USER"); +void shell_loop(disk *disk) { + char *user = get_env_value("USER"); - char *hostname = malloc(BUFSIZE * sizeof(char)); - if (hostname == NULL) { - dprintf(STDERR_FILENO, "Allocation error"); + if (user == NULL) { + exit(EXIT_FAILURE); } - // sur le sgf le hostname se récupèrera pas comme ça donc à changer :) - gethostname(hostname, sizeof(hostname)); + + char *hostname = get_env_value("HOST"); char *line; char **args; @@ -86,13 +88,19 @@ void shell_loop(void) { do { // ça aussi c'est pas bien, ça sera à changer une fois le sgf fonctionnel - dprintf(STDOUT_FILENO, "%s@%s %s> ", user, hostname, getenv("PWD")); + dprintf(STDOUT_FILENO, "%s@%s %s> ", user, hostname, get_env_value("PWD")); line = read_line(); args = split_line(line); - status = execute_cmd(args); + status = execute_cmd(disk, args); free(line); free(args); } while (status); } +void open_seyshell(disk* disk) { + env* envs = init_envs(); + shell_loop(disk); + free(envs); +} + diff --git a/src/parsing.h b/src/parsing.h index ac8543a..8b2f140 100644 --- a/src/parsing.h +++ b/src/parsing.h @@ -1,7 +1,9 @@ /** @file */ #pragma once +#include "env.h" #include #include #include +#include "struct.h" -void shell_loop(void); \ No newline at end of file +void open_seyshell(disk* disk); \ No newline at end of file diff --git a/src/struct.h b/src/struct.h index cd03a79..e60687e 100644 --- a/src/struct.h +++ b/src/struct.h @@ -2,6 +2,11 @@ #pragma once #include "const.h" +typedef struct env { + char* key; + char* value; +} env; + /** * @struct inode * @brief Un inode est un fichier, il possède des permissions, un type