#include <new>
#include "Settings.h"
#include "Debug.h"
using std::nothrow;
\class Settings
\brief Manages the ReiserFS settings.
*/
static const char *kFSName = "reiserfs";
static const char *kDefaultDefaultVolumeName = "ReiserFS untitled";
static const bool kDefaultHideEsoteric = true;
Settings::Settings()
:
fDefaultVolumeName(),
fVolumeName(),
fHideEsoteric(kDefaultHideEsoteric),
fHiddenEntries(5)
{
}
Settings::~Settings()
{
Unset();
}
status_t
Settings::SetTo(const char *volumeName)
{
Unset();
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(ds, volume);
unload_driver_settings(settings);
return B_OK;
}
status_t
Settings::SetTo(off_t volumeOffset, off_t volumeSize)
{
PRINT(("Settings::SetTo(%" B_PRIdOFF ", %" B_PRIdOFF ")\n", volumeOffset,
volumeSize));
Unset();
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(ds, volume);
unload_driver_settings(settings);
PRINT(("Settings::SetTo(%" B_PRIdOFF ", %" B_PRIdOFF ") done: B_OK\n",
volumeOffset, volumeSize));
return B_OK;
}
void
Settings::Unset()
{
fDefaultVolumeName.Unset();
fVolumeName.Unset();
fHideEsoteric = kDefaultHideEsoteric;
fHiddenEntries.MakeEmpty();
}
const char *
Settings::GetDefaultVolumeName() const
{
if (fDefaultVolumeName.GetLength() > 0)
return fDefaultVolumeName.GetString();
return kDefaultDefaultVolumeName;
}
const char *
Settings::GetVolumeName() const
{
if (fVolumeName.GetLength() > 0)
return fVolumeName.GetString();
return GetDefaultVolumeName();
}
bool
Settings::GetHideEsoteric() const
{
return fHideEsoteric;
}
const char *
Settings::HiddenEntryAt(int32 index) const
{
const char *entry = NULL;
if (index >= 0 && index < fHiddenEntries.CountItems())
entry = fHiddenEntries.ItemAt(index).GetString();
return entry;
}
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
}
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;
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));
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]));
}
}
}
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;
}
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;
}
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;
}
void
Settings::_CheckVolumeName(String &name)
{
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);
}
bool invalid = false;
const char *string = name.GetString();
for (int32 i = 0; !invalid && i < name.GetLength(); i++) {
if (string[i] == '/')
invalid = true;
}
if (invalid)
name.Unset();
}
bool
Settings::_CheckEntryName(const char *name)
{
int32 len = (name ? strlen(name) : 0);
return (len > 0);
}