xref: /haiku/src/bin/isvolume.cpp (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
1 /*
2  * Copyright 2002-2009, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Jonas Sundstrom, jonas.sundstrom@kirilla.com
7  *		Stephan Aßmus <superstippi@gmx.de>
8  */
9 
10 #include <fs_info.h>
11 
12 #include <stdio.h>
13 #include <string.h>
14 
15 #include <DiskDevice.h>
16 #include <DiskDeviceRoster.h>
17 #include <Volume.h>
18 
19 
20 static void
21 usage()
22 {
23 	fprintf(stderr,
24 		"Usage: isvolume {-OPTION} [volumename]\n"
25 		"   Where OPTION is one of:\n"
26 		"      -readonly         - volume is read-only\n"
27 		"      -readonly-partion - partition for the volume is read-only\n"
28 		"      -query            - volume supports queries\n"
29 		"      -attribute        - volume supports attributes\n"
30 		"      -mime             - volume supports MIME information\n"
31 		"      -shared           - volume is shared\n"
32 		"      -persistent       - volume is backed on permanent storage\n"
33 		"      -removable        - volume is on removable media\n"
34 		"   If the option is true for the named volume, 'yes' is printed\n"
35 		"   and if the option is false, 'no' is printed. Multiple options\n"
36 		"   can be specified in which case all of them must be true.\n\n"
37 		"   If no volume is specified, the volume of the current directory is "
38 		"assumed.\n");
39 }
40 
41 
42 int
43 main(int argc, char** argv)
44 {
45 	dev_t volumeDevice = dev_for_path(".");
46 	uint32 isVolumeFlags = 0;
47 	fs_info volumeInfo;
48 	bool doPartitionReadOnlyCheck = false;
49 
50 	for (int i = 1; i < argc; i++) {
51 		if (!strcmp(argv[i], "--help")) {
52 			usage();
53 			return 0;
54 		}
55 
56 		if (argv[i][0] == '-') {
57 			if (strcmp(argv[i], "-readonly") == 0)
58 				isVolumeFlags |= B_FS_IS_READONLY;
59 			else if (strcmp(argv[i], "-query") == 0)
60 				isVolumeFlags |= B_FS_HAS_QUERY;
61 			else if (strcmp(argv[i], "-attribute") == 0)
62 				isVolumeFlags |= B_FS_HAS_ATTR;
63 			else if (strcmp(argv[i], "-mime") == 0)
64 				isVolumeFlags |= B_FS_HAS_MIME;
65 			else if (strcmp(argv[i], "-shared") == 0)
66 				isVolumeFlags |= B_FS_IS_SHARED;
67 			else if (strcmp(argv[i], "-persistent") == 0)
68 				isVolumeFlags |= B_FS_IS_PERSISTENT;
69 			else if (strcmp(argv[i], "-removable") == 0)
70 				isVolumeFlags |= B_FS_IS_REMOVABLE;
71 			else if (strcmp(argv[i], "-readonly-partion"))
72 				doPartitionReadOnlyCheck = true;
73 			else {
74 				fprintf(stderr,
75 					"%s: option %s is not understood (use --help for help)\n",
76 					argv[0], argv[i]);
77 				return 1;
78 			}
79 		} else {
80 			volumeDevice = dev_for_path(argv[i]);
81 
82 			if (volumeDevice < 0) {
83 				fprintf(stderr, "%s: can't get information about volume: %s\n",
84 					argv[0], argv[i]);
85 				return 1;
86 			}
87 		}
88 	}
89 
90 	if (doPartitionReadOnlyCheck) {
91 		// This requires an extra code-path, because volumes may now appear
92 		// writable, but only because of the "write" file-system overlay.
93 		BVolume volume(volumeDevice);
94 		status_t ret = volume.InitCheck();
95 		if (ret != B_OK) {
96 			fprintf(stderr, "%s: failed to get BVolume for device %" B_PRIdDEV
97 				": %s\n", argv[0], volumeDevice, strerror(ret));
98 			return 1;
99 		}
100 
101 		BDiskDeviceRoster roster;
102 		BDiskDevice diskDevice;
103 		BPartition* partition;
104 		ret = roster.FindPartitionByVolume(volume, &diskDevice, &partition);
105 		if (ret != B_OK) {
106 			fprintf(stderr, "%s: failed to get partition for device %" B_PRIdDEV
107 				": %s\n", argv[0], volumeDevice, strerror(ret));
108 			return 1;
109 		}
110 		// check this option directly and not via fs_stat_dev()
111 		if (partition->IsReadOnly()) {
112 			printf("yes\n");
113 			return 0;
114 		}
115 	}
116 
117 	if (fs_stat_dev(volumeDevice, &volumeInfo) == B_OK) {
118 		if (volumeInfo.flags & isVolumeFlags)
119 			printf("yes\n");
120 		else
121 			printf("no\n");
122 
123 		return 0;
124 	} else {
125 		fprintf(stderr, "%s: can't get information about dev_t: %" B_PRIdDEV
126 			"\n", argv[0], volumeDevice);
127 		return 1;
128 	}
129 }
130