add: rm
This commit is contained in:
parent
c82deb402c
commit
15ff8e5b23
110
src/disk.c
110
src/disk.c
@ -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");
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
@ -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;
|
||||
|
||||
31
src/utils.c
31
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;
|
||||
|
||||
@ -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);
|
||||
Loading…
Reference in New Issue
Block a user