1c966bfdaSAxel Dörfler/*
24b723e3fSAxel Dörfler * Copyright 2003-2013, Axel D��rfler, axeld@pinc-software.de.
32f0e75deSAxel Dörfler * Distributed under the terms of the MIT License.
42f0e75deSAxel Dörfler */
5c966bfdaSAxel Dörfler
6c966bfdaSAxel Dörfler
7c966bfdaSAxel Dörfler#include "Directory.h"
8e3505b15SAxel Dörfler#include "File.h"
9ff76eb5cSAxel Dörfler#include "Link.h"
10e3505b15SAxel Dörfler
11e3505b15SAxel Dörfler#include <StorageDefs.h>
12ff76eb5cSAxel Dörfler#include <KernelExport.h>
13687cfec3SAxel Dörfler
14e3505b15SAxel Dörfler#include <string.h>
15ff76eb5cSAxel Dörfler#include <unistd.h>
16ff76eb5cSAxel Dörfler
17ff76eb5cSAxel Dörfler
18ff76eb5cSAxel Dörfler// temp. private VFS API
19ff76eb5cSAxel Dörflerextern Node *get_node_from(int fd);
20c966bfdaSAxel Dörfler
21c966bfdaSAxel Dörfler
2295d4ed67SJonathan Schleiferusing std::nothrow;
2395d4ed67SJonathan Schleifer
2495d4ed67SJonathan Schleifer
25c966bfdaSAxel Dörflernamespace BFS {
26c966bfdaSAxel Dörfler
272f0e75deSAxel Dörfler
280dc4d1e5SIngo WeinholdDirectory::Directory(Volume &volume, block_run run)
29c966bfdaSAxel Dörfler	:
30e3505b15SAxel Dörfler	fStream(volume, run),
31e3505b15SAxel Dörfler	fTree(&fStream)
32e3505b15SAxel Dörfler{
33e3505b15SAxel Dörfler}
34e3505b15SAxel Dörfler
35e3505b15SAxel Dörfler
360dc4d1e5SIngo WeinholdDirectory::Directory(Volume &volume, off_t id)
37e3505b15SAxel Dörfler	:
38e3505b15SAxel Dörfler	fStream(volume, id),
39e3505b15SAxel Dörfler	fTree(&fStream)
40e3505b15SAxel Dörfler{
41e3505b15SAxel Dörfler}
42e3505b15SAxel Dörfler
43e3505b15SAxel Dörfler
440dc4d1e5SIngo WeinholdDirectory::Directory(const Stream &stream)
45e3505b15SAxel Dörfler	:
46e3505b15SAxel Dörfler	fStream(stream),
47e3505b15SAxel Dörfler	fTree(&fStream)
48c966bfdaSAxel Dörfler{
49c966bfdaSAxel Dörfler}
50c966bfdaSAxel Dörfler
51c966bfdaSAxel Dörfler
52c966bfdaSAxel DörflerDirectory::~Directory()
53c966bfdaSAxel Dörfler{
54c966bfdaSAxel Dörfler}
55c966bfdaSAxel Dörfler
56c966bfdaSAxel Dörfler
57cbc85916SIngo Weinholdstatus_t
58c966bfdaSAxel DörflerDirectory::InitCheck()
59c966bfdaSAxel Dörfler{
60e3505b15SAxel Dörfler	return fStream.InitCheck();
61c966bfdaSAxel Dörfler}
62c966bfdaSAxel Dörfler
63c966bfdaSAxel Dörfler
64cbc85916SIngo Weinholdstatus_t
65c966bfdaSAxel DörflerDirectory::Open(void **_cookie, int mode)
66c966bfdaSAxel Dörfler{
67553e5a0fSAxel Dörfler	_inherited::Open(_cookie, mode);
68553e5a0fSAxel Dörfler
6982029bdaSMarcus Overhagen	*_cookie = (void *)new(nothrow) TreeIterator(&fTree);
70e3505b15SAxel Dörfler	if (*_cookie == NULL)
71e3505b15SAxel Dörfler		return B_NO_MEMORY;
72e3505b15SAxel Dörfler
73e3505b15SAxel Dörfler	return B_OK;
74c966bfdaSAxel Dörfler}
75c966bfdaSAxel Dörfler
76c966bfdaSAxel Dörfler
77cbc85916SIngo Weinholdstatus_t
78c966bfdaSAxel DörflerDirectory::Close(void *cookie)
79c966bfdaSAxel Dörfler{
80553e5a0fSAxel Dörfler	_inherited::Close(cookie);
81553e5a0fSAxel Dörfler
82e3505b15SAxel Dörfler	delete (TreeIterator *)cookie;
83e3505b15SAxel Dörfler	return B_OK;
84c966bfdaSAxel Dörfler}
85c966bfdaSAxel Dörfler
86c966bfdaSAxel Dörfler
87cbc85916SIngo WeinholdNode*
88cbc85916SIngo WeinholdDirectory::LookupDontTraverse(const char* name)
89c966bfdaSAxel Dörfler{
90e3505b15SAxel Dörfler	off_t id;
91e3505b15SAxel Dörfler	if (fTree.Find((uint8 *)name, strlen(name), &id) < B_OK)
92e3505b15SAxel Dörfler		return NULL;
93e3505b15SAxel Dörfler
94cbc85916SIngo Weinhold	return Stream::NodeFactory(fStream.GetVolume(), id);
95e3505b15SAxel Dörfler}
96e3505b15SAxel Dörfler
97e3505b15SAxel Dörfler
98cbc85916SIngo Weinholdstatus_t
99e3505b15SAxel DörflerDirectory::GetNextEntry(void *cookie, char *name, size_t size)
100e3505b15SAxel Dörfler{
101e3505b15SAxel Dörfler	TreeIterator *iterator = (TreeIterator *)cookie;
102e3505b15SAxel Dörfler	uint16 length;
103e3505b15SAxel Dörfler	off_t id;
104e3505b15SAxel Dörfler
105e3505b15SAxel Dörfler	return iterator->GetNextEntry(name, &length, size, &id);
106c966bfdaSAxel Dörfler}
107c966bfdaSAxel Dörfler
108c966bfdaSAxel Dörfler
109cbc85916SIngo Weinholdstatus_t
110c966bfdaSAxel DörflerDirectory::GetNextNode(void *cookie, Node **_node)
111c966bfdaSAxel Dörfler{
112e3505b15SAxel Dörfler	TreeIterator *iterator = (TreeIterator *)cookie;
113e3505b15SAxel Dörfler	char name[B_FILE_NAME_LENGTH];
114e3505b15SAxel Dörfler	uint16 length;
115e3505b15SAxel Dörfler	off_t id;
116e3505b15SAxel Dörfler
117e3505b15SAxel Dörfler	status_t status = iterator->GetNextEntry(name, &length, sizeof(name), &id);
118e3505b15SAxel Dörfler	if (status != B_OK)
119e3505b15SAxel Dörfler		return status;
120e3505b15SAxel Dörfler
1210dc4d1e5SIngo Weinhold	*_node = Stream::NodeFactory(fStream.GetVolume(), id);
122e3505b15SAxel Dörfler	if (*_node == NULL)
123e3505b15SAxel Dörfler		return B_ERROR;
124e3505b15SAxel Dörfler
125e3505b15SAxel Dörfler	return B_OK;
126c966bfdaSAxel Dörfler}
127c966bfdaSAxel Dörfler
128c966bfdaSAxel Dörfler
129cbc85916SIngo Weinholdstatus_t
130c966bfdaSAxel DörflerDirectory::Rewind(void *cookie)
131c966bfdaSAxel Dörfler{
132e3505b15SAxel Dörfler	TreeIterator *iterator = (TreeIterator *)cookie;
133e3505b15SAxel Dörfler
134e3505b15SAxel Dörfler	return iterator->Rewind();
135e3505b15SAxel Dörfler}
136e3505b15SAxel Dörfler
137e3505b15SAxel Dörfler
138cbc85916SIngo Weinholdbool
139d178a0d7SAxel DörflerDirectory::IsEmpty()
140d178a0d7SAxel Dörfler{
141d178a0d7SAxel Dörfler	TreeIterator iterator(&fTree);
142d178a0d7SAxel Dörfler
143d178a0d7SAxel Dörfler	// index and attribute directories are really empty when they are
144d178a0d7SAxel Dörfler	// empty - directories for standard files always contain ".", and
145d178a0d7SAxel Dörfler	// "..", so we need to ignore those two
146d178a0d7SAxel Dörfler
147d178a0d7SAxel Dörfler	uint32 count = 0;
148d178a0d7SAxel Dörfler	char name[BPLUSTREE_MAX_KEY_LENGTH];
149d178a0d7SAxel Dörfler	uint16 length;
150d178a0d7SAxel Dörfler	off_t id;
1512f0e75deSAxel Dörfler	while (iterator.GetNextEntry(name, &length, B_FILE_NAME_LENGTH, &id)
1522f0e75deSAxel Dörfler			== B_OK) {
153d178a0d7SAxel Dörfler		if (fStream.Mode() & (S_ATTR_DIR | S_INDEX_DIR))
154d178a0d7SAxel Dörfler			return false;
155d178a0d7SAxel Dörfler
1562f0e75deSAxel Dörfler		if (++count > 2 || (strcmp(".", name) && strcmp("..", name)))
157d178a0d7SAxel Dörfler			return false;
158d178a0d7SAxel Dörfler	}
159d178a0d7SAxel Dörfler	return true;
160d178a0d7SAxel Dörfler}
161d178a0d7SAxel Dörfler
162d178a0d7SAxel Dörfler
1630e3f14eeSAxel Dörflerstatus_t
164e3505b15SAxel DörflerDirectory::GetName(char *name, size_t size) const
165e3505b15SAxel Dörfler{
1660dc4d1e5SIngo Weinhold	if (fStream.inode_num == fStream.GetVolume().Root()) {
167e3505b15SAxel Dörfler		strlcpy(name, fStream.GetVolume().SuperBlock().name, size);
168e3505b15SAxel Dörfler		return B_OK;
169e3505b15SAxel Dörfler	}
170e3505b15SAxel Dörfler
171e3505b15SAxel Dörfler	return fStream.GetName(name, size);
172c966bfdaSAxel Dörfler}
173c966bfdaSAxel Dörfler
1740e3f14eeSAxel Dörfler
1750e3f14eeSAxel Dörflerino_t
1760e3f14eeSAxel DörflerDirectory::Inode() const
1770e3f14eeSAxel Dörfler{
1780e3f14eeSAxel Dörfler	return fStream.ID();
1790e3f14eeSAxel Dörfler}
1800e3f14eeSAxel Dörfler
1812f0e75deSAxel Dörfler
182c966bfdaSAxel Dörfler}	// namespace BFS
183