1 /* 2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "PackageSettingsItem.h" 8 9 #include <driver_settings.h> 10 11 #include <AutoDeleter.h> 12 #include <boot/vfs.h> 13 #include <system/directories.h> 14 15 16 namespace PackageFS { 17 18 19 // #pragma mark - PackageSettingsItem 20 21 22 PackageSettingsItem::PackageSettingsItem() 23 : 24 fEntries() 25 { 26 } 27 28 29 PackageSettingsItem::~PackageSettingsItem() 30 { 31 Entry* entry = fEntries.Clear(true); 32 while (entry != NULL) { 33 Entry* next = entry->HashNext(); 34 delete entry; 35 entry = next; 36 } 37 } 38 39 40 /*static*/ PackageSettingsItem* 41 PackageSettingsItem::Load(::Directory* systemDirectory, const char* name) 42 { 43 // open the driver settings file 44 const char* settingsFilePath 45 = kSystemSettingsDirectory "/packages" + strlen(kSystemDirectory) + 1; 46 47 int fd = open_from(systemDirectory, settingsFilePath, B_READ_ONLY, 0); 48 if (fd < 0) 49 return NULL; 50 FileDescriptorCloser fdCloser(fd); 51 52 // load the driver settings 53 void* settingsHandle = load_driver_settings_file(fd); 54 if (settingsHandle == NULL) 55 return NULL; 56 CObjectDeleter<void, status_t> settingsDeleter(settingsHandle, 57 &unload_driver_settings); 58 59 const driver_settings* settings = get_driver_settings(settingsHandle); 60 for (int i = 0; i < settings->parameter_count; i++) { 61 const driver_parameter& parameter = settings->parameters[i]; 62 if (strcmp(parameter.name, "Package") != 0 63 || parameter.value_count < 1 64 || strcmp(parameter.values[0], name) != 0) { 65 continue; 66 } 67 68 PackageSettingsItem* settingsItem 69 = new(std::nothrow) PackageSettingsItem; 70 if (settingsItem == NULL || settingsItem->Init(parameter) != B_OK) { 71 delete settingsItem; 72 return NULL; 73 } 74 75 return settingsItem; 76 } 77 78 return NULL; 79 } 80 81 82 status_t 83 PackageSettingsItem::Init(const driver_parameter& parameter) 84 { 85 if (fEntries.Init() != B_OK) 86 return B_NO_MEMORY; 87 88 for (int i = 0; i < parameter.parameter_count; i++) { 89 const driver_parameter& subParameter = parameter.parameters[i]; 90 if (strcmp(subParameter.name, "EntryBlacklist") != 0) 91 continue; 92 93 status_t error = _AddBlackListedEntries(subParameter); 94 // abort only in case of serious issues (memory shortage) 95 if (error == B_NO_MEMORY) 96 return error; 97 } 98 99 return B_OK; 100 } 101 102 103 void 104 PackageSettingsItem::AddEntry(Entry* entry) 105 { 106 fEntries.Insert(entry); 107 } 108 109 110 status_t 111 PackageSettingsItem::AddEntry(const char* path, Entry*& _entry) 112 { 113 Entry* parent = NULL; 114 115 while (*path != '\0') { 116 while (*path == '/') { 117 path++; 118 continue; 119 } 120 121 const char* componentEnd = strchr(path, '/'); 122 if (componentEnd == NULL) 123 componentEnd = path + strlen(path); 124 125 const char* name = path; 126 size_t nameLength = componentEnd - path; 127 128 Entry* entry = FindEntry(parent, name, nameLength); 129 if (entry == NULL) { 130 entry = new(std::nothrow) Entry(parent); 131 if (entry == NULL || !entry->SetName(name, nameLength)) { 132 delete entry; 133 return B_NO_MEMORY; 134 } 135 AddEntry(entry); 136 } 137 138 path = componentEnd; 139 parent = entry; 140 } 141 142 if (parent == NULL) 143 return B_BAD_VALUE; 144 145 _entry = parent; 146 return B_OK; 147 } 148 149 150 PackageSettingsItem::Entry* 151 PackageSettingsItem::FindEntry(Entry* parent, const char* name) const 152 { 153 return fEntries.Lookup(EntryKey(parent, name)); 154 } 155 156 157 PackageSettingsItem::Entry* 158 PackageSettingsItem::FindEntry(Entry* parent, const char* name, 159 size_t nameLength) const 160 { 161 return fEntries.Lookup(EntryKey(parent, name, nameLength)); 162 } 163 164 165 status_t 166 PackageSettingsItem::_AddBlackListedEntries(const driver_parameter& parameter) 167 { 168 for (int i = 0; i < parameter.parameter_count; i++) { 169 Entry* entry; 170 status_t error = AddEntry(parameter.parameters[i].name, entry); 171 // abort only in case of serious issues (memory shortage) 172 if (error == B_NO_MEMORY) 173 return error; 174 175 entry->SetBlackListed(true); 176 } 177 178 return B_OK; 179 } 180 181 182 } // namespace PackageFS 183