1 // Settings.cpp 2 // 3 // Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de) 4 // 5 // This program is free software; you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation; either version 2 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with this program; if not, write to the Free Software 17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 // 19 // You can alternatively use *this file* under the terms of the the MIT 20 // license included in this package. 21 22 #include <new> 23 24 #include "Settings.h" 25 #include "Debug.h" 26 27 using std::nothrow; 28 29 /*! 30 \class Settings 31 \brief Manages the ReiserFS settings. 32 */ 33 34 static const char *kFSName = "reiserfs"; 35 36 // defaults 37 static const char *kDefaultDefaultVolumeName = "ReiserFS untitled"; 38 static const bool kDefaultHideEsoteric = true; 39 40 // constructor 41 Settings::Settings() 42 : 43 fDefaultVolumeName(), 44 fVolumeName(), 45 fHideEsoteric(kDefaultHideEsoteric), 46 fHiddenEntries(5) 47 { 48 } 49 50 // destructor 51 Settings::~Settings() 52 { 53 Unset(); 54 } 55 56 // SetTo 57 status_t 58 Settings::SetTo(const char *volumeName) 59 { 60 // unset 61 Unset(); 62 // load the driver settings and find the entry for the volume 63 void *settings = load_driver_settings(kFSName); 64 const driver_parameter *volume = NULL; 65 const driver_settings *ds = get_driver_settings(settings); 66 if (ds && volumeName) 67 volume = _FindVolumeParameter(ds, volumeName); 68 // init the object and unload the settings 69 _Init(ds, volume); 70 unload_driver_settings(settings); 71 return B_OK; 72 } 73 74 // SetTo 75 status_t 76 Settings::SetTo(off_t volumeOffset, off_t volumeSize) 77 { 78 PRINT(("Settings::SetTo(%" B_PRIdOFF ", %" B_PRIdOFF ")\n", volumeOffset, 79 volumeSize)); 80 // unset 81 Unset(); 82 // load the driver settings and find the entry for the volume 83 void *settings = load_driver_settings(kFSName); 84 const driver_parameter *volume = NULL; 85 const driver_settings *ds = get_driver_settings(settings); 86 if (ds) 87 volume = _FindVolumeParameter(ds, volumeOffset, volumeSize); 88 // init the object and unload the settings 89 _Init(ds, volume); 90 unload_driver_settings(settings); 91 PRINT(("Settings::SetTo(%" B_PRIdOFF ", %" B_PRIdOFF ") done: B_OK\n", 92 volumeOffset, volumeSize)); 93 return B_OK; 94 } 95 96 // Unset 97 void 98 Settings::Unset() 99 { 100 fDefaultVolumeName.Unset(); 101 fVolumeName.Unset(); 102 fHideEsoteric = kDefaultHideEsoteric; 103 fHiddenEntries.MakeEmpty(); 104 } 105 106 // GetDefaultVolumeName 107 const char * 108 Settings::GetDefaultVolumeName() const 109 { 110 if (fDefaultVolumeName.GetLength() > 0) 111 return fDefaultVolumeName.GetString(); 112 return kDefaultDefaultVolumeName; 113 } 114 115 // GetVolumeName 116 const char * 117 Settings::GetVolumeName() const 118 { 119 if (fVolumeName.GetLength() > 0) 120 return fVolumeName.GetString(); 121 return GetDefaultVolumeName(); 122 } 123 124 // GetHideEsoteric 125 bool 126 Settings::GetHideEsoteric() const 127 { 128 return fHideEsoteric; 129 } 130 131 // HiddenEntryAt 132 const char * 133 Settings::HiddenEntryAt(int32 index) const 134 { 135 const char *entry = NULL; 136 if (index >= 0 && index < fHiddenEntries.CountItems()) 137 entry = fHiddenEntries.ItemAt(index).GetString(); 138 return entry; 139 } 140 141 // Dump 142 void 143 Settings::Dump() 144 { 145 #if DEBUG 146 PRINT(("Settings:\n")); 147 PRINT((" default volume name: `%s'\n", GetDefaultVolumeName())); 148 PRINT((" volume name: `%s'\n", GetVolumeName())); 149 PRINT((" hide esoteric entries: %d\n", GetHideEsoteric())); 150 PRINT((" %" B_PRId32 " hidden entries:\n", fHiddenEntries.CountItems())); 151 for (int32 i = 0; const char *entry = HiddenEntryAt(i); i++) 152 PRINT((" `%s'\n", entry)); 153 #endif 154 } 155 156 // _Init 157 status_t 158 Settings::_Init(const driver_settings *settings, 159 const driver_parameter *volume) 160 { 161 PRINT(("Settings::_Init(%p, %p)\n", settings, volume)); 162 status_t error = B_OK; 163 // get the global values 164 fDefaultVolumeName.SetTo(_GetParameterValue(settings, 165 "default_volume_name", (const char*)NULL, NULL)); 166 PRINT((" default_volume_name is: `%s'\n", fDefaultVolumeName.GetString())); 167 fHideEsoteric = _GetParameterValue(settings, "hide_esoteric_entries", 168 kDefaultHideEsoteric, 169 kDefaultHideEsoteric); 170 PRINT((" hide_esoteric_entries is: %d\n", fHideEsoteric)); 171 // get the per volume settings 172 if (volume) { 173 PRINT((" getting volume parameters:\n")); 174 fVolumeName.SetTo(_GetParameterValue(volume, "name", (const char*)NULL, 175 NULL)); 176 PRINT((" name is: `%s'\n", fVolumeName.GetString())); 177 fHideEsoteric = _GetParameterValue(volume, "hide_esoteric_entries", 178 fHideEsoteric, fHideEsoteric); 179 PRINT((" hide_esoteric_entries is: %d\n", fHideEsoteric)); 180 int32 cookie = 0; 181 while (const driver_parameter *parameter 182 = _FindNextParameter(volume, "hide_entries", cookie)) { 183 for (int32 i = 0; i < parameter->value_count; i++) 184 { 185 fHiddenEntries.AddItem(parameter->values[i]); 186 PRINT((" hidden entry: `%s'\n", parameter->values[i])); 187 } 188 } 189 } 190 // check the values 191 PRINT((" checking volume names...'\n")); 192 _CheckVolumeName(fDefaultVolumeName); 193 _CheckVolumeName(fVolumeName); 194 PRINT((" checking hidden entry names...'\n")); 195 for (int32 i = fHiddenEntries.CountItems(); i >= 0; i--) { 196 String &entry = fHiddenEntries.ItemAt(i); 197 if (!_CheckEntryName(entry.GetString())) 198 { 199 PRINT((" ignoring: `%s'\n", entry.GetString())); 200 fHiddenEntries.RemoveItem(i); 201 } 202 } 203 PRINT(("Settings::_Init() done: %s\n", strerror(error))); 204 return error; 205 } 206 207 // _FindVolumeParameter 208 const driver_parameter * 209 Settings::_FindVolumeParameter(const driver_settings *settings, 210 const char *name) 211 { 212 if (settings) { 213 int32 cookie = 0; 214 while (const driver_parameter *parameter 215 = _FindNextParameter(settings, "volume", cookie)) { 216 if (parameter->value_count == 1 217 && !strcmp(parameter->values[0], name)) { 218 return parameter; 219 } 220 } 221 } 222 return NULL; 223 } 224 225 // _FindVolumeParameter 226 const driver_parameter * 227 Settings::_FindVolumeParameter(const driver_settings *settings, 228 off_t offset, off_t size) 229 { 230 PRINT(("Settings::_FindVolumeParameter(%" B_PRIdOFF ", %" B_PRIdOFF ")\n", 231 offset, size)); 232 if (settings) { 233 int32 cookie = 0; 234 while (const driver_parameter *parameter 235 = _FindNextParameter(settings, "volume", cookie)) { 236 if (_GetParameterValue(parameter, "offset", offset + 1, offset + 1) 237 == offset 238 && _GetParameterValue(parameter, "size", size + 1, size + 1) 239 == size) { 240 PRINT(("Settings::_FindVolumeParameter() done: found parameter:" 241 " index: %" B_PRId32 ", (%p)\n", cookie - 1, parameter)); 242 return parameter; 243 } 244 } 245 } 246 PRINT(("Settings::_FindVolumeParameter() done: failed\n")); 247 return NULL; 248 } 249 250 // _CheckVolumeName 251 void 252 Settings::_CheckVolumeName(String &name) 253 { 254 // truncate, if it is too long 255 if (name.GetLength() >= B_FILE_NAME_LENGTH) { 256 char buffer[B_FILE_NAME_LENGTH]; 257 memcpy(buffer, name.GetString(), B_FILE_NAME_LENGTH - 1); 258 name.SetTo(buffer, B_FILE_NAME_LENGTH - 1); 259 } 260 // check for bad characters 261 bool invalid = false; 262 const char *string = name.GetString(); 263 for (int32 i = 0; !invalid && i < name.GetLength(); i++) { 264 if (string[i] == '/') // others? 265 invalid = true; 266 } 267 if (invalid) 268 name.Unset(); 269 } 270 271 // _CheckEntryName 272 bool 273 Settings::_CheckEntryName(const char *name) 274 { 275 int32 len = (name ? strlen(name) : 0); 276 // any further restictions? 277 return (len > 0); 278 } 279 280