Removed unused files.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34223 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-11-24 22:29:48 +00:00
parent 9fd6a5448d
commit d1b0d5a4af
24 changed files with 0 additions and 7938 deletions

View File

@ -1,54 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include "AddOnImage.h"
// constructor
AddOnImage::AddOnImage()
: fID(-1)
{
}
// destructor
AddOnImage::~AddOnImage()
{
Unload();
}
// Load
status_t
AddOnImage::Load(const char *path)
{
Unload();
status_t error = (path ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
image_id id = load_add_on(path);
if (id >= 0)
fID = id;
else
error = id;
}
return error;
}
// Unload
void
AddOnImage::Unload()
{
if (fID >= 0) {
unload_add_on(fID);
fID = -1;
}
}
// SetID
void
AddOnImage::SetID(image_id id)
{
Unload();
if (id >= 0)
fID = id;
}

View File

@ -1,32 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#ifndef _ADD_ON_IMAGE_H
#define _ADD_ON_IMAGE_H
#include <image.h>
namespace BPrivate {
class AddOnImage {
public:
AddOnImage();
~AddOnImage();
status_t Load(const char *path);
void Unload();
void SetID(image_id id);
image_id ID() const { return fID; }
private:
image_id fID;
};
} // namespace BPrivate
using BPrivate::AddOnImage;
#endif // _ADD_ON_IMAGE_H

View File

@ -1,55 +0,0 @@
#include "AddOnMonitor.h"
#include "AddOnMonitorHandler.h"
#include <Message.h>
#include <MessageRunner.h>
#include <Messenger.h>
#include <stdio.h>
AddOnMonitor::AddOnMonitor(AddOnMonitorHandler * handler)
: BLooper("AddOnMonitor")
{
fInitCheck = B_NO_INIT;
AddHandler(handler);
SetPreferredHandler(handler);
status_t status;
BMessenger messenger(handler, this, &status);
if (status != B_OK) {
fInitCheck = status;
return;
}
if (!messenger.IsValid()) {
fInitCheck = B_ERROR;
return;
}
fPulseMessage = new BMessage(B_PULSE);
fPulseRunner = new BMessageRunner(messenger, fPulseMessage, 1000000);
status = fPulseRunner->InitCheck();
if (status != B_OK) {
fInitCheck = status;
fprintf(stderr, "AddOnMonitor() : bad status returned by fPulseRunner->InitCheck()\n");
return;
}
thread_id id = Run();
if (id < 0) {
fInitCheck = (status_t)id;
fprintf(stderr, "AddOnMonitor() : bad id returned by Run()\n");
return;
}
fInitCheck = B_OK;
return;
}
/* virtual */
AddOnMonitor::~AddOnMonitor()
{
delete fPulseMessage;
delete fPulseRunner;
}
/* virtual */ status_t
AddOnMonitor::InitCheck()
{
return fInitCheck;
}

View File

@ -1,558 +0,0 @@
#include "AddOnMonitorHandler.h"
#include <Directory.h>
#ifndef ADD_ON_STABLE_SECONDS
#define ADD_ON_STABLE_SECONDS 15
#endif
/*
* public functions
*/
AddOnMonitorHandler::AddOnMonitorHandler(const char * name)
: NodeMonitorHandler(name)
{
}
AddOnMonitorHandler::~AddOnMonitorHandler()
{
}
/* virtual */ void
AddOnMonitorHandler::MessageReceived(BMessage * msg)
{
if (msg->what == B_PULSE) {
HandlePulse();
}
inherited::MessageReceived(msg);
}
/* virtual */ status_t
AddOnMonitorHandler::AddDirectory(const node_ref * nref)
{
// ignore directories added twice
std::list<add_on_directory_info>::iterator diter = directories.begin();
for( ; diter != directories.end() ; diter++) {
if (diter->nref == *nref) {
return B_OK;
}
}
BDirectory directory(nref);
status_t status = directory.InitCheck();
if (status != B_OK) {
return status;
}
add_on_directory_info dir_info;
dir_info.nref = *nref;
directories.push_back(dir_info);
status = watch_node(nref, B_WATCH_DIRECTORY, this);
if (status != B_OK) {
directories.pop_back();
return status;
}
BEntry entry;
while (directory.GetNextEntry(&entry, true) == B_OK) {
add_on_entry_info entry_info;
if (entry.GetName(entry_info.name) != B_OK) {
continue; // discard and proceed
}
if (entry.GetNodeRef(&entry_info.nref) != B_OK) {
continue; // discard and proceed
}
entry_info.dir_nref = *nref;
pending_entries.push_back(entry_info);
}
return B_OK;
}
/*
* AddOnMonitorHandler hooks
*/
/* virtual */ void
AddOnMonitorHandler::AddOnCreated(const add_on_entry_info * entry_info)
{
}
/* virtual */ void
AddOnMonitorHandler::AddOnEnabled(const add_on_entry_info * entry_info)
{
}
/* virtual */ void
AddOnMonitorHandler::AddOnDisabled(const add_on_entry_info * entry_info)
{
}
/* virtual */ void
AddOnMonitorHandler::AddOnRemoved(const add_on_entry_info * entry_info)
{
}
/*
* NodeMonitorHandler hooks
*/
/* virtual */ void
AddOnMonitorHandler::EntryCreated(const char *name, ino_t directory,
dev_t device, ino_t node)
{
add_on_entry_info entry_info;
strncpy(entry_info.name, name, sizeof(entry_info.name));
make_node_ref(device, node, &entry_info.nref);
make_node_ref(device, directory, &entry_info.dir_nref);
pending_entries.push_back(entry_info);
}
/* virtual */ void
AddOnMonitorHandler::EntryRemoved(ino_t directory, dev_t device, ino_t node)
{
node_ref entry_nref;
make_node_ref(device, node, &entry_nref);
// Search pending entries first, which can simply be discarded
// We might have this entry in the pending list multiple times,
// so we search entire list through, even after finding one.
std::list<add_on_entry_info>::iterator eiter = pending_entries.begin();
while (eiter != pending_entries.end()) {
if (eiter->nref == entry_nref) {
eiter = pending_entries.erase(eiter);
} else {
eiter++;
}
}
add_on_entry_info info;
node_ref dir_nref;
make_node_ref(device, directory, &dir_nref);
// find the entry's info, and the entry's directory info
std::list<add_on_directory_info>::iterator diter = directories.begin();
for( ; diter != directories.end() ; diter++) {
if (diter->nref == dir_nref) {
std::list<add_on_entry_info>::iterator eiter = diter->entries.begin();
for( ; eiter != diter->entries.end() ; eiter++) {
info = *eiter;
if (eiter->nref == entry_nref) {
info = *eiter;
diter->entries.erase(eiter);
break;
}
}
break;
}
}
// if it was not found, we're done
if (diter == directories.end()) {
return;
}
// Start at the top again, and search until the directory we found
// the old add_on in. If we find a add_on with the same name then
// the old add_on was not enabled. So we deallocate the old
// add_on and return.
std::list<add_on_directory_info>::iterator diter2 = directories.begin();
for( ; diter2 != diter ; diter2++) {
std::list<add_on_entry_info>::iterator eiter = diter2->entries.begin();
for( ; eiter != diter2->entries.end() ; eiter++) {
if (strcmp(eiter->name, info.name) == 0) {
AddOnRemoved(&info);
return;
}
}
}
// The active plugin was removed. We need to disable and
// then subsequently deallocate it.
AddOnDisabled(&info);
AddOnRemoved(&info);
// Continue searching for a add_on below us. If we find a add_on
// with the same name, we must enable it.
for (diter++ ; diter != directories.end() ; diter++) {
std::list<add_on_entry_info>::iterator eiter = diter->entries.begin();
for( ; eiter != diter->entries.end() ; eiter++) {
if (strcmp(eiter->name, info.name) == 0) {
AddOnEnabled(&*eiter);
return;
}
}
}
}
/* virtual */ void
AddOnMonitorHandler::EntryMoved(const char *name, ino_t from_directory,
ino_t to_directory, dev_t device, ino_t node)
{
node_ref from_nref;
make_node_ref(device, from_directory, &from_nref);
std::list<add_on_directory_info>::iterator from_iter = directories.begin();
for ( ; from_iter != directories.end() ; from_iter++) {
if (from_iter->nref == from_nref) {
break;
}
}
node_ref to_nref;
make_node_ref(device, to_directory, &to_nref);
std::list<add_on_directory_info>::iterator to_iter = directories.begin();
for ( ; to_iter != directories.end() ; to_iter++) {
if (to_iter->nref == to_nref) {
break;
}
}
if ((from_iter == directories.end()) && (to_iter == directories.end())) {
// huh? whatever...
return;
}
add_on_entry_info info;
node_ref entry_nref;
make_node_ref(device, node, &entry_nref);
if (to_iter == directories.end()) {
// moved out of our view
std::list<add_on_entry_info>::iterator eiter = from_iter->entries.begin();
for( ; eiter != from_iter->entries.end() ; eiter++) {
if (entry_nref == eiter->nref) {
// save the info and remove the entry
info = *eiter;
from_iter->entries.erase(eiter);
break;
}
}
if (eiter == from_iter->entries.end()) {
// we don't know anything about this entry yet.. ignore it
return;
}
// if the name is the same, save the information about this
// add_on into former_entries for later use
if (strcmp(info.name, name) == 0) {
former_entries.push_back(info);
}
// Start at the top again, and search until the from directory.
// If we find a add_on with the same name then the moved add_on
// was not enabled. So we are done.
std::list<add_on_directory_info>::iterator diter = directories.begin();
for( ; diter != from_iter ; diter++) {
std::list<add_on_entry_info>::iterator eiter2 = diter->entries.begin();
for( ; eiter2 != diter->entries.end() ; eiter2++) {
if (strcmp(eiter2->name, info.name) == 0) {
return;
}
}
}
// finally disable the add_on
AddOnDisabled(&info);
// Continue searching for a add_on below us. If we find a add_on
// with the same name, we must enable it.
for (from_iter++ ; from_iter != directories.end() ; from_iter++) {
std::list<add_on_entry_info>::iterator eiter2 = from_iter->entries.begin();
for( ; eiter2 != from_iter->entries.end() ; eiter2++) {
if (strcmp(eiter2->name, info.name) == 0) {
AddOnEnabled(&*eiter2);
return;
}
}
}
// finally, if the new name is different, destroy the addon
if (strcmp(info.name, name) != 0) {
AddOnRemoved(&info);
}
// done
return;
}
if (from_iter == directories.end()) {
// moved into our view
std::list<add_on_entry_info>::iterator eiter = former_entries.begin();
for( ; eiter != former_entries.end() ; eiter++) {
if (entry_nref == eiter->nref) {
// save the info and remove the entry
info = *eiter;
former_entries.erase(eiter);
break;
}
}
if (eiter != former_entries.end()) {
if (strcmp(info.name, name) != 0) {
// name changed on the way in, remove the old one
AddOnRemoved(&info);
}
}
// update the info
strncpy(info.name, name, sizeof(info.name));
info.nref = entry_nref;
info.dir_nref = to_nref;
if (eiter == former_entries.end()) {
// this add_on was not seen before
AddOnCreated(&info);
}
// Start at the top again, and search until the to directory.
// If we find a add_on with the same name then the moved add_on
// is not to be enabled. So we are done.
std::list<add_on_directory_info>::iterator diter = directories.begin();
for( ; diter != to_iter ; diter++) {
std::list<add_on_entry_info>::iterator eiter2 = diter->entries.begin();
for( ; eiter2 != diter->entries.end() ; eiter2++) {
if (strcmp(eiter2->name, info.name) == 0) {
return;
}
}
}
// The new add_on should be enabled, but first we check to see
// if there is an add_on below us. If we find one, we disable it.
bool shadowing = false;
for (diter++ ; diter != directories.end() ; diter++) {
std::list<add_on_entry_info>::iterator eiter2 = diter->entries.begin();
for( ; eiter2 != diter->entries.end() ; eiter2++) {
if (strcmp(eiter2->name, info.name) == 0) {
AddOnDisabled(&*eiter2);
shadowing = true;
break;
}
}
if (shadowing) {
break;
}
}
// enable the new add_on
AddOnEnabled(&info);
// put the new entry into the target directory
to_iter->entries.push_back(info);
// done
return;
}
std::list<add_on_entry_info>::iterator eiter = from_iter->entries.begin();
for( ; eiter != from_iter->entries.end() ; eiter++) {
if (entry_nref == eiter->nref) {
// save the old info and remove the entry
info = *eiter;
from_iter->entries.erase(eiter);
break;
}
}
if (strcmp(info.name, name) == 0) {
// same name moved in heirarchy
debugger("add_on moved inside the heirarchy");
} else {
// check to see if it was formerly enabled
bool was_enabled = true;
std::list<add_on_directory_info>::iterator old_iter = directories.begin();
for( ; old_iter != from_iter ; old_iter++) {
std::list<add_on_entry_info>::iterator eiter2 = old_iter->entries.begin();
for( ; eiter2 != old_iter->entries.end() ; eiter2++) {
if (strcmp(eiter2->name, info.name) == 0) {
was_enabled = false;
break;
}
}
if (!was_enabled) {
break;
}
}
// if it was enabled, disable it and enable the one under us, if it exists
if (was_enabled) {
AddOnDisabled(&info);
bool done = false;
for( ; old_iter != directories.end() ; old_iter++) {
std::list<add_on_entry_info>::iterator eiter2 = old_iter->entries.begin();
for( ; eiter2 != old_iter->entries.end() ; eiter2++) {
if (strcmp(eiter2->name, info.name) == 0) {
AddOnEnabled(&*eiter2);
done = true;
break;
}
}
if (done) {
break;
}
}
}
// kaboom!
AddOnRemoved(&info);
// set up new addon info
strncpy(info.name, name, sizeof(info.name));
info.dir_nref = to_nref;
// presto!
AddOnCreated(&info);
// check to see if we are newly enabled
bool is_enabled = true;
std::list<add_on_directory_info>::iterator new_iter = directories.begin();
for( ; new_iter != to_iter ; new_iter++) {
std::list<add_on_entry_info>::iterator eiter2 = new_iter->entries.begin();
for( ; eiter2 != new_iter->entries.end() ; eiter2++) {
if (strcmp(eiter2->name, info.name) == 0) {
is_enabled = false;
break;
}
}
if (!is_enabled) {
break;
}
}
// if it is newly enabled, check under us for an enabled one, and disable that first
if (is_enabled) {
bool done = false;
for( ; new_iter != directories.end() ; new_iter++) {
std::list<add_on_entry_info>::iterator eiter2 = new_iter->entries.begin();
for( ; eiter2 != new_iter->entries.end() ; eiter2++) {
if (strcmp(eiter2->name, info.name) == 0) {
AddOnDisabled(&*eiter2);
done = true;
break;
}
}
if (done) {
break;
}
}
AddOnEnabled(&info);
}
}
// put the new entry into the target directory
to_iter->entries.push_back(info);
}
/*
* process pending entries
*/
void
AddOnMonitorHandler::HandlePulse()
{
BDirectory directory;
std::list<add_on_entry_info>::iterator iter = pending_entries.begin();
while (iter != pending_entries.end()) {
add_on_entry_info info = *iter;
node_ref dir_nref;
if ((directory.GetNodeRef(&dir_nref) != B_OK) ||
(dir_nref != info.dir_nref)) {
if (directory.SetTo(&info.dir_nref) != B_OK) {
// invalid directory, discard this pending entry
iter = pending_entries.erase(iter);
continue;
}
dir_nref = info.dir_nref;
}
struct stat st;
if (directory.GetStatFor(info.name, &st) != B_OK) {
// invalid file name, discard this pending entry
iter = pending_entries.erase(iter);
continue;
}
// stat units are seconds, real_time_clock units are seconds
if (real_time_clock() - st.st_mtime < ADD_ON_STABLE_SECONDS) {
// entry not stable, skip the entry for this pulse
iter++;
continue;
}
// we are going to deal with the stable entry, so remove it
iter = pending_entries.erase(iter);
// put the new entry into the directory info
std::list<add_on_directory_info>::iterator diter = directories.begin();
for( ; diter != directories.end() ; diter++) {
if (diter->nref == dir_nref) {
diter->entries.push_back(info);
break;
}
}
// report it
AddOnCreated(&info);
// Start at the top again, and search until the directory we put
// the new add_on in. If we find a add_on with the same name then
// the new add_on should not be enabled.
bool enabled = true;
std::list<add_on_directory_info>::iterator diter2 = directories.begin();
for( ; diter2 != diter ; diter2++) {
std::list<add_on_entry_info>::iterator eiter = diter2->entries.begin();
for( ; eiter != diter2->entries.end() ; eiter++) {
if (strcmp(eiter->name, info.name) == 0) {
enabled = false;
break;
}
}
if (!enabled) {
break;
}
}
if (!enabled) {
// if we are not enabled, go on to the next pending entry
continue;
}
// The new add_on should be enabled, but first we check to see
// if there is an add_on below us. If we find one, we disable it.
bool shadowing = false;
for (diter++ ; diter != directories.end() ; diter++) {
std::list<add_on_entry_info>::iterator eiter = diter->entries.begin();
for( ; eiter != diter->entries.end() ; eiter++) {
if (strcmp(eiter->name, info.name) == 0) {
AddOnDisabled(&*eiter);
shadowing = true;
break;
}
}
if (shadowing) {
break;
}
}
// finally, enable the new entry
AddOnEnabled(&info);
}
}

View File

