Kernel 0.5.9-r7; New iso9660 filesystem support, better exec () function, some change...
[ZeXOS.git] / kernel / core / vfs.c
blobe00a3c1530e6e97a697b885182ef62c21c74d274
1 /*
2 * ZeX/OS
3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <system.h>
22 #include <string.h>
23 #include <vfs.h>
24 #include <mount.h>
26 vfs_t vfs_list;
27 extern mount_t mount_list;
28 fd_t fd_list;
29 extern unsigned int fd_count;
31 vfs_t *vfs_list_findbymp (char *mountpoint)
33 vfs_t *vfs;
34 for (vfs = vfs_list.next; vfs != &vfs_list; vfs = vfs->next) {
35 if (!strcmp (vfs->mountpoint, mountpoint))
36 return vfs;
39 return 0;
42 bool vfs_list_add (char *name, unsigned attrib, char *mountpoint)
44 unsigned name_len = strlen (name);
45 unsigned mp_len = strlen (mountpoint);
47 vfs_t *vfs;
49 /* alloc and init context */
50 vfs = (vfs_t *) kmalloc (sizeof (vfs_t));
51 if (!vfs)
52 return 0;
54 memset (vfs, 0, sizeof (vfs_t));
56 vfs->name = (char *) kmalloc (sizeof (char) * VFS_FILENAME_LEN + 2);
57 if (!vfs->name) {
58 kfree (vfs);
59 return 0;
62 memset (vfs->name, 0, VFS_FILENAME_LEN);
63 memcpy (vfs->name, name, name_len);
64 vfs->name[name_len] = '\0';
65 //printf ("dd: '%s' '%s'", name, vfs->name);
66 memset (vfs->mountpoint, 0, VFS_MOUNTPOINT_LEN);
67 memcpy (vfs->mountpoint, mountpoint, mp_len);
68 vfs->mountpoint[mp_len] = '\0';
70 vfs->attrib = attrib;
72 vfs->ptr = 0;
74 /* add into list */
75 vfs->next = &vfs_list;
76 vfs->prev = vfs_list.prev;
77 vfs->prev->next = vfs;
78 vfs->next->prev = vfs;
80 return 1;
83 bool vfs_list_del (char *mountpoint)
85 bool f = 0;
86 vfs_t *vfs;
87 for (vfs = vfs_list.next; vfs != &vfs_list; vfs = vfs->next) {
88 if (!strncmp (vfs->mountpoint, mountpoint, strlen (mountpoint))) {
89 f = 1;
90 break;
94 if (f) {
95 vfs->next->prev = vfs->prev;
96 vfs->prev->next = vfs->next;
98 //kfree (vfs);
99 return 1;
102 return 0;
105 bool vfs_ls (char *file, unsigned file_len)
107 char pwd[64];
108 strcpy (pwd, (char *) env_get ("PWD"));
110 // puts ("name rwhsdb\n");
112 vfs_t *vfs;
113 bool res = false;
115 if (!file_len) {
116 for (vfs = vfs_list.next; vfs != &vfs_list; vfs = vfs->next)
117 if (!strcmp (vfs->mountpoint, pwd)) {
118 printf ("%s\t", vfs->name);
119 res = true;
121 } else {
122 for (vfs = vfs_list.next; vfs != &vfs_list; vfs = vfs->next)
123 if (!strcmp (vfs->mountpoint, file) ||
124 !strcmp (vfs->mountpoint+1, file)) {
125 printf ("%s\t", vfs->name);
126 res = true;
130 /*printf ("%s\t%u%u%u%u%u%u%u\n", vfs->name,
131 vfs->attrib & VFS_FILEATTR_READ,
132 vfs->attrib & VFS_FILEATTR_WRITE,
133 vfs->attrib & VFS_FILEATTR_HIDDEN,
134 vfs->attrib & VFS_FILEATTR_SYSTEM,
135 vfs->attrib & VFS_FILEATTR_DIR,
136 vfs->attrib & VFS_FILEATTR_BIN);*/
138 if (res)
139 printf ("\n");
141 return 1;
144 bool vfs_cd (char *file, unsigned file_len)
146 /* go back */
147 if (!strcmp (file, "..")) {
148 char pwd[64];
149 strcpy (pwd, (char *) env_get ("PWD"));
151 unsigned pwd_len = strlen (pwd);
153 if (!strcmp (pwd, "/"))
154 return 0;
156 /* vymaze kus retezce - az po predposledni / */
157 pwd_len --; // preskoci / na konci retezce
158 while (pwd_len) {
159 pwd_len --;
160 if (pwd[pwd_len] == '/') {
161 pwd[pwd_len+1] = '\0';
162 break;
166 vfs_t *vfs;
167 for (vfs = vfs_list.next; vfs != &vfs_list; vfs = vfs->next)
168 if (!strcmp (vfs->mountpoint, pwd)) {
169 if (vfs->attrib & VFS_FILEATTR_MOUNTED) {
170 //printf ("vfs->mountpoint: %s | pwd: %s\n", vfs->mountpoint, pwd);
171 partition_t *p = mount_find (pwd);
173 if (p) {
174 mount (p, file, ""); // first return to last directory
176 umount (p, (char *) env_get ("PWD")); // then umount old directory
178 while (vfs_list_del ((char *) env_get ("PWD")));
180 } else {
181 printf ("ERROR -> device not respond\n");
182 return 0;
187 env_set ("PWD", pwd); // set new directory
189 return 1;
192 /* nothing */
193 if (!strcmp (file, "."))
194 return 1;
196 vfs_t *vfs;
197 /* go to root fs dir */
198 if (!strcmp (file, "/")) {
200 env_set ("PWD", file);
202 for (vfs = vfs_list.next; vfs != &vfs_list; vfs = vfs->next) {
203 if (vfs->attrib & VFS_FILEATTR_MOUNTED) {
204 partition_t *p = mount_find ((char *) env_get ("PWD"));
206 if (p)
207 mount (p, file, "");
211 return 1;
214 /* go to another directory */
215 char pwd[64];
216 strcpy (pwd, (char *) env_get ("PWD"));
219 char buf[65];
220 unsigned pwd_len = strlen (pwd);
222 unsigned i = file[0] == '/' ? 1 : 0;
224 if (!i) {
225 memcpy (buf, pwd, pwd_len);
226 memcpy (buf+pwd_len, file+i, file_len-i);
227 buf[pwd_len+file_len-i] = '\0';
228 } else {
229 memcpy (buf, file, file_len);
230 buf[file_len] = '\0';
233 if (buf[pwd_len+file_len-i-1] == '/')
234 buf[pwd_len+file_len-i-1] = '\0';
237 for (vfs = vfs_list.next; vfs != &vfs_list; vfs = vfs->next) {
238 unsigned mp_len = strlen (vfs->mountpoint);
239 unsigned nm_len = strlen (vfs->name);
241 char buf2[65];
242 memcpy (buf2, vfs->mountpoint, mp_len);
243 memcpy (buf2+mp_len, vfs->name, nm_len);
244 buf2[mp_len+nm_len] = '\0';
246 if (!strcmp (buf, buf2)) {
247 if (vfs->attrib & VFS_FILEATTR_FILE) {
248 printf ("ERROR -> this is a file, not an directory\n");
249 return 0;
252 // check permissions
253 if (vfs->attrib & VFS_FILEATTR_SYSTEM && strcmp ((char *) env_get ("USER"), "root")) {
254 printf ("ERROR -> only root can do that\n");
255 return 0;
258 memcpy (pwd, buf2, mp_len+nm_len);
259 pwd[mp_len+nm_len] = '/';
260 pwd[mp_len+nm_len+1] = '\0';
262 if (vfs->attrib & VFS_FILEATTR_MOUNTED) {
263 partition_t *p = mount_find ((char *) env_get ("PWD"));
265 if (p)
266 mount (p, file, pwd);
267 else {
268 printf ("ERROR -> device not respond\n");
269 return 0;
273 env_set ("PWD", pwd);
275 return 1;
279 return 0;
282 bool vfs_mkdir (char *file, unsigned file_len)
284 if (file_len) {
285 char pwd[64];
286 strcpy (pwd, (char *) env_get ("PWD"));
288 vfs_list_add (file, VFS_FILEATTR_DIR | VFS_FILEATTR_READ | VFS_FILEATTR_MOUNTED, (char *) pwd);
290 partition_t *p = mount_find ((char *) pwd);
292 if (p)
293 p->fs->handler (FS_ACT_WRITE, FS_ARG_DIR, file, 0, file_len);
294 else {
295 printf ("ERROR -> device not respond\n");
296 return 0;
299 DPRINT ("vfs_mkdir ()\n");
300 return 1;
303 return 0;
306 vfs_dirent_t *vfs_dirent ()
308 char pwd[64];
309 strcpy (pwd, (char *) env_get ("PWD"));
311 vfs_t *vfs;
312 bool res = false;
314 unsigned dirents = 0;
316 for (vfs = vfs_list.next; vfs != &vfs_list; vfs = vfs->next)
317 if (!strcmp (vfs->mountpoint, pwd))
318 dirents ++;
320 if (!dirents)
321 return 0;
323 vfs_dirent_t *dirent = (vfs_dirent_t *) kmalloc (sizeof (vfs_dirent_t) * (dirents+1));
325 if (!dirent)
326 return 0;
328 unsigned i = 0;
329 for (vfs = vfs_list.next; vfs != &vfs_list; vfs = vfs->next)
330 if (!strcmp (vfs->mountpoint, pwd)) {
331 /*unsigned len = strlen (vfs->name);
332 dirent[i].name = (char *) kmalloc (sizeof (char) * (len + 1));
334 if (!dirent[i].name)
335 return 0;
337 memcpy (dirent[i].name, vfs->name, len);
338 dirent[i].name[len] = '\0';*/
339 dirent[i].name = vfs->name;
341 dirent[i].attrib = vfs->attrib;
343 if ((i+1) == dirents)
344 dirent[i].next = 0;
345 else
346 dirent[i].next = 1;
348 i ++;
353 dirent[dirents].next = 0;
357 unsigned int init_vfs ()
359 fd_count = 3;
361 fd_list.next = &fd_list;
362 fd_list.prev = &fd_list;
364 mount_list.next = &mount_list;
365 mount_list.prev = &mount_list;
367 vfs_list.next = &vfs_list;
368 vfs_list.prev = &vfs_list;
370 vfs_list_add ("bin", VFS_FILEATTR_DIR | VFS_FILEATTR_SYSTEM | VFS_FILEATTR_READ, "/");
371 vfs_list_add ("cd", VFS_FILEATTR_FILE | VFS_FILEATTR_SYSTEM | VFS_FILEATTR_READ | VFS_FILEATTR_BIN, "/bin/");
372 vfs_list_add ("ls", VFS_FILEATTR_FILE | VFS_FILEATTR_SYSTEM | VFS_FILEATTR_READ | VFS_FILEATTR_BIN, "/bin/");
373 vfs_list_add ("exec", VFS_FILEATTR_FILE | VFS_FILEATTR_SYSTEM | VFS_FILEATTR_READ | VFS_FILEATTR_BIN, "/bin/");
374 vfs_list_add ("dev", VFS_FILEATTR_DIR | VFS_FILEATTR_SYSTEM | VFS_FILEATTR_READ, "/");
375 vfs_list_add ("etc", VFS_FILEATTR_DIR | VFS_FILEATTR_SYSTEM | VFS_FILEATTR_READ, "/");
376 vfs_list_add ("mnt", VFS_FILEATTR_DIR | VFS_FILEATTR_SYSTEM | VFS_FILEATTR_READ, "/");
377 vfs_list_add ("floppy", VFS_FILEATTR_DIR | VFS_FILEATTR_SYSTEM | VFS_FILEATTR_READ, "/mnt/");
378 vfs_list_add ("cdrom", VFS_FILEATTR_DIR | VFS_FILEATTR_SYSTEM | VFS_FILEATTR_READ, "/mnt/");
379 vfs_list_add ("hdd", VFS_FILEATTR_DIR | VFS_FILEATTR_SYSTEM | VFS_FILEATTR_READ, "/mnt/");
380 vfs_list_add ("usr", VFS_FILEATTR_DIR | VFS_FILEATTR_SYSTEM | VFS_FILEATTR_READ, "/");
381 vfs_list_add ("root", VFS_FILEATTR_DIR | VFS_FILEATTR_SYSTEM | VFS_FILEATTR_READ, "/usr/");
382 vfs_list_add ("proc", VFS_FILEATTR_DIR | VFS_FILEATTR_SYSTEM | VFS_FILEATTR_READ, "/");
384 /*dev_t *dev = dev_find ("/dev/fd0");
386 if (dev)
387 mount (dev, "", "/mnt/floppy/");*/
389 return 1;