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 : fDefaultVolumeName(), 43 fVolumeName(), 44 fHideEsoteric(kDefaultHideEsoteric), 45 fHiddenEntries(5) 46 { 47 } 48 49 // destructor 50 Settings::~Settings() 51 { 52 Unset(); 53 } 54 55 // SetTo 56 status_t 57 Settings::SetTo(const char *volumeName) 58 { 59 // unset 60 Unset(); 61 // load the driver settings and find the entry for the volume 62 void *settings = load_driver_settings(kFSName); 63 const driver_parameter *volume = NULL; 64 const driver_settings *ds = get_driver_settings(settings); 65 if (ds && volumeName) 66 volume = _FindVolumeParameter(ds, volumeName); 67 // init the object and unload the settings 68 _Init(ds, volume); 69 unload_driver_settings(settings); 70 return B_OK; 71 } 72 73 // SetTo 74 status_t 75 Settings::SetTo(off_t volumeOffset, off_t volumeSize) 76 { 77 PRINT(("Settings::SetTo(%Ld, %Ld)\n", volumeOffset, volumeSize)); 78 // unset 79 Unset(); 80 // load the driver settings and find the entry for the volume 81 void *settings = load_driver_settings(kFSName); 82 const driver_parameter *volume = NULL; 83 const driver_settings *ds = get_driver_settings(settings); 84 if (ds) 85 volume = _FindVolumeParameter(ds, volumeOffset, volumeSize); 86 // init the object and unload the settings 87 _Init(ds, volume); 88 unload_driver_settings(settings); 89 PRINT(("Settings::SetTo(%Ld, %Ld) done: B_OK\n", volumeOffset, volumeSize)); 90 return B_OK; 91 } 92 93 // Unset 94 void 95 Settings::Unset() 96 { 97 fDefaultVolumeName.Unset(); 98 fVolumeName.Unset(); 99 fHideEsoteric = kDefaultHideEsoteric; 100 fHiddenEntries.MakeEmpty(); 101 } 102 103 // GetDefaultVolumeName 104 const char * 105 Settings::GetDefaultVolumeName() const 106 { 107 if (fDefaultVolumeName.GetLength() > 0) 108 return fDefaultVolumeName.GetString(); 109 return kDefaultDefaultVolumeName; 110 } 111 112 // GetVolumeName 113 const char * 114 Settings::GetVolumeName() const 115 { 116 if (fVolumeName.GetLength() > 0) 117 return fVolumeName.GetString(); 118 return GetDefaultVolumeName(); 119 } 120 121 // GetHideEsoteric 122 bool 123 Settings::GetHideEsoteric() const 124 { 125 return fHideEsoteric; 126 } 127 128 // HiddenEntryAt 129 const char * 130 Settings::HiddenEntryAt(int32 index) const 131 { 132 const char *entry = NULL; 133 if (index >= 0 && index < fHiddenEntries.CountItems()) 134 entry = fHiddenEntries.ItemAt(index).GetString(); 135 return entry; 136 } 137 138 // Dump 139 void 140 Settings::Dump() 141 { 142 PRINT(("Settings:\n")); 143 PRINT((" default volume name: `%s'\n", GetDefaultVolumeName())); 144 PRINT((" volume name: `%s'\n", GetVolumeName())); 145 PRINT((" hide esoteric entries: %d\n", GetHideEsoteric())); 146 PRINT((" %ld hidden entries:\n", fHiddenEntries.CountItems())); 147 for (int32 i = 0; const char *entry = HiddenEntryAt(i); i++) 148 PRINT((" `%s'\n", entry)); 149 } 150 151 // _Init 152 status_t 153 Settings::_Init(const driver_settings *settings, 154 const driver_parameter *volume) 155 { 156 PRINT(("Settings::_Init(%p, %p)\n", settings, volume)); 157 status_t error = B_OK; 158 // get the global values 159 fDefaultVolumeName.SetTo(_GetParameterValue(settings, 160 "default_volume_name", (const char*)NULL, NULL)); 161 PRINT((" default_volume_name is: `%s'\n", fDefaultVolumeName.GetString())); 162 fHideEsoteric = _GetParameterValue(settings, "hide_esoteric_entries", 163 kDefaultHideEsoteric, 164 kDefaultHideEsoteric); 165 PRINT((" hide_esoteric_entries is: %d\n", fHideEsoteric)); 166 // get the per volume settings 167 if (volume) { 168 PRINT((" getting volume parameters:\n")); 169 fVolumeName.SetTo(_GetParameterValue(volume, "name", (const char*)NULL, 170 NULL)); 171 PRINT((" name is: `%s'\n", fVolumeName.GetString())); 172 fHideEsoteric = _GetParameterValue(volume, "hide_esoteric_entries", 173 fHideEsoteric, fHideEsoteric); 174 PRINT((" hide_esoteric_entries is: %d\n", fHideEsoteric)); 175 int32 cookie = 0; 176 while (const driver_parameter *parameter 177 = _FindNextParameter(volume, "hide_entries", cookie)) { 178 for (int32 i = 0; i < parameter->value_count; i++) 179 { 180 fHiddenEntries.AddItem(parameter->values[i]); 181 PRINT((" hidden entry: `%s'\n", parameter->values[i])); 182 } 183 } 184 } 185 // check the values 186 PRINT((" checking volume names...'\n")); 187 _CheckVolumeName(fDefaultVolumeName); 188 _CheckVolumeName(fVolumeName); 189 PRINT((" checking hidden entry names...'\n")); 190 for (int32 i = fHiddenEntries.CountItems(); i >= 0; i--) { 191 String &entry = fHiddenEntries.ItemAt(i); 192 if (!_CheckEntryName(entry.GetString())) 193 { 194 PRINT((" ignoring: `%s'\n", entry.GetString())); 195 fHiddenEntries.RemoveItem(i); 196 } 197 } 198 PRINT(("Settings::_Init() done: %s\n", strerror(error))); 199 return error; 200 } 201 202 // _FindVolumeParameter 203 const driver_parameter * 204 Settings::_FindVolumeParameter(const driver_settings *settings, 205 const char *name) 206 { 207 if (settings) { 208 int32 cookie = 0; 209 while (const driver_parameter *parameter 210 = _FindNextParameter(settings, "volume", cookie)) { 211 if (parameter->value_count == 1 212 && !strcmp(parameter->values[0], name)) { 213 return parameter; 214 } 215 } 216 } 217 return NULL; 218 } 219 220 // _FindVolumeParameter 221 const driver_parameter * 222 Settings::_FindVolumeParameter(const driver_settings *settings, 223 off_t offset, off_t size) 224 { 225 PRINT(("Settings::_FindVolumeParameter(%Ld, %Ld)\n", offset, size)); 226 if (settings) { 227 int32 cookie = 0; 228 while (const driver_parameter *parameter 229 = _FindNextParameter(settings, "volume", cookie)) { 230 if (_GetParameterValue(parameter, "offset", offset + 1, offset + 1) 231 == offset 232 && _GetParameterValue(parameter, "size", size + 1, size + 1) 233 == size) { 234 PRINT(("Settings::_FindVolumeParameter() done: found parameter: index: %ld, " 235 "(%p)\n", cookie - 1, parameter)); 236 return parameter; 237 } 238 } 239 } 240 PRINT(("Settings::_FindVolumeParameter() done: failed\n")); 241 return NULL; 242 } 243 244 // _CheckVolumeName 245 void 246 Settings::_CheckVolumeName(String &name) 247 { 248 // truncate, if it is too long 249 if (name.GetLength() >= B_FILE_NAME_LENGTH) { 250 char buffer[B_FILE_NAME_LENGTH]; 251 memcpy(buffer, name.GetString(), B_FILE_NAME_LENGTH - 1); 252 name.SetTo(buffer, B_FILE_NAME_LENGTH - 1); 253 } 254 // check for bad characters 255 bool invalid = false; 256 const char *string = name.GetString(); 257 for (int32 i = 0; !invalid && i < name.GetLength(); i++) { 258 if (string[i] == '/') // others? 259 invalid = true; 260 } 261 if (invalid) 262 name.Unset(); 263 } 264 265 // _CheckEntryName 266 bool 267 Settings::_CheckEntryName(const char *name) 268 { 269 int32 len = (name ? strlen(name) : 0); 270 // any further restictions? 271 return (len > 0); 272 } 273 274