add: rm
This commit is contained in:
parent
c82deb402c
commit
15ff8e5b23
110
src/disk.c
110
src/disk.c
@ -1,6 +1,8 @@
|
|||||||
/** @file */
|
/** @file */
|
||||||
#include "disk.h"
|
#include "disk.h"
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
|
#include "struct.h"
|
||||||
|
#include <linux/limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -80,6 +82,101 @@ int allocate_node(disk *disk, inode *parent, char *name, char type) {
|
|||||||
return inode_index;
|
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) {
|
int create_file(disk *disk, inode *parent, char *filename) {
|
||||||
return allocate_node(disk, parent, filename, TYPE_FILE);
|
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,
|
if (get_name_and_parent_path_by_absolute_path(filepath, &parent_path,
|
||||||
&dirname) == -1) {
|
&dirname) == -1) {
|
||||||
dprintf(STDERR_FILENO, "touch: erreur jsp");
|
dprintf(STDERR_FILENO, "touch: erreur jsp\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,11 +425,6 @@ char *read_in_file(disk *d, int file_index) {
|
|||||||
return out;
|
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,
|
* @brief Créer un fichier "disk" de taille MAX_BYTES_PER_BLOC * MAX_BLOCS,
|
||||||
* renvoi ce disque
|
* renvoi ce disque
|
||||||
@ -365,8 +457,6 @@ disk create_disk() {
|
|||||||
int point_inode = 1;
|
int point_inode = 1;
|
||||||
memcpy(&d.blocs[0].datas[MAX_INODE_NAME], &point_inode, sizeof(int));
|
memcpy(&d.blocs[0].datas[MAX_INODE_NAME], &point_inode, sizeof(int));
|
||||||
|
|
||||||
init_test_files(&d);
|
|
||||||
|
|
||||||
int n = fwrite(&d, sizeof(disk), 1, fptr);
|
int n = fwrite(&d, sizeof(disk), 1, fptr);
|
||||||
if (n == 1) {
|
if (n == 1) {
|
||||||
dprintf(STDOUT_FILENO, "Disk of size %.2fKb created successfully.\n",
|
dprintf(STDOUT_FILENO, "Disk of size %.2fKb created successfully.\n",
|
||||||
@ -392,12 +482,12 @@ disk open_disk(char *filename) {
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void persist_on_disk(disk* d) {
|
void persist_on_disk(disk *d) {
|
||||||
FILE *fptr;
|
FILE *fptr;
|
||||||
fptr = fopen("disk", "wb");
|
fptr = fopen("disk", "wb");
|
||||||
|
|
||||||
int n = fwrite(d, sizeof(disk), 1, fptr);
|
int n = fwrite(d, sizeof(disk), 1, fptr);
|
||||||
if (n != 1) {
|
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_touch(disk *d, char *filepath);
|
||||||
int do_mkdir(disk* d, char *dirpath);
|
int do_mkdir(disk* d, char *dirpath);
|
||||||
int do_df(disk *d);
|
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);
|
int find_dir_inode_by_name(char *name, int dir_index, disk *d);
|
||||||
void persist_on_disk(disk* d);
|
void persist_on_disk(disk* d);
|
||||||
@ -98,7 +98,9 @@ int child_process_job(disk *d, char **args) {
|
|||||||
persist_on_disk(d);
|
persist_on_disk(d);
|
||||||
} else if (strcmp("df", args[0]) == 0) {
|
} else if (strcmp("df", args[0]) == 0) {
|
||||||
do_df(d);
|
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]);
|
dprintf(STDERR_FILENO, "%s: no such command\n", args[0]);
|
||||||
}
|
}
|
||||||
return 1;
|
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;
|
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) {
|
void canonicalize_path(char *path) {
|
||||||
char *tokens[100];
|
char *tokens[100];
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
|
|||||||
@ -9,3 +9,4 @@
|
|||||||
void canonicalize_path(char *path);
|
void canonicalize_path(char *path);
|
||||||
void format_path(char *dest, char *src, int dest_len);
|
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