diff --git a/systeme_fichiers/libminix/.gitignore b/systeme_fichiers/libminix/.gitignore index 52ffa4225d6cc1c0213aed7ecec31ad36b5a14d6..b8a43c37ec6f306a8f683c4499d6c06c89781a53 100644 --- a/systeme_fichiers/libminix/.gitignore +++ b/systeme_fichiers/libminix/.gitignore @@ -8,6 +8,7 @@ list_inodes read_dir read_file read_file_path +read_dir_path tmp/ libminix* compile_commands.json diff --git a/systeme_fichiers/libminix/Makefile b/systeme_fichiers/libminix/Makefile index 87cf2f909ab2bd73df919fe681bceabefbe88ed2..a9df1f49b83206da3310b9675c9b622f82c410aa 100644 --- a/systeme_fichiers/libminix/Makefile +++ b/systeme_fichiers/libminix/Makefile @@ -1,9 +1,9 @@ CC := clang -CFLAGS := -g -pedantic -Wall -Wextra -fPIC +CFLAGS := -O3 -pedantic -Wall -Wextra -Werror -fPIC LDFLAGS := -fsanitize=address,leak,undefined -L$(shell pwd)/ -lminix SHELL := /bin/bash VPATH := struct -TARGET := sb_info inode_info list_inodes read_file read_dir read_file_path +TARGET := sb_info inode_info list_inodes read_file read_dir read_file_path read_dir_path OBJECTS := $(addsuffix .o, $(TARGET)) all: $(TARGET) diff --git a/systeme_fichiers/libminix/inode_info.c b/systeme_fichiers/libminix/inode_info.c index b98c32273a288e789461b51f77a6b657ba25ad0e..0a7c68277dfd81b0a1786380d44248b15de66542 100644 --- a/systeme_fichiers/libminix/inode_info.c +++ b/systeme_fichiers/libminix/inode_info.c @@ -13,6 +13,12 @@ int main(int argc, char *argv[]) { struct minix_inode inode = {0}; int inode_nb = atoi(argv[2]); + if (inode_nb < 1) { + fprintf(stderr, "Invalid inode value\n"); + fprintf(stderr, "Exiting...\n"); + exit(EXIT_FAILURE); + } + if (unmarshal_inode(&inode, inode_nb, argv[1]) == -1) { fprintf(stdout, "marshal_inode has failed\n"); exit(EXIT_FAILURE); diff --git a/systeme_fichiers/libminix/list_inodes.c b/systeme_fichiers/libminix/list_inodes.c index 3b075104df1cc7a689ca07985b9baacbd04972b6..75f514172445bc71e9d5109261790168953d02e3 100644 --- a/systeme_fichiers/libminix/list_inodes.c +++ b/systeme_fichiers/libminix/list_inodes.c @@ -29,7 +29,7 @@ int main(int argc, char *argv[]) { fprintf(stderr, "Exiting...\n"); exit(EXIT_FAILURE); } - fprintf(stdout, "\nInode n°%d ", i); + fprintf(stdout, "Inode n°%d : ", i); read_inode(&inode); } } diff --git a/systeme_fichiers/libminix/read_dir.c b/systeme_fichiers/libminix/read_dir.c index 5700d019a5603207335d53d0a4259c43b3bc8a8f..85ae34bd49433b0e7cee9874c77aa47b11de699d 100644 --- a/systeme_fichiers/libminix/read_dir.c +++ b/systeme_fichiers/libminix/read_dir.c @@ -3,6 +3,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/stat.h> int main(int argc, char *argv[]) { if (argc != 3) { @@ -16,8 +17,8 @@ int main(int argc, char *argv[]) { unmarshal_inode(&inode, inode_nb, argv[1]); - int nb_blocks_used = inode.i_size / BLOCK_SIZE; - if (inode.i_size % BLOCK_SIZE != 0) { + int nb_blocks_used = (inode.i_size / BLOCK_SIZE) + 1; + if (inode.i_size > BLOCK_SIZE && inode.i_size % BLOCK_SIZE != 0) { nb_blocks_used++; } @@ -42,14 +43,20 @@ int main(int argc, char *argv[]) { memcpy(&dir_entry, &buf[j * sizeof(struct minix_dir_entry)], sizeof(struct minix_dir_entry)); + if (!S_ISDIR(inode.i_mode)) { + fprintf(stderr, + "Inode isn't associated to a directory, cannot read " + "the contents associated with the given inode (n°%d)\n", + inode_nb); + exit(EXIT_FAILURE); + } + if (strlen(dir_entry.name) != 0) { - fprintf(stdout, "Filename : %s\tInode n°%d\n", dir_entry.name, - dir_entry.inode); + fprintf(stdout, "Directory entry : %s\t(Inode n°%d)\n", + dir_entry.name, dir_entry.inode); } } } - fprintf(stdout, "\n"); - return EXIT_SUCCESS; } diff --git a/systeme_fichiers/libminix/read_dir_path.c b/systeme_fichiers/libminix/read_dir_path.c new file mode 100644 index 0000000000000000000000000000000000000000..3a658002112351bdf810368a21dc2b8c040857a2 --- /dev/null +++ b/systeme_fichiers/libminix/read_dir_path.c @@ -0,0 +1,19 @@ +#include <libgen.h> +#include <minix.h> +#include <stdio.h> +#include <stdlib.h> + +int main(int argc, char *argv[]) { + if (argc != 3) { + fprintf(stderr, "Usage :\n"); + fprintf(stderr, "\t./%s <image file> <dir_path>\n", basename(argv[0])); + exit(EXIT_FAILURE); + } + + const char *fs_img = argv[1]; + const char *dir_path = argv[2]; + + namei(fs_img, dir_path); + + return EXIT_SUCCESS; +} diff --git a/systeme_fichiers/libminix/read_file.c b/systeme_fichiers/libminix/read_file.c index 100d10b9b9f6ba03903de36aac4404f4fa32a57e..6a5602c8fd7c1295f42586e2930d5b644dfad596 100644 --- a/systeme_fichiers/libminix/read_file.c +++ b/systeme_fichiers/libminix/read_file.c @@ -2,6 +2,7 @@ #include <minix.h> #include <stdio.h> #include <stdlib.h> +#include <sys/stat.h> int main(int argc, char *argv[]) { if (argc != 3) { @@ -15,30 +16,43 @@ int main(int argc, char *argv[]) { unmarshal_inode(&inode, inode_nb, argv[1]); - int nb_blocks_used = inode.i_size / BLOCK_SIZE; - if (inode.i_size % BLOCK_SIZE != 0) { + int nb_blocks_used = (inode.i_size / BLOCK_SIZE) + 1; + + if (inode.i_size > BLOCK_SIZE && inode.i_size % BLOCK_SIZE != 0) { nb_blocks_used++; } + size_t buf_size = BLOCK_SIZE * nb_blocks_used + 1; + char *buf = calloc(buf_size, sizeof(char)); + for (int i = 0; i < nb_blocks_used; i++) { ssize_t phys_num = bmap(&inode, argv[1], i); if (phys_num == -1) { fprintf(stderr, "bmap has failed...\n"); + free(buf); exit(EXIT_FAILURE); } - char buf[BLOCK_SIZE + 1] = {0}; - - if (read_data_block(buf, argv[1], phys_num) == -1) { + if (read_data_block(buf + BLOCK_SIZE * i, argv[1], phys_num) == -1) { fprintf(stderr, "read_data_block has failed...\n"); + free(buf); exit(EXIT_FAILURE); } - fprintf(stdout, "%s", buf); + if (!S_ISREG(inode.i_mode)) { + fprintf(stderr, + "No files were found associated with the given inode " + "(n°%d)\n", + inode_nb); + free(buf); + exit(EXIT_FAILURE); + } } - fprintf(stdout, "\n"); + fprintf(stdout, "%s", buf); + + free(buf); return EXIT_SUCCESS; } diff --git a/systeme_fichiers/libminix/read_file_path.c b/systeme_fichiers/libminix/read_file_path.c index 8252e23e2ebcb8e918589b9a902108a89d2eefbb..6b1f9ea36c4f043a9abb8005e7a3a1913d3a957d 100644 --- a/systeme_fichiers/libminix/read_file_path.c +++ b/systeme_fichiers/libminix/read_file_path.c @@ -10,7 +10,10 @@ int main(int argc, char *argv[]) { exit(EXIT_FAILURE); } - namei(argv[1], argv[2]); + const char *fs_img = argv[1]; + const char *filepath = argv[2]; + + namei(fs_img, filepath); return EXIT_SUCCESS; } diff --git a/systeme_fichiers/libminix/struct/minix.c b/systeme_fichiers/libminix/struct/minix.c index 09ab07f64035ad255dbd6d4847a0139e5087386f..4f0f7783c067e11bb4e56692a7baf6cbfd1b0da7 100644 --- a/systeme_fichiers/libminix/struct/minix.c +++ b/systeme_fichiers/libminix/struct/minix.c @@ -1,7 +1,9 @@ #include "minix.h" +#include <alloca.h> #include <fcntl.h> #include <stdint.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <unistd.h> @@ -55,7 +57,6 @@ int unmarshal_inode(struct minix_inode *inode, const uint32_t inode_nb, if (inode_nb == 0 || inode_nb > sb.s_ninodes || !is_inode_allocated(inode_nb, img_filepath)) { - fprintf(stderr, "Inode isn't allocated or inode value is invalid\n"); return -1; } @@ -221,7 +222,7 @@ int read_inode(const struct minix_inode *inode) { fprintf(stdout, "UID : %d\n", inode->i_uid); fprintf(stdout, "GID : %d\n", inode->i_gid); fprintf(stdout, "Size (in bytes) : %d\n", inode->i_size); - fprintf(stdout, "NB links : %d\n", inode->i_nlinks); + fprintf(stdout, "NB links : %d\n\n", inode->i_nlinks); return 0; } @@ -258,7 +259,6 @@ int read_indir_block(uint16_t *buf, const char *img_filepath, ssize_t bmap(const struct minix_inode *inode, const char *img_filepath, size_t logical_block) { - size_t direct_zone_len = sizeof(inode->i_zone) / sizeof(inode->i_zone[0]); size_t ptr_by_block = BLOCK_SIZE / sizeof(inode->i_indir_zone); @@ -300,7 +300,7 @@ ssize_t bmap(const struct minix_inode *inode, const char *img_filepath, return buf2[logical_block % BLOCK_SIZE * sizeof(uint16_t)]; } - return 0; + return -1; } int read_data_block(char *buf, const char *img_filepath, @@ -334,8 +334,9 @@ int read_data_block(char *buf, const char *img_filepath, int lookup_entry(const struct minix_inode *inode, const char *token, const char *img_filepath) { - int nb_blocks_used = inode->i_size / BLOCK_SIZE; - if (inode->i_size % BLOCK_SIZE != 0) { + int nb_blocks_used = (inode->i_size / BLOCK_SIZE) + 1; + + if (inode->i_size > BLOCK_SIZE && inode->i_size % BLOCK_SIZE != 0) { nb_blocks_used++; } @@ -369,14 +370,14 @@ int lookup_entry(const struct minix_inode *inode, const char *token, return -1; } -int namei(const char *img_filepath, char *filepath) { +int namei(const char *img_filepath, const char *filepath) { struct minix_inode inode = {0}; if (unmarshal_inode(&inode, 1, img_filepath) == -1) { fprintf(stderr, "marshal_inode has failed\n"); return -1; } - char *token = strtok(filepath, "/"); + char *token = strtok((char *)filepath, "/"); int next_inode = 0; while (token != NULL) { @@ -401,30 +402,66 @@ int namei(const char *img_filepath, char *filepath) { } } - int nb_blocks_used = inode.i_size / BLOCK_SIZE; - if (inode.i_size % BLOCK_SIZE != 0) { + int nb_blocks_used = (inode.i_size / BLOCK_SIZE) + 1; + if (inode.i_size > BLOCK_SIZE && inode.i_size % BLOCK_SIZE != 0) { nb_blocks_used++; } + size_t buf_size = BLOCK_SIZE * nb_blocks_used + 1; + char *buf = calloc(buf_size, sizeof(char)); + for (int i = 0; i < nb_blocks_used; i++) { ssize_t phys_num = bmap(&inode, img_filepath, i); if (phys_num == -1) { fprintf(stderr, "bmap has failed...\n"); + free(buf); return -1; } - char buf[BLOCK_SIZE + 1] = {0}; - - if (read_data_block(buf, img_filepath, phys_num) == -1) { + if (read_data_block(buf + BLOCK_SIZE * i, img_filepath, phys_num) == + -1) { fprintf(stderr, "read_data_block has failed...\n"); + free(buf); return -1; } + } + + if (S_ISDIR(inode.i_mode)) { + fprintf(stdout, "Reading directory entries :\n\n"); + struct minix_dir_entry dir_entry = {0}; + for (size_t j = 0; j < BLOCK_SIZE / sizeof(struct minix_dir_entry); + j++) { + memcpy(&dir_entry, &buf[j * sizeof(struct minix_dir_entry)], + sizeof(struct minix_dir_entry)); + + if (!S_ISDIR(inode.i_mode)) { + fprintf(stderr, + "Inode isn't associated to a directory, cannot read " + "the contents associated with the given inode (n°%d)\n", + buf[0]); + free(buf); + return -1; + } + + if (strlen(dir_entry.name) != 0) { + fprintf(stdout, "Directory entry : %s\t(Inode n°%d)\n", + dir_entry.name, dir_entry.inode); + } + } + } + + if (S_ISREG(inode.i_mode)) { + fprintf(stdout, "Reading file contents :\n\n"); fprintf(stdout, "%s", buf); } - fprintf(stdout, "\n"); + if (S_ISDIR(inode.i_mode) || S_ISREG(inode.i_mode)) { + free(buf); + return 0; + } - return 0; + free(buf); + return -1; } diff --git a/systeme_fichiers/libminix/struct/minix.h b/systeme_fichiers/libminix/struct/minix.h index ac0c580adbae3e281cc90142faa6e0ad3dcc6486..271e0812854e5e7de4dc347aa4434529ed356aa8 100644 --- a/systeme_fichiers/libminix/struct/minix.h +++ b/systeme_fichiers/libminix/struct/minix.h @@ -146,6 +146,6 @@ extern int lookup_entry(const struct minix_inode *inode, const char *token, * @param filepath Absolute path to the file in the FS image * @return -1 in case of an error, 0 otherwise */ -extern int namei(const char *img_filepath, char *filepath); +extern int namei(const char *img_filepath, const char *filepath); #endif // !_MINIX_H_