This commit is contained in:
Guamss 2026-05-04 22:56:56 +02:00
parent c82deb402c
commit 15ff8e5b23
5 changed files with 137 additions and 12 deletions

View File

@ -1,6 +1,8 @@
/** @file */
#include "disk.h"
#include "env.h"
#include "struct.h"
#include <linux/limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@ -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");
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);
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);