@ -1,385 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <DiskDevice.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <new.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <syscalls.h>
#include <DiskDevice.h>
#include <DiskDeviceVisitor.h>
#include <Drivers.h>
#include <Message.h>
#include <Path.h>
/*! \class BDiskDevice
\brief A BDiskDevice object represents a storage device.
*/
// constructor
/*! \brief Creates an uninitialized BDiskDevice object.
*/
BDiskDevice::BDiskDevice()
: fDeviceData(NULL)
{
}
// destructor
/*! \brief Frees all resources associated with this object.
*/
BDiskDevice::~BDiskDevice()
{
}
// HasMedia
/*! \brief Returns whether the device contains a media.
\return \c true, if the device contains a media, \c false otherwise.
*/
bool
BDiskDevice::HasMedia() const
{
return (fDeviceData
&& fDeviceData->device_flags & B_DISK_DEVICE_HAS_MEDIA);
}
// IsRemovableMedia
/*! \brief Returns whether the device media are removable.
\return \c true, if the device media are removable, \c false otherwise.
*/
bool
BDiskDevice::IsRemovableMedia() const
{
return (fDeviceData
&& fDeviceData->device_flags & B_DISK_DEVICE_REMOVABLE);
}
// IsReadOnlyMedia
bool
BDiskDevice::IsReadOnlyMedia() const
{
return (fDeviceData
&& fDeviceData->device_flags & B_DISK_DEVICE_READ_ONLY);
}
// IsWriteOnceMedia
bool
BDiskDevice::IsWriteOnceMedia() const
{
return (fDeviceData
&& fDeviceData->device_flags & B_DISK_DEVICE_WRITE_ONCE);
}
// Eject
/*! \brief Eject the device's media.
The device media must, of course, be removable, and the device must
support ejecting the media.
\param update If \c true, Update() is invoked after successful ejection.
\return
- \c B_OK: Everything went fine.
- \c B_NO_INIT: The device is not properly initialized.
- \c B_BAD_VALUE: The device media is not removable.
- other error codes
*/
status_t
BDiskDevice::Eject(bool update)
{
/* // get path
const char *path = Path();
status_t error = (path ? B_OK : B_NO_INIT);
// check whether the device media is removable
if (error == B_OK && !IsRemovable())
error = B_BAD_VALUE;
// open, eject and close the device
if (error == B_OK) {
int fd = open(path, O_RDONLY);
if (fd < 0 || ioctl(fd, B_EJECT_DEVICE) != 0)
error = errno;
if (fd >= 0)
close(fd);
}
if (error == B_OK && update)
error = Update();
return error;
*/
// not implemented
return B_ERROR;
}
// SetTo
status_t
BDiskDevice::SetTo(partition_id id)
{
return _SetTo(id, true, false, 0);
}
// Update
/*! \brief Updates the object to reflect the latest changes to the device.
Note, that subobjects (BSessions, BPartitions) may be deleted during this
operation. It is also possible, that the device doesn't exist anymore --
e.g. if it is hot-pluggable. Then an error is returned and the object is
uninitialized.
\param updated Pointer to a bool variable which shall be set to \c true,
if the object needed to be updated and to \c false otherwise.
May be \c NULL. Is not touched, if the method fails.
\return \c B_OK, if the update went fine, another error code otherwise.
*/
status_t
BDiskDevice::Update(bool *updated)
{
return _Update(_IsShadow(), updated);
}
// Unset
void
BDiskDevice::Unset()
{
BPartition::_Unset();
free(fDeviceData);
fDeviceData = NULL;
}
// InitCheck
status_t
BDiskDevice::InitCheck() const
{
return (fDeviceData ? B_OK : B_NO_INIT);
}
// GetPath
status_t
BDiskDevice::GetPath(BPath *path) const
{
if (!path || !fDeviceData)
return B_BAD_VALUE;
return path->SetTo(fDeviceData->path);
}
// IsModified
bool
BDiskDevice::IsModified() const
{
return (InitCheck() == B_OK && _IsShadow()
&& _kern_is_disk_device_modified(ID()));
}
// PrepareModifications
status_t
BDiskDevice::PrepareModifications()
{
// check initialization
status_t error = InitCheck();
if (error != B_OK)
return error;
if (_IsShadow())
return B_ERROR;
// ask kernel to prepare for modifications
error = _kern_prepare_disk_device_modifications(ID());
if (error != B_OK)
return error;
// update
error = _Update(true, NULL);
if (error != B_OK) {
// bad -- cancelling the modifications is all we can do
_kern_cancel_disk_device_modifications(ID());
}
return error;
}
// CommitModifications
status_t
BDiskDevice::CommitModifications(bool synchronously,
BMessenger progressMessenger,
bool receiveCompleteProgressUpdates)
{
status_t error = InitCheck();
if (error != B_OK)
return error;
if (!_IsShadow())
return B_BAD_VALUE;
// TODO: Get port and token from the progressMessenger
port_id port = -1;
int32 token = -1;
error = _kern_commit_disk_device_modifications(ID(), port, token,
receiveCompleteProgressUpdates);
if (error == B_OK)
error = _SetTo(ID(), true, false, 0);
return error;
}
// CancelModifications
status_t
BDiskDevice::CancelModifications()
{
status_t error = InitCheck();
if (error != B_OK)
return error;
if (!_IsShadow())
return B_BAD_VALUE;
error = _kern_cancel_disk_device_modifications(ID());
if (error == B_OK)
error = _SetTo(ID(), true, false, 0);
return error;
}
// copy constructor
/*! \brief Privatized copy constructor to avoid usage.
*/
BDiskDevice::BDiskDevice(const BDiskDevice &)
{
}
// =
/*! \brief Privatized assignment operator to avoid usage.
*/
BDiskDevice &
BDiskDevice::operator=(const BDiskDevice &)
{
return *this;
}
// _GetData
status_t
BDiskDevice::_GetData(partition_id id, bool deviceOnly, bool shadow,
size_t neededSize, user_disk_device_data **data)
{
// get the device data
void *buffer = NULL;
size_t bufferSize = 0;
if (neededSize > 0) {
// allocate initial buffer
buffer = malloc(neededSize);
if (!buffer)
return B_NO_MEMORY;
bufferSize = neededSize;
}
status_t error = B_OK;
do {
error = _kern_get_disk_device_data(id, deviceOnly, shadow,
(user_disk_device_data*)buffer,
bufferSize, &neededSize);
if (error == B_BUFFER_OVERFLOW) {
// buffer to small re-allocate it
if (buffer)
free(buffer);
buffer = malloc(neededSize);
if (buffer)
bufferSize = neededSize;
else
error = B_NO_MEMORY;
}
} while (error == B_BUFFER_OVERFLOW);
// set result / cleanup on error
if (error == B_OK)
*data = (user_disk_device_data*)buffer;
else if (buffer)
free(buffer);
return error;
}
// _SetTo
status_t
BDiskDevice::_SetTo(partition_id id, bool deviceOnly, bool shadow,
size_t neededSize)
{
Unset();
// get the device data
user_disk_device_data *data = NULL;
status_t error = _GetData(id, deviceOnly, shadow, neededSize, &data);
// set the data
if (error == B_OK)
error = _SetTo(data);
// cleanup on error
if (error != B_OK && data)
free(data);
return error;
}
// _SetTo
status_t
BDiskDevice::_SetTo(user_disk_device_data *data)
{
Unset();
if (!data)
return B_BAD_VALUE;
fDeviceData = data;
status_t error = BPartition::_SetTo(this, NULL,
&fDeviceData->device_partition_data);
if (error != B_OK) {
// If _SetTo() fails, the caller retains ownership of the supplied
// data. So, unset fDeviceData before calling Unset().
fDeviceData = NULL;
Unset();
}
return error;
}
// _Update
status_t
BDiskDevice::_Update(bool shadow, bool *updated)
{
if (InitCheck() != B_OK)
return InitCheck();
// get the device data
user_disk_device_data *data = NULL;
status_t error = _GetData(ID(), true, shadow, 0, &data);
// set the data
if (error == B_OK)
error = _Update(data, updated);
// cleanup on error
if (error != B_OK && data)
free(data);
return error;
}
// _Update
status_t
BDiskDevice::_Update(user_disk_device_data *data, bool *updated)
{
if (!data || !fDeviceData || ID() != data->device_partition_data.id)
return B_BAD_VALUE;
bool _updated;
if (!updated)
updated = &_updated;
*updated = false;
// remove obsolete partitions
status_t error = _RemoveObsoleteDescendants(&data->device_partition_data,
updated);
if (error != B_OK)
return error;
// update existing partitions and add new ones
error = BPartition::_Update(&data->device_partition_data, updated);
if (error == B_OK) {
user_disk_device_data *oldData = fDeviceData;
fDeviceData = data;
// check for changes
if (data->device_flags != oldData->device_flags
|| strcmp(data->path, oldData->path)) {
*updated = true;
}
free(oldData);
}
return error;
}
// _AcceptVisitor
bool
BDiskDevice::_AcceptVisitor(BDiskDeviceVisitor *visitor, int32 level)
{
return visitor->Visit(this);
}

View File

@ -1,167 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <syscalls.h>
#include <DiskDeviceJob.h>
// constructor
BDiskDeviceJob::BDiskDeviceJob()
: fID(B_NO_INIT),
fType(B_DISK_DEVICE_JOB_BAD_TYPE),
fPartitionID(-1),
fDescription()
{
}
// destructor
BDiskDeviceJob::~BDiskDeviceJob()
{
}
// InitCheck
status_t
BDiskDeviceJob::InitCheck() const
{
return (fID >= 0 ? B_OK : fID);
}
// SetTo
status_t
BDiskDeviceJob::SetTo(disk_job_id id)
{
Unset();
user_disk_device_job_info info;
status_t error = _kern_get_disk_device_job_info(id, &info);
if (error != B_OK)
return error;
return _SetTo(&info);
}
// Unset
void
BDiskDeviceJob::Unset()
{
fID = B_NO_INIT;
fType = B_DISK_DEVICE_JOB_BAD_TYPE;
fPartitionID = -1;
fDescription.SetTo(NULL);
}
// ID
disk_job_id
BDiskDeviceJob::ID() const
{
return fID;
}
// Type
uint32
BDiskDeviceJob::Type() const
{
return fType;
}
// PartitionID
partition_id
BDiskDeviceJob::PartitionID() const
{
return fPartitionID;
}
// Description
const char *
BDiskDeviceJob::Description() const
{
return fDescription.String();
}
// Status
uint32
BDiskDeviceJob::Status() const
{
if (InitCheck() != B_OK)
return B_DISK_DEVICE_JOB_UNINITIALIZED;
disk_device_job_progress_info info;
status_t error = _kern_get_disk_device_job_progress_info(fID, &info);
if (error != B_OK)
return B_DISK_DEVICE_JOB_UNINITIALIZED;
return info.status;
}
// Progress
float
BDiskDeviceJob::Progress() const
{
if (InitCheck() != B_OK)
return 0;
disk_device_job_progress_info info;
status_t error = _kern_get_disk_device_job_progress_info(fID, &info);
if (error != B_OK)
return 0;
if (info.task_count < 1 || info.task_count <= info.completed_tasks)
return 1;
if (info.current_task_progress < 0)
info.current_task_progress = 0;
if (info.current_task_progress > 1)
info.current_task_progress = 1;
return (info.completed_tasks + info.current_task_progress)
/ info.task_count;
}
// GetProgressInfo
status_t
BDiskDeviceJob::GetProgressInfo(disk_device_job_progress_info *info) const
{
if (InitCheck() != B_OK)
return InitCheck();
return _kern_get_disk_device_job_progress_info(fID, info);
}
// InterruptProperties
uint32
BDiskDeviceJob::InterruptProperties() const
{
if (InitCheck() != B_OK)
return 0;
disk_device_job_progress_info info;
status_t error = _kern_get_disk_device_job_progress_info(fID, &info);
if (error != B_OK)
return 0;
return info.interrupt_properties;
}
// Cancel
status_t
BDiskDeviceJob::Cancel(bool reverse)
{
if (InitCheck() != B_OK)
return InitCheck();
return _kern_cancel_disk_device_job(fID, reverse);
}
// Pause
status_t
BDiskDeviceJob::Pause()
{
if (InitCheck() != B_OK)
return InitCheck();
return _kern_pause_disk_device_job(fID);
}
// _SetTo
status_t
BDiskDeviceJob::_SetTo(user_disk_device_job_info *info)
{
Unset();
if (!info)
return B_BAD_VALUE;
fID = info->id;
fType = info->type;
fPartitionID = info->partition;
fDescription.SetTo(info->description);
return B_OK;
}

View File

@ -1,832 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <new.h>
#include <DiskDevice.h>
#include <DiskDeviceList.h>
#include <DiskDevicePrivate.h>
#include <DiskDeviceRoster.h>
#include <Locker.h>
#include <Looper.h>
#include <ObjectLocker.h>
#include <Partition.h>
#include <Session.h>
using BPrivate::BObjectLocker;
// constructor
/*! \brief Creates an empty BDiskDeviceList object.
*/
BDiskDeviceList::BDiskDeviceList(bool useOwnLocker)
: fLocker(NULL),
fDevices(20, true),
fSubscribed(false)
{
if (useOwnLocker)
fLocker = new(nothrow) BLocker;
}
// destructor
/*! \brief Frees all resources associated with the object.
*/
BDiskDeviceList::~BDiskDeviceList()
{
if (fLocker)
delete fLocker;
}
// MessageReceived
/*! \brief Implemented to handle notification messages.
*/
void
BDiskDeviceList::MessageReceived(BMessage *message)
{
BObjectLocker<BDiskDeviceList> _(this);
switch (message->what) {
case B_DEVICE_UPDATE:
{
uint32 event;
if (message->FindInt32("event", (int32*)&event) == B_OK) {
switch (event) {
case B_DEVICE_MOUNT_POINT_MOVED:
_MountPointMoved(message);
break;
case B_DEVICE_PARTITION_MOUNTED:
_PartitionMounted(message);
break;
case B_DEVICE_PARTITION_UNMOUNTED:
_PartitionUnmounted(message);
break;
case B_DEVICE_PARTITION_INITIALIZED:
_PartitionInitialized(message);
break;
case B_DEVICE_PARTITION_RESIZED:
_PartitionResized(message);
break;
case B_DEVICE_PARTITION_MOVED:
_PartitionMoved(message);
break;
case B_DEVICE_PARTITION_CREATED:
_PartitionCreated(message);
break;
case B_DEVICE_PARTITION_DELETED:
_PartitionDeleted(message);
break;
case B_DEVICE_PARTITION_DEFRAGMENTED:
_PartitionDefragmented(message);
break;
case B_DEVICE_PARTITION_REPAIRED:
_PartitionRepaired(message);
break;
case B_DEVICE_MEDIA_CHANGED:
_MediaChanged(message);
break;
case B_DEVICE_ADDED:
_DeviceAdded(message);
break;
case B_DEVICE_REMOVED:
_DeviceRemoved(message);
break;
}
}
}
default:
BHandler::MessageReceived(message);
}
}
// SetNextHandler
/*! \brief Implemented to unsubscribe from notification services when going
to be detached from looper.
*/
void
BDiskDeviceList::SetNextHandler(BHandler *handler)
{
if (!handler) {
BObjectLocker<BDiskDeviceList> _(this);
if (fSubscribed)
_StopWatching();
}
BHandler::SetNextHandler(handler);
}
// Fetch
/*! \brief Empties the list and refills it according to the current state.
Furthermore, if added to a looper, the list subscribes to notification
services needed to keep the list up-to-date.
If an error occurs, the list Unset()s itself.
The object doesn't need to be locked, when this method is invoked. The
method does itself try to lock the list, but doesn't fail, if that
doesn't succeed. That way an object can be used without locking in a
single threaded environment.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
BDiskDeviceList::Fetch()
{
Unset();
BObjectLocker<BDiskDeviceList> _(this);
// register for notifications
status_t error = B_OK;
if (Looper())
error = _StartWatching();
// get the devices
BDiskDeviceRoster roster;
while (error == B_OK) {
if (BDiskDevice *device = new(nothrow) BDiskDevice) {
status_t status = roster.GetNextDevice(device);
if (status == B_OK)
fDevices.AddItem(device);
else if (status == B_ENTRY_NOT_FOUND)
break;
else
error = status;
} else
error = B_NO_MEMORY;
}
// cleanup on error
if (error != B_OK)
Unset();
return error;
}
// Unset
/*! \brief Empties the list and unsubscribes from all notification services.
The object doesn't need to be locked, when this method is invoked. The
method does itself try to lock the list, but doesn't fail, if that
doesn't succeed. That way an object can be used without locking in a
single threaded environment.
*/
void
BDiskDeviceList::Unset()
{
BObjectLocker<BDiskDeviceList> _(this);
// unsubscribe from notification services
_StopWatching();
// empty the list
fDevices.MakeEmpty();
}
// Lock
/*! \brief Locks the list.
If on construction it had been specified, that the list shall use an
own BLocker, then this locker is locked, otherwise LockLooper() is
invoked.
\return \c true, if the list could be locked successfully, \c false
otherwise.
*/
bool
BDiskDeviceList::Lock()
{
if (fLocker)
return fLocker->Lock();
return LockLooper();
}
// Unlock
/*! \brief Unlocks the list.
If on construction it had been specified, that the list shall use an
own BLocker, then this locker is unlocked, otherwise UnlockLooper() is
invoked.
*/
void
BDiskDeviceList::Unlock()
{
if (fLocker)
return fLocker->Unlock();
return UnlockLooper();
}
// CountDevices
/*! \brief Returns the number of devices in the list.
The list must be locked.
\return The number of devices in the list.
*/
int32
BDiskDeviceList::CountDevices() const
{
return fDevices.CountItems();
}
// DeviceAt
/*! \brief Retrieves a device by index.
The list must be locked.
\param index The list index of the device to be returned.
\return The device with index \a index, or \c NULL, if the list is not
locked or \a index is out of range.
*/
BDiskDevice *
BDiskDeviceList::DeviceAt(int32 index) const
{
return fDevices.ItemAt(index);
}
// VisitEachDevice
/*! \brief Iterates through the all devices in the list.
The supplied visitor's Visit(BDiskDevice*) is invoked for each device.
If Visit() returns \c true, the iteration is terminated and this method
returns the respective device.
The list must be locked.
\param visitor The visitor.
\return The respective device, if the iteration was terminated early,
\c NULL otherwise.
*/
BDiskDevice *
BDiskDeviceList::VisitEachDevice(BDiskDeviceVisitor *visitor)
{
if (visitor) {
for (int32 i = 0; BDiskDevice *device = DeviceAt(i); i++) {
if (visitor->Visit(device))
return device;
}
}
return NULL;
}
// VisitEachPartition
/*! \brief Iterates through the all devices' partitions.
The supplied visitor's Visit(BPartition*) is invoked for each partition.
If Visit() returns \c true, the iteration is terminated and this method
returns the respective partition.
The list must be locked.
\param visitor The visitor.
\return The respective partition, if the iteration was terminated early,
\c NULL otherwise.
*/
BPartition *
BDiskDeviceList::VisitEachPartition(BDiskDeviceVisitor *visitor)
{
if (visitor) {
for (int32 i = 0; BDiskDevice *device = DeviceAt(i); i++) {
if (BPartition *partition = device->VisitEachDescendant(visitor))
return partition;
}
}
return NULL;
}
// VisitEachMountedPartition
/*! \brief Iterates through the all devices' partitions that are mounted.
The supplied visitor's Visit(BPartition*) is invoked for each mounted
partition.
If Visit() returns \c true, the iteration is terminated and this method
returns the respective partition.
The list must be locked.
\param visitor The visitor.
\return The respective partition, if the iteration was terminated early,
\c NULL otherwise.
*/
BPartition *
BDiskDeviceList::VisitEachMountedPartition(BDiskDeviceVisitor *visitor)
{
BPartition *partition = NULL;
if (visitor) {
struct MountedPartitionFilter : public PartitionFilter {
virtual bool Filter(BPartition *partition, int32 level)
{ return partition->IsMounted(); }
} filter;
PartitionFilterVisitor filterVisitor(visitor, &filter);
partition = VisitEachPartition(&filterVisitor);
}
return partition;
}
// VisitEachMountablePartition
/*! \brief Iterates through the all devices' partitions that are mountable.
The supplied visitor's Visit(BPartition*) is invoked for each mountable
partition.
If Visit() returns \c true, the iteration is terminated and this method
returns the respective partition.
The list must be locked.
\param visitor The visitor.
\return The respective partition, if the iteration was terminated early,
\c NULL otherwise.
*/
BPartition *
BDiskDeviceList::VisitEachMountablePartition(BDiskDeviceVisitor *visitor)
{
BPartition *partition = NULL;
if (visitor) {
struct MountablePartitionFilter : public PartitionFilter {
virtual bool Filter(BPartition *partition, int32 level)
{ return partition->ContainsFileSystem(); }
} filter;
PartitionFilterVisitor filterVisitor(visitor, &filter);
partition = VisitEachPartition(&filterVisitor);
}
return partition;
}
// DeviceWithID
/*! \brief Retrieves a device by ID.
The list must be locked.
\param id The ID of the device to be returned.
\return The device with ID \a id, or \c NULL, if the list is not
locked or no device with ID \a id is in the list.
*/
BDiskDevice *
BDiskDeviceList::DeviceWithID(int32 id) const
{
IDFinderVisitor visitor(id);
return const_cast<BDiskDeviceList*>(this)->VisitEachDevice(&visitor);
}
// PartitionWithID
/*! \brief Retrieves a partition by ID.
The list must be locked.
\param id The ID of the partition to be returned.
\return The partition with ID \a id, or \c NULL, if the list is not
locked or no partition with ID \a id is in the list.
*/
BPartition *
BDiskDeviceList::PartitionWithID(int32 id) const
{
IDFinderVisitor visitor(id);
return const_cast<BDiskDeviceList*>(this)->VisitEachPartition(&visitor);
}
// MountPointMoved
/*! \brief Invoked, when the mount point of a partition has been moved.
The list is locked, when this method is invoked.
\param partition The concerned partition.
*/
void
BDiskDeviceList::MountPointMoved(BPartition *partition)
{
PartitionChanged(partition, B_DEVICE_MOUNT_POINT_MOVED);
}
// PartitionMounted
/*! \brief Invoked, when a partition has been mounted.
The list is locked, when this method is invoked.
\param partition The concerned partition.
*/
void
BDiskDeviceList::PartitionMounted(BPartition *partition)
{
PartitionChanged(partition, B_DEVICE_PARTITION_MOUNTED);
}
// PartitionUnmounted
/*! \brief Invoked, when a partition has been unmounted.
The list is locked, when this method is invoked.
\param partition The concerned partition.
*/
void
BDiskDeviceList::PartitionUnmounted(BPartition *partition)
{
PartitionChanged(partition, B_DEVICE_PARTITION_UNMOUNTED);
}
// PartitionInitialized
/*! \brief Invoked, when a partition has been initialized.
The list is locked, when this method is invoked.
\param partition The concerned partition.
*/
void
BDiskDeviceList::PartitionInitialized(BPartition *partition)
{
PartitionChanged(partition, B_DEVICE_PARTITION_INITIALIZED);
}
// PartitionResized
/*! \brief Invoked, when a partition has been resized.
The list is locked, when this method is invoked.
\param partition The concerned partition.
*/
void
BDiskDeviceList::PartitionResized(BPartition *partition)
{
PartitionChanged(partition, B_DEVICE_PARTITION_RESIZED);
}
// PartitionMoved
/*! \brief Invoked, when a partition has been moved.
The list is locked, when this method is invoked.
\param partition The concerned partition.
*/
void
BDiskDeviceList::PartitionMoved(BPartition *partition)
{
PartitionChanged(partition, B_DEVICE_PARTITION_MOVED);
}
// PartitionCreated
/*! \brief Invoked, when a partition has been created.
The list is locked, when this method is invoked.
\param partition The concerned partition.
*/
void
BDiskDeviceList::PartitionCreated(BPartition *partition)
{
}
// PartitionDeleted
/*! \brief Invoked, when a partition has been deleted.
The method is called twice for a deleted partition. The first time
before the BDiskDevice the partition belongs to has been updated. The
\a partition parameter will point to a still valid BPartition object.
On the second invocation the device object will have been updated and
the partition object will have been deleted -- \a partition will be
\c NULL then.
The list is locked, when this method is invoked.
\param partition The concerned partition. Only non- \c NULL on the first
invocation.
\param partitionID The ID of the concerned partition.
*/
void
BDiskDeviceList::PartitionDeleted(BPartition *partition,
partition_id partitionID)
{
}
// PartitionDefragmented
/*! \brief Invoked, when a partition has been defragmented.
The list is locked, when this method is invoked.
\param partition The concerned partition.
*/
void
BDiskDeviceList::PartitionDefragmented(BPartition *partition)
{
PartitionChanged(partition, B_DEVICE_PARTITION_DEFRAGMENTED);
}
// PartitionRepaired
/*! \brief Invoked, when a partition has been repaired.
The list is locked, when this method is invoked.
\param partition The concerned partition.
*/
void
BDiskDeviceList::PartitionRepaired(BPartition *partition)
{
PartitionChanged(partition, B_DEVICE_PARTITION_REPAIRED);
}
// PartitionChanged
/*! \brief Catch-all method invoked by the \c Partition*() hooks, save by
PartitionCreated() and PartitionDeleted().
If you're interested only in the fact, that something about the partition
changed, you can just override this hook instead of the ones telling you
exactly what happened.
\param partition The concerned partition.
\param event The event that occurred, if you are interested in it after all.
*/
void
BDiskDeviceList::PartitionChanged(BPartition *partition, uint32 event)
{
}
// MediaChanged
/*! \brief Invoked, when the media of a device has been changed.
The list is locked, when this method is invoked.
\param device The concerned device.
*/
void
BDiskDeviceList::MediaChanged(BDiskDevice *device)
{
}
// DeviceAdded
/*! \brief Invoked, when a device has been added.
The list is locked, when this method is invoked.
\param device The concerned device.
*/
void
BDiskDeviceList::DeviceAdded(BDiskDevice *device)
{
}
// DeviceRemoved
/*! \brief Invoked, when a device has been removed.
The supplied object is already removed from the list and is going to be
deleted after the hook returns.
The list is locked, when this method is invoked.
\param device The concerned device.
*/
void
BDiskDeviceList::DeviceRemoved(BDiskDevice *device)
{
}
// _StartWatching
/*! \brief Starts watching for disk device notifications.
The object must be locked (if possible at all), when this method is
invoked.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
BDiskDeviceList::_StartWatching()
{
if (!Looper() || fSubscribed)
return B_BAD_VALUE;
status_t error = BDiskDeviceRoster().StartWatching(BMessenger(this));
fSubscribed = (error == B_OK);
return error;
}
// _StopWatching
/*! \brief Stop watching for disk device notifications.
The object must be locked (if possible at all), when this method is
invoked.
*/
void
BDiskDeviceList::_StopWatching()
{
if (fSubscribed) {
BDiskDeviceRoster().StopWatching(BMessenger(this));
fSubscribed = false;
}
}
// _MountPointMoved
/*! \brief Handles a "mount point moved" message.
\param message The respective notification message.
*/
void
BDiskDeviceList::_MountPointMoved(BMessage *message)
{
if (BDiskDevice *device = _UpdateDevice(message)) {
if (BPartition *partition = _FindPartition(message))
MountPointMoved(partition);
}
}
// _PartitionMounted
/*! \brief Handles a "partition mounted" message.
\param message The respective notification message.
*/
void
BDiskDeviceList::_PartitionMounted(BMessage *message)
{
if (BDiskDevice *device = _UpdateDevice(message)) {
if (BPartition *partition = _FindPartition(message))
PartitionMounted(partition);
}
}
// _PartitionUnmounted
/*! \brief Handles a "partition unmounted" message.
\param message The respective notification message.
*/
void
BDiskDeviceList::_PartitionUnmounted(BMessage *message)
{
if (BDiskDevice *device = _UpdateDevice(message)) {
if (BPartition *partition = _FindPartition(message))
PartitionUnmounted(partition);
}
}
// _PartitionInitialized
/*! \brief Handles a "partition initialized" message.
\param message The respective notification message.
*/
void
BDiskDeviceList::_PartitionInitialized(BMessage *message)
{
if (BDiskDevice *device = _UpdateDevice(message)) {
if (BPartition *partition = _FindPartition(message))
PartitionInitialized(partition);
}
}
// _PartitionResized
/*! \brief Handles a "partition resized" message.
\param message The respective notification message.
*/
void
BDiskDeviceList::_PartitionResized(BMessage *message)
{
if (BDiskDevice *device = _UpdateDevice(message)) {
if (BPartition *partition = _FindPartition(message))
PartitionResized(partition);
}
}
// _PartitionMoved
/*! \brief Handles a "partition moved" message.
\param message The respective notification message.
*/
void
BDiskDeviceList::_PartitionMoved(BMessage *message)
{
if (BDiskDevice *device = _UpdateDevice(message)) {
if (BPartition *partition = _FindPartition(message))
PartitionMoved(partition);
}
}
// _PartitionCreated
/*! \brief Handles a "partition created" message.
\param message The respective notification message.
*/
void
BDiskDeviceList::_PartitionCreated(BMessage *message)
{
if (BDiskDevice *device = _UpdateDevice(message)) {
if (BPartition *partition = _FindPartition(message))
PartitionCreated(partition);
}
}
// _PartitionDeleted
/*! \brief Handles a "partition deleted" message.
\param message The respective notification message.
*/
void
BDiskDeviceList::_PartitionDeleted(BMessage *message)
{
if (BPartition *partition = _FindPartition(message)) {
partition_id id = partition->ID();
PartitionDeleted(partition, id);
if (_UpdateDevice(message))
PartitionDeleted(NULL, id);
}
}
// _PartitionDefragmented
/*! \brief Handles a "partition defragmented" message.
\param message The respective notification message.
*/
void
BDiskDeviceList::_PartitionDefragmented(BMessage *message)
{
if (BDiskDevice *device = _UpdateDevice(message)) {
if (BPartition *partition = _FindPartition(message))
PartitionDefragmented(partition);
}
}
// _PartitionRepaired
/*! \brief Handles a "partition repaired" message.
\param message The respective notification message.
*/
void
BDiskDeviceList::_PartitionRepaired(BMessage *message)
{
if (BDiskDevice *device = _UpdateDevice(message)) {
if (BPartition *partition = _FindPartition(message))
PartitionRepaired(partition);
}
}
// _MediaChanged
/*! \brief Handles a "media changed" message.
\param message The respective notification message.
*/
void
BDiskDeviceList::_MediaChanged(BMessage *message)
{
if (BDiskDevice *device = _UpdateDevice(message))
MediaChanged(device);
}
// _DeviceAdded
/*! \brief Handles a "device added" message.
\param message The respective notification message.
*/
void
BDiskDeviceList::_DeviceAdded(BMessage *message)
{
int32 id;
if (message->FindInt32("device_id", &id) == B_OK && !DeviceWithID(id)) {
BDiskDevice *device = new(nothrow) BDiskDevice;
if (BDiskDeviceRoster().GetDeviceWithID(id, device) == B_OK) {
fDevices.AddItem(device);
DeviceAdded(device);
} else
delete device;
}
}
// _DeviceRemoved
/*! \brief Handles a "device removed" message.
\param message The respective notification message.
*/
void
BDiskDeviceList::_DeviceRemoved(BMessage *message)
{
if (BDiskDevice *device = _FindDevice(message)) {
fDevices.RemoveItem(device, false);
DeviceRemoved(device);
delete device;
}
}
// _FindDevice
/*! \brief Returns the device for the ID contained in a motification message.
\param message The notification message.
\return The device with the ID, or \c NULL, if the ID or the device could
not be found.
*/
BDiskDevice *
BDiskDeviceList::_FindDevice(BMessage *message)
{
BDiskDevice *device = NULL;
int32 id;
if (message->FindInt32("device_id", &id) == B_OK)
device = DeviceWithID(id);
return device;
}
// _FindPartition
/*! \brief Returns the partition for the ID contained in a motification
message.
\param message The notification message.
\return The partition with the ID, or \c NULL, if the ID or the partition
could not be found.*/
BPartition *
BDiskDeviceList::_FindPartition(BMessage *message)
{
BPartition *partition = NULL;
int32 id;
if (message->FindInt32("partition_id", &id) == B_OK)
partition = PartitionWithID(id);
return partition;
}
// _UpdateDevice
/*! \brief Finds the device for the ID contained in a motification message
and updates it.
\param message The notification message.
\return The device with the ID, or \c NULL, if the ID or the device could
not be found.
*/
BDiskDevice *
BDiskDeviceList::_UpdateDevice(BMessage *message)
{
BDiskDevice *device = _FindDevice(message);
if (device) {
if (device->Update() != B_OK) {
fDevices.RemoveItem(device);
device = NULL;
}
}
return device;
}

