static char *getMountPoint(const char *devname) { BVolumeRoster mounts; BVolume vol; mounts.Rewind(); while (mounts.GetNextVolume(&vol) == B_NO_ERROR) { fs_info fsinfo; fs_stat_dev(vol.Device(), &fsinfo); if (strcmp(devname, fsinfo.device_name) == 0) { //char buf[B_FILE_NAME_LENGTH]; BDirectory directory; BEntry entry; BPath path; status_t rc; rc = vol.GetRootDirectory(&directory); BAIL_IF_MACRO(rc < B_OK, strerror(rc), NULL); rc = directory.GetEntry(&entry); BAIL_IF_MACRO(rc < B_OK, strerror(rc), NULL); rc = entry.GetPath(&path); BAIL_IF_MACRO(rc < B_OK, strerror(rc), NULL); const char *str = path.Path(); BAIL_IF_MACRO(str == NULL, ERR_OS_ERROR, NULL); /* ?! */ char *retval = (char *) allocator.Malloc(strlen(str) + 1); BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL); strcpy(retval, str); return(retval); } /* if */ } /* while */ return(NULL); } /* getMountPoint */
void AutoMounter::GetSettings(BMessage *_DEVICE_MAP_ONLY(message)) { #if _INCLUDES_CLASS_DEVICE_MAP message->AddBool("checkRemovableOnly", fScanParams.removableOrUnknownOnly); message->AddBool("checkCDs", fScanParams.checkCDROMs); message->AddBool("checkFloppies", fScanParams.checkFloppies); message->AddBool("checkOtherRemovables", fScanParams.checkOtherRemovable); message->AddBool("autoMountRemovableOnly", fAutomountParams.mountRemovableDisksOnly); message->AddBool("autoMountAll", fAutomountParams.mountAllFS); message->AddBool("autoMountAllBFS", fAutomountParams.mountBFS); message->AddBool("autoMountAllHFS", fAutomountParams.mountHFS); message->AddBool("initialMountAll", fInitialMountAll); message->AddBool("initialMountAllBFS", fInitialMountAllBFS); message->AddBool("initialMountRestore", fInitialMountRestore); message->AddBool("initialMountAllHFS", fInitialMountAllHFS); message->AddBool("suspended", fSuspended); // Save mounted volumes so we can optionally mount them on next // startup BVolumeRoster volumeRoster; BVolume volume; while (volumeRoster.GetNextVolume(&volume) == B_OK) { fs_info info; if (fs_stat_dev(volume.Device(), &info) == 0 && info.flags & (B_FS_IS_REMOVABLE | B_FS_IS_PERSISTENT)) message->AddString(info.device_name, info.volume_name); } #endif }
static char *getMountPoint(const char *devname, char *buf, size_t bufsize) { BVolumeRoster mounts; BVolume vol; mounts.Rewind(); while (mounts.GetNextVolume(&vol) == B_NO_ERROR) { fs_info fsinfo; fs_stat_dev(vol.Device(), &fsinfo); if (strcmp(devname, fsinfo.device_name) == 0) { BDirectory directory; BEntry entry; BPath path; const char *str; if ( (vol.GetRootDirectory(&directory) < B_OK) || (directory.GetEntry(&entry) < B_OK) || (entry.GetPath(&path) < B_OK) || ( (str = path.Path()) == NULL) ) return NULL; strncpy(buf, str, bufsize-1); buf[bufsize-1] = '\0'; return buf; } /* if */ } /* while */ return NULL; } /* getMountPoint */
void PrintCompact(dev_t device, bool showBlocks, bool all) { fs_info info; if (fs_stat_dev(device, &info) != B_OK) return; if (!all && (info.flags & B_FS_IS_PERSISTENT) == 0) return; PrintMountPoint(info.dev, false); PrintType(info.fsh_name); PrintBlocks(info.total_blocks, info.block_size, showBlocks); PrintBlocks(info.free_blocks, info.block_size, showBlocks); printf(" "); PrintFlag(info.flags, B_FS_HAS_QUERY, "Q", "-"); PrintFlag(info.flags, B_FS_HAS_ATTR, "A", "-"); PrintFlag(info.flags, B_FS_HAS_MIME, "M", "-"); PrintFlag(info.flags, B_FS_IS_SHARED, "S", "-"); PrintFlag(info.flags, B_FS_IS_PERSISTENT, "P", "-"); PrintFlag(info.flags, B_FS_IS_REMOVABLE, "R", "-"); PrintFlag(info.flags, B_FS_IS_READONLY, "-", "W"); printf(" %s\n", info.device_name); }
void PrintVerbose(dev_t device) { fs_info info; if (fs_stat_dev(device, &info) != B_OK) { fprintf(stderr, "Could not stat fs: %s\n", strerror(errno)); return; } printf(" Device No.: %ld\n", info.dev); PrintMountPoint(info.dev, true); printf(" Volume Name: \"%s\"\n", info.volume_name); printf(" File System: %s\n", info.fsh_name); printf(" Device: %s\n", info.device_name); printf(" Flags: "); PrintFlag(info.flags, B_FS_HAS_QUERY, "Q", "-"); PrintFlag(info.flags, B_FS_HAS_ATTR, "A", "-"); PrintFlag(info.flags, B_FS_HAS_MIME, "M", "-"); PrintFlag(info.flags, B_FS_IS_SHARED, "S", "-"); PrintFlag(info.flags, B_FS_IS_PERSISTENT, "P", "-"); PrintFlag(info.flags, B_FS_IS_REMOVABLE, "R", "-"); PrintFlag(info.flags, B_FS_IS_READONLY, "-", "W"); printf("\n I/O Size: %10s (%Ld byte)\n", ByteString(info.io_size, 1), info.io_size); printf(" Block Size: %10s (%Ld byte)\n", ByteString(info.block_size, 1), info.block_size); printf(" Total Blocks: %10s (%Ld blocks)\n", ByteString(info.total_blocks, info.block_size), info.total_blocks); printf(" Free Blocks: %10s (%Ld blocks)\n", ByteString(info.free_blocks, info.block_size), info.free_blocks); printf(" Total Nodes: %Ld\n", info.total_nodes); printf(" Free Nodes: %Ld\n", info.free_nodes); printf(" Root Inode: %Ld\n", info.root); }
inline bool QStorageIterator::next() { BVolume volume; if (m_volumeRoster.GetNextVolume(&volume) != B_OK) return false; BDirectory directory; if (volume.GetRootDirectory(&directory) != B_OK) return false; const BPath path(&directory); fs_info fsInfo; memset(&fsInfo, 0, sizeof(fsInfo)); if (fs_stat_dev(volume.Device(), &fsInfo) != 0) return false; m_rootPath = path.Path(); m_fileSystemType = QByteArray(fsInfo.fsh_name); const QByteArray deviceName(fsInfo.device_name); m_device = (deviceName.isEmpty() ? QByteArray::number(qint32(volume.Device())) : deviceName); return true; }
// get_volume_info bool get_volume_info( BVolume& volume, BString& volumeName, bool& isCDROM, BString& deviceName ) { bool success = false; isCDROM = false; deviceName = ""; volumeName = ""; char name[B_FILE_NAME_LENGTH]; if ( volume.GetName( name ) >= B_OK ) // disk is currently mounted { volumeName = name; dev_t dev = volume.Device(); fs_info info; if ( fs_stat_dev( dev, &info ) == B_OK ) { success = true; deviceName = info.device_name; if ( volume.IsReadOnly() ) { int i_dev = open( info.device_name, O_RDONLY ); if ( i_dev >= 0 ) { device_geometry g; if ( ioctl( i_dev, B_GET_GEOMETRY, &g, sizeof( g ) ) >= 0 ) isCDROM = ( g.device_type == B_CD ); close( i_dev ); } } } } return success; }
static bool is_drive_mounted(const char *dev_name, char *mount_name) { int32 i = 0; dev_t d; fs_info info; while ((d = next_dev(&i)) >= 0) { fs_stat_dev(d, &info); if (strcmp(dev_name, info.device_name) == 0) { status_t err = -1; BPath mount; BDirectory dir; BEntry entry; node_ref node; node.device = info.dev; node.node = info.root; err = dir.SetTo(&node); if (!err) err = dir.GetEntry(&entry); if (!err) err = entry.GetPath(&mount); if (!err) { strcpy(mount_name, mount.Path()); return true; } } } return false; }
status_t Settings::WriteSwapSettings() { BPath path; if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) return B_ERROR; path.Append("kernel/drivers"); path.Append(kVirtualMemorySettings); BFile file; if (file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE) != B_OK) return B_ERROR; fs_info info; if (fs_stat_dev(SwapVolume(), &info) != 0) return B_ERROR; char buffer[1024]; snprintf(buffer, sizeof(buffer), "vm %s\nswap_auto %s\nswap_size %" B_PRIdOFF "\nswap_volume_name %s\nswap_volume_device %s\n" "swap_volume_filesystem %s\nswap_volume_capacity %" B_PRIdOFF "\n", SwapEnabled() ? "on" : "off", SwapAutomatic() ? "yes" : "no", SwapSize(), info.volume_name, info.device_name, info.fsh_name, info.total_blocks * info.block_size); file.Write(buffer, strlen(buffer)); return B_OK; }
static inline QString retrieveLabel(const QByteArray &device) { #ifdef Q_OS_LINUX static const char pathDiskByLabel[] = "/dev/disk/by-label"; QDirIterator it(QLatin1String(pathDiskByLabel), QDir::NoDotAndDotDot); while (it.hasNext()) { it.next(); QFileInfo fileInfo(it.fileInfo()); if (fileInfo.isSymLink() && fileInfo.symLinkTarget().toLocal8Bit() == device) return fileInfo.fileName(); } #elif defined Q_OS_HAIKU fs_info fsInfo; memset(&fsInfo, 0, sizeof(fsInfo)); int32 pos = 0; dev_t dev; while ((dev = next_dev(&pos)) >= 0) { if (fs_stat_dev(dev, &fsInfo) != 0) continue; if (qstrcmp(fsInfo.device_name, device.constData()) == 0) return QString::fromLocal8Bit(fsInfo.volume_name); } #else Q_UNUSED(device); #endif return QString(); }
bool CDDBDaemon::_CanLookup(const dev_t device, uint32* cddbId, scsi_toc_toc* toc) const { if (cddbId == NULL || toc == NULL) return false; // Is it an Audio disk? fs_info info; fs_stat_dev(device, &info); if (strncmp(info.fsh_name, kCddaFsName, strlen(kCddaFsName)) != 0) return false; // Does it have the CD:do_lookup attribute and is it true? BVolume volume(device); BDirectory directory; volume.GetRootDirectory(&directory); bool doLookup; if (directory.ReadAttr("CD:do_lookup", B_BOOL_TYPE, 0, (void *)&doLookup, sizeof(bool)) < B_OK || !doLookup) return false; // Does it have the CD:cddbid attribute? if (directory.ReadAttr("CD:cddbid", B_UINT32_TYPE, 0, (void *)cddbId, sizeof(uint32)) < B_OK) return false; // Does it have the CD:toc attribute? if (directory.ReadAttr("CD:toc", B_RAW_TYPE, 0, (void *)toc, kMaxTocSize) < B_OK) return false; return true; }
/*! \brief Returns whether the volume is shared. \return \c true, when the object is properly initialized and the referred to volume is shared, \c false otherwise. */ bool BVolume::IsShared(void) const { // check initialization status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); // get FS stat fs_info info; if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) error = errno; return (error == B_OK && (info.flags & B_FS_IS_SHARED)); }
/*! \brief Returns whether the volume is removable. \return \c true, when the object is properly initialized and the referred to volume is removable, \c false otherwise. */ bool BVolume::IsRemovable() const { // check initialization status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); // get FS stat fs_info info; if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) error = errno; return (error == B_OK && (info.flags & B_FS_IS_REMOVABLE)); }
/*! \brief Returns the amount of storage that's currently unused on the volume (in bytes). \return - The amount of storage that's currently unused on the volume (in bytes), when the object is properly initialized. - \c B_BAD_VALUE otherwise. */ off_t BVolume::FreeBytes() const { // check initialization status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); // get FS stat fs_info info; if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) error = errno; return (error == B_OK ? info.free_blocks * info.block_size : error); }
/*! \brief Returns whether the directory represented by this BDirectory is a root directory of a volume. \return - \c true, if the BDirectory is properly initialized and represents a root directory of some volume, - \c false, otherwise. */ bool BDirectory::IsRootDirectory() const { // compare the directory's node ID with the ID of the root node of the FS bool result = false; node_ref ref; fs_info info; if (GetNodeRef(&ref) == B_OK && fs_stat_dev(ref.device, &info) == 0) result = (ref.node == info.root); return result; }
/*! \brief Returns whether the volume supports queries. \return \c true, when the object is properly initialized and the referred to volume supports queries, \c false otherwise. */ bool BVolume::KnowsQuery(void) const { // check initialization status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); // get FS stat fs_info info; if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) error = errno; return (error == B_OK && (info.flags & B_FS_HAS_QUERY)); }
uint32 GetVolumeFlags(Model *model) { fs_info info; if (model->IsVolume()) { // search for the correct volume int32 cookie = 0; dev_t device; while ((device = next_dev(&cookie)) >= B_OK) { if (fs_stat_dev(device,&info)) continue; if (!strcmp(info.volume_name,model->Name())) return info.flags; } return B_FS_HAS_ATTR; } if (!fs_stat_dev(model->NodeRef()->device,&info)) return info.flags; return B_FS_HAS_ATTR; }
/*! \brief Returns the size of one block (in bytes). It depends on the underlying file system what this means exactly. \return - The block size in bytes. - \c B_NO_INIT if the volume is not initialized. - Other errors forwarded from the file system. */ off_t BVolume::BlockSize() const { // check initialization if (InitCheck() != B_OK) return B_NO_INIT; // get FS stat fs_info info; if (fs_stat_dev(fDevice, &info) != 0) return errno; return info.block_size; }
/*! \brief Returns the name of the volume. The name of the volume is copied into the provided buffer. \param name A pointer to a pre-allocated character buffer of size \c B_FILE_NAME_LENGTH or larger into which the name of the volume shall be written. \return - \c B_OK: Everything went fine. - \c B_BAD_VALUE: \c NULL \a name or the object is not properly initialized. - another error code */ status_t BVolume::GetName(char *name) const { // check parameter and initialization status_t error = (name && InitCheck() == B_OK ? B_OK : B_BAD_VALUE); // get FS stat fs_info info; if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) error = errno; // copy the name if (error == B_OK) strncpy(name, info.volume_name, B_FILE_NAME_LENGTH); return error; }
/*! \brief Sets the name of the volume referred to by this object. \param name The volume's new name. Must not be longer than \c B_FILE_NAME_LENGTH (including the terminating null). \return - \c B_OK: Everything went fine. - \c B_BAD_VALUE: \c NULL \a name or the object is not properly initialized. - another error code */ status_t BVolume::SetName(const char *name) { // check initialization if (!name || InitCheck() != B_OK) return B_BAD_VALUE; if (strlen(name) >= B_FILE_NAME_LENGTH) return B_NAME_TOO_LONG; // get the FS stat (including the old name) first fs_info oldInfo; if (fs_stat_dev(fDevice, &oldInfo) != 0) return errno; if (strcmp(name, oldInfo.volume_name) == 0) return B_OK; // set the volume name fs_info newInfo; strlcpy(newInfo.volume_name, name, sizeof(newInfo.volume_name)); status_t error = _kern_write_fs_info(fDevice, &newInfo, FS_WRITE_FSINFO_NAME); if (error != B_OK) return error; // change the name of the mount point // R5 implementation checks, if an entry with the volume's old name // exists in the root directory and renames that entry, if it is indeed // the mount point of the volume (or a link referring to it). In all other // cases, nothing is done (even if the mount point is named like the // volume, but lives in a different directory). // We follow suit for the time being. // NOTE: If the volume name itself is actually "boot", then this code // tries to rename /boot, but that is prevented in the kernel. BPath entryPath; BEntry entry; BEntry traversedEntry; node_ref entryNodeRef; if (BPrivate::Storage::check_entry_name(name) == B_OK && BPrivate::Storage::check_entry_name(oldInfo.volume_name) == B_OK && entryPath.SetTo("/", oldInfo.volume_name) == B_OK && entry.SetTo(entryPath.Path(), false) == B_OK && entry.Exists() && traversedEntry.SetTo(entryPath.Path(), true) == B_OK && traversedEntry.GetNodeRef(&entryNodeRef) == B_OK && entryNodeRef.device == fDevice && entryNodeRef.node == oldInfo.root) { entry.Rename(name, false); } return error; }
/*! \brief Returns the icon of the volume. \param icon A pointer to a pre-allocated BBitmap of the correct dimension to store the requested icon (16x16 for the mini and 32x32 for the large icon). \param which Specifies the size of the icon to be retrieved: \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon. */ status_t BVolume::GetIcon(BBitmap *icon, icon_size which) const { // check initialization if (InitCheck() != B_OK) return B_NO_INIT; // get FS stat for the device name fs_info info; if (fs_stat_dev(fDevice, &info) != 0) return errno; // get the icon return get_device_icon(info.device_name, icon, which); }
status_t BVolume::GetIcon(uint8** _data, size_t* _size, type_code* _type) const { // check initialization if (InitCheck() != B_OK) return B_NO_INIT; // get FS stat for the device name fs_info info; if (fs_stat_dev(fDevice, &info) != 0) return errno; // get the icon return get_device_icon(info.device_name, _data, _size, _type); }
/* BeOS has a statvfs function, but it does not return sensible values for f_files, f_ffree and f_favail, and lacks f_type, f_basetype and f_fstypename. Use 'struct fs_info' instead. */ static int statfs (char const *filename, struct fs_info *buf) { dev_t device = dev_for_path (filename); if (device < 0) { errno = (device == B_ENTRY_NOT_FOUND ? ENOENT : device == B_BAD_VALUE ? EINVAL : device == B_NAME_TOO_LONG ? ENAMETOOLONG : device == B_NO_MEMORY ? ENOMEM : device == B_FILE_ERROR ? EIO : 0); return -1; } /* If successful, buf->dev will be == device. */ return fs_stat_dev (device, buf); }
status_t CDDBLookup::Lookup(CDDBServer& server, const char* path, bool dumpOnly, bool verbose) { BVolumeRoster roster; BVolume volume; while (roster.GetNextVolume(&volume) == B_OK) { fs_info info; if (fs_stat_dev(volume.Device(), &info) != B_OK) continue; if (strcmp(path, info.device_name) == 0) return Lookup(server, volume.Device(), dumpOnly, verbose); } return B_ENTRY_NOT_FOUND; }
int get_fs_usage (const char *path, const char *disk, struct fs_usage *fsp) { int result = -1; dev_t device = dev_for_path (path); if (device >0) { fs_info info; if (fs_stat_dev (device, &info) == 0) { fsp->fsu_blocks = adjust_blocks (info.total_blocks, info.block_size, 512); fsp->fsu_bfree = fsp->fsu_bavail = adjust_blocks (info.free_blocks, info.block_size, 512); fsp->fsu_files = info.total_nodes; fsp->fsu_ffree = info.free_nodes; result = 0; } } return result; };
/*! \brief Returns the root directory of the volume referred to by the object. \param directory A pointer to a pre-allocated BDirectory to be initialized to the volume's root directory. \return - \c B_OK: Everything went fine. - \c B_BAD_VALUE: \c NULL \a directory or the object is not properly initialized. - another error code */ status_t BVolume::GetRootDirectory(BDirectory *directory) const { // check parameter and initialization status_t error = (directory && InitCheck() == B_OK ? B_OK : B_BAD_VALUE); // get FS stat fs_info info; if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) error = errno; // init the directory if (error == B_OK) { node_ref ref; ref.device = info.dev; ref.node = info.root; error = directory->SetTo(&ref); } return error; }
static int fill_statvfs(dev_t device, struct statvfs *statvfs) { fs_info info; if (fs_stat_dev(device, &info) < 0) return -1; statvfs->f_frsize = statvfs->f_bsize = info.block_size; statvfs->f_blocks = info.total_blocks; statvfs->f_bavail = statvfs->f_bfree = info.free_blocks; statvfs->f_files = info.total_nodes; statvfs->f_favail = statvfs->f_ffree = info.free_nodes; statvfs->f_fsid = device; statvfs->f_flag = info.flags & B_FS_IS_READONLY ? ST_RDONLY : 0; statvfs->f_namemax = B_FILE_NAME_LENGTH; return 0; }
/*! \brief Re-initializes the object to refer to the volume specified by the supplied device ID. \param device The device ID of the volume. \param - \c B_OK: Everything went fine. - an error code otherwise */ status_t BVolume::SetTo(dev_t device) { // uninitialize Unset(); // check the parameter status_t error = (device >= 0 ? B_OK : B_BAD_VALUE); if (error == B_OK) { fs_info info; if (fs_stat_dev(device, &info) != 0) error = errno; } // set the new value if (error == B_OK) fDevice = device; // set the init status variable fCStatus = error; return fCStatus; }
void SysAddDiskPrefs(void) { // Let BeOS scan for HFS drives D(bug("Looking for Mac volumes...\n")); system("mountvolume -allhfs"); // Add all HFS volumes int32 i = 0; dev_t d; fs_info info; while ((d = next_dev(&i)) >= 0) { fs_stat_dev(d, &info); status_t err = -1; BPath mount; if (!strcmp(info.fsh_name, "hfs")) { BDirectory dir; BEntry entry; node_ref node; node.device = info.dev; node.node = info.root; err = dir.SetTo(&node); if (!err) err = dir.GetEntry(&entry); if (!err) err = entry.GetPath(&mount); } #warning TODO: unmount inuse disk! #if 0 if (!err) err = unmount(mount.Path()); #endif if (!err) { char dev_name[B_FILE_NAME_LENGTH]; if (info.flags & B_FS_IS_READONLY) { dev_name[0] = '*'; dev_name[1] = 0; } else dev_name[0] = 0; strcat(dev_name, info.device_name); PrefsAddString("disk", dev_name); } } }
// SymLink handling: // symlink pose uses the resolved model to retrieve the icon, if not broken // everything else, like the attributes, etc. is retrieved directly from the // symlink itself BPose::BPose(Model* model, BPoseView* view, uint32 clipboardMode, bool selected) : fModel(model), fWidgetList(4, true), fClipboardMode(clipboardMode), fPercent(-1), fSelectionTime(0), fIsSelected(selected), fHasLocation(false), fNeedsSaveLocation(false), fListModeInited(false), fWasAutoPlaced(false), fBrokenSymLink(false), fBackgroundClean(false) { CreateWidgets(view); if (model->IsVolume()) { fs_info info; dev_t device = model->NodeRef()->device; BVolume* volume = new BVolume(device); if (volume->InitCheck() == B_OK && fs_stat_dev(device, &info) == B_OK) { // Philosophy here: // Bars go on all read/write volumes // Exceptions: Not on CDDA if (strcmp(info.fsh_name,"cdda") != 0 && !volume->IsReadOnly()) { // The volume is ok and we want space bars on it gPeriodicUpdatePoses.AddPose(this, view, _PeriodicUpdateCallback, volume); if (TrackerSettings().ShowVolumeSpaceBar()) fPercent = CalcFreeSpace(volume); } else delete volume; } else delete volume; } }