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