View File

@ -1,64 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <DiskDevicePrivate.h>
#include <DiskDevice.h>
#include <Partition.h>
// PartitionFilterVisitor
// constructor
PartitionFilterVisitor::PartitionFilterVisitor(BDiskDeviceVisitor *visitor,
PartitionFilter *filter)
: BDiskDeviceVisitor(),
fVisitor(visitor),
fFilter(filter)
{
}
// Visit
bool
PartitionFilterVisitor::Visit(BDiskDevice *device)
{
if (fFilter->Filter(device, 0))
return fVisitor->Visit(device);
return false;
}
// Visit
bool
PartitionFilterVisitor::Visit(BPartition *partition, int32 level)
{
if (fFilter->Filter(partition, level))
return fVisitor->Visit(partition, level);
return false;
}
// #pragma mark -
// IDFinderVisitor
// constructor
IDFinderVisitor::IDFinderVisitor(int32 id)
: BDiskDeviceVisitor(),
fID(id)
{
}
// Visit
bool
IDFinderVisitor::Visit(BDiskDevice *device)
{
return (device->ID() == fID);
}
// Visit
bool
IDFinderVisitor::Visit(BPartition *partition, int32 level)
{
return (partition->ID() == fID);
}

View File

@ -1,870 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <new>
#include <syscalls.h>
#include <Directory.h>
#include <DiskDevice.h>
#include <DiskDeviceJob.h>
#include <DiskDevicePrivate.h>
#include <DiskDeviceRoster.h>
#include <DiskSystem.h>
#include <Entry.h>
#include <FindDirectory.h>
#include <Message.h>
#include <Partition.h>
#include <Path.h>
//#include "AddOnImage.h"
/*! \class BDiskDeviceRoster
\brief An interface for iterating through the disk devices known to the
system and for a notification mechanism provided to listen to their
changes.
*/
/*! \brief find_directory constants of the add-on dirs to be searched. */
static const directory_which kAddOnDirs[] = {
B_USER_ADDONS_DIRECTORY,
// B_COMMON_ADDONS_DIRECTORY,
B_BEOS_ADDONS_DIRECTORY
};
/*! \brief Size of the kAddOnDirs array. */
static const int32 kAddOnDirCount
= sizeof(kAddOnDirs) / sizeof(directory_which);
// constructor
/*! \brief Creates a BDiskDeviceRoster object.
The object is ready to be used after construction.
*/
BDiskDeviceRoster::BDiskDeviceRoster()
: fDeviceCookie(0),
fDiskSystemCookie(0),
fJobCookie(0)
// fPartitionAddOnDir(NULL),
// fFSAddOnDir(NULL),
// fPartitionAddOnDirIndex(0),
// fFSAddOnDirIndex(0)
{
}
// destructor
/*! \brief Frees all resources associated with the object.
*/
BDiskDeviceRoster::~BDiskDeviceRoster()
{
// if (fPartitionAddOnDir)
// delete fPartitionAddOnDir;
// if (fFSAddOnDir)
// delete fFSAddOnDir;
}
// GetNextDevice
/*! \brief Returns the next BDiskDevice.
\param device Pointer to a pre-allocated BDiskDevice to be initialized to
represent the next device.
\return
- \c B_OK: Everything went fine.
- \c B_ENTRY_NOT_FOUND: The end of the list of devices had already been
reached.
- another error code
*/
status_t
BDiskDeviceRoster::GetNextDevice(BDiskDevice *device)
{
if (!device)
return B_BAD_VALUE;
size_t neededSize = 0;
partition_id id = _kern_get_next_disk_device_id(&fDeviceCookie,
&neededSize);
if (id < 0)
return id;
return device->_SetTo(id, true, false, neededSize);
}
// RewindDevices
/*! \brief Rewinds the device list iterator.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
BDiskDeviceRoster::RewindDevices()
{
fDeviceCookie = 0;
return B_OK;
}
// GetNextDiskSystem
status_t
BDiskDeviceRoster::GetNextDiskSystem(BDiskSystem *system)
{
if (!system)
return B_BAD_VALUE;
user_disk_system_info info;
status_t error = _kern_get_next_disk_system_info(&fDiskSystemCookie,
&info);
if (error == B_OK)
error = system->_SetTo(&info);
return error;
}
// RewindDiskSystems
status_t
BDiskDeviceRoster::RewindDiskSystems()
{
fDiskSystemCookie = 0;
return B_OK;
}
// GetNextActiveJob
status_t
BDiskDeviceRoster::GetNextActiveJob(BDiskDeviceJob *job)
{
if (!job)
return B_BAD_VALUE;
user_disk_device_job_info info;
status_t error = _kern_get_next_disk_device_job_info(&fJobCookie, &info);
if (error == B_OK)
error = job->_SetTo(&info);
return error;
}
// RewindActiveJobs
status_t
BDiskDeviceRoster::RewindActiveJobs()
{
fJobCookie = 0;
return B_OK;
}
// RegisterFileDevice
partition_id
BDiskDeviceRoster::RegisterFileDevice(const char *filename)
{
if (!filename)
return B_BAD_VALUE;
return _kern_register_file_device(filename);
}
// UnregisterFileDevice
status_t
BDiskDeviceRoster::UnregisterFileDevice(const char *filename)
{
if (!filename)
return B_BAD_VALUE;
return _kern_unregister_file_device(-1, filename);
}
// UnregisterFileDevice
status_t
BDiskDeviceRoster::UnregisterFileDevice(partition_id device)
{
if (device < 0)
return B_BAD_VALUE;
return _kern_unregister_file_device(device, NULL);
}
// VisitEachDevice
/*! \brief Iterates through the all devices.
The supplied visitor's Visit(BDiskDevice*) is invoked for each device.
If Visit() returns \c true, the iteration is terminated and this method
returns \c true. If supplied, \a device is set to the concerned device.
\param visitor The visitor.
\param device Pointer to a pre-allocated BDiskDevice to be initialized
to the device at which the iteration was terminated.
May be \c NULL.
\return \c true, if the iteration was terminated, \c false otherwise.
*/
bool
BDiskDeviceRoster::VisitEachDevice(BDiskDeviceVisitor *visitor,
BDiskDevice *device)
{
bool terminatedEarly = false;
if (visitor) {
int32 oldCookie = fDeviceCookie;
fDeviceCookie = 0;
BDiskDevice deviceOnStack;
BDiskDevice *useDevice = (device ? device : &deviceOnStack);
while (!terminatedEarly && GetNextDevice(useDevice) == B_OK)
terminatedEarly = visitor->Visit(useDevice);
fDeviceCookie = oldCookie;
if (!terminatedEarly)
useDevice->Unset();
}
return terminatedEarly;
}
// VisitEachPartition
/*! \brief Pre-order traverses the trees spanned by the BDiskDevices and their
subobjects.
The supplied visitor's Visit(BDiskDevice*) method is invoked for each
disk device and Visit(BPartition*) for each (non-disk device) partition.
If Visit() returns \c true, the iteration is terminated and this method
returns \c true. If supplied, \a device is set to the concerned device
and in \a partition the pointer to the partition object is returned.
\param visitor The visitor.
\param device Pointer to a pre-allocated BDiskDevice to be initialized
to the device at which the iteration was terminated.
May be \c NULL.
\param partition Pointer to a pre-allocated BPartition pointer to be set
to the partition at which the iteration was terminated.
May be \c NULL.
\return \c true, if the iteration was terminated, \c false otherwise.
*/
bool
BDiskDeviceRoster::VisitEachPartition(BDiskDeviceVisitor *visitor,
BDiskDevice *device,
BPartition **partition)
{
bool terminatedEarly = false;
if (visitor) {
int32 oldCookie = fDeviceCookie;
fDeviceCookie = 0;
BDiskDevice deviceOnStack;
BDiskDevice *useDevice = (device ? device : &deviceOnStack);
BPartition *foundPartition = NULL;
while (!foundPartition && GetNextDevice(useDevice) == B_OK)
foundPartition = useDevice->VisitEachDescendant(visitor);
fDeviceCookie = oldCookie;
if (!terminatedEarly)
useDevice->Unset();
else if (device && partition)
*partition = foundPartition;
}
return terminatedEarly;
}
// VisitEachMountedPartition
/*! \brief Iterates through the all devices' partitions that are mounted.
The supplied visitor's Visit(BPartition*) is invoked for each mounted
partition.
If Visit() returns \c true, the iteration is terminated and this method
returns \c true. If supplied, \a device is set to the concerned device
and in \a partition the pointer to the partition object is returned.
\param visitor The visitor.
\param device Pointer to a pre-allocated BDiskDevice to be initialized
to the device at which the iteration was terminated.
May be \c NULL.
\param partition Pointer to a pre-allocated BPartition pointer to be set
to the partition at which the iteration was terminated.
May be \c NULL.
\return \c true, if the iteration was terminated, \c false otherwise.
*/
bool
BDiskDeviceRoster::VisitEachMountedPartition(BDiskDeviceVisitor *visitor,
BDiskDevice *device,
BPartition **partition)
{
bool terminatedEarly = false;
if (visitor) {
struct MountedPartitionFilter : public PartitionFilter {
virtual bool Filter(BPartition *partition, int32)
{ return partition->IsMounted(); }
} filter;
PartitionFilterVisitor filterVisitor(visitor, &filter);
terminatedEarly
= VisitEachPartition(&filterVisitor, device, partition);
}
return terminatedEarly;
}
// VisitEachMountablePartition
/*! \brief Iterates through the all devices' partitions that are mountable.
The supplied visitor's Visit(BPartition*) is invoked for each mountable
partition.
If Visit() returns \c true, the iteration is terminated and this method
returns \c true. If supplied, \a device is set to the concerned device
and in \a partition the pointer to the partition object is returned.
\param visitor The visitor.
\param device Pointer to a pre-allocated BDiskDevice to be initialized
to the device at which the iteration was terminated.
May be \c NULL.
\param partition Pointer to a pre-allocated BPartition pointer to be set
to the partition at which the iteration was terminated.
May be \c NULL.
\return \c true, if the iteration was terminated, \c false otherwise.
*/
bool
BDiskDeviceRoster::VisitEachMountablePartition(BDiskDeviceVisitor *visitor,
BDiskDevice *device,
BPartition **partition)
{
bool terminatedEarly = false;
if (visitor) {
struct MountablePartitionFilter : public PartitionFilter {
virtual bool Filter(BPartition *partition, int32)
{ return partition->ContainsFileSystem(); }
} filter;
PartitionFilterVisitor filterVisitor(visitor, &filter);
terminatedEarly
= VisitEachPartition(&filterVisitor, device, partition);
}
return terminatedEarly;
}
// GetDeviceWithID
/*! \brief Returns a BDiskDevice for a given ID.
The supplied \a device is initialized to the device identified by \a id.
\param id The ID of the device to be retrieved.
\param device Pointer to a pre-allocated BDiskDevice to be initialized
to the device identified by \a id.
\return
- \c B_OK: Everything went fine.
- \c B_ENTRY_NOT_FOUND: A device with ID \a id could not be found.
- other error codes
*/
status_t
BDiskDeviceRoster::GetDeviceWithID(int32 id, BDiskDevice *device) const
{
if (!device)
return B_BAD_VALUE;
return device->_SetTo(id, true, false, 0);
}
// GetPartitionWithID
/*! \brief Returns a BPartition for a given ID.
The supplied \a device is initialized to the device the partition
identified by \a id resides on, and \a partition is set to point to the
respective BPartition.
\param id The ID of the partition to be retrieved.
\param device Pointer to a pre-allocated BDiskDevice to be initialized
to the device the partition identified by \a id resides on.
\param partition Pointer to a pre-allocated BPartition pointer to be set
to the partition identified by \a id.
\return
- \c B_OK: Everything went fine.
- \c B_ENTRY_NOT_FOUND: A partition with ID \a id could not be found.
- other error codes
*/
status_t
BDiskDeviceRoster::GetPartitionWithID(int32 id, BDiskDevice *device,
BPartition **partition) const
{
if (!device || !partition)
return B_BAD_VALUE;
// download the device data
status_t error = device->_SetTo(id, false, false, 0);
if (error != B_OK)
return error;
// find the partition object
*partition = device->FindDescendant(id);
if (!*partition) // should never happen!
return B_ENTRY_NOT_FOUND;
return B_OK;
}
// GetDeviceForPath
status_t
BDiskDeviceRoster::GetDeviceForPath(const char *filename, BDiskDevice *device)
{
if (!filename || !device)
return B_BAD_VALUE;
// get the device ID
size_t neededSize = 0;
partition_id id = _kern_find_disk_device(filename, &neededSize);
if (id < 0)
return id;
// download the device data
return device->_SetTo(id, true, false, neededSize);
}
// GetPartitionForPath
status_t
BDiskDeviceRoster::GetPartitionForPath(const char *filename,
BDiskDevice *device,
BPartition **partition)
{
if (!filename || !device || !partition)
return B_BAD_VALUE;
// get the partition ID
size_t neededSize = 0;
partition_id id = _kern_find_partition(filename, &neededSize);
if (id < 0)
return id;
// download the device data
status_t error = device->_SetTo(id, false, false, neededSize);
if (error != B_OK)
return error;
// find the partition object
*partition = device->FindDescendant(id);
if (!*partition) // should never happen!
return B_ENTRY_NOT_FOUND;
return B_OK;
}
// StartWatching
/*! \brief Adds a target to the list of targets to be notified on disk device
events.
\todo List the event mask flags, the events and describe the layout of the
notification message.
If \a target is already listening to events, this method replaces the
former event mask with \a eventMask.
\param target A BMessenger identifying the target to which the events
shall be sent.
\param eventMask A mask specifying on which events the target shall be
notified.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
BDiskDeviceRoster::StartWatching(BMessenger target, uint32 eventMask)
{
/* status_t error = B_OK;
// compose request message
BMessage request(B_REG_DEVICE_START_WATCHING);
if (error == B_OK)
error = request.AddMessenger("target", target);
if (error == B_OK)
error = request.AddInt32("events", (int32)eventMask);
// send request
BMessage reply;
if (error == B_OK)
error = fManager.SendMessage(&request, &reply);
// analyze reply
if (error == B_OK) {
// result
status_t result = B_OK;
error = reply.FindInt32("result", &result);
if (error == B_OK)
error = result;
}
return error;
*/
// not implemented
return B_ERROR;
}
// StartWatchingJob
status_t
BDiskDeviceRoster::StartWatchingJob(BDiskDeviceJob *job, BMessenger target,
uint32 eventMask)
{
// not implemented
return B_ERROR;
}
// StopWatching
/*! \brief Remove a target from the list of targets to be notified on disk
device events.
\param target A BMessenger identifying the target to which notfication
message shall not longer be sent.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
BDiskDeviceRoster::StopWatching(BMessenger target)
{
/* status_t error = B_OK;
// compose request message
BMessage request(B_REG_DEVICE_STOP_WATCHING);
if (error == B_OK)
error = request.AddMessenger("target", target);
// send request
BMessage reply;
if (error == B_OK)
error = fManager.SendMessage(&request, &reply);
// analyze reply
if (error == B_OK) {
// result
status_t result = B_OK;
error = reply.FindInt32("result", &result);
if (error == B_OK)
error = result;
}
return error;
*/
// not implemented
return B_ERROR;
}
#if 0
// GetNextPartitioningSystem
/*! \brief Returns the next partitioning system capable of partitioning.
The returned \a shortName can be passed to BSession::Partition().
\param shortName Pointer to a pre-allocation char buffer, of size
\c B_FILE_NAME_LENGTH or larger into which the short name of the
partitioning system shall be written.
\param longName Pointer to a pre-allocation char buffer, of size
\c B_FILE_NAME_LENGTH or larger into which the long name of the
partitioning system shall be written. May be \c NULL.
\return
- \c B_OK: Everything went fine.
- \c B_BAD_VALUE: \c NULL \a shortName.
- \c B_ENTRY_NOT_FOUND: End of the list has been reached.
- other error codes
*/
status_t
BDiskDeviceRoster::GetNextPartitioningSystem(char *shortName, char *longName)
{
status_t error = (shortName ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
// search until an add-on has been found or the end of all directories
// has been reached
bool found = false;
do {
// get the next add-on in the current dir
AddOnImage image;
error = _GetNextAddOn(fPartitionAddOnDir, &image);
if (error == B_OK) {
// add-on loaded: get the function that creates an add-on
// object
BDiskScannerPartitionAddOn *(*create_add_on)();
if (get_image_symbol(image.ID(), "create_ds_partition_add_on",
B_SYMBOL_TYPE_TEXT,
(void**)&create_add_on) == B_OK) {
// create the add-on object and copy the requested data
if (BDiskScannerPartitionAddOn *addOn
= (*create_add_on)()) {
const char *addOnShortName = addOn->ShortName();
const char *addOnLongName = addOn->LongName();
if (addOnShortName && addOnLongName) {
strcpy(shortName, addOnShortName);
if (longName)
strcpy(longName, addOnLongName);
found = true;
}
delete addOn;
}
}
} else if (error == B_ENTRY_NOT_FOUND) {
// end of the current directory has been reached, try next dir
error = _GetNextAddOnDir(&fPartitionAddOnDir,
&fPartitionAddOnDirIndex,
"partition");
}
} while (error == B_OK && !found);
}
return error;
}
// GetNextFileSystem
/*! \brief Returns the next file system capable of initializing.
The returned \a shortName can be passed to BPartition::Initialize().
\param shortName Pointer to a pre-allocation char buffer, of size
\c B_FILE_NAME_LENGTH or larger into which the short name of the
file system shall be written.
\param longName Pointer to a pre-allocation char buffer, of size
\c B_FILE_NAME_LENGTH or larger into which the long name of the
file system shall be written. May be \c NULL.
\return
- \c B_OK: Everything went fine.
- \c B_BAD_VALUE: \c NULL \a shortName.
- \c B_ENTRY_NOT_FOUND: End of the list has been reached.
- other error codes
*/
status_t
BDiskDeviceRoster::GetNextFileSystem(char *shortName, char *longName)
{
status_t error = (shortName ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
// search until an add-on has been found or the end of all directories
// has been reached
bool found = false;
do {
// get the next add-on in the current dir
AddOnImage image;
error = _GetNextAddOn(fFSAddOnDir, &image);
if (error == B_OK) {
// add-on loaded: get the function that creates an add-on
// object
BDiskScannerFSAddOn *(*create_add_on)();
if (get_image_symbol(image.ID(), "create_ds_fs_add_on",
B_SYMBOL_TYPE_TEXT,
(void**)&create_add_on) == B_OK) {
// create the add-on object and copy the requested data
if (BDiskScannerFSAddOn *addOn = (*create_add_on)()) {
const char *addOnShortName = addOn->ShortName();
const char *addOnLongName = addOn->LongName();
if (addOnShortName && addOnLongName) {
strcpy(shortName, addOnShortName);
if (longName)
strcpy(longName, addOnLongName);
found = true;
}
delete addOn;
}
}
} else if (error == B_ENTRY_NOT_FOUND) {
// end of the current directory has been reached, try next dir
error = _GetNextAddOnDir(&fFSAddOnDir, &fFSAddOnDirIndex,
"fs");
}
} while (error == B_OK && !found);
}
return error;
}
// RewindPartitiningSystems
/*! \brief Rewinds the partitioning system list iterator.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
BDiskDeviceRoster::RewindPartitiningSystems()
{
if (fPartitionAddOnDir) {
delete fPartitionAddOnDir;
fPartitionAddOnDir = NULL;
}
fPartitionAddOnDirIndex = 0;
return B_OK;
}
// RewindFileSystems
/*! \brief Rewinds the file system list iterator.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
BDiskDeviceRoster::RewindFileSystems()
{
if (fFSAddOnDir) {
delete fFSAddOnDir;
fFSAddOnDir = NULL;
}
fFSAddOnDirIndex = 0;
return B_OK;
}
// _GetObjectWithID
/*! \brief Returns a BDiskDevice for a given device, session or partition ID.
The supplied \a device is initialized to the device the object identified
by \a id belongs to.
\param fieldName "device_id", "sesison_id" or "partition_id" according to
the type of object the device shall be retrieved for.
\param id The ID of the device, session or partition to be retrieved.
\param device Pointer to a pre-allocated BDiskDevice to be initialized
to the device to be retrieved.
\return
- \c B_OK: Everything went fine.
- \c B_ENTRY_NOT_FOUND: A device, session or partition respectively with
ID \a id could not be found.
- other error codes
*/
status_t
BDiskDeviceRoster::_GetObjectWithID(const char *fieldName, int32 id,
BDiskDevice *device) const
{
status_t error = (device ? B_OK : B_BAD_VALUE);
// compose request message
BMessage request(B_REG_GET_DISK_DEVICE);
if (error == B_OK)
error = request.AddInt32(fieldName, id);
// send request
BMessage reply;
if (error == B_OK)
error = fManager.SendMessage(&request, &reply);
// analyze reply
if (error == B_OK) {
// result
status_t result = B_OK;
error = reply.FindInt32("result", &result);
if (error == B_OK)
error = result;
// device
BMessage archive;
if (error == B_OK)
error = reply.FindMessage("device", &archive);
if (error == B_OK)
error = device->_Unarchive(&archive);
}
return error;
}
// _GetNextAddOn
/*! \brief Finds and loads the next add-on of an add-on subdirectory.
\param directory The add-on directory.
\param image Pointer to an image_id into which the image ID of the loaded
add-on shall be written.
\return
- \c B_OK: Everything went fine.
- \c B_ENTRY_NOT_FOUND: End of directory.
- other error codes
*/
status_t
BDiskDeviceRoster::_GetNextAddOn(BDirectory **directory, int32 *index,
const char *subdir, AddOnImage *image)
{
status_t error = (directory && index && subdir && image
? B_OK : B_BAD_VALUE);
if (error == B_OK) {
// search until an add-on has been found or the end of all directories
// has been reached
bool found = false;
do {
// get the next add-on in the current dir
error = _GetNextAddOn(*directory, image);
if (error == B_OK) {
found = true;
} else if (error == B_ENTRY_NOT_FOUND) {
// end of the current directory has been reached, try next dir
error = _GetNextAddOnDir(directory, index, subdir);
}
} while (error == B_OK && !found);
}
return error;
}
// _GetNextAddOn
/*! \brief Finds and loads the next add-on of an add-on subdirectory.
\param directory The add-on directory.
\param image Pointer to an image_id into which the image ID of the loaded
add-on shall be written.
\return
- \c B_OK: Everything went fine.
- \c B_ENTRY_NOT_FOUND: End of directory.
- other error codes
*/
status_t
BDiskDeviceRoster::_GetNextAddOn(BDirectory *directory, AddOnImage *image)
{
status_t error = (directory ? B_OK : B_ENTRY_NOT_FOUND);
if (error == B_OK) {
// iterate through the entry list and try to load the entries
bool found = false;
while (error == B_OK && !found) {
BEntry entry;
error = directory->GetNextEntry(&entry);
BPath path;
if (error == B_OK && entry.GetPath(&path) == B_OK)
found = (image->Load(path.Path()) == B_OK);
}
}
return error;
}
// _GetNextAddOnDir
/*! \brief Gets the next add-on directory path.
\param path Pointer to a BPath to be set to the found directory.
\param index Pointer to an index into the kAddOnDirs array indicating
which add-on dir shall be retrieved next.
\param subdir Name of the subdirectory (in the "disk_scanner" subdirectory
of the add-on directory) \a directory shall be set to.
\return
- \c B_OK: Everything went fine.
- \c B_ENTRY_NOT_FOUND: End of directory list.
- other error codes
*/
status_t
BDiskDeviceRoster::_GetNextAddOnDir(BPath *path, int32 *index,
const char *subdir)
{
status_t error = (*index < kAddOnDirCount ? B_OK : B_ENTRY_NOT_FOUND);
// get the add-on dir path
if (error == B_OK) {
error = find_directory(kAddOnDirs[*index], path);
(*index)++;
}
// construct the subdirectory path
if (error == B_OK) {
error = path->Append("disk_scanner");
if (error == B_OK)
error = path->Append(subdir);
}
if (error == B_OK)
printf(" next add-on dir: `%s'\n", path->Path());
return error;
}
// _GetNextAddOnDir
/*! \brief Gets the next add-on directory.
\param directory Pointer to a BDirectory* to be set to the found directory.
\param index Pointer to an index into the kAddOnDirs array indicating
which add-on dir shall be retrieved next.
\param subdir Name of the subdirectory (in the "disk_scanner" subdirectory
of the add-on directory) \a directory shall be set to.
\return
- \c B_OK: Everything went fine.
- \c B_ENTRY_NOT_FOUND: End of directory list.
- other error codes
*/
status_t
BDiskDeviceRoster::_GetNextAddOnDir(BDirectory **directory, int32 *index,
const char *subdir)
{
BPath path;
status_t error = _GetNextAddOnDir(&path, index, subdir);
// create a BDirectory object, if there is none yet.
if (error == B_OK && !*directory) {
*directory = new BDirectory;
if (!*directory)
error = B_NO_MEMORY;
}
// init the directory
if (error == B_OK)
error = (*directory)->SetTo(path.Path());
// cleanup on error
if (error != B_OK && *directory) {
delete *directory;
*directory = NULL;
}
return error;
}
// _LoadPartitionAddOn
status_t
BDiskDeviceRoster::_LoadPartitionAddOn(const char *partitioningSystem,
AddOnImage *image,
BDiskScannerPartitionAddOn **_addOn)
{
status_t error = (partitioningSystem && image && _addOn
? B_OK : B_BAD_VALUE);
// load the image
bool found = false;
BPath path;
BDirectory *directory = NULL;
int32 index = 0;
while (error == B_OK && !found) {
error = _GetNextAddOn(&directory, &index, "partition", image);
if (error == B_OK) {
// add-on loaded: get the function that creates an add-on
// object
BDiskScannerPartitionAddOn *(*create_add_on)();
if (get_image_symbol(image->ID(), "create_ds_partition_add_on",
B_SYMBOL_TYPE_TEXT,
(void**)&create_add_on) == B_OK) {
// create the add-on object and copy the requested data
if (BDiskScannerPartitionAddOn *addOn = (*create_add_on)()) {
if (!strcmp(addOn->ShortName(), partitioningSystem)) {
*_addOn = addOn;
found = true;
} else
delete addOn;
}
}
}
}
// cleanup
if (directory)
delete directory;
if (error != B_OK && image)
image->Unload();
return error;
}
#endif // 0

