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