From 15ff8e5b23ac6a929f3862ad4c956ddff29fedb0 Mon Sep 17 00:00:00 2001 From: Guamss Date: Mon, 4 May 2026 22:56:56 +0200 Subject: [PATCH] add: rm --- src/disk.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++----- src/disk.h | 1 + src/exec.c | 4 +- src/utils.c | 31 +++++++++++++++ src/utils.h | 3 +- 5 files changed, 137 insertions(+), 12 deletions(-) diff --git a/src/disk.c b/src/disk.c index 49194b5..b65f619 100644 --- a/src/disk.c +++ b/src/disk.c @@ -1,6 +1,8 @@ /** @file */ #include "disk.h" #include "env.h" +#include "struct.h" +#include #include #include #include @@ -80,6 +82,101 @@ int allocate_node(disk *disk, inode *parent, char *name, char type) { return inode_index; } +int remove_file(disk *disk, inode *parent, inode *inode_to_remove, + int inode_to_remove_idx) { + + if (parent == inode_to_remove) { + dprintf(STDERR_FILENO, "rm: can't delete root\n"); + return -1; + } + int parent_bloc_idx = parent->blocs[0]; + if (parent_bloc_idx == -1) { + return -1; + } + + int found = 0; + + // on efface la référence du fichier dans son parent + for (int i = 0; i < MAX_BYTES_PER_BLOC && !found; + i += MAX_INODE_NAME + sizeof(int)) { + if (*(int *)&disk->blocs[parent_bloc_idx].datas[i + MAX_INODE_NAME] == + inode_to_remove_idx) { + memset(&disk->blocs[parent_bloc_idx].datas[i], 0, + MAX_INODE_NAME + sizeof(int)); + found = 1; + } + } + + // on efface tout le contenu du fichier + int bloc_inode_idx = inode_to_remove->blocs[0]; + memset(&disk->blocs[bloc_inode_idx].datas[0], 0, MAX_BYTES_PER_BLOC); + + disk->owned_blocs[inode_to_remove->blocs[0]] = 0; + inode_to_remove->blocs[0] = -1; + inode_to_remove->perms = 0b000000000; + inode_to_remove->filetype = TYPE_NULL; + + return 1; +} + +int do_rm(disk *disk, char *filepath) { + char *parent_path = NULL; + char *dirname = NULL; + + if (get_dirname_and_parent_path_by_absolute_path(filepath, &parent_path, &dirname) == -1) { + dprintf(STDERR_FILENO, "rm: erreur de chemin\n"); + return -1; + } + + int parent_index = 0; + char *token = strtok(parent_path, "/"); + + while (token != NULL) { + parent_index = find_dir_inode_by_name(token, parent_index, disk); + + if (parent_index == -1) { + dprintf(STDERR_FILENO, "rm: le chemin '%s' n'existe pas\n", token); + free(parent_path); free(dirname); + return -1; + } + + if (disk->inodes[parent_index].filetype != TYPE_DIRECTORY) { + dprintf(STDERR_FILENO, "rm: '%s' n'est pas un dossier\n", token); + free(parent_path); free(dirname); + return -1; + } + + token = strtok(NULL, "/"); + } + + int file_index = find_dir_inode_by_name(dirname, parent_index, disk); + + if (file_index == -1) { + dprintf(STDERR_FILENO, "rm: impossible de supprimer '%s': Aucun fichier de ce nom\n", dirname); + free(parent_path); free(dirname); + return -1; + } + + if (disk->inodes[file_index].filetype != TYPE_FILE && + disk->inodes[file_index].filetype != TYPE_SYMBOLIC_LINK) { + dprintf(STDERR_FILENO, "rm: impossible de supprimer '%s': est un dossier\n", dirname); + free(parent_path); free(dirname); + return -1; + } + + int res = remove_file(disk, &disk->inodes[parent_index], &disk->inodes[file_index], file_index); + + if (res == 1) { + } else { + dprintf(STDERR_FILENO, "rm: erreur fatale lors de la suppression en mémoire\n"); + } + + free(parent_path); + free(dirname); + + return (res == 1) ? 0 : -1; +} + int create_file(disk *disk, inode *parent, char *filename) { return allocate_node(disk, parent, filename, TYPE_FILE); } @@ -110,7 +207,7 @@ int do_touch(disk *d, char *filepath) { if (get_name_and_parent_path_by_absolute_path(filepath, &parent_path, &dirname) == -1) { - dprintf(STDERR_FILENO, "touch: erreur jsp"); + dprintf(STDERR_FILENO, "touch: erreur jsp\n"); return -1; } @@ -328,11 +425,6 @@ char *read_in_file(disk *d, int file_index) { return out; } -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"); -} - /** * @brief Créer un fichier "disk" de taille MAX_BYTES_PER_BLOC * MAX_BLOCS, * renvoi ce disque @@ -365,8 +457,6 @@ disk create_disk() { int point_inode = 1; memcpy(&d.blocs[0].datas[MAX_INODE_NAME], &point_inode, sizeof(int)); - init_test_files(&d); - int n = fwrite(&d, sizeof(disk), 1, fptr); if (n == 1) { dprintf(STDOUT_FILENO, "Disk of size %.2fKb created successfully.\n", @@ -392,12 +482,12 @@ disk open_disk(char *filename) { return d; } -void persist_on_disk(disk* d) { +void persist_on_disk(disk *d) { FILE *fptr; fptr = fopen("disk", "wb"); int n = fwrite(d, sizeof(disk), 1, fptr); if (n != 1) { - dprintf(STDERR_FILENO, "Failed to persist datas on disk\n"); + dprintf(STDERR_FILENO, "Failed to persist datas on disk.\n"); } } \ No newline at end of file diff --git a/src/disk.h b/src/disk.h index c7a3c11..bd183b9 100644 --- a/src/disk.h +++ b/src/disk.h @@ -18,5 +18,6 @@ int do_ls(disk *d, char* path); int do_touch(disk *d, char *filepath); int do_mkdir(disk* d, char *dirpath); int do_df(disk *d); +int do_rm(disk *disk, char *filepath); int find_dir_inode_by_name(char *name, int dir_index, disk *d); void persist_on_disk(disk* d); \ No newline at end of file diff --git a/src/exec.c b/src/exec.c index 4429d8b..4c9f370 100644 --- a/src/exec.c +++ b/src/exec.c @@ -98,7 +98,9 @@ int child_process_job(disk *d, char **args) { persist_on_disk(d); } else if (strcmp("df", args[0]) == 0) { do_df(d); - } else { + } else if (strcmp("rm", args[0]) == 0) { + do_rm(d, args[1]); + }else { dprintf(STDERR_FILENO, "%s: no such command\n", args[0]); } return 1; diff --git a/src/utils.c b/src/utils.c index 936bf78..4eb9daf 100644 --- a/src/utils.c +++ b/src/utils.c @@ -41,6 +41,37 @@ int get_name_and_parent_path_by_absolute_path(char* path, char** parent_path, ch return 0; } +int get_dirname_and_parent_path_by_absolute_path(char* dirpath, char** parent_path, char** dirname) { + if (dirpath == NULL || strlen(dirpath) == 0) { + return -1; + } + + size_t len = strlen(dirpath); + if (len > 1 && dirpath[len - 1] == '/') { + dirpath[len - 1] = '\0'; + } + + char *last_occ = strrchr(dirpath, '/'); + + if (last_occ == NULL) { + *parent_path = strdup(get_env_value("PWD")); + *dirname = strdup(dirpath); + } else { + + *dirname = strdup(last_occ + 1); + + if (last_occ == dirpath) { + *parent_path = strdup("/"); + } else { + *last_occ = '\0'; + *parent_path = strdup(dirpath); + *last_occ = '/'; + } + } + + return 0; +} + void canonicalize_path(char *path) { char *tokens[100]; int depth = 0; diff --git a/src/utils.h b/src/utils.h index ec8ba52..807d8a6 100644 --- a/src/utils.h +++ b/src/utils.h @@ -8,4 +8,5 @@ void canonicalize_path(char *path); void format_path(char *dest, char *src, int dest_len); -int get_name_and_parent_path_by_absolute_path(char* dirpath, char** parent_path, char** dirname); \ No newline at end of file +int get_name_and_parent_path_by_absolute_path(char* dirpath, char** parent_path, char** dirname); +int get_dirname_and_parent_path_by_absolute_path(char* dirpath, char** parent_path, char** dirname); \ No newline at end of file