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