View File

@ -1,41 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the Haiku distribution and is covered
// by the MIT license.
//---------------------------------------------------------------------
#include <DiskDeviceTypes.h>
// Device Types
const char *kDeviceTypeFloppyDisk = "Floppy Disk Media";
const char *kDeviceTypeHardDisk = "Hard Disk Media";
const char *kDeviceTypeOptical = "Optical Media";
// Partition types
const char *kPartitionTypeUnrecognized = "Unrecognized";
const char *kPartitionTypeMultisession = "Multisession Storage Device";
const char *kPartitionTypeAudioSession = "Audio Session";
const char *kPartitionTypeDataSession = "Data Session";
const char *kPartitionTypeAmiga = "Amiga Partition Map";
const char *kPartitionTypeApple = "Apple Partition Map";
const char *kPartitionTypeIntel = "Intel Partition Map";
const char *kPartitionTypeIntelPrimary = "Intel Primary Partition";
const char *kPartitionTypeIntelExtended = "Intel Extended Partition";
const char *kPartitionTypeIntelLogical = "Intel Logical Partition";
const char *kPartitionTypeAmigaFFS = "AmigaFFS Filesystem";
const char *kPartitionTypeBFS = "BFS Filesystem";
const char *kPartitionTypeEXT2 = "EXT2 Filesystem";
const char *kPartitionTypeEXT3 = "EXT3 Filesystem";
const char *kPartitionTypeFAT12 = "FAT12 Filesystem";
const char *kPartitionTypeFAT32 = "FAT32 Filesystem";
const char *kPartitionTypeHFS = "HFS Filesystem";
const char *kPartitionTypeHFSPlus = "HFS+ Filesystem";
const char *kPartitionTypeISO9660 = "ISO9660 Filesystem";
const char *kPartitionTypeReiser = "Reiser Filesystem";
const char *kPartitionTypeUDF = "UDF Filesystem";

View File

@ -1,74 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <DiskDeviceVisitor.h>
/*! \class BDiskDeviceVisitor
\brief Base class of visitors used for BDiskDevice and
BPartition iteration.
BDiskDeviceRoster and BDiskDevice provide iteration methods,
that work together with an instance of a derived class of
BDiskDeviceVisitor. For each encountered BDiskDevice and
BPartition the respective Visit() method is invoked. The return value
of that method specifies whether the iteration shall be terminated at
that point.
*/
// constructor
/*! \brief Creates a new disk device visitor.
*/
BDiskDeviceVisitor::BDiskDeviceVisitor()
{
}
// destructor
/*! \brief Free all resources associated with this object.
Does nothing.
*/
BDiskDeviceVisitor::~BDiskDeviceVisitor()
{
}
// Visit
/*! \brief Invoked when a BDiskDevice is visited.
If the method returns \c true, the iteration is terminated at this point,
on \c false continued.
Overridden by derived classes.
This class' version does nothing and it returns \c false.
\param device The visited disk device.
\return \c true, if the iteration shall be terminated at this point,
\c false otherwise.
*/
bool
BDiskDeviceVisitor::Visit(BDiskDevice *device)
{
return false;
}
// Visit
/*! \brief Invoked when a BPartition is visited.
If the method returns \c true, the iteration is terminated at this point,
on \c false continued.
Overridden by derived classes.
This class' version does nothing and it returns \c false.
\param partition The visited partition.
\param level The level of the partition in the partition tree.
\return \c true, if the iteration shall be terminated at this point,
\c false otherwise.
*/
bool
BDiskDeviceVisitor::Visit(BPartition *partition, int32 level)
{
return false;
}

View File

@ -1,212 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <DiskScannerAddOn.h>
#include <String.h>
// BDiskScannerPartitionAddOn
// constructor
/*! \brief Creates a partition disk scanner add-on.
*/
BDiskScannerPartitionAddOn::BDiskScannerPartitionAddOn()
{
}
// destructor
/*! \brief Frees all resources associated with this object.
*/
BDiskScannerPartitionAddOn::~BDiskScannerPartitionAddOn()
{
}
/*! \fn virtual const char *BDiskScannerPartitionAddOn::ShortName() = 0;
\brief Returns a short name for the add-on.
To be implemented by derived classes.
The returned string identifies the respective partition kernel module is
passed to partition_session().
\return A short name for the add-on.
*/
/*! \fn virtual const char *BDiskScannerPartitionAddOn::LongName() = 0;
\brief Returns a user-readable long name for the add-on.
To be implemented by derived classes.
\return A long name for the add-on.
*/
/*! \fn virtual BDiskScannerPartitionAddOn::BDiskScannerParameterEditor *
CreateEditor(const BSession *session, const char *parameters) = 0;
\brief Creates and returns an editor for editing partitioning parameters
for a specified session.
To be implemented by derived classes.
\param session The session to be partitioned.
\param parameters Parameters retrieved from the partition module. Should
initially be presented to the user.
\return The newly created editor. \c NULL, if an error occurred.
*/
// FBC
void BDiskScannerPartitionAddOn::_ReservedDiskScannerPartitionAddOn1() {}
void BDiskScannerPartitionAddOn::_ReservedDiskScannerPartitionAddOn2() {}
void BDiskScannerPartitionAddOn::_ReservedDiskScannerPartitionAddOn3() {}
void BDiskScannerPartitionAddOn::_ReservedDiskScannerPartitionAddOn4() {}
void BDiskScannerPartitionAddOn::_ReservedDiskScannerPartitionAddOn5() {}
// BDiskScannerFSAddOn
// constructor
/*! \brief Creates a FS disk scanner add-on.
*/
BDiskScannerFSAddOn::BDiskScannerFSAddOn()
{
}
// destructor
/*! \brief Frees all resources associated with this object.
*/
BDiskScannerFSAddOn::~BDiskScannerFSAddOn()
{
}
/*! \fn virtual const char *BDiskScannerFSAddOn::ShortName() = 0;
\brief Returns a short name for the add-on.
To be implemented by derived classes.
The returned name identifies the file system (the kernel add-on) and is
passed to initialize_volume().
\return A short name for the add-on.
*/
/*! \fn virtual const char *BDiskScannerFSAddOn::LongName() = 0;
\brief Returns a user-readable long name for the add-on.
To be implemented by derived classes.
\return A long name for the add-on.
*/
/*! \fn virtual BDiskScannerFSAddOn::BDiskScannerParameterEditor *CreateEditor(
const BPartition *partition, const char *parameters) = 0;
\brief Creates and returns an editor for editing initialization parameters
for a specified partition.
To be implemented by derived classes.
\param partition The partition to be initialized.
\param parameters Parameters retrieved from the kernel FS add-on. Should
initially be presented to the user.
\return The newly created editor. \c NULL, if the FS doesn't need any
further parameters.
*/
// FBC
void BDiskScannerFSAddOn::_ReservedDiskScannerFSAddOn1() {}
void BDiskScannerFSAddOn::_ReservedDiskScannerFSAddOn2() {}
void BDiskScannerFSAddOn::_ReservedDiskScannerFSAddOn3() {}
void BDiskScannerFSAddOn::_ReservedDiskScannerFSAddOn4() {}
void BDiskScannerFSAddOn::_ReservedDiskScannerFSAddOn5() {}
// BDiskScannerParameterEditor
// constructor
/*! \brief Creates a disk scanner parameter editor.
*/
BDiskScannerParameterEditor::BDiskScannerParameterEditor()
{
}
// destructor
/*! \brief Frees all resources associated with this object.
*/
BDiskScannerParameterEditor::~BDiskScannerParameterEditor()
{
}
/*! \brief Returns a view containing the controls needed for editing the
parameters.
To be overridden by derived classes.
The base class version returns \c NULL.
The returned BView is added to a window occasionally and removed, when
editing is done. The view belongs to the editor and needs to be deleted
by it. Subsequent calls to this method may return the same view, or each
time delete the old one and return a new one.
\return A view containing the controls needed for editing the parameters.
\c NULL can be returned, if no parameters are needed.
*/
BView *
BDiskScannerParameterEditor::View()
{
return NULL;
}
// EditingDone
/*! \brief Called when the user finishes editing the parameters.
To be overridden by derived classes.
The base class version returns \c true.
The method is supposed to check whether the parameters the user set,
are valid, and, if so, return \c true. Otherwise an BAlert shall be
shown, explaining the problem to the user and \c false being returned
-- then the parameter dialog will not be closed.
\return \c true, if the current parameters are valid, \c false otherwise.
*/
bool
BDiskScannerParameterEditor::EditingDone()
{
return true;
}
/*! \brief Returns the edited parameters.
To be overridden by derived classes.
The base class version returns an empty string.
\param parameters A BString to be set to the edited parameters.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
BDiskScannerParameterEditor::GetParameters(BString *parameters)
{
status_t error = (parameters ? B_OK : B_BAD_VALUE);
if (error == B_OK)
parameters->SetTo("");
return error;
}
// FBC
void BDiskScannerParameterEditor::_ReservedDiskScannerParameterEditor1() {}
void BDiskScannerParameterEditor::_ReservedDiskScannerParameterEditor2() {}
void BDiskScannerParameterEditor::_ReservedDiskScannerParameterEditor3() {}
void BDiskScannerParameterEditor::_ReservedDiskScannerParameterEditor4() {}
void BDiskScannerParameterEditor::_ReservedDiskScannerParameterEditor5() {}
/*! \fn BDiskScannerPartitionAddOn *create_ds_partition_add_on();
\brief To be provided by partition add-ons to create an add-on object.
\return A newly created BDiskScannerPartitionAddOn for this add-on.
*/
/*! \fn BDiskScannerFSAddOn *create_ds_fs_add_on();
\brief To be provided by FS add-ons to create an add-on object.
\return A newly created BDiskScannerFSAddOn for this add-on.
*/

