diff --git a/src/servers/registrar/DiskDeviceManager.h b/src/servers/registrar/DiskDeviceManager.h index 0c92994144..2c8b59d1a1 100644 --- a/src/servers/registrar/DiskDeviceManager.h +++ b/src/servers/registrar/DiskDeviceManager.h @@ -8,12 +8,17 @@ #include +#include "RDiskDeviceList.h" + class DiskDeviceManager : public BLooper { public: DiskDeviceManager(); virtual ~DiskDeviceManager(); virtual void MessageReceived(BMessage *message); + +private: + RDiskDeviceList fDeviceList; }; #endif // DISK_DEVICE_MANAGER_H diff --git a/src/servers/registrar/Jamfile b/src/servers/registrar/Jamfile index cc5612d365..2008cfdfe1 100644 --- a/src/servers/registrar/Jamfile +++ b/src/servers/registrar/Jamfile @@ -1,9 +1,14 @@ SubDir OBOS_TOP src servers registrar ; UsePublicHeaders app ; +UsePrivateHeaders $(DOT) ; # needed for disk_scanner.cpp UsePrivateHeaders app ; +UsePrivateHeaders shared ; UsePrivateHeaders storage ; +# needed as long as disk_scanner.cpp is compiled in +SEARCH_SOURCE += [ FDirName $(OBOS_TOP) src kernel libroot os ] ; + Server obos_registrar : AppInfoList.cpp ClipboardHandler.cpp @@ -15,17 +20,25 @@ Server obos_registrar : MessageEvent.cpp MessageRunnerManager.cpp MIMEManager.cpp + RDiskDevice.cpp + RDiskDeviceList.cpp RecentApps.cpp RecentEntries.cpp Registrar.cpp RosterAppInfo.cpp RosterSettingsCharStream.cpp + RPartition.cpp + RSession.cpp TRoster.cpp Watcher.cpp WatchingService.cpp + + # from .../libroot/os + disk_scanner.cpp ; LinkSharedOSLibs obos_registrar : libopenbeos.so + libkernelland_emu.so # needed for disk_scanner.cpp stdc++.r4 - be root + be ; diff --git a/src/servers/registrar/RDiskDevice.cpp b/src/servers/registrar/RDiskDevice.cpp new file mode 100644 index 0000000000..e254ae87b6 --- /dev/null +++ b/src/servers/registrar/RDiskDevice.cpp @@ -0,0 +1,182 @@ +//---------------------------------------------------------------------- +// This software is part of the OpenBeOS distribution and is covered +// by the OpenBeOS license. +//--------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include + +#include + +#include "RDiskDevice.h" +#include "RDiskDeviceList.h" +#include "RPartition.h" +#include "RSession.h" + +// constructor +RDiskDevice::RDiskDevice() + : fSessions(10, true), + fDeviceList(NULL), + fID(-1), + fChangeCounter(0), + fTouched(false), + fPath(), + fFD(-1), + fMediaStatus(B_ERROR) +{ +} + +// destructor +RDiskDevice::~RDiskDevice() +{ + Unset(); +} + +// SetTo +status_t +RDiskDevice::SetTo(const char *path, int fd, const device_geometry *geometry, + status_t mediaStatus) +{ +FUNCTION_START(); + Unset(); + status_t error = B_OK; + fID = _NextID(); + fChangeCounter = 0; + fTouched = true; + fPath.SetTo(path); + fFD = fd; + fGeometry = *geometry; + fMediaStatus = mediaStatus; + // analyze the media status + switch (fMediaStatus) { + case B_NO_ERROR: + case B_DEV_NO_MEDIA: + case B_DEV_NOT_READY: + case B_DEV_MEDIA_CHANGE_REQUESTED: + case B_DEV_DOOR_OPEN: + break; + case B_DEV_MEDIA_CHANGED: + // the user was fast enough to change the media between opening + // and requesting the media status -- media is in, so we are fine + fMediaStatus = B_OK; + break; + default: + error = fMediaStatus; + } + // scan the device for sessions, if we have a media + if (fMediaStatus == B_OK) { + session_info sessionInfo; + for (int32 i = 0; ; i++) { + // get the session info + status_t status = get_nth_session_info(fFD, i, &sessionInfo); + if (status != B_OK) { + if (status != B_ENTRY_NOT_FOUND) + error = status; + break; + } + // create and add a RSession + if (RSession *session = new(nothrow) RSession) { + error = session->SetTo(fFD, &sessionInfo); + if (error == B_OK) + AddSession(session); + else + delete session; + } else + error = B_NO_MEMORY; + } + } + // cleanup on error + if (error != B_OK) + Unset(); +RETURN_ERROR(error); +// return error; +} + +// Unset +void +RDiskDevice::Unset() +{ + for (int32 i = CountSessions() - 1; i >= 0; i--) + RemoveSession(i); + fID = -1; + fPath.SetTo(""); + if (fFD >= 0) { + close(fFD); + fFD = -1; + } +} + +// AddSession +bool +RDiskDevice::AddSession(RSession *session) +{ + bool success = false; + if (session) { + success = fSessions.AddItem(session); + if (success) { + session->SetDevice(this); + if (RDiskDeviceList *deviceList = DeviceList()) + deviceList->SessionAdded(session); + } + } + return success; +} + +// RemoveSession +bool +RDiskDevice::RemoveSession(int32 index) +{ + RSession *session = SessionAt(index); + if (session) { + session->SetDevice(NULL); + fSessions.RemoveItemAt(index); + if (RDiskDeviceList *deviceList = DeviceList()) + deviceList->SessionRemoved(session); + delete session; + } + return (session != NULL); +} + +// RemoveSession +bool +RDiskDevice::RemoveSession(RSession *session) +{ + bool success = false; + if (session) { + int32 index = fSessions.IndexOf(session); + if (index >= 0) + success = RemoveSession(index); + } + return success; +} + +// Update +status_t +RDiskDevice::Update() +{ + return B_ERROR; +} + +// Dump +void +RDiskDevice::Dump() const +{ + printf("device `%s'\n", Path()); + for (int32 i = 0; RSession *session = SessionAt(i); i++) + session->Dump(); +} + +// _NextID +int32 +RDiskDevice::_NextID() +{ + return atomic_add(&fNextID, 1); +} + +// fNextID +vint32 RDiskDevice::fNextID = 0; + diff --git a/src/servers/registrar/RDiskDevice.h b/src/servers/registrar/RDiskDevice.h new file mode 100644 index 0000000000..922bcddbf2 --- /dev/null +++ b/src/servers/registrar/RDiskDevice.h @@ -0,0 +1,65 @@ +//---------------------------------------------------------------------- +// This software is part of the OpenBeOS distribution and is covered +// by the OpenBeOS license. +//--------------------------------------------------------------------- + +#ifndef DISK_DEVICE_H +#define DISK_DEVICE_H + +#include +#include +#include + +class RDiskDeviceList; +class RPartition; +class RSession; + +class RDiskDevice { +public: + RDiskDevice(); + ~RDiskDevice(); + + status_t SetTo(const char *path, int fd, const device_geometry *geometry, + status_t mediaStatus); + void Unset(); + + void SetDeviceList(RDiskDeviceList *deviceList) + { fDeviceList = deviceList ;} + RDiskDeviceList *DeviceList() const { return fDeviceList; } + + int32 ID() const { return fID; } + int32 ChangeCounter() const { return fChangeCounter; } + + void SetTouched(bool touched) { fTouched = touched; } + bool Touched() const { return fTouched; } + + const char *Path() const { return fPath.String(); } + + bool AddSession(RSession *session); + bool RemoveSession(int32 index); + bool RemoveSession(RSession *session); + int32 CountSessions() const { return fSessions.CountItems(); } + RSession *SessionAt(int32 index) const { return fSessions.ItemAt(index); } + + status_t Update(); + + void Dump() const; + +private: + static int32 _NextID(); + +private: + BObjectList fSessions; + RDiskDeviceList *fDeviceList; + int32 fID; + int32 fChangeCounter; + bool fTouched; + BString fPath; + int fFD; + device_geometry fGeometry; + status_t fMediaStatus; + + static vint32 fNextID; +}; + +#endif // DISK_DEVICE_H diff --git a/src/servers/registrar/RDiskDeviceList.cpp b/src/servers/registrar/RDiskDeviceList.cpp new file mode 100644 index 0000000000..a22fe583ab --- /dev/null +++ b/src/servers/registrar/RDiskDeviceList.cpp @@ -0,0 +1,325 @@ +//---------------------------------------------------------------------- +// This software is part of the OpenBeOS distribution and is covered +// by the OpenBeOS license. +//--------------------------------------------------------------------- + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +//#include +#include + +#include "RDiskDeviceList.h" +#include "Debug.h" +#include "RDiskDevice.h" +#include "RPartition.h" +#include "RSession.h" + +// compare_ids +/*template +static +int +compare_ids(const T *object1, const T *object2) +{ + int32 id1 = object1->ID(); + int32 id2 = object2->ID(); + if (id1 < id2) + return -1; + if (id1 > id2) + return 1; + return 0; +}*/ + +// CompareIDPredicate +template +struct CompareIDPredicate : public UnaryPredicate { + CompareIDPredicate(int32 id) : fID(id) {} + CompareIDPredicate(const T *object) : fID(object->ID()) {} + + virtual int operator()(const T *object) const + { + int32 id = object->ID(); + if (fID < id) + return -1; + if (fID > id) + return 1; + return 0; + } + +private: + int32 fID; +}; + +// CompareDevicePathPredicate +struct CompareDevicePathPredicate : public UnaryPredicate { + CompareDevicePathPredicate(const char *path) : fPath(path) {} + + virtual int operator()(const RDiskDevice *device) const + { + return strcmp(fPath, device->Path()); + } + +private: + const char *fPath; +}; + +// constructor +RDiskDeviceList::RDiskDeviceList() + : fLock(), + fDevices(20, true), + fSessions(40, false), + fPartitions(80, false) +{ +} + +// destructor +RDiskDeviceList::~RDiskDeviceList() +{ +} + +// AddDevice +bool +RDiskDeviceList::AddDevice(RDiskDevice *device) +{ + bool success = false; + if (device) { + fDevices.BinaryInsert(device, CompareIDPredicate(device)); + device->SetDeviceList(this); + DeviceAdded(device); + } + return success; +} + +// RemoveDevice +bool +RDiskDeviceList::RemoveDevice(int32 index) +{ + RDiskDevice *device = DeviceAt(index); + if (device) { + device->SetDeviceList(NULL); + fDevices.RemoveItemAt(index); + DeviceRemoved(device); + delete device; + } + return (device != NULL); +} + +// RemoveDevice +bool +RDiskDeviceList::RemoveDevice(RDiskDevice *device) +{ + bool success = false; + if (device) { + int32 index = fDevices.FindBinaryInsertionIndex( + CompareIDPredicate(device), &success); + if (success) + success = RemoveDevice(index); + } + return success; +} + +// DeviceWithID +RDiskDevice * +RDiskDeviceList::DeviceWithID(int32 id) const +{ + bool inList = false; + int32 index = fDevices.FindBinaryInsertionIndex( + CompareIDPredicate(id), &inList); + return (inList ? DeviceAt(index) : NULL); +} + +// SessionWithID +RSession * +RDiskDeviceList::SessionWithID(int32 id) const +{ + bool inList = false; + int32 index = fSessions.FindBinaryInsertionIndex( + CompareIDPredicate(id), &inList); + return (inList ? SessionAt(index) : NULL); +} + +// PartitionWithID +RPartition * +RDiskDeviceList::PartitionWithID(int32 id) const +{ + bool inList = false; + int32 index = fPartitions.FindBinaryInsertionIndex( + CompareIDPredicate(id), &inList); + return (inList ? PartitionAt(index) : NULL); +} + +// DeviceWithPath +RDiskDevice * +RDiskDeviceList::DeviceWithPath(const char *path) const +{ + const RDiskDevice *device + = fDevices.FindIf(CompareDevicePathPredicate(path)); + return const_cast(device); +} + +// Rescan +status_t +RDiskDeviceList::Rescan() +{ +FUNCTION_START(); + status_t error = B_OK; + if (Lock()) { + // marked all devices untouched + for (int32 i = 0; RDiskDevice *device = DeviceAt(i); i++) + device->SetTouched(false); + // scan the "/dev/disk" directory for devices + BDirectory dir; + if (dir.SetTo("/dev/disk") == B_OK) { + error = _Scan(dir); + } + // remove all untouched devices + for (int32 i = CountDevices() - 1; i >= 0; i--) { + if (!DeviceAt(i)->Touched()) + RemoveDevice(i); + } + Unlock(); + } else + error = B_ERROR; +FUNCTION_END(); + return error; +} + +// Lock +bool +RDiskDeviceList::Lock() +{ + return fLock.Lock(); +} + +// Unlock +void +RDiskDeviceList::Unlock() +{ + fLock.Unlock(); +} + +// DeviceAdded +void +RDiskDeviceList::DeviceAdded(RDiskDevice *device) +{ +} + +// DeviceRemoved +void +RDiskDeviceList::DeviceRemoved(RDiskDevice *device) +{ +} + +// SessionAdded +void +RDiskDeviceList::SessionAdded(RSession *session) +{ +} + +// SessionRemoved +void +RDiskDeviceList::SessionRemoved(RSession *session) +{ +} + +// PartitionAdded +void +RDiskDeviceList::PartitionAdded(RPartition *partition) +{ +} + +// PartitionRemoved +void +RDiskDeviceList::PartitionRemoved(RPartition *partition) +{ +} + +// Dump +void +RDiskDeviceList::Dump() const +{ + for (int32 i = 0; RDiskDevice *device = DeviceAt(i); i++) + device->Dump(); +} + +// _Scan +status_t +RDiskDeviceList::_Scan(BDirectory &dir) +{ +//BEntry dirEntry; +//BPath dirPath; +//dir.GetEntry(&dirEntry); +//dirEntry.GetPath(&dirPath); +//PRINT(("RDiskDeviceList::_Scan(`%s')\n", dirPath.Path())); + status_t error = B_OK; + BEntry entry; + while (dir.GetNextEntry(&entry) == B_OK) { + struct stat st; + if (entry.GetStat(&st) == B_OK) { +//PRINT(("st.st_mode: 0x%x\n", st.st_mode & S_IFMT)); + if (S_ISDIR(st.st_mode)) { + BDirectory subdir; + if (subdir.SetTo(&entry) == B_OK) + error = _Scan(subdir); + } else if (!S_ISLNK(st.st_mode)) { + BPath path; + if (entry.GetPath(&path) == B_OK) { + _ScanDevice(path.Path()); + } + } + } + } + return error; +} + +// _ScanDevice +status_t +RDiskDeviceList::_ScanDevice(const char *path) +{ + status_t error = B_OK; + // search the list for a device with that path + if (RDiskDevice *device = DeviceWithPath(path)) { + // found: just update it + error = device->Update(); + } else { + // not found: check whether it is really a disk device and add it to + // the list + int fd = open(path, O_RDONLY); + if (fd >= 0) { + bool closeFile = true; + device_geometry geometry; + status_t mediaStatus = B_OK; + partition_info partitionInfo; + if (ioctl(fd, B_GET_MEDIA_STATUS, &mediaStatus) == 0 + && ioctl(fd, B_GET_GEOMETRY, &geometry) == 0 + && ioctl(fd, B_GET_PARTITION_INFO, &partitionInfo) < 0) { +// int32 blockSize = geometry.bytes_per_sector; +// off_t deviceSize = (off_t)blockSize +// * geometry.sectors_per_track * geometry.cylinder_count +// * geometry.head_count; + RDiskDevice *device = new(nothrow) RDiskDevice; + if (device) { + error = device->SetTo(path, fd, &geometry, mediaStatus); + if (error == B_OK) { + closeFile = false; + AddDevice(device); + } else + delete device; + } else + error = B_NO_MEMORY; + } + if (closeFile) + close(fd); + } + } + return error; +} + diff --git a/src/servers/registrar/RDiskDeviceList.h b/src/servers/registrar/RDiskDeviceList.h new file mode 100644 index 0000000000..234f2056f0 --- /dev/null +++ b/src/servers/registrar/RDiskDeviceList.h @@ -0,0 +1,68 @@ +//---------------------------------------------------------------------- +// This software is part of the OpenBeOS distribution and is covered +// by the OpenBeOS license. +//--------------------------------------------------------------------- + +#ifndef DISK_DEVICE_LIST_H +#define DISK_DEVICE_LIST_H + +#include +#include + +class BDirectory; +class BEntry; + +class RDiskDevice; +class RPartition; +class RSession; + +class RDiskDeviceList { +public: + RDiskDeviceList(); + ~RDiskDeviceList(); + + bool AddDevice(RDiskDevice *device); + bool RemoveDevice(int32 index); + bool RemoveDevice(RDiskDevice *device); + int32 CountDevices() const { return fDevices.CountItems(); } + RDiskDevice *DeviceAt(int32 index) const { return fDevices.ItemAt(index); } + + int32 CountSessions() const { return fSessions.CountItems(); } + RSession *SessionAt(int32 index) const { return fSessions.ItemAt(index); } + + int32 CountPartitions() const { return fPartitions.CountItems(); } + RPartition *PartitionAt(int32 index) const + { return fPartitions.ItemAt(index); } + + RDiskDevice *DeviceWithID(int32 id) const; + RSession *SessionWithID(int32 id) const; + RPartition *PartitionWithID(int32 id) const; + + RDiskDevice *DeviceWithPath(const char *path) const; + + status_t Rescan(); + + bool Lock(); + void Unlock(); + + void DeviceAdded(RDiskDevice *device); + void DeviceRemoved(RDiskDevice *device); + void SessionAdded(RSession *session); + void SessionRemoved(RSession *session); + void PartitionAdded(RPartition *partition); + void PartitionRemoved(RPartition *partition); + + void Dump() const; + +private: + status_t _Scan(BDirectory &dir); + status_t _ScanDevice(const char *path); + +private: + BLocker fLock; + BObjectList fDevices; // sorted by ID + BObjectList fSessions; // + BObjectList fPartitions; // +}; + +#endif // DISK_DEVICE_LIST_H diff --git a/src/servers/registrar/RPartition.cpp b/src/servers/registrar/RPartition.cpp new file mode 100644 index 0000000000..46f9b1aaae --- /dev/null +++ b/src/servers/registrar/RPartition.cpp @@ -0,0 +1,96 @@ +//---------------------------------------------------------------------- +// This software is part of the OpenBeOS distribution and is covered +// by the OpenBeOS license. +//--------------------------------------------------------------------- + +#include "RPartition.h" +#include "RDiskDevice.h" +#include "RDiskDeviceList.h" +#include "RSession.h" + +// constructor +RPartition::RPartition() + : fSession(NULL), + fID(-1), + fChangeCounter(0) +{ +} + +// destructor +RPartition::~RPartition() +{ +} + +// SetTo +status_t +RPartition::SetTo(int fd, const extended_partition_info *partitionInfo) +{ + Unset(); + status_t error = B_OK; + fID = _NextID(); + fChangeCounter = 0; + fInfo = *partitionInfo; + return error; +} + +// Unset +void +RPartition::Unset() +{ + fID = -1; +} + +// DeviceList +RDiskDeviceList * +RPartition::DeviceList() const +{ + return (fSession ? fSession->DeviceList() : NULL); +} + +// Device +RDiskDevice * +RPartition::Device() const +{ + return (fSession ? fSession->Device() : NULL); +} + +// print_partition_info +static +void +print_partition_info(const char *prefix, const extended_partition_info &info) +{ + printf("%soffset: %lld\n", prefix, info.info.offset); + printf("%ssize: %lld\n", prefix, info.info.size); + printf("%sblock size: %ld\n", prefix, info.info.logical_block_size); + printf("%ssession ID: %ld\n", prefix, info.info.session); + printf("%spartition ID: %ld\n", prefix, info.info.partition); + printf("%sdevice: `%s'\n", prefix, info.info.device); + printf("%sflags: %lx\n", prefix, info.flags); + printf("%spartition code: 0x%lx\n", prefix, info.partition_code); + printf("%spartition name: `%s'\n", prefix, info.partition_name); + printf("%spartition type: `%s'\n", prefix, info.partition_type); + printf("%sFS short name: `%s'\n", prefix, info.file_system_short_name); + printf("%sFS long name: `%s'\n", prefix, info.file_system_long_name); + printf("%svolume name: `%s'\n", prefix, info.volume_name); + printf("%smounted at: `%s'\n", prefix, info.mounted_at); + printf("%sFS flags: 0x%lx\n", prefix, info.file_system_flags); +} + +// Dump +void +RPartition::Dump() const +{ + printf(" partition %ld:\n", fInfo.info.partition); + print_partition_info(" ", fInfo); +} + +// _NextID +int32 +RPartition::_NextID() +{ + return atomic_add(&fNextID, 1); +} + +// fNextID +vint32 RPartition::fNextID = 0; + diff --git a/src/servers/registrar/RPartition.h b/src/servers/registrar/RPartition.h new file mode 100644 index 0000000000..3c13574691 --- /dev/null +++ b/src/servers/registrar/RPartition.h @@ -0,0 +1,48 @@ +//---------------------------------------------------------------------- +// This software is part of the OpenBeOS distribution and is covered +// by the OpenBeOS license. +//--------------------------------------------------------------------- + +#ifndef PARTITION_H +#define PARTITION_H + +#include +#include + +class RDiskDevice; +class RDiskDeviceList; +class RSession; + +class RPartition { +public: + RPartition(); + ~RPartition(); + + status_t SetTo(int fd, const extended_partition_info *partitionInfo); + void Unset(); + + void SetSession(RSession *session) { fSession = session; } + RDiskDeviceList *DeviceList() const; + RDiskDevice *Device() const; + RSession *Session() const { return fSession; } + + int32 ID() const { return fID; } + int32 ChangeCounter() const { return fChangeCounter; } + + const extended_partition_info *Info() const { return &fInfo; } + + void Dump() const; + +private: + static int32 _NextID(); + +private: + RSession *fSession; + int32 fID; + int32 fChangeCounter; + extended_partition_info fInfo; + + static vint32 fNextID; +}; + +#endif // PARTITION_H diff --git a/src/servers/registrar/RSession.cpp b/src/servers/registrar/RSession.cpp new file mode 100644 index 0000000000..f620f23b40 --- /dev/null +++ b/src/servers/registrar/RSession.cpp @@ -0,0 +1,157 @@ +//---------------------------------------------------------------------- +// This software is part of the OpenBeOS distribution and is covered +// by the OpenBeOS license. +//--------------------------------------------------------------------- + +#include + +#include + +#include "RSession.h" +#include "RDiskDevice.h" +#include "RDiskDeviceList.h" +#include "RPartition.h" + +// constructor +RSession::RSession() + : fPartitions(10, true), + fDevice(NULL), + fID(-1), + fChangeCounter(0) +{ +} + +// destructor +RSession::~RSession() +{ +} + +// SetTo +status_t +RSession::SetTo(int fd, const session_info *sessionInfo) +{ + Unset(); + status_t error = B_OK; + fID = _NextID(); + fChangeCounter = 0; + fInfo = *sessionInfo; + // iterate through the partitions + for (int32 i = 0; ; i++) { + // get the partition info + extended_partition_info partitionInfo; + status_t status = get_nth_partition_info(fd, sessionInfo->index, i, + &partitionInfo, (i == 0 ? fPartitioningSystem : NULL)); + if (status != B_OK) { + if (status != B_ENTRY_NOT_FOUND) + error = status; + break; + } + // create and add a RPartition + if (RPartition *partition = new(nothrow) RPartition) { + error = partition->SetTo(fd, &partitionInfo); + if (error == B_OK) + AddPartition(partition); + else + delete partition; + } else + error = B_NO_MEMORY; + } + // cleanup on error + if (error != B_OK) + Unset(); + return error; +} + +// Unset +void +RSession::Unset() +{ + for (int32 i = CountPartitions() - 1; i >= 0; i--) + RemovePartition(i); + fID = -1; +} + +// DeviceList +RDiskDeviceList * +RSession::DeviceList() const +{ + return (fDevice ? fDevice->DeviceList() : NULL); +} + +// AddPartition +bool +RSession::AddPartition(RPartition *partition) +{ + bool success = false; + if (partition) { + success = fPartitions.AddItem(partition); + if (success) { + partition->SetSession(this); + if (RDiskDeviceList *deviceList = DeviceList()) + deviceList->PartitionAdded(partition); + } + } + return success; +} + +// RemovePartition +bool +RSession::RemovePartition(int32 index) +{ + RPartition *partition = PartitionAt(index); + if (partition) { + partition->SetSession(NULL); + fPartitions.RemoveItemAt(index); + if (RDiskDeviceList *deviceList = DeviceList()) + deviceList->PartitionRemoved(partition); + delete partition; + } + return (partition != NULL); +} + +// RemovePartition +bool +RSession::RemovePartition(RPartition *partition) +{ + bool success = false; + if (partition) { + int32 index = fPartitions.IndexOf(partition); + if (index >= 0) + success = RemovePartition(index); + } + return success; +} + +// print_session_info +static +void +print_session_info(const char *prefix, const session_info &info) +{ + printf("%soffset: %lld\n", prefix, info.offset); + printf("%ssize: %lld\n", prefix, info.size); + printf("%sblock size: %ld\n", prefix, info.logical_block_size); + printf("%sindex: %ld\n", prefix, info.index); + printf("%sflags: %lx\n", prefix, info.flags); +} + +// Dump +void +RSession::Dump() const +{ + printf(" session %ld:\n", fInfo.index); + print_session_info(" ", fInfo); + printf(" partitioning : `%s'\n", fPartitioningSystem); + for (int32 i = 0; RPartition *partition = PartitionAt(i); i++) + partition->Dump(); +} + +// _NextID +int32 +RSession::_NextID() +{ + return atomic_add(&fNextID, 1); +} + +// fNextID +vint32 RSession::fNextID = 0; + diff --git a/src/servers/registrar/RSession.h b/src/servers/registrar/RSession.h new file mode 100644 index 0000000000..726c2ea2e1 --- /dev/null +++ b/src/servers/registrar/RSession.h @@ -0,0 +1,56 @@ +//---------------------------------------------------------------------- +// This software is part of the OpenBeOS distribution and is covered +// by the OpenBeOS license. +//--------------------------------------------------------------------- + +#ifndef SESSION_H +#define SESSION_H + +#include +#include + +class RDiskDevice; +class RDiskDeviceList; +class RPartition; + +class RSession { +public: + RSession(); + ~RSession(); + + status_t SetTo(int fd, const session_info *sessionInfo); + void Unset(); + + void SetDevice(RDiskDevice *device) { fDevice = device; } + RDiskDeviceList *DeviceList() const; + RDiskDevice *Device() const { return fDevice; } + + int32 ID() const { return fID; } + int32 ChangeCounter() const { return fChangeCounter; } + + bool AddPartition(RPartition *partition); + bool RemovePartition(int32 index); + bool RemovePartition(RPartition *partition); + int32 CountPartitions() const { return fPartitions.CountItems(); } + RPartition *PartitionAt(int32 index) const + { return fPartitions.ItemAt(index); } + + const session_info *Info() const { return &fInfo; } + + void Dump() const; + +private: + static int32 _NextID(); + +private: + BObjectList fPartitions; + RDiskDevice *fDevice; + int32 fID; + int32 fChangeCounter; + session_info fInfo; + char fPartitioningSystem[B_FILE_NAME_LENGTH]; + + static vint32 fNextID; +}; + +#endif // SESSION_H