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