vfs: check userland buffers before reading them.
[haiku.git] / src / system / boot / loader / file_systems / packagefs / PackageSettingsItem.cpp
blob23ea4853787130a96ea0204001ab211ef75e0ead
1 /*
2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "PackageSettingsItem.h"
9 #include <driver_settings.h>
11 #include <AutoDeleter.h>
12 #include <boot/vfs.h>
13 #include <system/directories.h>
16 namespace PackageFS {
19 // #pragma mark - PackageSettingsItem
22 PackageSettingsItem::PackageSettingsItem()
24 fEntries(),
25 fHashNext(NULL)
30 PackageSettingsItem::~PackageSettingsItem()
32 Entry* entry = fEntries.Clear(true);
33 while (entry != NULL) {
34 Entry* next = entry->HashNext();
35 delete entry;
36 entry = next;
41 /*static*/ PackageSettingsItem*
42 PackageSettingsItem::Load(::Directory* systemDirectory, const char* name)
44 // open the driver settings file
45 const char* settingsFilePath
46 = kSystemSettingsDirectory "/packages" + strlen(kSystemDirectory) + 1;
48 int fd = open_from(systemDirectory, settingsFilePath, B_READ_ONLY, 0);
49 if (fd < 0)
50 return NULL;
51 FileDescriptorCloser fdCloser(fd);
53 // load the driver settings
54 void* settingsHandle = load_driver_settings_file(fd);
55 if (settingsHandle == NULL)
56 return NULL;
57 CObjectDeleter<void, status_t> settingsDeleter(settingsHandle,
58 &unload_driver_settings);
60 const driver_settings* settings = get_driver_settings(settingsHandle);
61 for (int i = 0; i < settings->parameter_count; i++) {
62 const driver_parameter& parameter = settings->parameters[i];
63 if (strcmp(parameter.name, "Package") != 0
64 || parameter.value_count < 1
65 || strcmp(parameter.values[0], name) != 0) {
66 continue;
69 PackageSettingsItem* settingsItem
70 = new(std::nothrow) PackageSettingsItem;
71 if (settingsItem == NULL || settingsItem->Init(parameter) != B_OK) {
72 delete settingsItem;
73 return NULL;
76 return settingsItem;
79 return NULL;
83 status_t
84 PackageSettingsItem::Init(const driver_parameter& parameter)
86 if (fEntries.Init() != B_OK)
87 return B_NO_MEMORY;
89 for (int i = 0; i < parameter.parameter_count; i++) {
90 const driver_parameter& subParameter = parameter.parameters[i];
91 if (strcmp(subParameter.name, "EntryBlacklist") != 0)
92 continue;
94 status_t error = _AddBlackListedEntries(subParameter);
95 // abort only in case of serious issues (memory shortage)
96 if (error == B_NO_MEMORY)
97 return error;
100 return B_OK;
104 void
105 PackageSettingsItem::AddEntry(Entry* entry)
107 fEntries.Insert(entry);
111 status_t
112 PackageSettingsItem::AddEntry(const char* path, Entry*& _entry)
114 Entry* parent = NULL;
116 while (*path != '\0') {
117 while (*path == '/') {
118 path++;
119 continue;
122 const char* componentEnd = strchr(path, '/');
123 if (componentEnd == NULL)
124 componentEnd = path + strlen(path);
126 const char* name = path;
127 size_t nameLength = componentEnd - path;
129 Entry* entry = FindEntry(parent, name, nameLength);
130 if (entry == NULL) {
131 entry = new(std::nothrow) Entry(parent);
132 if (entry == NULL || !entry->SetName(name, nameLength)) {
133 delete entry;
134 return B_NO_MEMORY;
136 AddEntry(entry);
139 path = componentEnd;
140 parent = entry;
143 if (parent == NULL)
144 return B_BAD_VALUE;
146 _entry = parent;
147 return B_OK;
151 PackageSettingsItem::Entry*
152 PackageSettingsItem::FindEntry(Entry* parent, const char* name) const
154 return fEntries.Lookup(EntryKey(parent, name));
158 PackageSettingsItem::Entry*
159 PackageSettingsItem::FindEntry(Entry* parent, const char* name,
160 size_t nameLength) const
162 return fEntries.Lookup(EntryKey(parent, name, nameLength));
166 status_t
167 PackageSettingsItem::_AddBlackListedEntries(const driver_parameter& parameter)
169 for (int i = 0; i < parameter.parameter_count; i++) {
170 Entry* entry;
171 status_t error = AddEntry(parameter.parameters[i].name, entry);
172 // abort only in case of serious issues (memory shortage)
173 if (error == B_NO_MEMORY)
174 return error;
176 entry->SetBlackListed(true);
179 return B_OK;
183 } // namespace PackageFS