Kernel 0.6.3; ZNFS filesystem is able to create file, directories, change directory...
[ZeXOS.git] / kernel / drivers / fs / znfs.c
blobf38bac7cadb1ed3f318de7e3de55b20eb70e19ce
1 /*
2 * ZeX/OS
3 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <config.h>
21 #include <build.h>
23 #ifdef ARCH_i386
25 #include <system.h>
26 #include <string.h>
27 #include <dev.h>
28 #include <fs.h>
29 #include <partition.h>
30 #include <net/socket.h>
32 #define PROTO_MKDIR 0x1
33 #define PROTO_RMDIR 0x2
34 #define PROTO_CREAT 0x3
35 #define PROTO_RM 0x4
36 #define PROTO_CHDIR 0x5
37 #define PROTO_READ 0x6
39 partition_t *znfs_part;
40 int sock;
41 unsigned char znfs_dir_id;
43 /* clear and pre-set dir[] structure */
44 void znfs_dir_flush (unsigned n)
46 strcpy (dir[0].name, ".");
47 strcpy (dir[1].name, "..");
49 znfs_dir_id = 2;
51 unsigned i = znfs_dir_id;
53 for (; i < 223; i ++)
54 memset (dir[i].name, 0, 10);
57 int znfs_send (int fd, unsigned char cmd, char *data, unsigned len)
59 char *s = kmalloc (sizeof (char) * len + 2);
61 if (!s)
62 return 0;
64 s[0] = cmd;
65 memcpy (s+1, data, len);
67 int ret = send (fd, s, len+1, 0);
69 kfree (s);
71 return ret;
74 int znfs_recv (int fd, char *data, unsigned len)
76 return recv (fd, data, len, 0);
79 /* function for read file content */
80 unsigned znfs_read (partition_t *p, unsigned char *name)
82 unsigned char l = strlen (name);
84 if (l > 10)
85 l = 10;
87 char data[12];
89 data[0] = l;
90 memcpy (data+1, name, l);
92 // Set socket to blocking mode
93 int oldFlag = fcntl (sock, F_GETFL, 0);
94 oldFlag &= ~O_NONBLOCK;
96 if (fcntl (sock, F_SETFL, oldFlag) == -1) {
97 printf ("Cant set socket to nonblocking mode\n");
100 znfs_send (sock, PROTO_READ, data, l+1);
102 int r = 0;
104 file_cache = (char *) 0x35000;
105 file_cache_id = 0;
107 char *s = (char *) file_cache;
109 while (1) {
110 r = znfs_recv (sock, s, 1024);
112 s += r;
114 if (r != 1024)
115 break;
118 file_cache[r] = '\0';
119 file_cache_id = r;
121 // Set socket to non-blocking mode
122 oldFlag = fcntl (sock, F_GETFL, 0);
123 if (fcntl (sock, F_SETFL, oldFlag | O_NONBLOCK) == -1) {
124 printf ("Cant set socket to nonblocking mode\n");
127 return 1;
130 /* function for create clear directory */
131 unsigned znfs_create_directory (partition_t *p, unsigned char *name)
133 unsigned char l = strlen (name);
135 if (l > 10)
136 l = 10;
138 char data[12];
140 data[0] = l;
141 memcpy (data+1, name, l);
143 znfs_send (sock, PROTO_MKDIR, data, l+1);
146 memcpy (dir[znfs_dir_id].name, name, l);
147 dir[znfs_dir_id].name[l] = '\0';
149 dir[znfs_dir_id].dir = 1;
151 znfs_dir_id ++;
153 return 1;
156 /* function for create blank file */
157 unsigned znfs_create_file (partition_t *p, unsigned char *name)
159 unsigned char l = strlen (name);
161 if (l > 10)
162 l = 10;
164 char data[12];
166 data[0] = l;
167 memcpy (data+1, name, l);
169 znfs_send (sock, PROTO_CREAT, data, l+1);
171 memcpy (dir[znfs_dir_id].name, name, l);
172 dir[znfs_dir_id].name[l] = '\0';
174 dir[znfs_dir_id].dir = 0;
176 znfs_dir_id ++;
178 return 1;
181 /* go to next directory placed in current directory */
182 void znfs_cd (partition_t *p, unsigned char *name)
184 unsigned short l = strlen (name);
186 if (l > 1023)
187 l = 1023;
189 char data[1024];
191 data[0] = l;
192 memcpy (data+1, name, l);
194 znfs_send (sock, PROTO_CHDIR, data, l+1);
196 znfs_dir_flush (1);
198 // Set socket to blocking mode
199 int oldFlag = fcntl (sock, F_GETFL, 0);
200 oldFlag &= ~O_NONBLOCK;
202 if (fcntl (sock, F_SETFL, oldFlag) == -1) {
203 printf ("Cant set socket to nonblocking mode\n");
206 int r = znfs_recv (sock, data, 1024);
208 // Set socket to non-blocking mode
209 oldFlag = fcntl (sock, F_GETFL, 0);
210 if (fcntl (sock, F_SETFL, oldFlag | O_NONBLOCK) == -1) {
211 printf ("Cant set socket to nonblocking mode\n");
214 if (r < 1) {
215 kprintf ("ZNFS -> error in receiving directory list\n");
216 return;
219 unsigned char n = r/13;
221 struct dent {
222 unsigned char type;
223 char name[12];
224 } __attribute__ ((__packed__));
226 struct dent *d = (struct dent *) data;
228 for (l = 0; l < n; l ++) {
229 memcpy (dir[l].name, d[l].name, 12);
231 if (d[l].type == 0x4)
232 dir[l].dir = 1;
233 else
234 dir[l].dir = 0;
238 /* go to root '/' directory on partition */
239 void znfs_cd_root (partition_t *p)
241 char data[1024];
243 data[0] = 1;
244 data[1] = '/';
246 znfs_send (sock, PROTO_CHDIR, data, 2);
248 znfs_dir_flush (1);
250 // Set socket to blocking mode
251 int oldFlag = fcntl (sock, F_GETFL, 0);
252 oldFlag &= ~O_NONBLOCK;
254 if (fcntl (sock, F_SETFL, oldFlag) == -1) {
255 printf ("Cant set socket to nonblocking mode\n");
258 int r = znfs_recv (sock, data, 1024);
260 // Set socket to non-blocking mode
261 oldFlag = fcntl (sock, F_GETFL, 0);
262 if (fcntl (sock, F_SETFL, oldFlag | O_NONBLOCK) == -1) {
263 printf ("Cant set socket to nonblocking mode\n");
266 if (r < 1) {
267 kprintf ("ZNFS -> error in receiving directory list\n");
268 return;
271 unsigned char n = r/13;
272 unsigned char l;
274 struct dent {
275 unsigned char type;
276 char name[12];
277 } __attribute__ ((__packed__));
279 struct dent *d = (struct dent *) data;
281 for (l = 0; l < n; l ++) {
282 memcpy (dir[l].name, d[l].name, 12);
284 if (d[l].type == 0x4)
285 dir[l].dir = 1;
286 else
287 dir[l].dir = 0;
291 /* zexos filesystem initialization function */
292 unsigned znfs_init (partition_t *p, char *addr)
294 #ifdef CONFIG_DRV_ZNFS
295 znfs_part = p;
297 int port = 5333;
298 hostent *host;
299 sockaddr_in serverSock;
301 // Let's get info about remote computer
302 if ((host = gethostbyname ((char *) addr)) == NULL) {
303 //printf ("Wrong address -> %s:%d\n", addr, port);
304 printf ("Wrong address\n");
305 return 0;
308 // Create socket
309 if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
310 printf ("Cant create socket\n");
311 return 0;
314 // Fill structure sockaddr_in
315 // 1) Family of protocols
316 serverSock.sin_family = AF_INET;
317 // 2) Number of server port
318 serverSock.sin_port = swap16 (port);
319 // 3) Setup ip address of server, where we want to connect
320 memcpy (&(serverSock.sin_addr), host->h_addr, host->h_length);
322 // Now we are able to connect to remote server
323 if (connect (sock, (void *) &serverSock, sizeof (serverSock)) == -1) {
324 printf ("Connection cant be estabilished -> %s:%d\n", addr, port);
325 return -1;
328 // Set socket to non-blocking mode
329 int oldFlag = fcntl (sock, F_GETFL, 0);
330 if (fcntl (sock, F_SETFL, oldFlag | O_NONBLOCK) == -1) {
331 printf ("Cant set socket to nonblocking mode\n");
332 return 0;
335 znfs_dir_id = 0;
337 timer_wait (100);
340 #endif
341 return 1;
344 /* handler which is used by device management and pretty needed
345 for communication between zexos and this filesystem */
346 bool znfs_handler (unsigned act, char *block, unsigned n, unsigned long l)
348 switch (act) {
349 case FS_ACT_INIT:
351 return 1;
353 break;
354 case FS_ACT_READ:
356 znfs_read (curr_part, dir[n].name);
358 return 1;
360 break;
361 case FS_ACT_WRITE:
363 /*znfs_write (curr_part, block);*/
365 return 0;
367 break;
368 case FS_ACT_CHDIR:
370 if (n == -1) {
371 znfs_cd_root (curr_part);
372 return 1;
375 /* re-load content of current directory */
376 if (n == 0)
377 return 1;
379 /* go to previous directory */
380 if (n == 1) {
381 znfs_cd (curr_part, "..");
382 return 1;
385 /* go to another directory */
386 znfs_cd (curr_part, dir[n].name);
388 return 1;
390 break;
391 case FS_ACT_MKDIR:
393 znfs_create_directory (curr_part, block);
395 return 1;
397 break;
398 case FS_ACT_TOUCH:
400 znfs_create_file (curr_part, block);
402 return 1;
406 return 0;
408 #endif