1 /*
2 * This software is licensed under the terms of the MIT License.
3 * See COPYING for further information.
4 * ---
5 * Copyright (c) 2011-2019, Lukas Weber <laochailan@web.de>.
6 * Copyright (c) 2012-2019, Andrei Alexeyev <akari@taisei-project.org>.
7 */
8
9 #include "taisei.h"
10
11 #include "syspath.h"
12 #include "readonly_wrapper.h"
13
striptrailing(char * p,char ** pend)14 static void striptrailing(char *p, char **pend) {
15 while(*pend > p && strchr(vfs_syspath_separators, *(*pend - 1))) {
16 *--*pend = 0;
17 }
18 }
19
stripname(char * p,char ** pend)20 static void stripname(char *p, char **pend) {
21 striptrailing(p, pend);
22 while(*pend > p && !strchr(vfs_syspath_separators, *(*pend - 1))) {
23 *--*pend = 0;
24 }
25 striptrailing(p, pend);
26 }
27
mkdir_with_parents(VFSNode * n,const char * fspath)28 static bool mkdir_with_parents(VFSNode *n, const char *fspath) {
29 if(vfs_node_mkdir(n, NULL)) {
30 return true;
31 }
32
33 char p[strlen(fspath) + 1];
34 char *pend = p + sizeof(p) - 1;
35
36 memcpy(p, fspath, sizeof(p));
37 stripname(p, &pend);
38
39 if(p == pend) {
40 return false;
41 }
42
43 VFSNode *pnode = vfs_alloc();
44 if(!vfs_syspath_init(pnode, p)) {
45 vfs_decref(pnode);
46 return false;
47 }
48
49 bool ok = mkdir_with_parents(pnode, p);
50 vfs_decref(pnode);
51 return ok && vfs_node_mkdir(n, NULL);
52 }
53
vfs_mount_syspath(const char * mountpoint,const char * fspath,uint flags)54 bool vfs_mount_syspath(const char *mountpoint, const char *fspath, uint flags) {
55 VFSNode *rdir = vfs_alloc();
56
57 if(!vfs_syspath_init(rdir, fspath)) {
58 vfs_set_error("Can't initialize path: %s", vfs_get_error());
59 vfs_decref(rdir);
60 return false;
61 }
62
63 if((flags & VFS_SYSPATH_MOUNT_MKDIR) && !mkdir_with_parents(rdir, fspath)) {
64 vfs_set_error("Can't create directory: %s", vfs_get_error());
65 vfs_decref(rdir);
66 return false;
67 }
68
69 if(flags & VFS_SYSPATH_MOUNT_READONLY) {
70 VFSNode *rdir_ro = vfs_ro_wrap(rdir);
71 vfs_decref(rdir);
72 rdir = rdir_ro;
73 }
74
75 return vfs_mount_or_decref(vfs_root, mountpoint, rdir);
76 }
77
vfs_get_syspath_separator(void)78 char vfs_get_syspath_separator(void) {
79 return vfs_syspath_separators[0];
80 }
81