xref: /haiku/src/bin/rmindex.cpp (revision d3d8b26997fac34a84981e6d2b649521de2cc45a)
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