1 // Copyright (c) 2003, OpenBeOS 2 // 3 // This software is part of the OpenBeOS distribution and is covered 4 // by the OpenBeOS license. 5 // 6 // File: rmindex.cpp 7 // Author: Scott Dellinger (dellinsd@myrealbox.com) 8 // Description: Removes an index from a volume. 9 // 10 // Changelog: 11 // 2003-03-09 initial version 12 // 13 14 // std C includes 15 #include <stdio.h> 16 #include <string.h> 17 #include <errno.h> 18 19 // BeOS C includes 20 #include <fs_info.h> 21 #include <fs_index.h> 22 #include <TypeConstants.h> 23 #include <Directory.h> 24 #include <Path.h> 25 #include <Volume.h> 26 27 #include <getopt.h> 28 29 // The following enum and #define are copied from gnu/sys2.h, because it 30 // didn't want to compile when including that directly. Since that file 31 // is marked as being temporary and getting migrated into system.h, 32 // assume these'll go away soon. 33 34 /* These enum values cannot possibly conflict with the option values 35 ordinarily used by commands, including CHAR_MAX + 1, etc. Avoid 36 CHAR_MIN - 1, as it may equal -1, the getopt end-of-options value. */ 37 enum 38 { 39 GETOPT_HELP_CHAR = (CHAR_MIN - 2), 40 GETOPT_VERSION_CHAR = (CHAR_MIN - 3) 41 }; 42 43 #define GETOPT_HELP_OPTION_DECL \ 44 "help", no_argument, 0, GETOPT_HELP_CHAR 45 46 static struct option const longopts[] = 47 { 48 {"volume", required_argument, 0, 'd'}, 49 {"type", required_argument, 0, 't'}, 50 {"verbose", no_argument, 0, 'v'}, 51 {GETOPT_HELP_OPTION_DECL}, 52 {0, 0, 0, 0} 53 }; 54 55 void usage(int); 56 const char* lookup_index_type(uint32); 57 58 int main (int32 argc, char **argv) 59 { 60 int c; 61 int verbose = 0; 62 dev_t vol_device = 0; 63 char *index_name = NULL; 64 int retval; 65 char *error_message; 66 67 while ((c = getopt_long(argc, argv, "d:ht:v", longopts, NULL)) != -1) 68 { 69 switch (c) 70 { 71 case 0: 72 break; 73 case 'd': 74 vol_device = dev_for_path(optarg); 75 if (vol_device < 0) 76 { 77 fprintf(stderr, "%s: can't get information about volume: %s\n", argv[0], optarg); 78 return (-1); 79 } 80 break; 81 case GETOPT_HELP_CHAR: 82 usage(0); 83 break; 84 case 'v': 85 verbose = 1; 86 break; 87 default: 88 usage(1); 89 break; 90 } 91 } 92 93 /* Remove the index from the volume of the current 94 directory if no volume was specified. */ 95 if (vol_device == 0) 96 { 97 vol_device = dev_for_path("."); 98 if (vol_device < 0) 99 { 100 fprintf(stderr, "%s: can't get information about current volume\n", argv[0]); 101 return (-1); 102 } 103 } 104 105 if (argc - optind == 1) // last argument 106 { 107 index_name = argv[optind]; 108 } else 109 { 110 usage(1); 111 } 112 113 if (verbose) 114 { 115 /* Get the mount point of the specified volume. */ 116 BVolume volume(vol_device); 117 BDirectory dir; 118 volume.GetRootDirectory(&dir); 119 BPath path(&dir, NULL); 120 121 /* Get the index type. */ 122 index_info i_info; 123 status_t status = fs_stat_index(vol_device, index_name, &i_info); 124 if (status != B_OK) 125 { 126 printf("%s: fs_stat_index(): (%d) %s\n", argv[0], errno, strerror(errno)); 127 return (errno); 128 } 129 130 /* Look up the string name equivalent of the index type. */ 131 const char* index_type_str = lookup_index_type(i_info.type); 132 133 fprintf(stdout, "Removing index \"%s\" of type %s from volume mounted at %s.\n", index_name, index_type_str, path.Path()); 134 } 135 136 if ((retval = fs_remove_index(vol_device, index_name)) != 0) 137 { 138 switch (errno) 139 { 140 B_FILE_ERROR: 141 error_message = "A filesystem error prevented the operation."; 142 break; 143 B_BAD_VALUE: 144 error_message = "Invalid device specified."; 145 break; 146 B_NOT_ALLOWED: 147 error_message = "Can't remove a system-reserved index, or the device is read-only."; 148 break; 149 B_NO_MEMORY: 150 error_message = "Insufficient memory to complete the operation."; 151 break; 152 B_ENTRY_NOT_FOUND: 153 error_message = "The specified index does not exist."; 154 break; 155 default: 156 error_message = "An unknown error has occured."; 157 break; 158 } 159 160 fprintf(stderr, "%s\n", error_message); 161 } 162 163 return (0); 164 } 165 166 void usage (int status) 167 { 168 fprintf (stderr, 169 "Usage: rmindex [OPTION]... INDEX_NAME\n" 170 "\n" 171 "Removes the index named INDEX_NAME from a disk volume. Once this has been\n" 172 "done, it will no longer be possible to use the query system to search for\n" 173 "files with the INDEX_NAME attribute.\n" 174 "\n" 175 " -d, --volume=PATH a path on the volume from which the index will be\n" 176 " removed\n" 177 " -h, --help display this help and exit\n" 178 " -v, --verbose print information about the index being removed\n" 179 "\n" 180 "INDEX_NAME is the name of a file attribute.\n" 181 "\n" 182 "If no volume is specified, the volume of the current directory is assumed.\n"); 183 184 exit(status); 185 } 186 187 const char* lookup_index_type(uint32 device_type) 188 { 189 switch (device_type) 190 { 191 case B_DOUBLE_TYPE: 192 return "double"; 193 break; 194 case B_FLOAT_TYPE: 195 return "float"; 196 break; 197 case B_INT64_TYPE: 198 return "llong"; 199 break; 200 case B_INT32_TYPE: 201 return "int"; 202 break; 203 case B_STRING_TYPE: 204 return "string"; 205 break; 206 default: 207 return "unknown"; 208 break; 209 } 210 } 211