7 #ifndef EXT_FILESYSTEM_INTERFACE_WRITE_TO_FILE_H_
8 #define EXT_FILESYSTEM_INTERFACE_WRITE_TO_FILE_H_
16 #include "../core/superblock.h"
17 #include "../core/descriptors_table.h"
18 #include "../core/defines.h"
19 #include "../core/methods.h"
33 uint16_t file_descriptor,
35 uint32_t size,
int output_fd) {
37 size_t buffer_size = 0;
38 int fd = open(path_to_fs_file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
40 fprintf(stderr,
"Can't open file. Abort!\n");
44 struct superblock superblock;
46 if (superblock.fs_info->magic != MAGIC) {
47 fprintf(stderr,
"Magic does not match. Abort!\n");
53 if (!superblock.reserved_inodes_mask[ROOT_INODE_ID]) {
54 fprintf(stderr,
"Root directory doesn't exist. Abort!\n");
64 struct descriptors_table descriptors_table;
66 fprintf(stderr,
"Can't read descriptors_table. Abort!\n");
72 if (!descriptors_table.reserved_fd[file_descriptor]) {
73 buffered_write(&buffer, &buffer_size,
"Trying to write to closed fd. Abort!\n", strlen(
"Trying to write to closed fd. Abort!\n"));
75 send_data(output_fd, buffer, buffer_size);
83 uint32_t fd_position = descriptors_table.fd_to_position[file_descriptor];
84 uint16_t inode_id = descriptors_table.fd_to_inode[file_descriptor];
87 if (
read_inode(fd, &inode, inode_id, &superblock) == -1) {
88 fprintf(stderr,
"Can't read inode. Abort!\n");
95 uint32_t total_written = 0;
96 uint32_t need_to_write_size = size;
97 while (total_written != size) {
98 uint16_t block_to_write_pos =
101 if (block_to_write_pos < inode.inode_info->blocks_count) {
104 inode.block_ids[block_to_write_pos],
105 &superblock) == -1) {
106 fprintf(stderr,
"Can't read block. Abort!\n");
115 if (new_block_id == superblock.fs_info->blocks_count) {
116 buffered_write(&buffer, &buffer_size,
"Can't create more blocks in FS. Abort!\n", strlen(
"Can't create more blocks in FS. Abort!\n"));
118 send_data(output_fd, buffer, buffer_size);
121 descriptors_table.fd_to_position[file_descriptor] = fd_position;
123 fprintf(stderr,
"Can't write descriptor table. Abort!\n");
133 fprintf(stderr,
"Can't write inode. Abort!\n");
142 fprintf(stderr,
"Can't write superblock. Abort!\n");
152 if (inode.inode_info->blocks_count
153 == superblock.fs_info->blocks_count_in_inode) {
154 buffered_write(&buffer, &buffer_size,
"Can't create more blocks in this inode. Abort!\n", strlen(
"Can't create more blocks in this inode. Abort!\n"));
156 send_data(output_fd, buffer, buffer_size);
159 descriptors_table.fd_to_position[file_descriptor] = fd_position;
161 fprintf(stderr,
"Can't write descriptor table. Abort!\n");
171 fprintf(stderr,
"Can't write inode. Abort!\n");
180 fprintf(stderr,
"Can't write superblock. Abort!\n");
189 init_block(&block, &superblock, new_block_id, inode_id);
190 block.data = (
char*) calloc(superblock.fs_info->block_size,
sizeof(
char));
191 inode.block_ids[inode.inode_info->blocks_count] = new_block_id;
192 inode.inode_info->blocks_count += 1;
194 fprintf(stderr,
"Can't write inode. Abort!\n");
203 uint32_t position_in_block_data =
205 char* position_to_write = block.data + position_in_block_data;
206 uint32_t remain_size =
208 uint32_t size_to_write = need_to_write_size < remain_size ? need_to_write_size : remain_size;
209 block.block_info->data_size = position_in_block_data;
210 memcpy(position_to_write, data, size_to_write);
211 block.block_info->data_size += size_to_write;
213 fprintf(stderr,
"Can't write block. Abort!\n");
222 fd_position += size_to_write;
223 data += size_to_write;
224 total_written += size_to_write;
225 need_to_write_size -= size_to_write;
228 descriptors_table.fd_to_position[file_descriptor] = fd_position;
230 fprintf(stderr,
"Can't write descriptor table. Abort!\n");
240 fprintf(stderr,
"Can't write inode. Abort!\n");
249 fprintf(stderr,
"Can't write superblock. Abort!\n");
257 char string_buffer[1024];
258 size_t string_size = sprintf(string_buffer,
"Total written: %d\n", total_written);
259 buffered_write(&buffer, &buffer_size, string_buffer, strlen(string_buffer));
260 send_data(output_fd, buffer, buffer_size);
272 uint16_t file_descriptor,
const char* path_to_file) {
278 int descriptor = open(path_to_file, O_RDONLY);
279 if (descriptor == -1) {
280 fprintf(stderr,
"Can't read file with data. Abort!\n");
284 char* buffer = (
char*) calloc(size,
sizeof(
char));
290 fprintf(stderr,
"Can't read file with data. Abort!\n");
294 write_to_file(path_to_fs_file, file_descriptor, buffer, size, STDOUT_FILENO);
297 #endif //EXT_FILESYSTEM_INTERFACE_WRITE_TO_FILE_H_
ssize_t write_descriptor_table(int fd, struct descriptors_table *descriptors_table, const struct superblock *superblock)
Write descriptors_table to memory.
ssize_t write_inode(int fd, struct inode *inode, const struct superblock *superblock)
Write inode from memory.
void write_to_file_from_file(const char *path_to_fs_file, uint16_t file_descriptor, const char *path_to_file)
Write data to file Write data from path_to_file to file by file_descriptor.
ssize_t write_block(int fd, struct block *block, const struct superblock *superblock)
Write.
ssize_t write_super_block(int fd, struct superblock *superblock)
Write sb to memory.
void destroy_inode(struct inode *inode)
Destructor of inode.
void destruct_descriptors_table(struct descriptors_table *descriptors_table, const struct superblock *superblock)
Destructor of superblock.
uint32_t get_max_data_size_of_all_blocks(const struct superblock *superblock)
void destroy_super_block(struct superblock *superblock)
Destructor of superblock.
ssize_t read_block(int fd, struct block *block, uint16_t block_id, const struct superblock *superblock)
Read block from memory.
ssize_t read_descriptors_table(int fd, struct descriptors_table *descriptors_table, const struct superblock *superblock)
Read descriptors_table from memory.
Contains some useful methods.
int read_while(int fd, char *buffer, size_t to_read)
Properly reading from memory.
ssize_t read_super_block(int fd, struct superblock *superblock)
Read sb from memory.
int write_while(int fd, const char *buffer, size_t to_write)
Properly writing to memory.
bool send_data(int sockd, char *data, size_t size)
uint16_t reserve_block(const struct superblock *superblock)
Reserve block.
void destruct_block(struct block *block)
Destructor of block.
uint32_t get_max_data_in_block(const struct superblock *superblock)
ssize_t get_file_size(const char *path_to_file)
Get size of file.
void write_to_file(const char *path_to_fs_file, uint16_t file_descriptor, char *data, uint32_t size, int output_fd)
Write data to file Write data from data to file by file_descriptor.
int buffered_write(char **buffer, size_t *buffer_size, char *data, size_t size)
void init_block(struct block *block, const struct superblock *superblock, uint16_t block_id, uint16_t inode_id)
Constructor of block Init block and set its block_records array to nullptr.
ssize_t read_inode(int fd, struct inode *inode, uint16_t inode_id, const struct superblock *superblock)
Read inode from memory.