// Settings.cpp // // Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de) // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // You can alternatively use *this file* under the terms of the the MIT // license included in this package. #include #include "Settings.h" #include "Debug.h" using std::nothrow; /*! \class Settings \brief Manages the ReiserFS settings. */ static const char *kFSName = "reiserfs"; // defaults static const char *kDefaultDefaultVolumeName = "ReiserFS untitled"; static const bool kDefaultHideEsoteric = true; // constructor Settings::Settings() : fDefaultVolumeName(), fVolumeName(), fHideEsoteric(kDefaultHideEsoteric), fHiddenEntries(5) { } // destructor Settings::~Settings() { Unset(); } // SetTo status_t Settings::SetTo(const char *volumeName) { // unset Unset(); // load the driver settings and find the entry for the volume void *settings = load_driver_settings(kFSName); const driver_parameter *volume = NULL; const driver_settings *ds = get_driver_settings(settings); if (ds && volumeName) volume = _FindVolumeParameter(ds, volumeName); // init the object and unload the settings _Init(ds, volume); unload_driver_settings(settings); return B_OK; } // SetTo status_t Settings::SetTo(off_t volumeOffset, off_t volumeSize) { PRINT(("Settings::SetTo(%" B_PRIdOFF ", %" B_PRIdOFF ")\n", volumeOffset, volumeSize)); // unset Unset(); // load the driver settings and find the entry for the volume void *settings = load_driver_settings(kFSName); const driver_parameter *volume = NULL; const driver_settings *ds = get_driver_settings(settings); if (ds) volume = _FindVolumeParameter(ds, volumeOffset, volumeSize); // init the object and unload the settings _Init(ds, volume); unload_driver_settings(settings); PRINT(("Settings::SetTo(%" B_PRIdOFF ", %" B_PRIdOFF ") done: B_OK\n", volumeOffset, volumeSize)); return B_OK; } // Unset void Settings::Unset() { fDefaultVolumeName.Unset(); fVolumeName.Unset(); fHideEsoteric = kDefaultHideEsoteric; fHiddenEntries.MakeEmpty(); } // GetDefaultVolumeName const char * Settings::GetDefaultVolumeName() const { if (fDefaultVolumeName.GetLength() > 0) return fDefaultVolumeName.GetString(); return kDefaultDefaultVolumeName; } // GetVolumeName const char * Settings::GetVolumeName() const { if (fVolumeName.GetLength() > 0) return fVolumeName.GetString(); return GetDefaultVolumeName(); } // GetHideEsoteric bool Settings::GetHideEsoteric() const { return fHideEsoteric; } // HiddenEntryAt const char * Settings::HiddenEntryAt(int32 index) const { const char *entry = NULL; if (index >= 0 && index < fHiddenEntries.CountItems()) entry = fHiddenEntries.ItemAt(index).GetString(); return entry; } // Dump void Settings::Dump() { #if DEBUG PRINT(("Settings:\n")); PRINT((" default volume name: `%s'\n", GetDefaultVolumeName())); PRINT((" volume name: `%s'\n", GetVolumeName())); PRINT((" hide esoteric entries: %d\n", GetHideEsoteric())); PRINT((" %" B_PRId32 " hidden entries:\n", fHiddenEntries.CountItems())); for (int32 i = 0; const char *entry = HiddenEntryAt(i); i++) PRINT((" `%s'\n", entry)); #endif } // _Init status_t Settings::_Init(const driver_settings *settings, const driver_parameter *volume) { PRINT(("Settings::_Init(%p, %p)\n", settings, volume)); status_t error = B_OK; // get the global values fDefaultVolumeName.SetTo(_GetParameterValue(settings, "default_volume_name", (const char*)NULL, NULL)); PRINT((" default_volume_name is: `%s'\n", fDefaultVolumeName.GetString())); fHideEsoteric = _GetParameterValue(settings, "hide_esoteric_entries", kDefaultHideEsoteric, kDefaultHideEsoteric); PRINT((" hide_esoteric_entries is: %d\n", fHideEsoteric)); // get the per volume settings if (volume) { PRINT((" getting volume parameters:\n")); fVolumeName.SetTo(_GetParameterValue(volume, "name", (const char*)NULL, NULL)); PRINT((" name is: `%s'\n", fVolumeName.GetString())); fHideEsoteric = _GetParameterValue(volume, "hide_esoteric_entries", fHideEsoteric, fHideEsoteric); PRINT((" hide_esoteric_entries is: %d\n", fHideEsoteric)); int32 cookie = 0; while (const driver_parameter *parameter = _FindNextParameter(volume, "hide_entries", cookie)) { for (int32 i = 0; i < parameter->value_count; i++) { fHiddenEntries.AddItem(parameter->values[i]); PRINT((" hidden entry: `%s'\n", parameter->values[i])); } } } // check the values PRINT((" checking volume names...'\n")); _CheckVolumeName(fDefaultVolumeName); _CheckVolumeName(fVolumeName); PRINT((" checking hidden entry names...'\n")); for (int32 i = fHiddenEntries.CountItems(); i >= 0; i--) { String &entry = fHiddenEntries.ItemAt(i); if (!_CheckEntryName(entry.GetString())) { PRINT((" ignoring: `%s'\n", entry.GetString())); fHiddenEntries.RemoveItem(i); } } PRINT(("Settings::_Init() done: %s\n", strerror(error))); return error; } // _FindVolumeParameter const driver_parameter * Settings::_FindVolumeParameter(const driver_settings *settings, const char *name) { if (settings) { int32 cookie = 0; while (const driver_parameter *parameter = _FindNextParameter(settings, "volume", cookie)) { if (parameter->value_count == 1 && !strcmp(parameter->values[0], name)) { return parameter; } } } return NULL; } // _FindVolumeParameter const driver_parameter * Settings::_FindVolumeParameter(const driver_settings *settings, off_t offset, off_t size) { PRINT(("Settings::_FindVolumeParameter(%" B_PRIdOFF ", %" B_PRIdOFF ")\n", offset, size)); if (settings) { int32 cookie = 0; while (const driver_parameter *parameter = _FindNextParameter(settings, "volume", cookie)) { if (_GetParameterValue(parameter, "offset", offset + 1, offset + 1) == offset && _GetParameterValue(parameter, "size", size + 1, size + 1) == size) { PRINT(("Settings::_FindVolumeParameter() done: found parameter:" " index: %" B_PRId32 ", (%p)\n", cookie - 1, parameter)); return parameter; } } } PRINT(("Settings::_FindVolumeParameter() done: failed\n")); return NULL; } // _CheckVolumeName void Settings::_CheckVolumeName(String &name) { // truncate, if it is too long if (name.GetLength() >= B_FILE_NAME_LENGTH) { char buffer[B_FILE_NAME_LENGTH]; memcpy(buffer, name.GetString(), B_FILE_NAME_LENGTH - 1); name.SetTo(buffer, B_FILE_NAME_LENGTH - 1); } // check for bad characters bool invalid = false; const char *string = name.GetString(); for (int32 i = 0; !invalid && i < name.GetLength(); i++) { if (string[i] == '/') // others? invalid = true; } if (invalid) name.Unset(); } // _CheckEntryName bool Settings::_CheckEntryName(const char *name) { int32 len = (name ? strlen(name) : 0); // any further restictions? return (len > 0); }