1/*
2 * Copyright 2003-2006, Axel D��rfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "RootFileSystem.h"
8
9#include <OS.h>
10#include <util/kernel_cpp.h>
11
12#include <string.h>
13#include <fcntl.h>
14
15
16RootFileSystem::RootFileSystem()
17{
18}
19
20
21RootFileSystem::~RootFileSystem()
22{
23	struct entry *entry = NULL;
24
25	while ((entry = fList.RemoveHead()) != NULL) {
26		entry->root->Release();
27		delete entry;
28	}
29}
30
31
32status_t
33RootFileSystem::Open(void **_cookie, int mode)
34{
35	EntryIterator *iterator = new (std::nothrow) EntryIterator(&fList);
36	if (iterator == NULL)
37		return B_NO_MEMORY;
38
39	*_cookie = iterator;
40
41	return B_OK;
42}
43
44
45status_t
46RootFileSystem::Close(void *cookie)
47{
48	delete (EntryIterator *)cookie;
49	return B_OK;
50}
51
52
53Node *
54RootFileSystem::Lookup(const char *name, bool /*traverseLinks*/)
55{
56	EntryIterator iterator = fLinks.GetIterator();
57	struct entry *entry;
58
59	// first check the links
60
61	while ((entry = iterator.Next()) != NULL) {
62		if (!strcmp(name, entry->name)) {
63			entry->root->Acquire();
64			return entry->root;
65		}
66	}
67
68	// then all mounted file systems
69
70	iterator = fList.GetIterator();
71
72	while ((entry = iterator.Next()) != NULL) {
73		char entryName[B_OS_NAME_LENGTH];
74		if (entry->root->GetName(entryName, sizeof(entryName)) != B_OK)
75			continue;
76
77		if (!strcmp(entryName, name)) {
78			entry->root->Acquire();
79			return entry->root;
80		}
81	}
82
83	return NULL;
84}
85
86
87status_t
88RootFileSystem::GetNextEntry(void *_cookie, char *name, size_t size)
89{
90	EntryIterator *iterator = (EntryIterator *)_cookie;
91	struct entry *entry;
92
93	entry = iterator->Next();
94	if (entry != NULL)
95		return entry->root->GetName(name, size);
96
97	return B_ENTRY_NOT_FOUND;
98}
99
100
101status_t
102RootFileSystem::GetNextNode(void *_cookie, Node **_node)
103{
104	EntryIterator *iterator = (EntryIterator *)_cookie;
105	struct entry *entry;
106
107	entry = iterator->Next();
108	if (entry != NULL) {
109		*_node = entry->root;
110		return B_OK;
111	}
112	return B_ENTRY_NOT_FOUND;
113}
114
115
116status_t
117RootFileSystem::Rewind(void *_cookie)
118{
119	EntryIterator *iterator = (EntryIterator *)_cookie;
120
121	iterator->Rewind();
122	return B_OK;
123}
124
125
126bool
127RootFileSystem::IsEmpty()
128{
129	return fList.IsEmpty();
130}
131
132
133status_t
134RootFileSystem::AddVolume(Directory *volume, Partition *partition)
135{
136	struct entry *entry = new (std::nothrow) RootFileSystem::entry();
137	if (entry == NULL)
138		return B_NO_MEMORY;
139
140	volume->Acquire();
141	entry->name = NULL;
142	entry->root = volume;
143	entry->partition = partition;
144
145	fList.Add(entry);
146
147	return B_OK;
148}
149
150
151status_t
152RootFileSystem::AddLink(const char *name, Directory *target)
153{
154	struct entry *entry = new (std::nothrow) RootFileSystem::entry();
155	if (entry == NULL)
156		return B_NO_MEMORY;
157
158	target->Acquire();
159	entry->name = name;
160	entry->root = target;
161
162	fLinks.Add(entry);
163
164	return B_OK;
165}
166
167
168status_t
169RootFileSystem::GetPartitionFor(Directory *volume, Partition **_partition)
170{
171	EntryIterator iterator = fList.GetIterator();
172	struct entry *entry;
173
174	while ((entry = iterator.Next()) != NULL) {
175		if (entry->root == volume) {
176			*_partition = entry->partition;
177			return B_OK;
178		}
179	}
180
181	return B_ENTRY_NOT_FOUND;
182}
183
184