vfs: check userland buffers before reading them.
[haiku.git] / src / system / boot / loader / file_systems / bfs / Directory.cpp
blobce1a688630f21786e8276ddb4f5742a4c0566171
1 /*
2 * Copyright 2003-2013, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "Directory.h"
8 #include "File.h"
9 #include "Link.h"
11 #include <StorageDefs.h>
12 #include <KernelExport.h>
14 #include <string.h>
15 #include <unistd.h>
18 // temp. private VFS API
19 extern Node *get_node_from(int fd);
22 using std::nothrow;
25 namespace BFS {
28 Directory::Directory(Volume &volume, block_run run)
30 fStream(volume, run),
31 fTree(&fStream)
36 Directory::Directory(Volume &volume, off_t id)
38 fStream(volume, id),
39 fTree(&fStream)
44 Directory::Directory(const Stream &stream)
46 fStream(stream),
47 fTree(&fStream)
52 Directory::~Directory()
57 status_t
58 Directory::InitCheck()
60 return fStream.InitCheck();
64 status_t
65 Directory::Open(void **_cookie, int mode)
67 _inherited::Open(_cookie, mode);
69 *_cookie = (void *)new(nothrow) TreeIterator(&fTree);
70 if (*_cookie == NULL)
71 return B_NO_MEMORY;
73 return B_OK;
77 status_t
78 Directory::Close(void *cookie)
80 _inherited::Close(cookie);
82 delete (TreeIterator *)cookie;
83 return B_OK;
87 Node*
88 Directory::LookupDontTraverse(const char* name)
90 off_t id;
91 if (fTree.Find((uint8 *)name, strlen(name), &id) < B_OK)
92 return NULL;
94 return Stream::NodeFactory(fStream.GetVolume(), id);
98 status_t
99 Directory::GetNextEntry(void *cookie, char *name, size_t size)
101 TreeIterator *iterator = (TreeIterator *)cookie;
102 uint16 length;
103 off_t id;
105 return iterator->GetNextEntry(name, &length, size, &id);
109 status_t
110 Directory::GetNextNode(void *cookie, Node **_node)
112 TreeIterator *iterator = (TreeIterator *)cookie;
113 char name[B_FILE_NAME_LENGTH];
114 uint16 length;
115 off_t id;
117 status_t status = iterator->GetNextEntry(name, &length, sizeof(name), &id);
118 if (status != B_OK)
119 return status;
121 *_node = Stream::NodeFactory(fStream.GetVolume(), id);
122 if (*_node == NULL)
123 return B_ERROR;
125 return B_OK;
129 status_t
130 Directory::Rewind(void *cookie)
132 TreeIterator *iterator = (TreeIterator *)cookie;
134 return iterator->Rewind();
138 bool
139 Directory::IsEmpty()
141 TreeIterator iterator(&fTree);
143 // index and attribute directories are really empty when they are
144 // empty - directories for standard files always contain ".", and
145 // "..", so we need to ignore those two
147 uint32 count = 0;
148 char name[BPLUSTREE_MAX_KEY_LENGTH];
149 uint16 length;
150 off_t id;
151 while (iterator.GetNextEntry(name, &length, B_FILE_NAME_LENGTH, &id)
152 == B_OK) {
153 if (fStream.Mode() & (S_ATTR_DIR | S_INDEX_DIR))
154 return false;
156 if (++count > 2 || (strcmp(".", name) && strcmp("..", name)))
157 return false;
159 return true;
163 status_t
164 Directory::GetName(char *name, size_t size) const
166 if (fStream.inode_num == fStream.GetVolume().Root()) {
167 strlcpy(name, fStream.GetVolume().SuperBlock().name, size);
168 return B_OK;
171 return fStream.GetName(name, size);
175 ino_t
176 Directory::Inode() const
178 return fStream.ID();
182 } // namespace BFS