Cleanup in elf.c with .bss section clean; adm command mounts cdrom instead of floppy...
[ZeXOS.git] / kernel / drivers / fs / znfs.c
blobb89e32ec86ae6e7eb142baa5b9ae8272a68d603f
1 /*
2 * ZeX/OS
3 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
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>
31 #include <cache.h>
32 #include <vfs.h>
34 #define PROTO_MKDIR 0x1
35 #define PROTO_RMDIR 0x2
36 #define PROTO_CREAT 0x3
37 #define PROTO_RM 0x4
38 #define PROTO_CHDIR 0x5
39 #define PROTO_READ 0x6
41 partition_t *znfs_part;
42 int sock;
43 unsigned char znfs_dir_id;
45 /* clear and pre-set dir[] structure */
46 void znfs_dir_flush (unsigned n)
48 strcpy (dir[0].name, ".");
49 strcpy (dir[1].name, "..");
51 znfs_dir_id = 2;
53 unsigned i = znfs_dir_id;
55 for (; i < 223; i ++)
56 memset (dir[i].name, 0, 10);
59 int znfs_send (int fd, unsigned char cmd, char *data, unsigned len)
61 char *s = kmalloc (sizeof (char) * len + 2);
63 if (!s)
64 return 0;
66 s[0] = cmd;
67 memcpy (s+1, data, len);
69 int ret = send (fd, s, len+1, 0);
71 kfree (s);
73 return ret;
76 int znfs_recv (int fd, char *data, unsigned len)
78 return recv (fd, data, len, 0);
81 /* function for read file content */
82 unsigned znfs_read (partition_t *p, unsigned char *name, vfs_content_t *content)
84 unsigned char l = strlen (name);
86 if (l > 10)
87 l = 10;
89 char data[12];
91 data[0] = l;
92 memcpy (data+1, name, l);
94 // Set socket to blocking mode
95 int oldFlag = fcntl (sock, F_GETFL, 0);
96 oldFlag &= ~O_NONBLOCK;
98 if (fcntl (sock, F_SETFL, oldFlag) == -1) {
99 printf ("Cant set socket to nonblocking mode\n");
100 return 0;
103 znfs_send (sock, PROTO_READ, data, l+1);
105 int r = 0;
107 cache_t *cache = cache_create (0, 0, 0);
109 if (!cache)
110 return 0;
112 char block[512];
114 while (1) {
115 r = znfs_recv (sock, block, 512);
117 cache_add (block, r);
119 if (r != 512)
120 break;
123 // Set socket to non-blocking mode
124 oldFlag = fcntl (sock, F_GETFL, 0);
125 if (fcntl (sock, F_SETFL, oldFlag | O_NONBLOCK) == -1) {
126 printf ("Cant set socket to nonblocking mode\n");
127 return 0;
130 content->ptr = (char *) &cache->data;
131 content->len = cache->limit;
133 return 1;
136 /* function for create clear directory */
137 unsigned znfs_create_directory (partition_t *p, unsigned char *name)
139 unsigned char l = strlen (name);
141 if (l > 10)
142 l = 10;
144 char data[12];
146 data[0] = l;
147 memcpy (data+1, name, l);
149 znfs_send (sock, PROTO_MKDIR, data, l+1);
152 memcpy (dir[znfs_dir_id].name, name, l);
153 dir[znfs_dir_id].name[l] = '\0';
155 dir[znfs_dir_id].dir = 1;
157 znfs_dir_id ++;
159 return 1;
162 /* function for create blank file */
163 unsigned znfs_create_file (partition_t *p, unsigned char *name)
165 unsigned char l = strlen (name);
167 if (l > 10)
168 l = 10;
170 char data[12];
172 data[0] = l;
173 memcpy (data+1, name, l);
175 znfs_send (sock, PROTO_CREAT, data, l+1);
177 memcpy (dir[znfs_dir_id].name, name, l);
178 dir[znfs_dir_id].name[l] = '\0';
180 dir[znfs_dir_id].dir = 0;
182 znfs_dir_id ++;
184 return 1;
187 /* go to next directory placed in current directory */
188 void znfs_cd (partition_t *p, unsigned char *name)
190 unsigned short l = strlen (name);
192 if (l > 1023)
193 l = 1023;
195 char data[1024];
197 data[0] = l;
198 memcpy (data+1, name, l);
200 znfs_send (sock, PROTO_CHDIR, data, l+1);
202 znfs_dir_flush (1);
204 // Set socket to blocking mode
205 int oldFlag = fcntl (sock, F_GETFL, 0);
206 oldFlag &= ~O_NONBLOCK;
208 if (fcntl (sock, F_SETFL, oldFlag) == -1) {
209 printf ("Cant set socket to nonblocking mode\n");
212 int r = znfs_recv (sock, data, 1024);
214 // Set socket to non-blocking mode
215 oldFlag = fcntl (sock, F_GETFL, 0);
216 if (fcntl (sock, F_SETFL, oldFlag | O_NONBLOCK) == -1) {
217 printf ("Cant set socket to nonblocking mode\n");
220 if (r < 1) {
221 kprintf ("ZNFS -> error in receiving directory list\n");
222 return;
225 unsigned char n = r/13;
227 struct dent {
228 unsigned char type;
229 char name[12];
230 } __attribute__ ((__packed__));
232 struct dent *d = (struct dent *) data;
234 for (l = 0; l < n; l ++) {
235 memcpy (dir[l].name, d[l].name, 12);
237 if (d[l].type == 0x4)
238 dir[l].dir = 1;
239 else
240 dir[l].dir = 0;
244 /* go to root '/' directory on partition */
245 void znfs_cd_root (partition_t *p)
247 char data[1024];
249 data[0] = 1;
250 data[1] = '/';
252 znfs_send (sock, PROTO_CHDIR, data, 2);
254 znfs_dir_flush (1);
256 // Set socket to blocking mode
257 int oldFlag = fcntl (sock, F_GETFL, 0);
258 oldFlag &= ~O_NONBLOCK;
260 if (fcntl (sock, F_SETFL, oldFlag) == -1) {
261 printf ("Cant set socket to nonblocking mode\n");
264 int r = znfs_recv (sock, data, 1024);
266 // Set socket to non-blocking mode
267 oldFlag = fcntl (sock, F_GETFL, 0);
268 if (fcntl (sock, F_SETFL, oldFlag | O_NONBLOCK) == -1) {
269 printf ("Cant set socket to nonblocking mode\n");
272 if (r < 1) {
273 kprintf ("ZNFS -> error in receiving directory list\n");
274 return;
277 unsigned char n = r/13;
278 unsigned char l;
280 struct dent {
281 unsigned char type;
282 char name[12];
283 } __attribute__ ((__packed__));
285 struct dent *d = (struct dent *) data;
287 for (l = 0; l < n; l ++) {
288 memcpy (dir[l].name, d[l].name, 12);
290 if (d[l].type == 0x4)
291 dir[l].dir = 1;
292 else
293 dir[l].dir = 0;
297 /* zexos filesystem initialization function */
298 unsigned znfs_init (partition_t *p, char *addr)
300 #ifdef CONFIG_DRV_ZNFS
301 znfs_part = p;
303 int port = 5333;
304 hostent *host;
305 sockaddr_in serverSock;
307 // Let's get info about remote computer
308 if ((host = gethostbyname ((char *) addr)) == NULL) {
309 printf ("Wrong address -> %s:%d\n", addr, port);
310 return 0;
313 // Create socket
314 if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
315 printf ("Cant create socket\n");
316 return 0;
319 // Fill structure sockaddr_in
320 // 1) Family of protocols
321 serverSock.sin_family = AF_INET;
322 // 2) Number of server port
323 serverSock.sin_port = swap16 (port);
324 // 3) Setup ip address of server, where we want to connect
325 memcpy (&(serverSock.sin_addr), host->h_addr, host->h_length);
327 kfree (host);
329 // Now we are able to connect to remote server
330 if (connect (sock, (void *) &serverSock, sizeof (serverSock)) == -1) {
331 printf ("Connection cant be estabilished -> %s:%d\n", addr, port);
332 return -1;
335 // Set socket to non-blocking mode
336 int oldFlag = fcntl (sock, F_GETFL, 0);
337 if (fcntl (sock, F_SETFL, oldFlag | O_NONBLOCK) == -1) {
338 printf ("Cant set socket to nonblocking mode\n");
339 return 0;
342 znfs_dir_id = 0;
343 #endif
344 return 1;
347 /* handler which is used by device management and pretty needed
348 for communication between zexos and this filesystem */
349 bool znfs_handler (unsigned act, char *block, unsigned n, unsigned long l)
351 switch (act) {
352 case FS_ACT_INIT:
354 return 1;
356 break;
357 case FS_ACT_READ:
359 return znfs_read (curr_part, dir[n].name, (vfs_content_t *) block);
361 break;
362 case FS_ACT_WRITE:
364 /* TODO */
365 //znfs_write (curr_part, block);
367 return 0;
369 break;
370 case FS_ACT_CHDIR:
372 if (n == -1) {
373 znfs_cd_root (curr_part);
374 return 1;
377 /* re-load content of current directory */
378 if (n == 0)
379 return 1;
381 /* go to previous directory */
382 if (n == 1) {
383 znfs_cd (curr_part, "..");
384 return 1;
387 /* go to another directory */
388 znfs_cd (curr_part, dir[n].name);
390 return 1;
392 break;
393 case FS_ACT_MKDIR:
395 znfs_create_directory (curr_part, block);
397 return 1;
399 break;
400 case FS_ACT_TOUCH:
402 znfs_create_file (curr_part, block);
404 return 1;
408 return 0;
410 #endif