Ext
 All Files Functions
server.c
1 
3 #include "server.h"
4 #include "utils.h"
5 #include "net_utils.h"
6 #include <unistd.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #if __APPLE__
12  #include <sys/event.h>
13 #else
14  #include <sys/epoll.h>
15 #endif
16 
17 #include "init.h"
18 #include "ls.h"
19 #include "create_dir.h"
20 #include "create_file.h"
21 #include "open_file.h"
22 #include "close_file.h"
23 #include "write_to_file.h"
24 #include "read_file.h"
25 #include "lseek_pos.h"
26 
27 
28 bool process_command(int sockd, const char* fs_file_path) {
29  enum Command command;
30  if (!receive_command(sockd, &command)) {
31  return false;
32  }
33 
34  switch (command) {
35  case Help: {
36  char* help_text = "You are working with minifs\n"
37  "Authored by yaishenka\n"
38  "Source available ad github.com/yaishenka/ext\n"
39  "Available commands:\n"
40  "help -- print this text\n"
41  "quit -- close program\n"
42  "ls [path] -- list directory contents\n"
43  "init -- init file system\n"
44  "read_fs -- read fs_file and checks it\n"
45  "mkdir [path] -- make directories\n"
46  "touch [path] -- create files\n"
47  "open [path] -- open file and return FD\n"
48  "close [fd] -- close FD\n"
49  "write [fd] [data] -- write data to FD\n"
50  "write_from [fd] [path] -- read data from path and write to FD\n"
51  "read [fd] [size] -- read size bytes from FD\n"
52  "read_to [fd] [path] [size] -- read file from fd.pos and write data to path. "
53  "If size not specified file will be readed till end\n"
54  "lseek [fd] [pos] -- set fd.pos = pos\n";
55  send_data(sockd, help_text, strlen(help_text));
56  break;
57  }
58 
59  case Quit: {
60  return false;
61  }
62 
63  case Init: {
64  init_fs(fs_file_path);
65  break;
66  }
67 
68  case ReadFs: {
69  read_fs(fs_file_path);
70  break;
71  }
72 
73  case Ls: {
74  char* path = NULL;
75  size_t path_len = 0;
76  receive_data(sockd, &path, &path_len);
77  ls(fs_file_path, path, sockd);
78  free(path);
79  break;
80  }
81 
82  case Mkdir: {
83  char* path = NULL;
84  size_t path_len = 0;
85  receive_data(sockd, &path, &path_len);
86  create_dir(fs_file_path, path, sockd);
87  break;
88  }
89 
90  case Touch: {
91  char* path = NULL;
92  size_t path_len = 0;
93  receive_data(sockd, &path, &path_len);
94  create_file(fs_file_path, path, sockd);
95  break;
96  }
97 
98  case Open: {
99  char* path = NULL;
100  size_t path_len = 0;
101  receive_data(sockd, &path, &path_len);
102  open_file(fs_file_path, path, sockd);
103  break;
104  }
105 
106  case Close: {
107  char* fd_to_close_string = NULL;
108  size_t fd_to_close_string_len = 0;
109  receive_data(sockd, &fd_to_close_string, &fd_to_close_string_len);
110  int fd_to_close = strtol(fd_to_close_string, NULL, 10);
111  close_file(fs_file_path, fd_to_close, sockd);
112  break;
113  }
114 
115  case Lseek: {
116  char* full_string = NULL;
117  size_t len = 0;
118  receive_data(sockd, &full_string, &len);
119  char* next_arg = NULL;
120  int fd = strtol(full_string, &next_arg, 10);
121  int position = strtol(next_arg, NULL, 10);
122  lseek_pos(fs_file_path, fd, position, sockd);
123  break;
124  }
125 
126  case Write: {
127  char* full_string = NULL;
128  size_t len = 0;
129  receive_data(sockd, &full_string, &len);
130  char* next_arg = NULL;
131  int fd = strtol(full_string, &next_arg, 10);
132  char* data = NULL;
133  size_t size = strtol(next_arg, &data, 10);
134  write_to_file(fs_file_path, fd, data + 1, size, sockd);
135  break;
136  }
137 
138  case Read: {
139  char* full_string = NULL;
140  size_t len = 0;
141  receive_data(sockd, &full_string, &len);
142  char* next_arg = NULL;
143  int fd = strtol(full_string, &next_arg, 10);
144  int size = strtol(next_arg, NULL, 10);
145  char data[buffer_length];
146 
147  size_t total_read = read_file(fs_file_path, fd, data, size, sockd);
148  data[size] = '\0';
149 
150  char* buffer = NULL;
151  size_t buffer_size = 0;
152  char string_buffer[size + 1];
153  size_t string_size = sprintf(string_buffer, "\t%zu\t%s", total_read, data);
154  buffered_write(&buffer, &buffer_size, string_buffer, strlen(string_buffer));
155  send_data(sockd, buffer, buffer_size);
156  free(buffer);
157  break;
158  }
159 
160  default: {
161  break;
162  }
163 
164  }
165 
166  return true;
167 }
168 
169 int server_loop(long port, const char* fs_file_path) {
170  int sockd = socket(AF_INET, SOCK_STREAM, 0);
171 
172  if (sockd == -1) {
173  fprintf(stderr, "Can't create socket. Abort!\n");
174  exit(EXIT_FAILURE);
175  }
176 
177  struct sockaddr_in addr;
178  memset(&addr, 0, sizeof(struct sockaddr_in));
179  addr.sin_family = AF_INET;
180  addr.sin_port = htons(port);
181  addr.sin_addr.s_addr = htonl(INADDR_ANY);
182 
183  if (bind(sockd, (struct sockaddr*) &addr, sizeof(addr)) == -1) {
184  fprintf(stderr, "Can't create connection. Abort!\n");
185  exit(EXIT_FAILURE);
186  }
187 
188  if (listen(sockd, 1) == -1) {
189  fprintf(stderr, "Can't listen. Abort!\n");
190  exit(EXIT_FAILURE);
191  }
192 
193 #if __APPLE__
194  int kq = kqueue();
195  struct kevent change_event[4];
196  EV_SET(change_event, sockd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
197  if (kevent(kq, change_event, 1, NULL, 0, NULL) == -1) {
198  fprintf(stderr, "Can't register kevent. Abort!\n");
199  exit(EXIT_FAILURE);
200  }
201 #else
202  int epoll_fd = epoll_create1(0);
203  struct epoll_event event;
204  memset(&event, 0, sizeof(struct epoll_event));
205  event.events = EPOLLIN | EPOLLERR | EPOLLHUP;
206  event.data.fd = sockd;
207  epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sockd, &event);
208 #endif
209 
210  while (true) {
211  int connection_fd = -1;
212 #if __APPLE__
213  struct kevent event[4];
214  int new_events = kevent(kq, NULL, 0, event, 1, NULL);
215  if (new_events <= 0) {
216  continue;
217  }
218 
219  int event_fd = event[0].ident;
220 
221  if (event_fd == sockd) {
222  connection_fd = accept(sockd, NULL, NULL);
223 
224  if (connection_fd == -1) {
225  fprintf(stderr, "Connection error. Abort!\n");
226  shutdown(sockd, SHUT_RDWR);
227  close(sockd);
228  return 1;
229  }
230  }
231 #else
232  struct epoll_event event;
233  memset(&event, 0, sizeof(struct epoll_event));
234  int new_events = epoll_wait(epoll_fd, &event, 1, 1000);
235  if (new_events <= 0) {
236  continue;
237  }
238  connection_fd = accept(sockd, NULL, NULL);
239  if (connection_fd == -1) {
240  fprintf(stderr, "Connection error. Abort!\n");
241  shutdown(sockd, SHUT_RDWR);
242  close(sockd);
243  return 1;
244  }
245 #endif
246  while (process_command(connection_fd, fs_file_path)) {
247  }
248 
249  shutdown(connection_fd, SHUT_RDWR);
250  close(connection_fd);
251  }
252  shutdown(sockd, SHUT_RDWR);
253  close(sockd);
254 
255 #if __APPLE__
256 #else
257  close(epoll_fd);
258 #endif
259 
260  return 0;
261 }
Contains method to close FD.
Contains methods to init FS.
void create_dir(const char *path_to_fs_file, const char *path, int output_fd)
Create new directory.
Definition: create_dir.h:29
void ls(const char *path_to_fs_file, const char *path_to_dir, int output_fd)
List directory.
Definition: ls.h:30
void close_file(const char *path_to_fs_file, const int fd_to_close, int output_fd)
Close file.
Definition: close_file.h:28
Contains method to create dir.
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.
Contains method to create file.
Contains methods to write to file.
bool send_data(int sockd, char *data, size_t size)
Definition: net_utils.c:75
int server_loop(long port, const char *fs_file_path)
Definition: server.c:169
bool receive_command(int sockd, enum Command *command)
Definition: net_utils.c:84
Contains method to open file.
bool receive_data(int sockd, char **data, size_t *size)
Definition: net_utils.c:94
void open_file(const char *path_to_fs_file, const char *path, int output_fd)
Open file and printf fd.
Definition: open_file.h:27
Contains method to list dir.
void init_fs(const char *path_to_fs_file)
Init filesystem Trunc file and init our FS in it. Creates superblock, descriptor_table and root_dir...
Definition: init.h:28
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
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.
Definition: write_to_file.h:32
Contains methods to read from file.
Contains method to lseek.
int buffered_write(char **buffer, size_t *buffer_size, char *data, size_t size)
Definition: utils.c:10