Ext
 All Files Functions
create_dir.h
Go to the documentation of this file.
1 
7 #ifndef EXT_FILESYSTEM_INTERFACE_CREATE_DIR_H_
8 #define EXT_FILESYSTEM_INTERFACE_CREATE_DIR_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_dir(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 
69  if (inode_id == superblock.fs_info->inodes_count) {
70  buffered_write(&buffer, &buffer_size, "Can't find directory. Abort!\n", strlen("Can't find directory. Abort!\n"));
71  write_while(STDERR_FILENO, buffer, buffer_size);
72  send_data(output_fd, buffer, buffer_size);
73  free(buffer);
74  destroy_super_block(&superblock);
75  close(fd);
76  return;
77  }
78 
79  struct inode inode;
80  if (read_inode(fd, &inode, inode_id, &superblock) == -1) {
81  buffered_write(&buffer, &buffer_size, "Can't read inode. Abort!\n", strlen("Can't read inode. Abort!\n"));
82  write_while(STDERR_FILENO, buffer, buffer_size);
83  send_data(output_fd, buffer, buffer_size);
84  free(buffer);
85  destroy_super_block(&superblock);
86  close(fd);
87  return;
88  }
89 
90  if (inode.inode_info->is_file) {
91  buffered_write(&buffer, &buffer_size, "Trying to mkdir in file. Abort!\n", strlen("Trying to mkdir in file. Abort!\n"));
92  write_while(STDERR_FILENO, buffer, buffer_size);
93  send_data(output_fd, buffer, buffer_size);
94  free(buffer);
95  destroy_inode(&inode);
96  destroy_super_block(&superblock);
97  close(fd);
98  return;
99  }
100 
101  if (is_dir_exist(fd, &inode, dirname, &superblock)) {
102  buffered_write(&buffer, &buffer_size, "File already exist! Abort!\n", strlen("File already exist! Abort!\n"));
103  write_while(STDERR_FILENO, buffer, buffer_size);
104  send_data(output_fd, buffer, buffer_size);
105  free(buffer);
106  destroy_inode(&inode);
107  destroy_super_block(&superblock);
108  close(fd);
109  return;
110  }
111 
112  uint16_t new_inode_id = create_dir_helper(fd, &superblock, inode_id, false);
113 
114  if (new_inode_id == superblock.fs_info->inodes_count) {
115  buffered_write(&buffer, &buffer_size, "Can't create more inodes! Abort!\n", strlen("Can't create more inodes! Abort!\n"));
116  write_while(STDERR_FILENO, buffer, buffer_size);
117  send_data(output_fd, buffer, buffer_size);
118  free(buffer);
119  destroy_inode(&inode);
120  destroy_super_block(&superblock);
121  close(fd);
122  return;
123  }
124 
125  struct block block;
126  if (read_block(fd, &block, inode.block_ids[0], &superblock) == -1) {
127  buffered_write(&buffer, &buffer_size, "Can't read block. Abort!\n", strlen("Can't read block. Abort!\n"));
128  write_while(STDERR_FILENO, buffer, buffer_size);
129  send_data(output_fd, buffer, buffer_size);
130  free(buffer);
131  destroy_inode(&inode);
132  destroy_super_block(&superblock);
133  close(fd);
134  return;
135  }
136 
137  if (block.block_info->records_count == get_max_records_count(&superblock)) {
138  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"));
139  write_while(STDERR_FILENO, buffer, buffer_size);
140  send_data(output_fd, buffer, buffer_size);
141  free(buffer);
142  destroy_inode(&inode);
143  destroy_super_block(&superblock);
144  close(fd);
145  return;
146  }
147 
148  block.block_records = (struct block_record*) realloc(block.block_records,
149  (block.block_info->records_count
150  + 1)
151  * sizeof(struct block_record));
152  struct block_record new_record;
153  init_block_record(&new_record, &superblock, new_inode_id);
154  strcpy(new_record.path, dirname);
155  block.block_records[block.block_info->records_count] = new_record;
156  block.block_info->records_count += 1;
157  if (write_block(fd, &block, &superblock) == -1) {
158  buffered_write(&buffer, &buffer_size, "Can't write block. Abort!\n", strlen("Can't write block. Abort!\n"));
159  write_while(STDERR_FILENO, buffer, buffer_size);
160  send_data(output_fd, buffer, buffer_size);
161  free(buffer);
162  destroy_inode(&inode);
163  destruct_block(&block);
164  destroy_super_block(&superblock);
165  close(fd);
166  return;
167  }
168 
169  if (buffer != NULL) {
170  write_while(STDERR_FILENO, buffer, buffer_size);
171  send_data(output_fd, buffer, buffer_size);
172  free(buffer);
173  } else {
174  send_data(output_fd, NULL, 0);
175  }
176 
177 
178 
179  destroy_inode(&inode);
180  destruct_block(&block);
181  destroy_super_block(&superblock);
182  close(fd);
183 }
184 
185 #endif //EXT_FILESYSTEM_INTERFACE_CREATE_DIR_H_
void create_dir(const char *path_to_fs_file, const char *path, int output_fd)
Create new directory.
Definition: create_dir.h:29
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
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 create_dir_helper(int fd, const struct superblock *superblock, uint16_t parent_node_id, bool is_root)
Helper for create new directory Creates dir with parent = parent_node_id (or itself if is_root)...
Definition: methods.c:8
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