xref: /haiku/src/servers/launch/Utility.cpp (revision 4bd0c1066b227cec4b79883bdef697c7a27f2e90)
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 
20 namespace {
21 
22 
23 status_t
24 IssueDeviceCommand(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 
52 namespace Utility {
53 
54 
55 bool
56 IsReadOnlyVolume(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 
80 bool
81 IsReadOnlyVolume(const char* path)
82 {
83 	return IsReadOnlyVolume(dev_for_path(path));
84 }
85 
86 
87 status_t
88 BlockMedia(const char* path, bool block)
89 {
90 	return IssueDeviceCommand(path, B_SCSI_PREVENT_ALLOW, &block,
91 		sizeof(block));
92 }
93 
94 
95 status_t
96 EjectMedia(const char* path)
97 {
98 	return IssueDeviceCommand(path, B_EJECT_DEVICE, NULL, 0);
99 }
100 
101 
102 BString
103 TranslatePath(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