View File

@ -1,306 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <syscalls.h>
#include <DiskSystem.h>
#include <Partition.h>
// constructor
BDiskSystem::BDiskSystem()
: fID(B_NO_INIT),
fName(),
fPrettyName(),
fFlags(0)
{
}
// destructor
BDiskSystem::~BDiskSystem()
{
}
// InitCheck
status_t
BDiskSystem::InitCheck() const
{
return (fID > 0 ? B_OK : fID);
}
// Name
const char *
BDiskSystem::Name() const
{
return fName.String();
}
// PrettyName
const char *
BDiskSystem::PrettyName() const
{
return fPrettyName.String();
}
// SupportsDefragmenting
bool
BDiskSystem::SupportsDefragmenting(bool *whileMounted) const
{
if (InitCheck() != B_OK
|| !(fFlags & B_DISK_SYSTEM_SUPPORTS_DEFRAGMENTING)) {
if (whileMounted)
*whileMounted = false;
return false;
}
if (whileMounted) {
*whileMounted = (IsFileSystem()
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_DEFRAGMENTING_WHILE_MOUNTED));
}
return true;
}
// SupportsRepairing
bool
BDiskSystem::SupportsRepairing(bool checkOnly, bool *whileMounted) const
{
uint32 mainBit = B_DISK_SYSTEM_SUPPORTS_REPAIRING;
uint32 mountedBit = B_DISK_SYSTEM_SUPPORTS_REPAIRING_WHILE_MOUNTED;
if (checkOnly) {
mainBit = B_DISK_SYSTEM_SUPPORTS_CHECKING;
mountedBit = B_DISK_SYSTEM_SUPPORTS_CHECKING_WHILE_MOUNTED;
}
if (InitCheck() != B_OK || !(fFlags & mainBit)) {
if (whileMounted)
*whileMounted = false;
return false;
}
if (whileMounted)
*whileMounted = (IsFileSystem() && (fFlags & mountedBit));
return true;
}
// SupportsResizing
bool
BDiskSystem::SupportsResizing(bool *whileMounted) const
{
if (InitCheck() != B_OK
|| !(fFlags & B_DISK_SYSTEM_SUPPORTS_RESIZING)) {
if (whileMounted)
*whileMounted = false;
return false;
}
if (whileMounted) {
*whileMounted = (IsFileSystem()
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_RESIZING_WHILE_MOUNTED));
}
return true;
}
// SupportsResizingChild
bool
BDiskSystem::SupportsResizingChild() const
{
return (InitCheck() == B_OK && IsPartitioningSystem()
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD));
}
// SupportsMoving
bool
BDiskSystem::SupportsMoving(bool *whileMounted) const
{
if (InitCheck() != B_OK
|| !(fFlags & B_DISK_SYSTEM_SUPPORTS_MOVING)) {
if (whileMounted)
*whileMounted = false;
return false;
}
if (whileMounted) {
*whileMounted = (IsFileSystem()
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_MOVING_WHILE_MOUNTED));
}
return true;
}
// SupportsMovingChild
bool
BDiskSystem::SupportsMovingChild() const
{
return (InitCheck() == B_OK && IsPartitioningSystem()
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD));
}
// SupportsSettingName
bool
BDiskSystem::SupportsSettingName() const
{
return (InitCheck() == B_OK && IsPartitioningSystem()
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_SETTING_NAME));
}
// SupportsSettingContentName
bool
BDiskSystem::SupportsSettingContentName(bool *whileMounted) const
{
if (InitCheck() != B_OK
|| !(fFlags & B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_NAME)) {
if (whileMounted)
*whileMounted = false;
return false;
}
if (whileMounted) {
*whileMounted = (IsFileSystem()
&& (fFlags
& B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_NAME_WHILE_MOUNTED));
}
return true;
}
// SupportsSettingType
bool
BDiskSystem::SupportsSettingType() const
{
return (InitCheck() == B_OK && IsPartitioningSystem()
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE));
}
// SupportsSettingParameters
bool
BDiskSystem::SupportsSettingParameters() const
{
return (InitCheck() == B_OK && IsPartitioningSystem()
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_SETTING_PARAMETERS));
}
// SupportsSettingContentParameters
bool
BDiskSystem::SupportsSettingContentParameters(bool *whileMounted) const
{
if (InitCheck() != B_OK
|| !(fFlags & B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS)) {
if (whileMounted)
*whileMounted = false;
return false;
}
if (whileMounted) {
*whileMounted = (IsFileSystem()
&& (fFlags
& B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS_WHILE_MOUNTED));
}
return true;
}
// SupportsCreatingChild
bool
BDiskSystem::SupportsCreatingChild() const
{
return (InitCheck() == B_OK && IsPartitioningSystem()
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD));
}
// SupportsDeletingChild
bool
BDiskSystem::SupportsDeletingChild() const
{
return (InitCheck() == B_OK && IsPartitioningSystem()
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD));
}
// SupportsInitializing
bool
BDiskSystem::SupportsInitializing() const
{
return (InitCheck() == B_OK
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_INITIALIZING));
}
// GetNextSupportedType
status_t
BDiskSystem::GetNextSupportedType(BPartition *partition, int32 *cookie,
char *type) const
{
if (InitCheck() != B_OK)
return InitCheck();
if (!cookie || !type || !partition || !partition->_IsShadow()
|| !partition->Parent() || partition->Parent()->_DiskSystem() != fID
|| !IsPartitioningSystem()) {
return B_BAD_VALUE;
}
return _kern_get_next_supported_partition_type(partition->_ShadowID(),
partition->_ChangeCounter(),
cookie, type);
}
// GetTypeForContentType
status_t
BDiskSystem::GetTypeForContentType(const char *contentType, char *type) const
{
if (InitCheck() != B_OK)
return InitCheck();
if (!contentType || !type || !IsPartitioningSystem())
return B_BAD_VALUE;
return _kern_get_partition_type_for_content_type(fID, contentType, type);
}
// IsPartitioningSystem
bool
BDiskSystem::IsPartitioningSystem() const
{
return (InitCheck() == B_OK && !(fFlags & B_DISK_SYSTEM_IS_FILE_SYSTEM));
}
// IsFileSystem
bool
BDiskSystem::IsFileSystem() const
{
return (InitCheck() == B_OK && (fFlags & B_DISK_SYSTEM_IS_FILE_SYSTEM));
}
// IsSubSystemFor
bool
BDiskSystem::IsSubSystemFor(BPartition *parent) const
{
return (InitCheck() == B_OK
&& parent && parent->_IsShadow()
&& _kern_is_sub_disk_system_for(fID, parent->_ShadowID(),
parent->_ChangeCounter()));
}
// _SetTo
status_t
BDiskSystem::_SetTo(disk_system_id id)
{
_Unset();
if (id < 0)
return fID;
user_disk_system_info info;
status_t error = _kern_get_disk_system_info(id, &info);
if (error != B_OK)
return (fID = error);
return _SetTo(&info);
}
// _SetTo
status_t
BDiskSystem::_SetTo(user_disk_system_info *info)
{
_Unset();
if (!info)
return (fID = B_BAD_VALUE);
fID = info->id;
fName = info->name;
fPrettyName = info->pretty_name;
fFlags = info->flags;
return B_OK;
}
// _Unset
void
BDiskSystem::_Unset()
{
fID = B_NO_INIT;
fName = (const char*)NULL;
fPrettyName = (const char*)NULL;
fFlags = 0;
}

View File

@ -1,722 +0,0 @@
// LibBeAdapter.cpp
#include <dirent.h>
#include <errno.h>
#include <new>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <Directory.h>
#include <Entry.h>
#include <fs_attr.h>
#include <fs_query.h>
#include <Path.h>
#include <syscalls.h>
mode_t __gUmask = 022;
// this is the standard umask and is used by BFile
enum {
FD_TYPE_UNKNOWN,
FD_TYPE_DIR,
FD_TYPE_ATTR_DIR,
FD_TYPE_QUERY,
};
static const int kFDTableSlotCount = 1024;
static uint8 sFDTable[kFDTableSlotCount];
static struct InitDirFDTable {
InitDirFDTable()
{
memset(sFDTable, FD_TYPE_UNKNOWN, sizeof(sFDTable));
}
} sInitDirFDTable;
// _kern_entry_ref_to_path
extern "C"
status_t
_kern_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
char *userPath, size_t pathLength)
{
// check buffer
if (!userPath)
return B_BAD_VALUE;
// construct an entry_ref
if (!leaf)
leaf = ".";
entry_ref ref(device, inode, leaf);
// get the path
BPath path;
status_t error = path.SetTo(&ref);
if (error != B_OK)
return error;
// copy the path into the buffer
if (strlcpy(userPath, path.Path(), pathLength) >= pathLength)
return B_BUFFER_OVERFLOW;
return B_OK;
}
// Syscall mapping between R5 and us
// private libroot.so functions
extern "C" status_t _kclosedir_(int fd);
extern "C" status_t _kclose_attr_dir_(int fd);
extern "C" status_t _kclose_query_(int fd);
extern "C" ssize_t _kreadlink_(int fd, const char *path, char *buffer,
size_t bufferSize);
extern "C" status_t _krstat_(int fd, const char *path, struct stat *st,
int16 unknown);
extern "C" status_t _kwstat_(int fd, const char *path, const struct stat *st,
uint32 mask, uint16 unknown);
extern "C" status_t _kwfsstat_(dev_t device, const struct fs_info *info,
long mask);
extern "C" status_t _klock_node_(int fd);
extern "C" status_t _kunlock_node_(int fd);
extern "C" status_t _kstart_watching_vnode_(dev_t device, ino_t node,
uint32 flags, port_id port,
int32 handlerToken);
extern "C" status_t _kstop_watching_vnode_(dev_t device, ino_t node,
port_id port, int32 handlerToken);
extern "C" status_t _kstop_notifying_(port_id port, int32 handlerToken);
extern "C" status_t _kget_safemode_option_(const char *parameter, char *buffer, size_t *_bufferSize);
status_t
_kern_write_fs_info(dev_t device, const struct fs_info *info, int mask)
{
return _kwfsstat_(device, info, mask);
}
status_t
_kern_stop_notifying(port_id port, uint32 token)
{
return _kstop_notifying_(port, token);
}
status_t
_kern_start_watching(dev_t device, ino_t node, uint32 flags,
port_id port, uint32 token)
{
return _kstart_watching_vnode_(device, node, flags, port, token);
}
status_t
_kern_stop_watching(dev_t device, ino_t node, uint32 flags,
port_id port, uint32 token)
{
(void)flags;
return _kstop_watching_vnode_(device, node, port, token);
}
// init_dir
static
status_t
init_dir(BDirectory &dir, int fd)
{
// get a node_ref for the dir
struct stat st;
if (fstat(fd, &st) < 0)
return errno;
node_ref ref;
ref.device = st.st_dev;
ref.node = st.st_ino;
// init the dir
return dir.SetTo(&ref);
}
// open_dir_hack
static
int
open_dir_hack(const char *path)
{
DIR *dirHandle = opendir(path);
if (!dirHandle)
return errno;
int dirFD = dirHandle->fd;
if (dirFD < 0 || dirFD >= kFDTableSlotCount) {
closedir(dirHandle);
return B_ERROR;
}
free(dirHandle);
sFDTable[dirFD] = FD_TYPE_DIR;
return dirFD;
}
// get_path
static
int
get_path(int fd, const char *relPath, BPath &path)
{
if (fd < 0 || relPath && relPath[0] == '/')
return path.SetTo(relPath);
BDirectory dir;
status_t error = init_dir(dir, fd);
if (error != B_OK)
return error;
return path.SetTo(&dir, relPath);
}
// _kern_open
extern "C"
int
_kern_open(int fd, const char *path, int omode, int permissions)
{
status_t error;
BPath fullPath;
if (!path)
path = ".";
if (fd >= 0) {
// construct the full path
error = get_path(fd, path, fullPath);
if (error != B_OK)
return error;
path = fullPath.Path();
}
// open the file
int result = open(path, omode, permissions);
if (result < 0)
return errno;
return result;
}
// _kern_open_entry_ref
extern "C"
int
_kern_open_entry_ref(dev_t device, ino_t inode, const char *name, int omode,
int permissions)
{
BPath fullPath;
node_ref ref;
ref.device = device;
ref.node = inode;
// init the dir and get the path
BDirectory dir;
status_t error = dir.SetTo(&ref);
if (error != B_OK)
return error;
error = fullPath.SetTo(&dir, name);
if (error != B_OK)
return error;
// open the file
int fd = open(fullPath.Path(), omode, permissions);
if (fd < 0)
return errno;
return fd;
}
// _kern_open_dir
extern "C"
int
_kern_open_dir(int fd, const char *path)
{
status_t error;
BPath fullPath;
if (fd >= 0) {
if (!path)
return _kern_dup(fd);
// construct the full path
error = get_path(fd, path, fullPath);
if (error != B_OK)
return error;
path = fullPath.Path();
}
// open the dir
return open_dir_hack(path);
}
// _kern_open_dir_entry_ref
extern "C"
int
_kern_open_dir_entry_ref(dev_t device, ino_t inode, const char *path)
{
BPath fullPath;
node_ref ref;
ref.device = device;
ref.node = inode;
// init the dir and get the path
BDirectory dir;
status_t error = dir.SetTo(&ref);
if (error != B_OK)
return error;
error = fullPath.SetTo(&dir, path);
if (error != B_OK)
return error;
path = fullPath.Path();
// open the dir
return open_dir_hack(path);
}
// _kern_open_parent_dir
extern "C"
int
_kern_open_parent_dir(int fd, char *name, size_t pathLength)
{
if (fd < 0)
return B_BAD_VALUE;
// get the dir
BDirectory dir;
status_t error = init_dir(dir, fd);
if (error != B_OK)
return error;
// get an entry
BEntry entry;
error = entry.SetTo(&dir, NULL);
if (error != B_OK)
return error;
// copy back the path
if (name) {
char tmpName[B_FILE_NAME_LENGTH];
error = entry.GetName(tmpName);
if (error != B_OK)
return error;
if (strlcpy(name, tmpName, pathLength) >= pathLength)
return B_BUFFER_OVERFLOW;
}
// get the parent dir path
BPath path;
error = path.SetTo(&dir, "..");
if (error != B_OK)
return error;
// open the dir
return open_dir_hack(path.Path());
}
// _kern_open_query
extern "C"
int
_kern_open_query(dev_t device, const char *query, size_t queryLength, uint32 flags, port_id port,
int32 token)
{
// check params
if (!query || queryLength == 0 || device < 0)
return B_BAD_VALUE;
if (flags & B_LIVE_QUERY && port < 0)
return B_BAD_VALUE;
// open query
DIR *dirHandle;
if (flags & B_LIVE_QUERY)
dirHandle = fs_open_live_query(device, query, flags, port, token);
else
dirHandle = fs_open_query(device, query, flags);
if (!dirHandle)
return errno;
// get FD and return result
int dirFD = dirHandle->fd;
if (dirFD < 0 || dirFD >= kFDTableSlotCount) {
fs_close_query(dirHandle);
return B_ERROR;
}
free(dirHandle);
sFDTable[dirFD] = FD_TYPE_QUERY;
return dirFD;
}
// _kern_create_dir
extern "C"
status_t
_kern_create_dir(int fd, const char *path, int perms)
{
if (!path)
return B_BAD_VALUE;
status_t error;
BPath fullPath;
if (fd >= 0) {
// construct the full path
error = get_path(fd, path, fullPath);
if (error != B_OK)
return error;
path = fullPath.Path();
}
// create the dir
return (mkdir(path, perms) < 0 ? errno : B_OK);
}
// _kern_create_symlink
extern "C"
status_t
_kern_create_symlink(int fd, const char *path, const char *toPath, int mode)
{
(void)mode;
if (!path)
return B_BAD_VALUE;
status_t error;
BPath fullPath;
if (fd >= 0) {
// construct the full path
error = get_path(fd, path, fullPath);
if (error != B_OK)
return error;
path = fullPath.Path();
}
// create the symlink
return (symlink(toPath, path) < 0 ? errno : B_OK);
}
// _kern_close
extern "C"
status_t
_kern_close(int fd)
{
if (fd >= 0 && fd < kFDTableSlotCount && sFDTable[fd] != FD_TYPE_UNKNOWN) {
status_t error;
switch (sFDTable[fd]) {
case FD_TYPE_DIR:
error = _kclosedir_(fd);
break;
case FD_TYPE_ATTR_DIR:
error = _kclose_attr_dir_(fd);
break;
case FD_TYPE_QUERY:
error = _kclose_query_(fd);
break;
default:
error = B_BAD_VALUE;
break;
}
sFDTable[fd] = FD_TYPE_UNKNOWN;
if (error != B_OK)
return error;
} else if (close(fd) < 0)
return errno;
return B_OK;
}
// _kern_dup
extern "C"
int
_kern_dup(int fd)
{
int clonedFD = dup(fd);
if (clonedFD < 0)
return errno;
if (fd >= 0 && fd < kFDTableSlotCount && sFDTable[fd] != FD_TYPE_UNKNOWN
&& clonedFD >= 0 && clonedFD < kFDTableSlotCount) {
sFDTable[clonedFD] = sFDTable[fd];
}
return clonedFD;
}
// _kern_read
extern "C"
ssize_t
_kern_read(int fd, off_t pos, void *buffer, size_t bufferSize)
{
if (!buffer)
return B_BAD_VALUE;
ssize_t result;
if (pos == -1)
result = read(fd, buffer, bufferSize);
else
result = read_pos(fd, pos, buffer, bufferSize);
return (result < 0 ? errno : result);
}
// _kern_write
extern "C"
ssize_t
_kern_write(int fd, off_t pos, const void *buffer, size_t bufferSize)
{
if (!buffer)
return B_BAD_VALUE;
ssize_t result;
if (pos == -1)
result = write(fd, buffer, bufferSize);
else
result = write_pos(fd, pos, buffer, bufferSize);
return (result < 0 ? errno : result);
}
// _kern_seek
extern "C"
off_t
_kern_seek(int fd, off_t pos, int seekType)
{
off_t result = lseek(fd, pos, seekType);
return (result < 0 ? errno : result);
}
// _kern_read_dir
extern "C"
ssize_t
_kern_read_dir(int fd, struct dirent *buffer, size_t bufferSize,
uint32 maxCount)
{
if (fd < 0 || !buffer)
return B_BAD_VALUE;
if (fd >= kFDTableSlotCount || sFDTable[fd] == FD_TYPE_UNKNOWN)
return B_BAD_VALUE;
if (maxCount < 1)
return 0;
char tmpBuffer[sizeof(struct dirent) + B_FILE_NAME_LENGTH];
DIR *dirDir = (DIR*)tmpBuffer;
dirDir->fd = fd;
dirent *entry = NULL;
switch (sFDTable[fd]) {
case FD_TYPE_DIR:
entry = readdir(dirDir);
break;
case FD_TYPE_ATTR_DIR:
entry = fs_read_attr_dir(dirDir);
break;
case FD_TYPE_QUERY:
entry = fs_read_query(dirDir);
break;
}
if (!entry)
return 0;
// Don't trust entry->d_reclen.
// Unlike stated in BeBook::BEntryList, the value is not the length
// of the whole structure, but only of the name. Some FSs count
// the terminating '\0', others don't.
// So we calculate the size ourselves (including the '\0'):
size_t entryLen = entry->d_name + strlen(entry->d_name) + 1
- (char*)entry;
if (bufferSize >= entryLen) {
memcpy(buffer, entry, entryLen);
return 1;
} else // buffer too small
return B_BUFFER_OVERFLOW;
}
// _kern_rewind_dir
extern "C"
status_t
_kern_rewind_dir(int fd)
{
if (fd < 0 || fd >= kFDTableSlotCount || sFDTable[fd] == FD_TYPE_UNKNOWN)
return B_BAD_VALUE;
char tmpBuffer[sizeof(struct dirent) + B_FILE_NAME_LENGTH];
DIR *dirDir = (DIR*)tmpBuffer;
dirDir->fd = fd;
switch (sFDTable[fd]) {
case FD_TYPE_DIR:
rewinddir(dirDir);
break;
case FD_TYPE_ATTR_DIR:
fs_rewind_attr_dir(dirDir);
break;
case FD_TYPE_QUERY:
return B_BAD_VALUE;
break;
}
return B_OK;
}
// _kern_read_link
extern "C"
status_t
_kern_read_link(int fd, const char *path, char *buffer, size_t *_bufferSize)
{
ssize_t result = _kreadlink_(fd, path, buffer, *_bufferSize);
if (result < 0)
return result;
buffer[result] = '\0';
*_bufferSize = result;
return B_OK;
}
// _kern_unlink
extern "C"
status_t
_kern_unlink(int fd, const char *relPath)
{
BPath path;
status_t error = get_path(fd, relPath, path);
if (error != B_OK)
return error;
if (unlink(path.Path()) < 0) {
error = errno;
if (error == B_IS_A_DIRECTORY) {
if (rmdir(path.Path()) < 0)
return errno;
} else
return error;
}
return B_OK;
}
// _kern_rename
extern "C"
status_t
_kern_rename(int oldDir, const char *oldRelPath, int newDir,
const char *newRelPath)
{
// get old path
BPath oldPath;
status_t error = get_path(oldDir, oldRelPath, oldPath);
if (error != B_OK)
return error;
// get new path
BPath newPath;
error = get_path(newDir, newRelPath, newPath);
if (error != B_OK)
return error;
// rename
if (rename(oldPath.Path(), newPath.Path()) < 0)
return errno;
return B_OK;
}
// _kern_read_stat
extern "C"
status_t
_kern_read_stat(int fd, const char *path, bool traverseLink, struct stat *st,
size_t statSize)
{
if (traverseLink)
return B_ERROR; // unsupported
return _krstat_(fd, path, st, 0);
}
// _kern_write_stat
extern "C"
status_t
_kern_write_stat(int fd, const char *path, bool traverseLink,
const struct stat *st, size_t statSize, int statMask)
{
if (traverseLink)
return B_ERROR; // unsupported
return _kwstat_(fd, path, st, statMask, 0);
}
// _kern_lock_node
extern "C"
status_t
_kern_lock_node(int fd)
{
return _klock_node_(fd);
}
// _kern_unlock_node
extern "C"
status_t
_kern_unlock_node(int fd)
{
return _kunlock_node_(fd);
}
// _kern_fsync
extern "C"
status_t
_kern_fsync(int fd)
{
return (fsync(fd) < 0) ? errno : B_OK ;
}
// _kern_open_attr_dir
extern "C"
int
_kern_open_attr_dir(int fd, const char *path)
{
if (fd < 0 && !path)
return B_BAD_VALUE;
if (fd >= 0 && path)
return B_ERROR; // unsupported
DIR *dirHandle = (fd >= 0 ? fs_fopen_attr_dir(fd) : fs_open_attr_dir(path));
if (!dirHandle)
return errno;
int dirFD = dirHandle->fd;
if (dirFD < 0 || dirFD >= kFDTableSlotCount) {
fs_close_attr_dir(dirHandle);
return B_ERROR;
}
free(dirHandle);
sFDTable[dirFD] = FD_TYPE_ATTR_DIR;
return dirFD;
}
// _kern_remove_attr
extern "C"
status_t
_kern_remove_attr(int fd, const char *name)
{
return fs_remove_attr(fd, name) == -1 ? errno : B_OK ;
}
// _kern_rename_attr
extern "C"
status_t
_kern_rename_attr(int fromFile, const char *fromName, int toFile,
const char *toName)
{
status_t error = (fromName && toName ? B_OK : B_BAD_VALUE);
// Figure out how much data there is
attr_info info;
if (error == B_OK) {
if (fs_stat_attr(fromFile, fromName, &info) < 0)
error = B_BAD_VALUE; // This is what R5::BNode returns...
}
// Alloc a buffer
char *data = NULL;
if (error == B_OK) {
// alloc at least one byte
data = new(nothrow) char[info.size >= 1 ? info.size : 1];
if (data == NULL)
error = B_NO_MEMORY;
}
// Read in the data
if (error == B_OK) {
ssize_t size = fs_read_attr(fromFile, fromName, info.type, 0, data,
info.size);
if (size != info.size) {
if (size < 0)
error = errno;
else
error = B_ERROR;
}
}
// Write it to the new attribute
if (error == B_OK) {
ssize_t size = 0;
if (info.size > 0)
size = fs_write_attr(toFile, toName, info.type, 0, data, info.size);
if (size != info.size) {
if (size < 0)
error = errno;
else
error = B_ERROR;
}
}
// free the buffer
if (data)
delete[] data;
// Remove the old attribute
if (error == B_OK)
error = _kern_remove_attr(fromFile, fromName);
return error;
}
extern "C" status_t
_kern_get_safemode_option(const char *parameter, char *buffer, size_t *_bufferSize)
{
return _kget_safemode_option_(parameter, buffer, _bufferSize);
}

