Skip to content
Snippets Groups Projects
Commit 51dc08d8 authored by iliya's avatar iliya
Browse files

feat: libc enjoyer

parent 75dd5cd9
No related branches found
No related tags found
No related merge requests found
...@@ -13,7 +13,7 @@ int main(int argc, char *argv[]) { ...@@ -13,7 +13,7 @@ int main(int argc, char *argv[]) {
struct minix_inode inode = {0}; struct minix_inode inode = {0};
int inode_nb = atoi(argv[2]); int inode_nb = atoi(argv[2]);
if (marshal_inode(&inode, inode_nb, argv[1]) == -1) { if (unmarshal_inode(&inode, inode_nb, argv[1]) == -1) {
fprintf(stdout, "marshal_inode has failed\n"); fprintf(stdout, "marshal_inode has failed\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
......
...@@ -12,7 +12,7 @@ int main(int argc, char *argv[]) { ...@@ -12,7 +12,7 @@ int main(int argc, char *argv[]) {
struct minix_super_block sb = {0}; struct minix_super_block sb = {0};
if (marshal_sb(&sb, argv[1]) == -1) { if (unmarshal_sb(&sb, argv[1]) == -1) {
fprintf(stderr, "Failed to marshal minix_super_block structure\n"); fprintf(stderr, "Failed to marshal minix_super_block structure\n");
fprintf(stderr, "Exiting...\n"); fprintf(stderr, "Exiting...\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
...@@ -24,7 +24,7 @@ int main(int argc, char *argv[]) { ...@@ -24,7 +24,7 @@ int main(int argc, char *argv[]) {
if (is_inode_allocated(i, argv[1])) { if (is_inode_allocated(i, argv[1])) {
nb_allocated_inodes++; nb_allocated_inodes++;
struct minix_inode inode = {0}; struct minix_inode inode = {0};
if (marshal_inode(&inode, i, argv[1]) == -1) { if (unmarshal_inode(&inode, i, argv[1]) == -1) {
fprintf(stderr, "Failed to marshal minix_inode structure\n"); fprintf(stderr, "Failed to marshal minix_inode structure\n");
fprintf(stderr, "Exiting...\n"); fprintf(stderr, "Exiting...\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
......
...@@ -14,7 +14,7 @@ int main(int argc, char *argv[]) { ...@@ -14,7 +14,7 @@ int main(int argc, char *argv[]) {
struct minix_inode inode = {0}; struct minix_inode inode = {0};
int inode_nb = atoi(argv[2]); int inode_nb = atoi(argv[2]);
marshal_inode(&inode, inode_nb, argv[1]); unmarshal_inode(&inode, inode_nb, argv[1]);
int nb_blocks_used = inode.i_size / BLOCK_SIZE; int nb_blocks_used = inode.i_size / BLOCK_SIZE;
if (inode.i_size % BLOCK_SIZE != 0) { if (inode.i_size % BLOCK_SIZE != 0) {
......
...@@ -13,7 +13,7 @@ int main(int argc, char *argv[]) { ...@@ -13,7 +13,7 @@ int main(int argc, char *argv[]) {
struct minix_inode inode = {0}; struct minix_inode inode = {0};
int inode_nb = atoi(argv[2]); int inode_nb = atoi(argv[2]);
marshal_inode(&inode, inode_nb, argv[1]); unmarshal_inode(&inode, inode_nb, argv[1]);
int nb_blocks_used = inode.i_size / BLOCK_SIZE; int nb_blocks_used = inode.i_size / BLOCK_SIZE;
if (inode.i_size % BLOCK_SIZE != 0) { if (inode.i_size % BLOCK_SIZE != 0) {
......
...@@ -12,7 +12,7 @@ int main(int argc, char *argv[]) { ...@@ -12,7 +12,7 @@ int main(int argc, char *argv[]) {
struct minix_super_block m_sb = {0}; struct minix_super_block m_sb = {0};
marshal_sb(&m_sb, argv[1]); unmarshal_sb(&m_sb, argv[1]);
read_sb(&m_sb); read_sb(&m_sb);
return EXIT_SUCCESS; return EXIT_SUCCESS;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
int marshal_sb(struct minix_super_block *sb, const char *img_filepath) { int unmarshal_sb(struct minix_super_block *sb, const char *img_filepath) {
int fd = open(img_filepath, O_RDONLY); int fd = open(img_filepath, O_RDONLY);
if (fd == -1) { if (fd == -1) {
...@@ -23,7 +23,7 @@ int marshal_sb(struct minix_super_block *sb, const char *img_filepath) { ...@@ -23,7 +23,7 @@ int marshal_sb(struct minix_super_block *sb, const char *img_filepath) {
return -1; return -1;
} }
if (sb->s_magic != MAGIC) { if (sb->s_magic != MINIX_MAGIC) {
fprintf(stderr, "The provided image isn't a minix-FS image whose magic " fprintf(stderr, "The provided image isn't a minix-FS image whose magic "
"value is 0x137F\n"); "value is 0x137F\n");
close(fd); close(fd);
...@@ -34,44 +34,11 @@ int marshal_sb(struct minix_super_block *sb, const char *img_filepath) { ...@@ -34,44 +34,11 @@ int marshal_sb(struct minix_super_block *sb, const char *img_filepath) {
return 0; return 0;
} }
bool is_inode_allocated(const uint32_t inode_nb, const char *img_filepath) { int unmarshal_inode(struct minix_inode *inode, const uint32_t inode_nb,
int fd = open(img_filepath, O_RDONLY);
if (fd == -1) {
perror("open");
close(fd);
return -1;
}
char buf[BLOCK_SIZE] = {0};
// int inode_bitmap_block = inode_nb / (BLOCK_SIZE * BYTE_BITSIZE);
lseek(fd, BLOCK_SIZE * BITMAP_INODE_FIRST_IDX, SEEK_SET);
// Checking if we've read an entire block or not
ssize_t bytes_read = read(fd, buf, BLOCK_SIZE);
if (bytes_read == -1) {
perror("read");
close(fd);
return false;
}
if (bytes_read == BLOCK_SIZE) {
uint16_t byte_idx = inode_nb / BYTE_BITSIZE;
uint8_t bit_idx = inode_nb % BYTE_BITSIZE;
close(fd);
return buf[byte_idx] & (0x01 << bit_idx);
}
close(fd);
return false;
}
int marshal_inode(struct minix_inode *inode, const uint32_t inode_nb,
const char *img_filepath) { const char *img_filepath) {
struct minix_super_block sb = {0}; struct minix_super_block sb = {0};
if (marshal_sb(&sb, img_filepath) == -1) { if (unmarshal_sb(&sb, img_filepath) == -1) {
perror("marshal_sb"); perror("marshal_sb");
return -1; return -1;
} }
...@@ -111,7 +78,50 @@ int marshal_inode(struct minix_inode *inode, const uint32_t inode_nb, ...@@ -111,7 +78,50 @@ int marshal_inode(struct minix_inode *inode, const uint32_t inode_nb,
return 0; return 0;
} }
bool is_inode_allocated(const uint32_t inode_nb, const char *img_filepath) {
int fd = open(img_filepath, O_RDONLY);
if (fd == -1) {
perror("open");
close(fd);
return -1;
}
// Computes in which block of the inode's bitmap is the bit associated
// to the given inode number
int inode_bitmap_block = (inode_nb / (BLOCK_SIZE * BYTE_BITSIZE)) + 1;
char buf[BLOCK_SIZE] = {0};
lseek(fd, BLOCK_SIZE * BITMAP_INODE_FIRST_IDX * inode_bitmap_block,
SEEK_SET);
// Checking if we've read an entire block or not
ssize_t bytes_read = read(fd, buf, BLOCK_SIZE);
if (bytes_read == -1) {
perror("read");
close(fd);
return false;
}
if (bytes_read == BLOCK_SIZE) {
uint16_t byte_idx = inode_nb / BYTE_BITSIZE;
uint8_t bit_idx = inode_nb % BYTE_BITSIZE;
close(fd);
return buf[byte_idx] & (0x01 << bit_idx);
}
close(fd);
return false;
}
int read_sb(const struct minix_super_block *sb) { int read_sb(const struct minix_super_block *sb) {
if (sb->s_magic != MINIX_MAGIC) {
fprintf(stdout, "Wrong magic value\n");
return -1;
}
uint16_t inode_table_size = sb->s_ninodes / sizeof(struct minix_inode); uint16_t inode_table_size = sb->s_ninodes / sizeof(struct minix_inode);
uint16_t idx_first_block_inode_table = uint16_t idx_first_block_inode_table =
sb->s_firstdatazone - inode_table_size; sb->s_firstdatazone - inode_table_size;
...@@ -248,13 +258,17 @@ int read_indir_block(uint16_t *buf, const char *img_filepath, ...@@ -248,13 +258,17 @@ int read_indir_block(uint16_t *buf, const char *img_filepath,
ssize_t bmap(const struct minix_inode *inode, const char *img_filepath, ssize_t bmap(const struct minix_inode *inode, const char *img_filepath,
size_t logical_block) { size_t logical_block) {
if (logical_block < sizeof(inode->i_zone) / sizeof(uint16_t)) {
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);
if (logical_block < direct_zone_len) {
return inode->i_zone[logical_block]; return inode->i_zone[logical_block];
} }
logical_block = logical_block - sizeof(inode->i_zone) / sizeof(uint16_t); logical_block -= direct_zone_len;
if (logical_block < BLOCK_SIZE / sizeof(uint16_t)) { if (logical_block < ptr_by_block) {
uint16_t buf[BLOCK_SIZE] = {0}; uint16_t buf[BLOCK_SIZE] = {0};
if (read_indir_block(buf, img_filepath, inode->i_indir_zone) == -1) { if (read_indir_block(buf, img_filepath, inode->i_indir_zone) == -1) {
...@@ -265,10 +279,9 @@ ssize_t bmap(const struct minix_inode *inode, const char *img_filepath, ...@@ -265,10 +279,9 @@ ssize_t bmap(const struct minix_inode *inode, const char *img_filepath,
return buf[logical_block]; return buf[logical_block];
} }
logical_block = logical_block - BLOCK_SIZE / sizeof(uint16_t); logical_block -= ptr_by_block;
if (logical_block < if (logical_block < (ptr_by_block * ptr_by_block)) {
BLOCK_SIZE / sizeof(uint16_t) * BLOCK_SIZE / sizeof(uint16_t)) {
uint16_t buf1[BLOCK_SIZE] = {0}; uint16_t buf1[BLOCK_SIZE] = {0};
uint16_t buf2[BLOCK_SIZE] = {0}; uint16_t buf2[BLOCK_SIZE] = {0};
...@@ -278,9 +291,8 @@ ssize_t bmap(const struct minix_inode *inode, const char *img_filepath, ...@@ -278,9 +291,8 @@ ssize_t bmap(const struct minix_inode *inode, const char *img_filepath,
return -1; return -1;
} }
if (read_indir_block( if (read_indir_block(buf2, img_filepath,
buf2, img_filepath, buf1[logical_block / ptr_by_block]) == -1) {
buf1[logical_block / BLOCK_SIZE * sizeof(uint16_t)]) == -1) {
fprintf(stderr, "read_indir_block failed\n"); fprintf(stderr, "read_indir_block failed\n");
return -1; return -1;
} }
...@@ -291,8 +303,9 @@ ssize_t bmap(const struct minix_inode *inode, const char *img_filepath, ...@@ -291,8 +303,9 @@ ssize_t bmap(const struct minix_inode *inode, const char *img_filepath,
return 0; return 0;
} }
int read_data_block(char *buf, const char *filepath, size_t phys_num_block) { int read_data_block(char *buf, const char *img_filepath,
int fd = open(filepath, O_RDONLY); size_t phys_num_block) {
int fd = open(img_filepath, O_RDONLY);
if (fd == -1) { if (fd == -1) {
perror("open"); perror("open");
...@@ -358,7 +371,7 @@ int lookup_entry(const struct minix_inode *inode, const char *token, ...@@ -358,7 +371,7 @@ int lookup_entry(const struct minix_inode *inode, const char *token,
int namei(const char *img_filepath, char *filepath) { int namei(const char *img_filepath, char *filepath) {
struct minix_inode inode = {0}; struct minix_inode inode = {0};
if (marshal_inode(&inode, 1, img_filepath) == -1) { if (unmarshal_inode(&inode, 1, img_filepath) == -1) {
fprintf(stderr, "marshal_inode has failed\n"); fprintf(stderr, "marshal_inode has failed\n");
return -1; return -1;
} }
...@@ -381,7 +394,7 @@ int namei(const char *img_filepath, char *filepath) { ...@@ -381,7 +394,7 @@ int namei(const char *img_filepath, char *filepath) {
token = strtok(NULL, "/"); token = strtok(NULL, "/");
memset(&inode, 0, sizeof(struct minix_inode)); memset(&inode, 0, sizeof(struct minix_inode));
if (marshal_inode(&inode, next_inode, img_filepath) == -1) { if (unmarshal_inode(&inode, next_inode, img_filepath) == -1) {
fprintf(stderr, "marshal_inode has failed\n"); fprintf(stderr, "marshal_inode has failed\n");
return -1; return -1;
} }
......
...@@ -5,16 +5,10 @@ ...@@ -5,16 +5,10 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
// Superblock magic 0x137f #define MINIX_MAGIC 0x137F
#define MAGIC 0x137F
#define MINIX_NAME_LEN 14 #define MINIX_NAME_LEN 14
// 1KB block size
#define BLOCK_SIZE 1024 #define BLOCK_SIZE 1024
#define BITMAP_INODE_FIRST_IDX 2 #define BITMAP_INODE_FIRST_IDX 2
#define IS_BIT_SET(value, pos) ((value >> pos) & 0x1)
#define BYTE_BITSIZE 8 #define BYTE_BITSIZE 8
struct __attribute__((packed)) minix_inode { struct __attribute__((packed)) minix_inode {
...@@ -46,54 +40,111 @@ struct __attribute__((packed)) minix_super_block { ...@@ -46,54 +40,111 @@ struct __attribute__((packed)) minix_super_block {
uint16_t s_state; // was the FS properly unmounted ? uint16_t s_state; // was the FS properly unmounted ?
}; };
extern int marshal_sb(struct minix_super_block *sb, const char *img_filepath); /**
extern int marshal_inode(struct minix_inode *inode, const uint32_t inode_nb, * @brief Function that deserializes a byte stream into a minix_super_block
* structure
*
* @param sb MINIX Superblock structure to populate
* @param img_filepath Path to the FS image
* @return -1 in case of an error, 0 otherwise
*/
extern int unmarshal_sb(struct minix_super_block *sb, const char *img_filepath);
/**
* @brief Function that deserializes a byte stream into a minix_inode structure
*
* @param inode MINIX Inode structure to populate
* @param inode_nb Number of the inode
* @param img_filepath Path to the FS image
* @return -1 in case of an error, 0 otherwise
*/
extern int unmarshal_inode(struct minix_inode *inode, const uint32_t inode_nb,
const char *img_filepath); const char *img_filepath);
/**
* @brief Function that determines if an inode is allocated or not based on the
* value of its corresponding bit in the inode's bitmap
*
* @param inode_nb Number of the inode
* @param img_filepath Path to the FS image
* @return true if inode is allocated, false otherwise
*/
extern bool is_inode_allocated(const uint32_t inode_nb, extern bool is_inode_allocated(const uint32_t inode_nb,
const char *img_filepath); const char *img_filepath);
/**
* @brief Function that displays the contents the minix_super_block structure
*
* @param sb MINIX Superblock structure to display
* @return -1 in case of an error, 0 otherwise
*/
extern int read_sb(const struct minix_super_block *sb); extern int read_sb(const struct minix_super_block *sb);
/**
* @brief Function that displays the contents of a minix_inode structure
*
* @param inode MINIX Inode structure to display
* @return -1 in case of an error, 0 otherwise
*/
extern int read_inode(const struct minix_inode *inode); extern int read_inode(const struct minix_inode *inode);
/**
* @brief Function that reads the contents of indirect block (aka one that
* contains pointers to other blocks of data)
*
* @param buf Allocated buffer of size BLOCKSIZE = 1024 whose entries are
* pointers to blocks of data
* @param img_filepath Path to the FS image
* @param block_number Block number that is going to be read
* @return -1 in case of an error, 0 otherwise
*/
extern int read_indir_block(uint16_t *buf, const char *img_filepath, extern int read_indir_block(uint16_t *buf, const char *img_filepath,
const size_t block_number); const size_t block_number);
/** /**
* @brief Returns physical number of data block based on its logical * @brief Function that translates a logical block value to a physical block
* representation * value
* *
* @param inode * @param inode MINIX Inode structure
* @param filepath * @param img_filepath Path to the FS image
* @param logical_block_idx * @param logical_block Value of the logical block to translated
* @return * @return -1 in case of an error, number of the physical block otherwise
*/ */
extern ssize_t bmap(const struct minix_inode *inode, const char *img_filepath, extern ssize_t bmap(const struct minix_inode *inode, const char *img_filepath,
size_t logical_block_idx); size_t logical_block_idx);
/** /**
* @brief * @brief Function that reads the contents of a block of data into the char *buf
* buffer
* *
* @param buf Buffer should allocated in such way that it accounts for a '\0' * @param buf Allocated buffer of size BLOCKSIZE = 1024 + 1 for the '\0'
* being placed at the end of it * character
* @param filepath * @param img_filepath Path to the FS image
* @param phys_num_block * @param phys_num_block Number of the physical data block to read
* @return * @return -1 in case of an error, 0 otherwise
*/ */
extern int read_data_block(char *buf, const char *filepath, extern int read_data_block(char *buf, const char *img_filepath,
const size_t phys_num_block); const size_t phys_num_block);
/** /**
* @brief * @brief Function that looks up the entries in a given inode and looks for an
* entry whose name matches the value the const char *token string. If it
* matches the name then the value of the corresponding inode shall be returned
* *
* @param dir_entry * @param inode MINIX Inode structure
* @param token * @param token Token that will be searched for in the given inode
* @return -1 in case of an error or if entry hasn't been found * @param img_filepath
* @return -1 in case of an error, value of the corresponding inode otherwise
*/ */
extern int lookup_entry(const struct minix_inode *inode, const char *token, extern int lookup_entry(const struct minix_inode *inode, const char *token,
const char *img_filepath); const char *img_filepath);
/** /**
* @brief Finding file's inode based on the absolute filepath * @brief Function that reads the content of a given file in the FS image
* *
* @param filepath * @param img_filepath Path to the FS image
* @return * @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, char *filepath);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment