Ext
 All Files Functions
create_file.h
Go to the documentation of this file.
1 
7 #ifndef EXT_FILESYSTEM_INTERFACE_CREATE_FILE_H_
8 #define EXT_FILESYSTEM_INTERFACE_CREATE_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 
29 void create_file(const char* path_to_fs_file, const char* path, int output_fd) {
30  char* buffer = NULL;
31  size_t buffer_size = 0;
32  int fd = open(path_to_fs_file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
33  if (fd == -1) {
34  fprintf(stderr, "Can't open file. Abort!\n");
35  exit(EXIT_FAILURE);
36  }
37 
38  struct superblock superblock;
39  read_super_block(fd, &superblock);
40  if (superblock.fs_info->magic != MAGIC) {
41  fprintf(stderr, "Magic does not match. Abort!\n");
42  destroy_super_block(&superblock);
43  close(fd);
44  exit(EXIT_FAILURE);
45  }
46 
47  if (!superblock.reserved_inodes_mask[ROOT_INODE_ID]) {
48  fprintf(stderr, "Root directory doesn't exist. Abort!\n");
49  destroy_super_block(&superblock);
50  close(fd);
51  exit(EXIT_FAILURE);
52  }
53 
54  char parent_path[buffer_length];
55  char dirname[buffer_length];
56 
57  if (!split_path(path, parent_path, dirname)) {
58  buffered_write(&buffer, &buffer_size, "Incorrect path. Abort!\n", strlen("Incorrect path. Abort!\n"));
59  write_while(STDERR_FILENO, buffer, buffer_size);
60  send_data(output_fd, buffer, buffer_size);
61  free(buffer);
62  destroy_super_block(&superblock);
63  close(fd);
64  return;
65  }
66 
67  uint16_t inode_id = get_inode_id_of_dir(fd, parent_path, &superblock);
68  if (inode_id == superblock.fs_info->inodes_count) {
69  buffered_write(&buffer, &buffer_size, "Can't find directory. Abort!\n", strlen("Can't find directory. Abort!\n"));
70  write_while(STDERR_FILENO, buffer, buffer_size);
71  send_data(output_fd, buffer, buffer_size);
72  free(buffer);
73  destroy_super_block(&superblock);
74  close(fd);
75  return;
76  }
77 
78  struct inode inode;
79  if (read_inode(fd, &inode, inode_id, &superblock) == -1) {
80  buffered_write(&buffer, &buffer_size, "Can't read inode. Abort!\n", strlen("Can't read inode. Abort!\n"));
81  write_while(STDERR_FILENO, buffer, buffer_size);
82  send_data(output_fd, buffer, buffer_size);
83  free(buffer);
84  destroy_super_block(&superblock);
85  close(fd);
86  return;
87  }
88 
89  if (inode.inode_info->is_file) {
90  buffered_write(&buffer, &buffer_size, "Trying to mkdir in file. Abort!\n", strlen("Trying to mkdir in file. Abort!\n"));
91  write_while(STDERR_FILENO, buffer, buffer_size);
92  send_data(output_fd, buffer, buffer_size);
93  free(buffer);
94  destroy_inode(&inode);
95  destroy_super_block(&superblock);
96  close(fd);
97  return;
98  }
99 
100  if (is_dir_exist(fd, &inode, dirname, &superblock)) {
101  buffered_write(&buffer, &buffer_size, "File already exist! Abort!\n", strlen("File already exist! Abort!\n"));
102  write_while(STDERR_FILENO, buffer, buffer_size);
103  send_data(output_fd, buffer, buffer_size);
104  free(buffer);
105  destroy_inode(&inode);
106  destroy_super_block(&superblock);
107  close(fd);
108  return;
109  }
110 
111  uint16_t new_inode_id = create_file_helper(fd, &superblock, inode_id);
112 
113  if (new_inode_id == superblock.fs_info->inodes_count) {
114  buffered_write(&buffer, &buffer_size, "Can't create more inodes! Abort!\n", strlen("Can't create more inodes! Abort!\n"));
115  write_while(STDERR_FILENO, buffer, buffer_size);
116  send_data(output_fd, buffer, buffer_size);
117  free(buffer);
118  destroy_inode(&inode);
119  destroy_super_block(&superblock);
120  close(fd);
121  return;
122  }
123 
124  struct block block;
125  if (read_block(fd, &block, inode.block_ids[0], &superblock) == -1) {
126  buffered_write(&buffer, &buffer_size, "Can't read block. Abort!\n", strlen("Can't read block. Abort!\n"));
127  write_while(STDERR_FILENO, buffer, buffer_size);
128  send_data(output_fd, buffer, buffer_size);
129  free(buffer);
130  destroy_inode(&inode);
131  destroy_super_block(&superblock);
132  close(fd);
133  return;
134  }
135 
136  if (block.block_info->records_count == get_max_records_count(&superblock)) {
137  buffered_write(&buffer, &buffer_size, "Can't create more files in this dir. Abort!\n", strlen("Can't create more files in this dir. Abort!\n"));
138  write_while(STDERR_FILENO, buffer, buffer_size);
139  send_data(output_fd, buffer, buffer_size);
140  free(buffer);
141  destroy_inode(&inode);
142  destroy_super_block(&superblock);
143  close(fd);
144  return;
145  }
146 
147  block.block_records = (struct block_record*) realloc(block.block_records,
148  (block.block_info->records_count
149  + 1)
150  * sizeof(struct block_record));
151  struct block_record new_record;
152  init_block_record(&new_record, &superblock, new_inode_id);
153  strcpy(new_record.path, dirname);
154  block.block_records[block.block_info->records_count] = new_record;
155  block.block_info->records_count += 1;
156  if (write_block(fd, &block, &superblock) == -1) {
157  buffered_write(&buffer, &buffer_size, "Can't write block. Abort!\n", strlen("Can't write block. Abort!\n"));
158  write_while(STDERR_FILENO, buffer, buffer_size);
159  send_data(output_fd, buffer, buffer_size);
160  free(buffer);
161  destroy_inode(&inode);
162  destruct_block(&block);
163  destroy_super_block(&superblock);
164  close(fd);
165  return;
166  }
167 
168  if (buffer != NULL) {
169  write_while(STDERR_FILENO, buffer, buffer_size);
170  send_data(output_fd, buffer, buffer_size);
171  free(buffer);
172  } else {
173  send_data(output_fd, NULL, 0);
174  }
175 
176  destroy_inode(&inode);
177  destruct_block(&block);
178  destroy_super_block(&superblock);
179  close(fd);
180 }
181 
182 #endif //EXT_FILESYSTEM_INTERFACE_CREATE_FILE_H_
uint16_t create_file_helper(int fd, const struct superblock *superblock, uint16_t parent_node_id)
Helper for create new file Creates file with parent = parent_node_id.
Definition: methods.c:76
ssize_t write_block(int fd, struct block *block, const struct superblock *superblock)
Write.
Definition: block.c:189
void destroy_inode(struct inode *inode)
Destructor of inode.
Definition: inode.c:44
void init_block_record(struct block_record *block_record, const struct superblock *superblock, uint16_t inode_id)
Constructor of block record Init block record and set its path array to char[max_len_path].
Definition: block.c:24
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
void create_file(const char *path_to_fs_file, const char *path, int output_fd)
Creates file.
Definition: create_file.h:29
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
uint8_t get_max_records_count(const struct superblock *superblock)
Definition: block.c:241
uint16_t get_inode_id_of_dir(int fd, const char *path, const struct superblock *superblock)
Parse path and find inode of this dir.
Definition: methods.c:197
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
bool is_dir_exist(int fd, struct inode *inode, const char *dirname, const struct superblock *superblock)
Check if dir exists in inode.
Definition: methods.c:210