summaryrefslogtreecommitdiff
path: root/Source/Kernel/VFS/FSNode-sc.proto.cpp
blob: 717ccef28109357fdd6312deed695ff1583e8bf4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "FSNode.proto.h"
#include <VFS/VFS.ns.h>
#include <SyscallManager/Res.ns.h>
#include <UserManager/Usr.ns.h>
#include <TaskManager/Task.ns.h>

call_t FSNode::m_callTable[] = {
	CALL0(FNIF_GETNAME, &FSNode::getNameSC),
	CALL0(FNIF_TYPE, &FSNode::typeSC),
	CALL0(FNIF_GETPARENT, &FSNode::getParentSC),
	CALL0(FNIF_GETLENGTH, &FSNode::getLengthSC),
	CALL0(FNIF_GETUID, &FSNode::getUid),
	CALL0(FNIF_GETGID, &FSNode::getGid),
	CALL0(FNIF_GETPERM, &FSNode::getPermissions),
	CALL0(FNIF_GETPATH, &FSNode::getPathSC),
	CALL0(FNIF_SETCWD, &FSNode::setCwdSC),
	CALL0(FNIF_REMOVE, &FSNode::removeSC),
	CALL0(0, 0)
};

u32int FSNode::scall(u8int wat, u32int a, u32int b, u32int c, u32int d) {
	if (wat == FNIF_SGETRFN) return VFS::getRootNode()->resId();
	if (wat == FNIF_SGETCWD) return Task::currProcess()->getCwd()->resId();
	if (wat == FNIF_SFIND) {
		String* path = (String*)a;
		FSNode* n;
		if (b == 0) {
			n = VFS::find(*path);
		} else {
			n = VFS::find(*path, Res::get<DirectoryNode>(b, FNIF_OBJTYPE));
		}
		if (n != 0) return n->resId();
	}
	if (wat == FNIF_SMKDIR) {
		String* path = (String*)a;
		FSNode* n;
		if (b == 0) {
			n = VFS::createDirectory(*path, 0, true);
		} else {
			n = VFS::createDirectory(*path, Res::get<DirectoryNode>(b, FNIF_OBJTYPE), true);
		}
		if (n != 0) return n->resId();
	}
	return (u32int) - 1;
}

u32int FSNode::getNameSC() {
	return getName().serialize();
}

u32int FSNode::typeSC() {
	return type();
}

u32int FSNode::getLengthSC() {
	u64int* a = (u64int*)Mem::mkXchgSpace(sizeof(u64int));
	*a = getLength();
	return (u32int)a;
}

u32int FSNode::getParentSC() {
	if (m_parent != 0) return m_parent->resId();
	return (u32int) - 1;
}

u32int FSNode::getPathSC() {
	return VFS::path(this).serialize();
}

u32int FSNode::setCwdSC() {
	if (type() == NT_DIRECTORY) {
		Task::currProcess()->setCwd((DirectoryNode*)this);
	}
	return 0;
}

u32int FSNode::removeSC() {
	if (!writable()) return 0;
	return (VFS::remove(this) ? 1 : 0);
}

bool FSNode::readable(User* user) {
	if (ISROOT) return true;
	if (user == 0) user = Usr::user();
	if (user->getUid() == m_uid)
		return ((m_permissions >> 6) & 4) != 0;
	if (user->isInGroup(m_gid))
		return ((m_permissions >> 3) & 4) != 0;
	return (m_permissions & 4) != 0;
}

bool FSNode::writable(User* user) {
	if (ISROOT) return true;
	if (user == 0) user = Usr::user();
	if (user->getUid() == m_uid)
		return ((m_permissions >> 6) & 2) != 0;
	if (user->isInGroup(m_gid))
		return ((m_permissions >> 3) & 2) != 0;
	return (m_permissions & 2) != 0;
}

bool FSNode::runnable(User* user) {
	if (ISROOT) return true;
	if (user == 0) user = Usr::user();
	if (user->getUid() == m_uid)
		return ((m_permissions >> 6) & 1) != 0;
	if (user->isInGroup(m_gid))
		return ((m_permissions >> 3) & 1) != 0;
	return (m_permissions & 1) != 0;
}

bool FSNode::accessible() {
	return readable();
}