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