View File

@ -1,11 +0,0 @@
Notes concerning the OpenBeOS implementation of BNode:
1. GetNextAttrName returns B_BAD_VALUE when passed a NULL pointer instead of crashing
2. R5::BNode returns B_BAD_ADDRESS when RewindAttrs() fails (not B_FILE_ERROR as claimed in the BeBook). We currently follow suit.
3. RenameAttr() actually works, whereas the R5 version doesn't (apparently because BFS doesn't implement it directly...).
4. Write/ReadAttrString() functions need to be documented (they aren't in the R5 BeBook).
5. ReadAttrString() adds an extra NULL char to the end of the string it reads as a precaution before handing it back to the BString result, since it's possible to read a non-NULL-terminated string of characters from an attribute.
6. Write/ReadAttrString() can't be tested until we have an OpenBeOS implementation of BString.
7. Dup() should be declared const, but it isn't by R5, so our implementation follows suit.
8. Locking is not supported by the Posix implemention of OpenBeOS BNode, due to fcntl(fd, F_SETLK, ...) not being implemented in R5.

View File

@ -1,169 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <AppMisc.h>
#include <Looper.h>
#include <Messenger.h>
#include <NodeMonitor.h>
#include <syscalls.h>
// TODO: Tests!
// watch_node
/*! \brief Subscribes a target to node and/or mount watching, or unsubscribes
it from node watching.
Depending of \a flags the action performed by this function varies:
- \a flags is \c 0: The target is unsubscribed from watching the node.
\a node must not be \c NULL in this case.
- \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount
watching.
- \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT,
\c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to
watching the specified aspects of the node. \a node must not be \c NULL
in this case.
Note, that the latter two cases are not mutual exlusive, i.e. mount and
node watching can be requested with a single call.
\param node node_ref referring to the node to be watched. May be \c NULL,
if only mount watching is requested.
\param flags Flags indicating the actions to be performed.
\param target Messenger referring to the target. Must be valid.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
watch_node(const node_ref *node, uint32 flags, BMessenger target)
{
status_t error = (target.IsValid() ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
BLooper *looper = NULL;
BHandler *handler = target.Target(&looper);
error = watch_node(node, flags, handler, looper);
}
return error;
}
// watch_node
/*! \brief Subscribes a target to node and/or mount watching, or unsubscribes
it from node watching.
Depending of \a flags the action performed by this function varies:
- \a flags is \c 0: The target is unsubscribed from watching the node.
\a node must not be \c NULL in this case.
- \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount
watching.
- \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT,
\c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to
watching the specified aspects of the node. \a node must not be \c NULL
in this case.
Note, that the latter two cases are not mutual exlusive, i.e. mount and
node watching can be requested with a single call.
\param node node_ref referring to the node to be watched. May be \c NULL,
if only mount watching is requested.
\param flags Flags indicating the actions to be performed.
\param handler The target handler. May be \c NULL, if \a looper is not
\c NULL. Then the preferred handler of the looper is targeted.
\param looper The target looper. May be \c NULL, if \a handler is not
\c NULL. Then the handler's looper is the target looper.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
watch_node(const node_ref *node, uint32 flags, const BHandler *handler,
const BLooper *looper)
{
status_t error = B_OK;
// check looper and handler and get the handler token
int32 handlerToken = -2;
if (handler) {
handlerToken = _get_object_token_(handler);
if (looper) {
if (looper != handler->Looper())
error = B_BAD_VALUE;
} else {
looper = handler->Looper();
if (!looper)
error = B_BAD_VALUE;
}
} else if (!looper)
error = B_BAD_VALUE;
if (error == B_OK) {
port_id port = _get_looper_port_(looper);
if (flags == B_STOP_WATCHING) {
// unsubscribe from node node watching
if (node)
error = _kern_stop_watching(node->device, node->node, flags, port, handlerToken);
else
error = B_BAD_VALUE;
} else {
// subscribe to...
// mount watching
if (flags & B_WATCH_MOUNT) {
error = _kern_start_watching((dev_t)-1, (ino_t)-1, 0, port, handlerToken);
flags &= ~B_WATCH_MOUNT;
}
// node watching
if (error == B_OK && flags)
error = _kern_start_watching(node->device, node->node, flags, port, handlerToken);
}
}
return error;
}
// stop_watching
/*! \brief Unsubscribes a target from node and mount monitoring.
\param target Messenger referring to the target. Must be valid.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
stop_watching(BMessenger target)
{
status_t error = (target.IsValid() ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
BLooper *looper = NULL;
BHandler *handler = target.Target(&looper);
error = stop_watching(handler, looper);
}
return error;
}
// stop_watching
/*! \brief Unsubscribes a target from node and mount monitoring.
\param handler The target handler. May be \c NULL, if \a looper is not
\c NULL. Then the preferred handler of the looper is targeted.
\param looper The target looper. May be \c NULL, if \a handler is not
\c NULL. Then the handler's looper is the target looper.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
stop_watching(const BHandler *handler, const BLooper *looper)
{
status_t error = B_OK;
// check looper and handler and get the handler token
int32 handlerToken = -2;
if (handler) {
handlerToken = _get_object_token_(handler);
if (looper) {
if (looper != handler->Looper())
error = B_BAD_VALUE;
} else {
looper = handler->Looper();
if (!looper)
error = B_BAD_VALUE;
}
} else if (!looper)
error = B_BAD_VALUE;
// unsubscribe
if (error == B_OK) {
port_id port = _get_looper_port_(looper);
error = _kern_stop_notifying(port, handlerToken);
}
return error;
}

View File

@ -1,250 +0,0 @@
#include "NodeMonitorHandler.h"
/*
* static util functions for the super lazy
*/
/* static */ status_t
NodeMonitorHandler::make_entry_ref(dev_t device, ino_t directory,
const char * name,
entry_ref * ref)
{
ref->device = device;
ref->directory = directory;
return ref->set_name(name);
}
/* static */ void
NodeMonitorHandler::make_node_ref(dev_t device, ino_t node, node_ref * ref)
{
ref->device = device;
ref->node = node;
}
/*
* public functions: constructor, destructor, MessageReceived
*/
NodeMonitorHandler::NodeMonitorHandler(const char * name)
: BHandler(name)
{
// nothing to do
}
NodeMonitorHandler::~NodeMonitorHandler()
{
// nothing to do
}
/* virtual */ void
NodeMonitorHandler::MessageReceived(BMessage * msg)
{
status_t status = B_MESSAGE_NOT_UNDERSTOOD;
if (msg->what == B_NODE_MONITOR) {
int32 opcode;
if (msg->FindInt32("opcode", &opcode) == B_OK) {
switch (opcode) {
case B_ENTRY_CREATED:
status = HandleEntryCreated(msg);
break;
case B_ENTRY_REMOVED:
status = HandleEntryRemoved(msg);
break;
case B_ENTRY_MOVED:
status = HandleEntryMoved(msg);
break;
case B_STAT_CHANGED:
status = HandleStatChanged(msg);
break;
case B_ATTR_CHANGED:
status = HandleAttrChanged(msg);
break;
case B_DEVICE_MOUNTED:
status = HandleDeviceMounted(msg);
break;
case B_DEVICE_UNMOUNTED:
status = HandleDeviceUnmounted(msg);
break;
default:
break;
}
}
}
if (status == B_MESSAGE_NOT_UNDERSTOOD) {
inherited::MessageReceived(msg);
}
}
/*
* default virtual functions do nothing
*/
/* virtual */ void
NodeMonitorHandler::EntryCreated(const char *name, ino_t directory,
dev_t device, ino_t node)
{
// ignore
}
/* virtual */ void
NodeMonitorHandler::EntryRemoved(ino_t directory, dev_t device, ino_t node)
{
// ignore
}
/* virtual */ void
NodeMonitorHandler::EntryMoved(const char *name, ino_t from_directory,
ino_t to_directory, dev_t device, ino_t node)
{
// ignore
}
/* virtual */ void
NodeMonitorHandler::StatChanged(ino_t node, dev_t device)
{
// ignore
}
/* virtual */ void
NodeMonitorHandler::AttrChanged(ino_t node, dev_t device)
{
// ignore
}
/* virtual */ void
NodeMonitorHandler::DeviceMounted(dev_t new_device, dev_t device,
ino_t directory)
{
// ignore
}
/* virtual */ void
NodeMonitorHandler::DeviceUnmounted(dev_t new_device)
{
// ignore
}
/*
* private functions to rip apart the corresponding BMessage
*/
status_t
NodeMonitorHandler::HandleEntryCreated(BMessage * msg)
{
const char *name;
ino_t directory;
dev_t device;
ino_t node;
if ((msg->FindString("name", &name) != B_OK) ||
(msg->FindInt64("directory", &directory) != B_OK) ||
(msg->FindInt32("device", &device) != B_OK) ||
(msg->FindInt64("node", &node) != B_OK)) {
return B_MESSAGE_NOT_UNDERSTOOD;
}
EntryCreated(name, directory, device, node);
return B_OK;
}
status_t
NodeMonitorHandler::HandleEntryRemoved(BMessage * msg)
{
ino_t directory;
dev_t device;
ino_t node;
if ((msg->FindInt64("directory", &directory) != B_OK) ||
(msg->FindInt32("device", &device) != B_OK) ||
(msg->FindInt64("node", &node) != B_OK)) {
return B_MESSAGE_NOT_UNDERSTOOD;
}
EntryRemoved(directory, device, node);
return B_OK;
}
status_t
NodeMonitorHandler::HandleEntryMoved(BMessage * msg)
{
const char *name;
ino_t from_directory;
ino_t to_directory;
dev_t device;
ino_t node;
if ((msg->FindString("name", &name) != B_OK) ||
(msg->FindInt64("from directory", &from_directory) != B_OK) ||
(msg->FindInt64("to directory", &to_directory) != B_OK) ||
(msg->FindInt32("device", &device) != B_OK) ||
(msg->FindInt64("node", &node) != B_OK)) {
return B_MESSAGE_NOT_UNDERSTOOD;
}
EntryMoved(name, from_directory, to_directory, device, node);
return B_OK;
}
status_t
NodeMonitorHandler::HandleStatChanged(BMessage * msg)
{
ino_t node;
dev_t device;
if ((msg->FindInt64("node", &node) != B_OK) ||
(msg->FindInt32("device", &device) != B_OK)) {
return B_MESSAGE_NOT_UNDERSTOOD;
}
StatChanged(node, device);
return B_OK;
}
status_t
NodeMonitorHandler::HandleAttrChanged(BMessage * msg)
{
ino_t node;
dev_t device;
if ((msg->FindInt64("node", &node) != B_OK) ||
(msg->FindInt32("device", &device) != B_OK)) {
return B_MESSAGE_NOT_UNDERSTOOD;
}
AttrChanged(node, device);
return B_OK;
}
status_t
NodeMonitorHandler::HandleDeviceMounted(BMessage * msg)
{
dev_t new_device;
dev_t device;
ino_t directory;
if ((msg->FindInt32("new device", &new_device) != B_OK) ||
(msg->FindInt32("device", &device) != B_OK) ||
(msg->FindInt64("directory", &directory) != B_OK)) {
return B_MESSAGE_NOT_UNDERSTOOD;
}
DeviceMounted(new_device, device, directory);
return B_OK;
}
status_t
NodeMonitorHandler::HandleDeviceUnmounted(BMessage * msg)
{
dev_t new_device;
if (msg->FindInt32("new device", &new_device) != B_OK) {
return B_MESSAGE_NOT_UNDERSTOOD;
}
DeviceUnmounted(new_device);
return B_OK;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,195 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <algobase.h>
#include <new.h>
#include <stdio.h>
#include <string.h>
#include <Button.h>
#include <DiskScannerAddOn.h>
#include <Screen.h>
#include <View.h>
#include "PartitioningDialog.h"
enum {
MSG_OK = 'okay',
MSG_CANCEL = 'cncl',
};
// constructor
PartitioningDialog::PartitioningDialog(BRect dialogCenter)
: BWindow(BRect(100, 100, 100, 100), "Partitioning Parameters",
B_TITLED_WINDOW,
B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE),
fEditor(NULL),
fEditorView(NULL),
fBlocker(-1),
fCancelled(NULL),
fCenter()
{
fBlocker = create_sem(0, "partitioning dialog blocker");
// calculate the dialog center point
if (!dialogCenter.IsValid())
dialogCenter = BScreen().Frame();
fCenter = dialogCenter.LeftTop() + dialogCenter.RightBottom();
fCenter.x /= 2;
fCenter.y /= 2;
}
// destructor
PartitioningDialog::~PartitioningDialog()
{
if (fEditorView)
fEditorView->RemoveSelf();
if (fBlocker >= 0)
delete_sem(fBlocker);
}
// MessageReceived
void
PartitioningDialog::MessageReceived(BMessage *message)
{
switch (message->what) {
case MSG_OK:
{
if (fEditor->EditingDone()) {
if (fCancelled)
*fCancelled = false;
Quit();
}
break;
}
case MSG_CANCEL:
if (fCancelled)
*fCancelled = true;
Quit();
break;
default:
BWindow::MessageReceived(message);
break;
}
}
// QuitRequested
bool
PartitioningDialog::QuitRequested()
{
if (fCancelled)
*fCancelled = true;
return true;
}
// Go
status_t
PartitioningDialog::Go(BDiskScannerParameterEditor *editor, bool *_cancelled)
{
status_t error = _Init(editor);
bool wasRun = false;
// fire up the window
if (error == B_OK) {
if (fBlocker >= 0) {
sem_id blocker = fBlocker;
bool cancelled = true;
fCancelled = &cancelled;
Show();
wasRun = true;
acquire_sem(blocker);
if (cancelled)
error = B_ERROR;
if (_cancelled)
*_cancelled = cancelled;
} else
error = fBlocker;
}
// delete the window if not run
if (!wasRun)
delete this;
return error;
}
// _Init
status_t
PartitioningDialog::_Init(BDiskScannerParameterEditor *editor)
{
status_t error = (editor ? B_OK : B_BAD_VALUE);
// set the parameter editor and view
if (error == B_OK) {
fEditor = editor;
fEditorView = editor->View();
if (!fEditorView)
error = B_ERROR;
}
// setup views
if (error == B_OK) {
BView *mainView = new(nothrow) BView(BRect(0, 0, 1, 1), "main",
B_FOLLOW_ALL, 0);
BMessage *okMessage = new BMessage(MSG_OK);
BMessage *cancelMessage = new BMessage(MSG_CANCEL);
BButton *okButton = new (nothrow) BButton(
BRect(0, 0, 1, 1), "ok", "OK", okMessage,
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
BButton *cancelButton = new (nothrow) BButton(
BRect(0, 0, 1, 1), "cancel", "Cancel", cancelMessage,
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
if (okMessage && cancelMessage && okButton && cancelButton) {
// add the views to the hierarchy
mainView->AddChild(fEditorView);
mainView->AddChild(okButton);
mainView->AddChild(cancelButton);
AddChild(mainView);
// set the buttons' preferred size
float buttonWidth = 0;
float buttonHeight = 0;
okButton->GetPreferredSize(&buttonWidth, &buttonHeight);
okButton->ResizeTo(buttonWidth, buttonHeight);
cancelButton->GetPreferredSize(&buttonWidth, &buttonHeight);
cancelButton->ResizeTo(buttonWidth, buttonHeight);
// setup their positions and sizes
int32 hSpacing = 10;
int32 vSpacing = 10;
BRect editorRect = fEditorView->Bounds();
BRect okRect = okButton->Bounds();
BRect cancelRect = cancelButton->Bounds();
// compute width and size of the main view
int32 width = max(editorRect.IntegerWidth() + 1,
okRect.IntegerWidth() + 1 + hSpacing
+ cancelRect.IntegerWidth() + 1)
+ 2 * hSpacing;
int32 height = editorRect.IntegerHeight() + 1
+ max(okRect.IntegerHeight(),
cancelRect.IntegerHeight()) + 1
+ 3 * vSpacing;
mainView->ResizeTo(width - 1, height -1);
ResizeTo(width - 1, height -1);
// set location of the editor view
fEditorView->MoveTo((width - editorRect.IntegerWidth() - 1) / 2,
vSpacing - 1);
fEditorView->ResizeTo(editorRect.Width(), editorRect.Height());
// set the location of the buttons
float buttonTop = 2 * vSpacing + editorRect.IntegerHeight();
float buttonLeft = width - hSpacing - okRect.IntegerWidth();
okButton->MoveTo(buttonLeft, buttonTop);
buttonLeft -= hSpacing + cancelRect.IntegerWidth();
cancelButton->MoveTo(buttonLeft, buttonTop);
} else {
// cleanup on error
error = B_NO_MEMORY;
if (!okButton && okMessage)
delete okMessage;
if (!cancelButton && cancelMessage)
delete cancelMessage;
if (okButton)
delete okButton;
if (cancelButton)
delete cancelButton;
if (mainView)
delete mainView;
}
}
return error;
}

View File

@ -1,41 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#ifndef _PARTITIONING_DIALOG_H
#define _PARTITIONING_DIALOG_H
#include <OS.h>
#include <Window.h>
class BDiskScannerParameterEditor;
namespace BPrivate {
class PartitioningDialog : public BWindow {
public:
PartitioningDialog(BRect dialogCenter);
virtual ~PartitioningDialog();
virtual void MessageReceived(BMessage *message);
virtual bool QuitRequested();
status_t Go(BDiskScannerParameterEditor *editor, bool *cancelled);
private:
status_t _Init(BDiskScannerParameterEditor *editor);
private:
BDiskScannerParameterEditor *fEditor;
BView *fEditorView;
sem_id fBlocker;
bool *fCancelled;
BPoint fCenter;
};
} // namespace BPrivate
using BPrivate::PartitioningDialog;
#endif // _PARTITIONING_DIALOG_H

View File

@ -1,96 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <new>
#include <syscalls.h>
#include <PartitioningInfo.h>
using namespace std;
// constructor
BPartitioningInfo::BPartitioningInfo()
: fPartitionID(-1),
fSpaces(NULL),
fCount(0)
{
}
// destructor
BPartitioningInfo::~BPartitioningInfo()
{
Unset();
}
// Unset
void
BPartitioningInfo::Unset()
{
delete[] fSpaces;
fPartitionID = -1;
fSpaces = NULL;
fCount = 0;
}
// PartitionID
partition_id
BPartitioningInfo::PartitionID() const
{
return fPartitionID;
}
// GetPartitionableSpaceAt
status_t
BPartitioningInfo::GetPartitionableSpaceAt(int32 index, off_t *offset,
off_t *size) const
{
if (!fSpaces || !offset || !size || index < 0 || index >= fCount)
return B_BAD_VALUE;
*offset = fSpaces[index].offset;
*size = fSpaces[index].size;
return B_OK;
}
// CountPartitionableSpaces
int32
BPartitioningInfo::CountPartitionableSpaces() const
{
return fCount;
}
// _SetTo
status_t
BPartitioningInfo::_SetTo(partition_id partition, int32 changeCounter)
{
Unset();
status_t error = B_OK;
partitionable_space_data *buffer = NULL;
int32 count = 0;
int32 actualCount = 0;
do {
error = _kern_get_partitionable_spaces(partition, changeCounter,
buffer, count, &actualCount);
if (error == B_BUFFER_OVERFLOW) {
// buffer to small re-allocate it
if (buffer)
delete[] buffer;
buffer = new(nothrow) partitionable_space_data[actualCount];
if (buffer)
count = actualCount;
else
error = B_NO_MEMORY;
}
} while (error == B_BUFFER_OVERFLOW);
// set data / cleanup on failure
if (error == B_OK) {
fPartitionID = partition;
fSpaces = buffer;
fCount = actualCount;
} else if (buffer)
delete[] buffer;
return error;
}

View File

@ -1,776 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the Haiku distribution and is covered
// by the MIT license.
//---------------------------------------------------------------------
/*!
\file Query.cpp
BQuery implementation.
*/
#include <fcntl.h>
#include <new>
#include <parsedate.h>
#include <time.h>
#include <Entry.h>
#include <fs_query.h>
#include <Query.h>
#include <Volume.h>
#include <MessengerPrivate.h>
#include <syscalls.h>
#include "QueryPredicate.h"
#include "storage_support.h"
using namespace std;
using namespace BPrivate::Storage;
// BQuery
// constructor
/*! \brief Creates an uninitialized BQuery.
*/
BQuery::BQuery()
: BEntryList(),
fStack(NULL),
fPredicate(NULL),
fDevice((dev_t)B_ERROR),
fLive(false),
fPort(B_ERROR),
fToken(0),
fQueryFd(-1)
{
}
// destructor
/*! \brief Frees all resources associated with the object.
*/
BQuery::~BQuery()
{
Clear();
}
// Clear
/*! \brief Resets the object to a uninitialized state.
\return \c B_OK
*/
status_t
BQuery::Clear()
{
// close the currently open query
status_t error = B_OK;
if (fQueryFd >= 0) {
error = _kern_close(fQueryFd);
fQueryFd = -1;
}
// delete the predicate stack and the predicate
delete fStack;
fStack = NULL;
delete[] fPredicate;
fPredicate = NULL;
// reset the other parameters
fDevice = (dev_t)B_ERROR;
fLive = false;
fPort = B_ERROR;
fToken = 0;
return error;
}
// PushAttr
/*! \brief Pushes an attribute name onto the BQuery's predicate stack.
\param attrName the attribute name
\return
- \c B_OK: Everything went fine.
- \c B_NO_MEMORY: Not enough memory.
- \c B_NOT_ALLOWED: PushAttribute() was called after Fetch().
\note In BeOS R5 this method returns \c void. That is checking the return
value will render your code source and binary incompatible!
Calling PushXYZ() after a Fetch() does change the predicate on R5,
but it doesn't affect the active query and the newly created
predicate can not even be used for the next query, since in order
to be able to reuse the BQuery object for another query, Clear() has
to be called and Clear() also deletes the predicate.
*/
status_t
BQuery::PushAttr(const char *attrName)
{
return _PushNode(new(nothrow) AttributeNode(attrName), true);
}
// PushOp
/*! \brief Pushes an operator onto the BQuery's predicate stack.
\param op the code representing the operator
\return
- \c B_OK: Everything went fine.
- \c B_NO_MEMORY: Not enough memory.
- \c B_NOT_ALLOWED: PushOp() was called after Fetch().
\note In BeOS R5 this method returns \c void. That is checking the return
value will render your code source and binary incompatible!
Calling PushXYZ() after a Fetch() does change the predicate on R5,
but it doesn't affect the active query and the newly created
predicate can not even be used for the next query, since in order
to be able to reuse the BQuery object for another query, Clear() has
to be called and Clear() also deletes the predicate.
*/
status_t
BQuery::PushOp(query_op op)
{
status_t error = B_OK;
switch (op) {
case B_EQ:
case B_GT:
case B_GE:
case B_LT:
case B_LE:
case B_NE:
case B_CONTAINS:
case B_BEGINS_WITH:
case B_ENDS_WITH:
case B_AND:
case B_OR:
error = _PushNode(new(nothrow) BinaryOpNode(op), true);
break;
case B_NOT:
error = _PushNode(new(nothrow) UnaryOpNode(op), true);
break;
default:
error = _PushNode(new(nothrow) SpecialOpNode(op), true);
break;
}
return error;
}
// PushUInt32
/*! \brief Pushes a uint32 value onto the BQuery's predicate stack.
\param value the value
\return
- \c B_OK: Everything went fine.
- \c B_NO_MEMORY: Not enough memory.
- \c B_NOT_ALLOWED: PushUInt32() was called after Fetch().
\note In BeOS R5 this method returns \c void. That is checking the return
value will render your code source and binary incompatible!
Calling PushXYZ() after a Fetch() does change the predicate on R5,
but it doesn't affect the active query and the newly created
predicate can not even be used for the next query, since in order
to be able to reuse the BQuery object for another query, Clear() has
to be called and Clear() also deletes the predicate.
*/
status_t
BQuery::PushUInt32(uint32 value)
{
return _PushNode(new(nothrow) UInt32ValueNode(value), true);
}
// PushInt32
/*! \brief Pushes an int32 value onto the BQuery's predicate stack.
\param value the value
\return
- \c B_OK: Everything went fine.
- \c B_NO_MEMORY: Not enough memory.
- \c B_NOT_ALLOWED: PushInt32() was called after Fetch().
\note In BeOS R5 this method returns \c void. That is checking the return
value will render your code source and binary incompatible!
Calling PushXYZ() after a Fetch() does change the predicate on R5,
but it doesn't affect the active query and the newly created
predicate can not even be used for the next query, since in order
to be able to reuse the BQuery object for another query, Clear() has
to be called and Clear() also deletes the predicate.
*/
status_t
BQuery::PushInt32(int32 value)
{
return _PushNode(new(nothrow) Int32ValueNode(value), true);
}
// PushUInt64
/*! \brief Pushes a uint64 value onto the BQuery's predicate stack.
\param value the value
\return
- \c B_OK: Everything went fine.
- \c B_NO_MEMORY: Not enough memory.
- \c B_NOT_ALLOWED: PushUInt64() was called after Fetch().
\note In BeOS R5 this method returns \c void. That is checking the return
value will render your code source and binary incompatible!
Calling PushXYZ() after a Fetch() does change the predicate on R5,
but it doesn't affect the active query and the newly created
predicate can not even be used for the next query, since in order
to be able to reuse the BQuery object for another query, Clear() has
to be called and Clear() also deletes the predicate.
*/
status_t
BQuery::PushUInt64(uint64 value)
{
return _PushNode(new(nothrow) UInt64ValueNode(value), true);
}
// PushInt64
/*! \brief Pushes an int64 value onto the BQuery's predicate stack.
\param value the value
\return
- \c B_OK: Everything went fine.
- \c B_NO_MEMORY: Not enough memory.
- \c B_NOT_ALLOWED: PushInt64() was called after Fetch().
\note In BeOS R5 this method returns \c void. That is checking the return
value will render your code source and binary incompatible!
Calling PushXYZ() after a Fetch() does change the predicate on R5,
but it doesn't affect the active query and the newly created
predicate can not even be used for the next query, since in order
to be able to reuse the BQuery object for another query, Clear() has
to be called and Clear() also deletes the predicate.
*/
status_t
BQuery::PushInt64(int64 value)
{
return _PushNode(new(nothrow) Int64ValueNode(value), true);
}
// PushFloat
/*! \brief Pushes a float value onto the BQuery's predicate stack.
\param value the value
\return
- \c B_OK: Everything went fine.
- \c B_NO_MEMORY: Not enough memory.
- \c B_NOT_ALLOWED: PushFloat() was called after Fetch().
\note In BeOS R5 this method returns \c void. That is checking the return
value will render your code source and binary incompatible!
Calling PushXYZ() after a Fetch() does change the predicate on R5,
but it doesn't affect the active query and the newly created
predicate can not even be used for the next query, since in order
to be able to reuse the BQuery object for another query, Clear() has
to be called and Clear() also deletes the predicate.
*/
status_t
BQuery::PushFloat(float value)
{
return _PushNode(new(nothrow) FloatValueNode(value), true);
}
// PushDouble
/*! \brief Pushes a double value onto the BQuery's predicate stack.
\param value the value
\return
- \c B_OK: Everything went fine.
- \c B_NO_MEMORY: Not enough memory.
- \c B_NOT_ALLOWED: PushDouble() was called after Fetch().
\note In BeOS R5 this method returns \c void. That is checking the return
value will render your code source and binary incompatible!
Calling PushXYZ() after a Fetch() does change the predicate on R5,
but it doesn't affect the active query and the newly created
predicate can not even be used for the next query, since in order
to be able to reuse the BQuery object for another query, Clear() has
to be called and Clear() also deletes the predicate.
*/
status_t
BQuery::PushDouble(double value)
{
return _PushNode(new(nothrow) DoubleValueNode(value), true);
}
// PushString
/*! \brief Pushes a string value onto the BQuery's predicate stack.
\param value the value
\param caseInsensitive \c true, if the case of the string should be
ignored, \c false otherwise
\return
- \c B_OK: Everything went fine.
- \c B_NO_MEMORY: Not enough memory.
- \c B_NOT_ALLOWED: PushString() was called after Fetch().
\note In BeOS R5 this method returns \c void. That is checking the return
value will render your code source and binary incompatible!
Calling PushXYZ() after a Fetch() does change the predicate on R5,
but it doesn't affect the active query and the newly created
predicate can not even be used for the next query, since in order
to be able to reuse the BQuery object for another query, Clear() has
to be called and Clear() also deletes the predicate.
*/
status_t
BQuery::PushString(const char *value, bool caseInsensitive)
{
return _PushNode(new(nothrow) StringNode(value, caseInsensitive), true);
}
// PushDate
/*! \brief Pushes a date value onto the BQuery's predicate stack.
The supplied date can be any string understood by the POSIX function
parsedate().
\param date the date string
\return
- \c B_OK: Everything went fine.
- \c B_ERROR: Error parsing the string.
- \c B_NOT_ALLOWED: PushDate() was called after Fetch().
\note Calling PushXYZ() after a Fetch() does change the predicate on R5,
but it doesn't affect the active query and the newly created
predicate can not even be used for the next query, since in order
to be able to reuse the BQuery object for another query, Clear() has
to be called and Clear() also deletes the predicate.
*/
status_t
BQuery::PushDate(const char *date)
{
status_t error = (date ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
time_t t;
time(&t);
t = parsedate(date, t);
if (t < 0)
error = B_BAD_VALUE;
}
if (error == B_OK)
error = _PushNode(new(nothrow) DateNode(date), true);
return error;
}
// SetVolume
/*! \brief Sets the BQuery's volume.
A query is restricted to one volume. This method sets this volume. It
fails, if called after Fetch(). To reuse a BQuery object it has to be
reset via Clear().
\param volume the volume
\return
- \c B_OK: Everything went fine.
- \c B_NOT_ALLOWED: SetVolume() was called after Fetch().
*/
status_t
BQuery::SetVolume(const BVolume *volume)
{
status_t error = (volume ? B_OK : B_BAD_VALUE);
if (error == B_OK && _HasFetched())
error = B_NOT_ALLOWED;
if (error == B_OK) {
if (volume->InitCheck() == B_OK)
fDevice = volume->Device();
else
fDevice = (dev_t)B_ERROR;
}
return error;
}
// SetPredicate
/*! \brief Sets the BQuery's predicate.
A predicate can be set either using this method or constructing one on
the predicate stack. The two methods can not be mixed. The letter one
has precedence over this one.
The method fails, if called after Fetch(). To reuse a BQuery object it has
to be reset via Clear().
\param predicate the predicate string
\return
- \c B_OK: Everything went fine.
- \c B_NOT_ALLOWED: SetPredicate() was called after Fetch().
- \c B_NO_MEMORY: Insufficient memory to store the predicate.
*/
status_t
BQuery::SetPredicate(const char *expression)
{
status_t error = (expression ? B_OK : B_BAD_VALUE);
if (error == B_OK && _HasFetched())
error = B_NOT_ALLOWED;
if (error == B_OK)
error = _SetPredicate(expression);
return error;
}
// SetTarget
/*! \brief Sets the BQuery's target and makes the query live.
The query update messages are sent to the specified target. They might
roll in immediately after calling Fetch().
This methods fails, if called after Fetch(). To reuse a BQuery object it
has to be reset via Clear().
\return
- \c B_OK: Everything went fine.
- \c B_BAD_VALUE: \a messenger was not properly initialized.
- \c B_NOT_ALLOWED: SetTarget() was called after Fetch().
*/
status_t
BQuery::SetTarget(BMessenger messenger)
{
status_t error = (messenger.IsValid() ? B_OK : B_BAD_VALUE);
if (error == B_OK && _HasFetched())
error = B_NOT_ALLOWED;
if (error == B_OK) {
BMessenger::Private messengerPrivate(messenger);
fPort = messengerPrivate.Port();
fToken = (messengerPrivate.IsPreferredTarget()
? -1 : messengerPrivate.Token());
fLive = true;
}
return error;
}
// IsLive
/*! \brief Returns whether the query associated with this object is live.
\return \c true, if the query is live, \c false otherwise
*/
bool
BQuery::IsLive() const
{
return fLive;
}
// GetPredicate
/*! \brief Returns the BQuery's predicate.
Regardless of whether the predicate has been constructed using the
predicate stack or set via SetPredicate(), this method returns a
string representation.
\param buffer a pointer to a buffer into which the predicate shall be
written
\param length the size of the provided buffer
\return
- \c B_OK: Everything went fine.
- \c B_NO_INIT: The predicate isn't set.
- \c B_BAD_VALUE: \a buffer is \c NULL or too short.
\note This method causes the predicate stack to be evaluated and cleared.
You can't interleave Push*() and GetPredicate() calls.
*/
status_t
BQuery::GetPredicate(char *buffer, size_t length)
{
status_t error = (buffer ? B_OK : B_BAD_VALUE);
if (error == B_OK)
_EvaluateStack();
if (error == B_OK && !fPredicate)
error = B_NO_INIT;
if (error == B_OK && length <= strlen(fPredicate))
error = B_BAD_VALUE;
if (error == B_OK)
strcpy(buffer, fPredicate);
return error;
}
// GetPredicate
/*! \brief Returns the BQuery's predicate.
Regardless of whether the predicate has been constructed using the
predicate stack or set via SetPredicate(), this method returns a
string representation.
\param predicate a pointer to a BString which shall be set to the
predicate string
\return
- \c B_OK: Everything went fine.
- \c B_NO_INIT: The predicate isn't set.
- \c B_BAD_VALUE: \c NULL \a predicate.
\note This method causes the predicate stack to be evaluated and cleared.
You can't interleave Push*() and GetPredicate() calls.
*/
status_t
BQuery::GetPredicate(BString *predicate)
{
status_t error = (predicate ? B_OK : B_BAD_VALUE);
if (error == B_OK)
_EvaluateStack();
if (error == B_OK && !fPredicate)
error = B_NO_INIT;
if (error == B_OK)
predicate->SetTo(fPredicate);
return error;
}
// PredicateLength
/*! \brief Returns the length of the BQuery's predicate string.
Regardless of whether the predicate has been constructed using the
predicate stack or set via SetPredicate(), this method returns the length
of its string representation (counting the terminating null).
\return
- the length of the predicate string (counting the terminating null) or
- 0, if an error occured
\note This method causes the predicate stack to be evaluated and cleared.
You can't interleave Push*() and PredicateLength() calls.
*/
size_t
BQuery::PredicateLength()
{
status_t error = _EvaluateStack();
if (error == B_OK && !fPredicate)
error = B_NO_INIT;
size_t size = 0;
if (error == B_OK)
size = strlen(fPredicate) + 1;
return size;
}
// TargetDevice
/*! \brief Returns the device ID identifying the BQuery's volume.
\return the device ID of the BQuery's volume or \c B_NO_INIT, if the
volume isn't set.
*/
dev_t
BQuery::TargetDevice() const
{
return fDevice;
}
// Fetch
/*! \brief Tells the BQuery to start fetching entries satisfying the predicate.
After Fetch() has been called GetNextEntry(), GetNextRef() and
GetNextDirents() can be used to retrieve the enties. Live query updates
may be sent immediately after this method has been called.
Fetch() fails, if it has already been called. To reuse a BQuery object it
has to be reset via Clear().
\return
- \c B_OK: Everything went fine.
- \c B_NO_INIT: The predicate or the volume aren't set.
- \c B_BAD_VALUE: The predicate is invalid.
- \c B_NOT_ALLOWED: Fetch() has already been called.
*/
status_t
BQuery::Fetch()
{
if (_HasFetched())
return B_NOT_ALLOWED;
_EvaluateStack();
if (!fPredicate || fDevice < 0)
return B_NO_INIT;
fQueryFd = _kern_open_query(fDevice, fPredicate, strlen(fPredicate),
fLive ? B_LIVE_QUERY : 0, fPort, fToken);
if (fQueryFd < 0)
return fQueryFd;
// set close on exec flag
fcntl(fQueryFd, F_SETFD, FD_CLOEXEC);
return B_OK;
}
// BEntryList interface
// GetNextEntry
/*! \brief Returns the BQuery's next entry as a BEntry.
Places the next entry in the list in \a entry, traversing symlinks if
\a traverse is \c true.
\param entry a pointer to a BEntry to be initialized with the found entry
\param traverse specifies whether to follow it, if the found entry
is a symbolic link.
\note The iterator used by this method is the same one used by
GetNextRef() and GetNextDirents().
\return
- \c B_OK if successful,
- \c B_ENTRY_NOT_FOUND when at the end of the list,
- \c B_BAD_VALUE: The queries predicate includes unindexed attributes.
- \c B_FILE_ERROR: Fetch() has not been called before.
*/
status_t
BQuery::GetNextEntry(BEntry *entry, bool traverse)
{
status_t error = (entry ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
entry_ref ref;
error = GetNextRef(&ref);
if (error == B_OK)
error = entry->SetTo(&ref, traverse);
}
return error;
}
// GetNextRef
/*! \brief Returns the BQuery's next entry as an entry_ref.
Places an entry_ref to the next entry in the list into \a ref.
\param ref a pointer to an entry_ref to be filled in with the data of the
found entry
\note The iterator used by this method is the same one used by
GetNextEntry() and GetNextDirents().
\return
- \c B_OK if successful,
- \c B_ENTRY_NOT_FOUND when at the end of the list,
- \c B_BAD_VALUE: The queries predicate includes unindexed attributes.
- \c B_FILE_ERROR: Fetch() has not been called before.
*/
status_t
BQuery::GetNextRef(entry_ref *ref)
{
status_t error = (ref ? B_OK : B_BAD_VALUE);
if (error == B_OK && !_HasFetched())
error = B_FILE_ERROR;
if (error == B_OK) {
BPrivate::Storage::LongDirEntry entry;
bool next = true;
while (error == B_OK && next) {
if (GetNextDirents(&entry, sizeof(entry), 1) != 1) {
error = B_ENTRY_NOT_FOUND;
} else {
next = (!strcmp(entry.d_name, ".")
|| !strcmp(entry.d_name, ".."));
}
}
if (error == B_OK) {
ref->device = entry.d_pdev;
ref->directory = entry.d_pino;
error = ref->set_name(entry.d_name);
}
}
return error;
}
// GetNextDirents
/*! \brief Returns the BQuery's next entries as dirent structures.
Reads a number of entries into the array of dirent structures pointed to by
\a buf. Reads as many but no more than \a count entries, as many entries as
remain, or as many entries as will fit into the array at \a buf with given
length \a length (in bytes), whichever is smallest.
\param buf a pointer to a buffer to be filled with dirent structures of
the found entries
\param length the maximal number of entries to be read.
\note The iterator used by this method is the same one used by
GetNextEntry() and GetNextRef().
\return
- The number of dirent structures stored in the buffer, 0 when there are
no more entries to be read.
- \c B_BAD_VALUE: The queries predicate includes unindexed attributes.
- \c B_FILE_ERROR: Fetch() has not been called before.
*/
int32
BQuery::GetNextDirents(struct dirent *buf, size_t length, int32 count)
{
if (!buf)
return B_BAD_VALUE;
if (!_HasFetched())
return B_FILE_ERROR;
return _kern_read_dir(fQueryFd, buf, length, count);
}
// Rewind
/*! \brief Rewinds the entry list back to the first entry.
Unlike R5 Haiku implements this method for BQuery.
\return
- \c B_OK on success,
- \c B_FILE_ERROR, if Fetch() has not yet been called.
*/
status_t
BQuery::Rewind()
{
if (!_HasFetched())
return B_FILE_ERROR;
return _kern_rewind_dir(fQueryFd);
}
// CountEntries
/*! \brief Unimplemented method of the BEntryList interface.
\return 0.
*/
int32
BQuery::CountEntries()
{
return B_ERROR;
}
// _HasFetched
/*! Returns whether Fetch() has already been called on this object.
\return \c true, if Fetch() has successfully been invoked, \c false
otherwise.
*/
bool
BQuery::_HasFetched() const
{
return (fQueryFd >= 0);
}
// _PushNode
/*! \brief Pushs a node onto the predicate stack.
If the stack has not been allocate until this time, this method does
allocate it.
If the supplied node is \c NULL, it is assumed that there was not enough
memory to allocate the node and thus \c B_NO_MEMORY is returned.
In case the method fails, the caller retains the ownership of the supplied
node and thus is responsible for deleting it, if \a deleteOnError is
\c false. If it is \c true, the node is deleted, if an error occurs.
\param node the node to be pushed
\param deleteOnError
\return
- \c B_OK: Everything went fine.
- \c B_NO_MEMORY: \c NULL \a node or insuffient memory to allocate the
predicate stack or push the node.
- \c B_NOT_ALLOWED: _PushNode() was called after Fetch().
*/
status_t
BQuery::_PushNode(QueryNode *node, bool deleteOnError)
{
status_t error = (node ? B_OK : B_NO_MEMORY);
if (error == B_OK && _HasFetched())
error = B_NOT_ALLOWED;
// allocate the stack, if necessary
if (error == B_OK && !fStack) {
fStack = new(nothrow) QueryStack;
if (!fStack)
error = B_NO_MEMORY;
}
if (error == B_OK)
error = fStack->PushNode(node);
if (error != B_OK && deleteOnError)
delete node;
return error;
}
// _SetPredicate
/*! \brief Helper method to set the BQuery's predicate.
It is not checked whether Fetch() has already been invoked.
\param predicate the predicate string
\return
- \c B_OK: Everything went fine.
- \c B_NO_MEMORY: Insufficient memory to store the predicate.
*/
status_t
BQuery::_SetPredicate(const char *expression)
{
status_t error = B_OK;
// unset the old predicate
delete[] fPredicate;
fPredicate = NULL;
// set the new one
if (expression) {
fPredicate = new(nothrow) char[strlen(expression) + 1];
if (fPredicate)
strcpy(fPredicate, expression);
else
error = B_NO_MEMORY;
}
return error;
}
// _EvaluateStack
/*! Evaluates the query's predicate stack.
The method does nothing (and returns \c B_OK), if the stack is \c NULL.
If the stack is non-null and Fetch() has already been called, the method
fails.
\return
- \c B_OK: Everything went fine.
- \c B_NO_MEMORY: Insufficient memory.
- \c B_NOT_ALLOWED: _EvaluateStack() was called after Fetch().
- another error code
*/
status_t
BQuery::_EvaluateStack()
{
status_t error = B_OK;
if (fStack) {
_SetPredicate(NULL);
if (_HasFetched())
error = B_NOT_ALLOWED;
// convert the stack to a tree and evaluate it
QueryNode *node = NULL;
if (error == B_OK)
error = fStack->ConvertToTree(node);
BString predicate;
if (error == B_OK)
error = node->GetString(predicate);
if (error == B_OK)
error = _SetPredicate(predicate.String());
delete fStack;
fStack = NULL;
}
return error;
}
// FBC
void BQuery::_QwertyQuery1() {}
void BQuery::_QwertyQuery2() {}
void BQuery::_QwertyQuery3() {}
void BQuery::_QwertyQuery4() {}
void BQuery::_QwertyQuery5() {}
void BQuery::_QwertyQuery6() {}

View File

@ -1,490 +0,0 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
/*!
\file QueryPredicate.cpp
BQuery predicate helper classes implementation.
*/
#include "QueryPredicate.h"
#include <ctype.h>
namespace BPrivate {
namespace Storage {
// QueryNode
// constructor
QueryNode::QueryNode()
{
}
// destructor
QueryNode::~QueryNode()
{
}
// LeafNode
// constructor
LeafNode::LeafNode()
: QueryNode()
{
}
// destructor
LeafNode::~LeafNode()
{
}
// Arity
uint32
LeafNode::Arity() const
{
return 0;
}
// SetChildAt
status_t
LeafNode::SetChildAt(QueryNode *child, int32 index)
{
return B_BAD_VALUE;
}
// ChildAt
QueryNode *
LeafNode::ChildAt(int32 index)
{
return NULL;
}
// UnaryNode
// constructor
UnaryNode::UnaryNode()
: QueryNode(),
fChild(NULL)
{
}
// destructor
UnaryNode::~UnaryNode()
{
delete fChild;
}
// Arity
uint32
UnaryNode::Arity() const
{
return 1;
}
// SetChildAt
status_t
UnaryNode::SetChildAt(QueryNode *child, int32 index)
{
status_t error = B_OK;
if (index == 0) {
delete fChild;
fChild = child;
} else
error = B_BAD_VALUE;
return error;
}
// ChildAt
QueryNode *
UnaryNode::ChildAt(int32 index)
{
QueryNode *result = NULL;
if (index == 0)
result = fChild;
return result;
}
// BinaryNode
// constructor
BinaryNode::BinaryNode()
: QueryNode(),
fChild1(NULL),
fChild2(NULL)
{
}
// destructor
BinaryNode::~BinaryNode()
{
delete fChild1;
delete fChild2;
}
// Arity
uint32
BinaryNode::Arity() const
{
return 2;
}
// SetChildAt
status_t
BinaryNode::SetChildAt(QueryNode *child, int32 index)
{
status_t error = B_OK;
if (index == 0) {
delete fChild1;
fChild1 = child;
} else if (index == 1) {
delete fChild2;
fChild2 = child;
} else
error = B_BAD_VALUE;
return error;
}
// ChildAt
QueryNode *
BinaryNode::ChildAt(int32 index)
{
QueryNode *result = NULL;
if (index == 0)
result = fChild1;
else if (index == 1)
result = fChild2;
return result;
}
// AttributeNode
// constructor
AttributeNode::AttributeNode(const char *attribute)
: LeafNode(),
fAttribute(attribute)
{
}
// GetString
status_t
AttributeNode::GetString(BString &predicate)
{
predicate.SetTo(fAttribute);
return B_OK;
}
// StringNode
// constructor
StringNode::StringNode(const char *value, bool caseInsensitive)
: LeafNode(),
fValue()
{
if (value) {
if (caseInsensitive) {
int32 len = strlen(value);
for (int32 i = 0; i < len; i++) {
char c = value[i];
if (isalpha(c)) {
int lower = tolower(c);
int upper = toupper(c);
if (lower < 0 || upper < 0)
fValue << c;
else
fValue << "[" << (char)lower << (char)upper << "]";
} else
fValue << c;
}
} else
fValue = value;
}
}
// GetString
status_t
StringNode::GetString(BString &predicate)
{
BString escaped(fValue);
escaped.CharacterEscape("\"\\'", '\\');
predicate.SetTo("");
predicate << "\"" << escaped << "\"";
return B_OK;
}
// DateNode
// constructor
DateNode::DateNode(const char *value)
: LeafNode(),
fValue(value)
{
}
// GetString
status_t
DateNode::GetString(BString &predicate)
{
BString escaped(fValue);
escaped.CharacterEscape("%\"\\'", '\\');
predicate.SetTo("");
predicate << "%" << escaped << "%";
return B_OK;
}
// ValueNode
// GetString
//
// float specialization
template<>
status_t
ValueNode<float>::GetString(BString &predicate)
{
char buffer[32];
sprintf(buffer, "0x%08lx", *(int32*)&fValue);
predicate.SetTo(buffer);
return B_OK;
}
// GetString
//
// double specialization
template<>
status_t
ValueNode<double>::GetString(BString &predicate)
{
char buffer[32];
sprintf(buffer, "0x%016Lx", *(int64*)&fValue);
predicate.SetTo(buffer);
return B_OK;
}
// SpecialOpNode
// constructor
SpecialOpNode::SpecialOpNode(query_op op)
: LeafNode(),
fOp(op)
{
}
// GetString
status_t
SpecialOpNode::GetString(BString &predicate)
{
return B_BAD_VALUE;
}
// UnaryOpNode
// constructor
UnaryOpNode::UnaryOpNode(query_op op)
: UnaryNode(),
fOp(op)
{
}
// GetString
status_t
UnaryOpNode::GetString(BString &predicate)
{
status_t error = (fChild ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
if (fOp == B_NOT) {
BString childString;
error = fChild->GetString(childString);
predicate.SetTo("(!");
predicate << childString << ")";
} else
error = B_BAD_VALUE;
}
return error;
}
// BinaryOpNode
// constructor
BinaryOpNode::BinaryOpNode(query_op op)
: BinaryNode(),
fOp(op)
{
}
// GetString
status_t
BinaryOpNode::GetString(BString &predicate)
{
status_t error = (fChild1 && fChild2 ? B_OK : B_BAD_VALUE);
BString childString1;
BString childString2;
if (error == B_OK)
error = fChild1->GetString(childString1);
if (error == B_OK)
error = fChild2->GetString(childString2);
predicate.SetTo("");
if (error == B_OK) {
switch (fOp) {
case B_EQ:
predicate << "(" << childString1 << "=="
<< childString2 << ")";
break;
case B_GT:
predicate << "(" << childString1 << ">"
<< childString2 << ")";
break;
case B_GE:
predicate << "(" << childString1 << ">="
<< childString2 << ")";
break;
case B_LT:
predicate << "(" << childString1 << "<"
<< childString2 << ")";
break;
case B_LE:
predicate << "(" << childString1 << "<="
<< childString2 << ")";
break;
case B_NE:
predicate << "(" << childString1 << "!="
<< childString2 << ")";
break;
case B_CONTAINS:
if (StringNode *strNode = dynamic_cast<StringNode*>(fChild2)) {
BString value;
value << "*" << strNode->Value() << "*";
error = StringNode(value.String()).GetString(childString2);
}
if (error == B_OK) {
predicate << "(" << childString1 << "=="
<< childString2 << ")";
}
break;
case B_BEGINS_WITH:
if (StringNode *strNode = dynamic_cast<StringNode*>(fChild2)) {
BString value;
value << strNode->Value() << "*";
error = StringNode(value.String()).GetString(childString2);
}
if (error == B_OK) {
predicate << "(" << childString1 << "=="
<< childString2 << ")";
}
break;
case B_ENDS_WITH:
if (StringNode *strNode = dynamic_cast<StringNode*>(fChild2)) {
BString value;
value << "*" << strNode->Value();
error = StringNode(value.String()).GetString(childString2);
}
if (error == B_OK) {
predicate << "(" << childString1 << "=="
<< childString2 << ")";
}
break;
case B_AND:
predicate << "(" << childString1 << "&&"
<< childString2 << ")";
break;
case B_OR:
predicate << "(" << childString1 << "||"
<< childString2 << ")";
break;
default:
error = B_BAD_VALUE;
break;
}
}
return error;
}
// QueryStack
// constructor
QueryStack::QueryStack()
: fNodes()
{
}
// destructor
QueryStack::~QueryStack()
{
for (int32 i = 0; QueryNode *node = (QueryNode*)fNodes.ItemAt(i); i++)
delete node;
}
// PushNode
status_t
QueryStack::PushNode(QueryNode *node)
{
status_t error = (node ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
if (!fNodes.AddItem(node))
error = B_NO_MEMORY;
}
return error;
}
// PopNode
QueryNode *
QueryStack::PopNode()
{
return (QueryNode*)fNodes.RemoveItem(fNodes.CountItems() - 1);
}
// ConvertToTree
status_t
QueryStack::ConvertToTree(QueryNode *&rootNode)
{
status_t error = _GetSubTree(rootNode);
if (error == B_OK && !fNodes.IsEmpty()) {
error = B_BAD_VALUE;
delete rootNode;
rootNode = NULL;
}
return error;
}
// _GetSubTree
status_t
QueryStack::_GetSubTree(QueryNode *&rootNode)
{
QueryNode *node = PopNode();
status_t error = (node ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
uint32 arity = node->Arity();
for (int32 i = (int32)arity - 1; error == B_OK && i >= 0; i--) {
QueryNode *child = NULL;
error = _GetSubTree(child);
if (error == B_OK) {
error = node->SetChildAt(child, i);
if (error != B_OK)
delete child;
}
}
}
// clean up, if something went wrong
if (error != B_OK && node) {
delete node;
node = NULL;
}
rootNode = node;
return error;
}
}; // namespace Storage
}; // namespace BPrivate

View File

@ -1,222 +0,0 @@
// ----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//
// File Name: VolumeRoster.cpp
//
// Description: BVolumeRoster class
// ----------------------------------------------------------------------
/*!
\file VolumeRoster.cpp
BVolumeRoster implementation.
*/
#include <errno.h>
#include <new>
#include <Bitmap.h>
#include <Directory.h>
#include <fs_info.h>
#include <Node.h>
#include <NodeMonitor.h>
#include <VolumeRoster.h>
static const char kBootVolumePath[] = "/boot";
using namespace std;
#ifdef USE_OPENBEOS_NAMESPACE
namespace OpenBeOS {
#endif
/*!
\class BVolumeRoster
\brief A roster of all volumes available in the system
Provides an interface for iterating through the volumes available in
the system and watching volume mounting/unmounting.
The class wraps the next_dev() function for iterating through the
volume list and the watch_node()/stop_watching() for the watching
features.
\author Vincent Dominguez
\author <a href='mailto:bonefish@users.sf.net'>Ingo Weinhold</a>
\version 0.0.0
*/
/*! \var dev_t BVolumeRoster::fCookie
\brief The iteration cookie for next_dev(). Initialized with 0.
*/
/*! \var dev_t BVolumeRoster::fTarget
\brief BMessenger referring to the target to which the watching
notification messages are sent.
The object is allocated and owned by the roster. \c NULL, if not watching.
*/
// constructor
/*! \brief Creates a new BVolumeRoster.
The object is ready to be used.
*/
BVolumeRoster::BVolumeRoster()
: fCookie(0),
fTarget(NULL)
{
}
// destructor
/*! \brief Frees all resources associated with this object.
If a watching was activated on (StartWatching()), it is deactived.
*/
BVolumeRoster::~BVolumeRoster()
{
StopWatching();
}
// GetNextVolume
/*! \brief Returns the next volume in the list of available volumes.
\param volume A pointer to a pre-allocated BVolume to be initialized to
refer to the next volume in the list of available volumes.
\return
- \c B_OK: Everything went fine.
- \c B_BAD_VALUE: The last volume in the list has already been returned.
*/
status_t
BVolumeRoster::GetNextVolume(BVolume *volume)
{
// check parameter
status_t error = (volume ? B_OK : B_BAD_VALUE);
// get next device
dev_t device;
if (error == B_OK) {
device = next_dev(&fCookie);
if (device < 0)
error = device;
}
// init volume
if (error == B_OK)
error = volume->SetTo(device);
return error;
}
// Rewind
/*! \brief Rewinds the list of available volumes such that the next call to
GetNextVolume() will return the first element in the list.
*/
void
BVolumeRoster::Rewind()
{
fCookie = 0;
}
// GetBootVolume
/*! \brief Returns the boot volume.
Currently, this function looks for the volume that is mounted at "/boot".
The only way to fool the system into thinking that there is not a boot
volume is to rename "/boot" -- but, please refrain from doing so...(:o(
\param volume A pointer to a pre-allocated BVolume to be initialized to
refer to the boot volume.
\return
- \c B_OK: Everything went fine.
- an error code otherwise
*/
status_t
BVolumeRoster::GetBootVolume(BVolume *volume)
{
// check parameter
status_t error = (volume ? B_OK : B_BAD_VALUE);
// get device
dev_t device;
if (error == B_OK) {
device = dev_for_path(kBootVolumePath);
if (device < 0)
error = device;
}
// init volume
if (error == B_OK)
error = volume->SetTo(device);
return error;
}
// StartWatching
/*! \brief Starts watching the list of volumes available in the system.
Notifications are sent to the specified target whenever a volume is
mounted or unmounted. The format of the notification messages is
described under watch_node(). Actually BVolumeRoster just provides a
more convenient interface for it.
If StartWatching() has been called before with another target and no
StopWatching() since, StopWatching() is called first, so that the former
target won't receive any notifications anymore.
When the object is destroyed all watching has an end as well.
\param messenger The target to which the notification messages shall be
sent.
\return
- \c B_OK: Everything went fine.
- \c B_BAD_VALUE: The supplied BMessenger is invalid.
- \c B_NO_MEMORY: Insufficient memory to carry out this operation.
*/
status_t
BVolumeRoster::StartWatching(BMessenger messenger)
{
StopWatching();
status_t error = (messenger.IsValid() ? B_OK : B_ERROR);
// clone messenger
if (error == B_OK) {
fTarget = new(nothrow) BMessenger(messenger);
if (!fTarget)
error = B_NO_MEMORY;
}
// start watching
if (error == B_OK)
error = watch_node(NULL, B_WATCH_MOUNT, messenger);
// cleanup on failure
if (error != B_OK && fTarget) {
delete fTarget;
fTarget = NULL;
}
return error;
}
// StopWatching
/*! \brief Stops volume watching initiated with StartWatching() before.
*/
void
BVolumeRoster::StopWatching()
{
if (fTarget) {
stop_watching(*fTarget);
delete fTarget;
fTarget = NULL;
}
}
// Messenger
/*! \brief Returns a messenger to the target currently watching the volume
list.
\return A messenger to the target currently watching the volume list, or
an invalid messenger, if noone is currently watching.
*/
BMessenger
BVolumeRoster::Messenger() const
{
return (fTarget ? *fTarget : BMessenger());
}
// FBC
void BVolumeRoster::_SeveredVRoster1() {}
void BVolumeRoster::_SeveredVRoster2() {}
#ifdef USE_OPENBEOS_NAMESPACE
}
#endif