1/* 2 * Copyright 2015, Axel D��rfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "Utility.h" 8 9#include <errno.h> 10#include <stdio.h> 11#include <string.h> 12 13#include <device/scsi.h> 14#include <DiskDevice.h> 15#include <DiskDeviceRoster.h> 16#include <fs_info.h> 17#include <Volume.h> 18 19 20namespace { 21 22 23status_t 24IssueDeviceCommand(const char* path, int opcode, void* buffer, 25 size_t bufferSize) 26{ 27 fs_info info; 28 if (fs_stat_dev(dev_for_path(path), &info) == B_OK) { 29 if (strcmp(info.fsh_name, "devfs") != 0) 30 path = info.device_name; 31 } 32 33 int device = open(path, O_RDONLY); 34 if (device < 0) 35 return device; 36 37 status_t status = B_OK; 38 39 if (ioctl(device, opcode, buffer, bufferSize) != 0) { 40 fprintf(stderr, "Failed to process %d on %s: %s\n", opcode, path, 41 strerror(errno)); 42 status = errno; 43 } 44 close(device); 45 return status; 46} 47 48 49} // private namespace 50 51 52namespace Utility { 53 54 55bool 56IsReadOnlyVolume(dev_t device) 57{ 58 BVolume volume; 59 status_t status = volume.SetTo(device); 60 if (status != B_OK) { 61 fprintf(stderr, "Failed to get BVolume for device %" B_PRIdDEV 62 ": %s\n", device, strerror(status)); 63 return false; 64 } 65 66 BDiskDeviceRoster roster; 67 BDiskDevice diskDevice; 68 BPartition* partition; 69 status = roster.FindPartitionByVolume(volume, &diskDevice, &partition); 70 if (status != B_OK) { 71 fprintf(stderr, "Failed to get partition for device %" B_PRIdDEV 72 ": %s\n", device, strerror(status)); 73 return false; 74 } 75 76 return partition->IsReadOnly(); 77} 78 79 80bool 81IsReadOnlyVolume(const char* path) 82{ 83 return IsReadOnlyVolume(dev_for_path(path)); 84} 85 86 87status_t 88BlockMedia(const char* path, bool block) 89{ 90 return IssueDeviceCommand(path, B_SCSI_PREVENT_ALLOW, &block, 91 sizeof(block)); 92} 93 94 95status_t 96EjectMedia(const char* path) 97{ 98 return IssueDeviceCommand(path, B_EJECT_DEVICE, NULL, 0); 99} 100 101 102BString 103TranslatePath(const char* originalPath) 104{ 105 BString path = originalPath; 106 107 // TODO: get actual home directory! 108 const char* home = "/boot/home"; 109 path.ReplaceAll("$HOME", home); 110 path.ReplaceAll("${HOME}", home); 111 if (path.StartsWith("~/")) 112 path.ReplaceFirst("~", home); 113 114 return path; 115} 116 117 118} // namespace Utility 119