Ext
 All Files Functions
read_file.h
Go to the documentation of this file.
1 
7 #ifndef EXT_FILESYSTEM_INTERFACE_READ_FILE_H_
8 #define EXT_FILESYSTEM_INTERFACE_READ_FILE_H_
9 
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <errno.h>
14 #include <string.h>
15 #include <fcntl.h>
16 #include "../core/superblock.h"
17 #include "../core/descriptors_table.h"
18 #include "../core/defines.h"
19 #include "../core/methods.h"
20 #include "utils.h"
21 #include "net_utils.h"
22 
31 ssize_t read_file(const char* path_to_fs_file,
32  uint16_t file_descriptor,
33  char* dest,
34  uint32_t size, int output_fd) {
35  char* buffer = NULL;
36  size_t buffer_size = 0;
37  int fd = open(path_to_fs_file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
38  if (fd == -1) {
39  fprintf(stderr, "Can't open file. Abort!\n");
40  exit(EXIT_FAILURE);
41  }
42 
43  struct superblock superblock;
44  read_super_block(fd, &superblock);
45  if (superblock.fs_info->magic != MAGIC) {
46  fprintf(stderr, "Magic does not match. Abort!\n");
47  destroy_super_block(&superblock);
48  close(fd);
49  exit(EXIT_FAILURE);
50  }
51 
52  if (!superblock.reserved_inodes_mask[ROOT_INODE_ID]) {
53  fprintf(stderr, "Root directory doesn't exist. Abort!\n");
54  destroy_super_block(&superblock);
55  close(fd);
56  exit(EXIT_FAILURE);
57  }
58 
59  if (size > get_max_data_size_of_all_blocks(&superblock)) {
60  size = get_max_data_size_of_all_blocks(&superblock);
61  }
62 
63  struct descriptors_table descriptors_table;
64  if (read_descriptors_table(fd, &descriptors_table, &superblock) == -1) {
65  fprintf(stderr, "Can't read descriptors_table. Abort!\n");
66  destroy_super_block(&superblock);
67  close(fd);
68  exit(EXIT_FAILURE);
69  }
70 
71  if (!descriptors_table.reserved_fd[file_descriptor]) {
72  buffered_write(&buffer, &buffer_size, "Trying to read from closed fd. Abort!\n", strlen("Trying to read from closed fd. Abort!\n"));
73  write_while(STDERR_FILENO, buffer, buffer_size);
74  send_data(output_fd, buffer, buffer_size);
75  free(buffer);
76  destruct_descriptors_table(&descriptors_table, &superblock);
77  destroy_super_block(&superblock);
78  close(fd);
79  return -1;
80  }
81 
82  uint32_t fd_position = descriptors_table.fd_to_position[file_descriptor];
83  uint16_t inode_id = descriptors_table.fd_to_inode[file_descriptor];
84 
85  struct inode inode;
86  if (read_inode(fd, &inode, inode_id, &superblock) == -1) {
87  fprintf(stderr, "Can't read inode. Abort!\n");
88  destruct_descriptors_table(&descriptors_table, &superblock);
89  destroy_super_block(&superblock);
90  close(fd);
91  exit(EXIT_FAILURE);
92  }
93 
94  uint32_t total_read = 0;
95  uint32_t need_to_read = size;
96 
97  while (total_read != size) {
98  uint16_t block_to_read_pos =
99  (uint16_t) fd_position / get_max_data_in_block(&superblock);
100  if (block_to_read_pos > inode.inode_info->blocks_count) {
101  break;
102  }
103 
104  struct block block;
105  if (read_block(fd,
106  &block,
107  inode.block_ids[block_to_read_pos],
108  &superblock) == -1) {
109  fprintf(stderr, "Can't read block. Abort!\n");
110  destruct_descriptors_table(&descriptors_table, &superblock);
111  destroy_inode(&inode);
112  destroy_super_block(&superblock);
113  close(fd);
114  exit(EXIT_FAILURE);
115  }
116 
117  uint32_t position_in_block_data =
118  (uint32_t) fd_position % get_max_data_in_block(&superblock);
119 
120  char* position_to_read = block.data + position_in_block_data;
121  uint32_t remain_read = block.block_info->data_size - position_in_block_data;
122  if (remain_read == 0) {
123  destruct_block(&block);
124  break;
125  }
126  uint32_t
127  size_to_read = need_to_read < remain_read ? need_to_read : remain_read;
128  memcpy(dest, position_to_read, size_to_read);
129  destruct_block(&block);
130  fd_position += size_to_read;
131  dest += size_to_read;
132  total_read += size_to_read;
133  need_to_read -= size_to_read;
134  }
135 
136  descriptors_table.fd_to_position[file_descriptor] = fd_position;
137  if (write_descriptor_table(fd, &descriptors_table, &superblock) == -1) {
138  fprintf(stderr, "Can't write descriptor table. Abort!\n");
139  destruct_descriptors_table(&descriptors_table, &superblock);
140  destroy_inode(&inode);
141  destroy_super_block(&superblock);
142  close(fd);
143  exit(EXIT_FAILURE);
144  }
145  destruct_descriptors_table(&descriptors_table, &superblock);
146  destroy_inode(&inode);
147  destroy_super_block(&superblock);
148  close(fd);
149 
150  return total_read;
151 }
152 
161 void read_file_to_file(const char* path_to_fs_file,
162  uint16_t file_descriptor,
163  const char* path, ssize_t size) {
164  int fd = open(path_to_fs_file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
165  if (fd == -1) {
166  fprintf(stderr, "Can't open file. Abort!\n");
167  exit(EXIT_FAILURE);
168  }
169 
170  struct superblock superblock;
171  read_super_block(fd, &superblock);
172  if (superblock.fs_info->magic != MAGIC) {
173  fprintf(stderr, "Magic does not match. Abort!\n");
174  destroy_super_block(&superblock);
175  close(fd);
176  exit(EXIT_FAILURE);
177  }
178 
179  if (!superblock.reserved_inodes_mask[ROOT_INODE_ID]) {
180  fprintf(stderr, "Root directory doesn't exist. Abort!\n");
181  destroy_super_block(&superblock);
182  close(fd);
183  exit(EXIT_FAILURE);
184  }
185 
186  ssize_t max_size = get_max_data_size_of_all_blocks(&superblock);
187  max_size = size == -1 ? max_size : (size > max_size ? max_size : size);
188  destroy_super_block(&superblock);
189  close(fd);
190 
191  char* buffer = calloc(max_size, sizeof(char));
192  ssize_t total_read = 0;
193  read_file(path_to_fs_file, file_descriptor, buffer, max_size, STDOUT_FILENO);
194 
195  if (total_read == -1) {
196  free(buffer);
197  return;
198  }
199 
200  fd = open(path, O_RDWR | O_CREAT);
201 
202  if (fd == -1) {
203  fprintf(stderr, "Can't open file to write. Abort!\n");
204  free(buffer);
205  return;
206  }
207 
208  ssize_t written = write_while(fd, buffer, total_read);
209  free(buffer);
210  close(fd);
211 
212  printf("Written %zd to %s\n", written, path);
213 }
214 
215 #endif //EXT_FILESYSTEM_INTERFACE_READ_FILE_H_
ssize_t write_descriptor_table(int fd, struct descriptors_table *descriptors_table, const struct superblock *superblock)
Write descriptors_table to memory.
void destroy_inode(struct inode *inode)
Destructor of inode.
Definition: inode.c:44
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)
Definition: block.c:250
void destroy_super_block(struct superblock *superblock)
Destructor of superblock.
Definition: superblock.c:41
ssize_t read_block(int fd, struct block *block, uint16_t block_id, const struct superblock *superblock)
Read block from memory.
Definition: block.c:133
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.
ssize_t read_super_block(int fd, struct superblock *superblock)
Read sb from memory.
Definition: superblock.c:47
int write_while(int fd, const char *buffer, size_t to_write)
Properly writing to memory.
Definition: utils.c:38
bool send_data(int sockd, char *data, size_t size)
Definition: net_utils.c:75
void destruct_block(struct block *block)
Destructor of block.
Definition: block.c:118
uint32_t get_max_data_in_block(const struct superblock *superblock)
Definition: block.c:246
void read_file_to_file(const char *path_to_fs_file, uint16_t file_descriptor, const char *path, ssize_t size)
Read data from file Read data from file and put it to path.
Definition: read_file.h:161
ssize_t read_file(const char *path_to_fs_file, uint16_t file_descriptor, char *dest, uint32_t size, int output_fd)
Read data from file.
Definition: read_file.h:31
int buffered_write(char **buffer, size_t *buffer_size, char *data, size_t size)
Definition: utils.c:10
ssize_t read_inode(int fd, struct inode *inode, uint16_t inode_id, const struct superblock *superblock)
Read inode from memory.
Definition: inode.c:49