btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / bin / query.cpp
blobd7e553bde22304f3b736652ce376ee3b0e5a9967
1 /*
2 * Copyright 2005, Haiku Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT license.
5 * Authors:
6 * Ficus Kirkpatrick (ficus@ior.com)
7 * Jérôme Duval
8 * Axel Dörfler, axeld@pinc-software.de
9 */
11 /* A shell utility for somewhat emulating the Tracker's "Find By Formula"
12 * functionality.
16 #include <Entry.h>
17 #include <LocaleRoster.h>
18 #include <Path.h>
19 #include <Query.h>
20 #include <String.h>
21 #include <Volume.h>
22 #include <VolumeRoster.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
30 extern const char *__progname;
31 static const char *kProgramName = __progname;
33 // Option variables.
34 static bool sAllVolumes = false; // Query all volumes?
35 static bool sEscapeMetaChars = true; // Escape metacharacters?
36 static bool sFilesOnly = false; // Show only files?
37 static bool sLocalizedAppNames = false; // match localized names
40 void
41 usage(void)
43 printf("usage: %s [ -ef ] [ -a || -v <path-to-volume> ] expression\n"
44 " -e\t\tdon't escape meta-characters\n"
45 " -f\t\tshow only files (ie. no directories or symbolic links)\n"
46 " -l\t\tmatch expression with localized application names\n"
47 " -a\t\tperform the query on all volumes\n"
48 " -v <file>\tperform the query on just one volume; <file> can be any\n"
49 "\t\tfile on that volume. Defaults to the current volume.\n"
50 " Hint: '%s name=foo' will find files named \"foo\"\n",
51 kProgramName, kProgramName);
52 exit(0);
56 void
57 perform_query(BVolume &volume, const char *predicate)
59 BQuery query;
60 query.SetVolume(&volume);
62 if (sLocalizedAppNames)
63 query.SetPredicate("BEOS:APP_SIG=*");
64 else
65 query.SetPredicate(predicate);
67 status_t status = query.Fetch();
68 if (status == B_BAD_VALUE) {
69 // the "name=" part may be omitted in our arguments
70 BString string = "name=";
71 string << predicate;
73 query.SetPredicate(string.String());
74 status = query.Fetch();
76 if (status != B_OK) {
77 fprintf(stderr, "%s: bad query expression\n", kProgramName);
78 return;
81 BEntry entry;
82 BPath path;
83 while (query.GetNextEntry(&entry) == B_OK) {
84 if (sFilesOnly && !entry.IsFile())
85 continue;
87 if (entry.GetPath(&path) < B_OK) {
88 fprintf(stderr, "%s: could not get path for entry\n", kProgramName);
89 continue;
92 BString string;
93 if (sLocalizedAppNames && predicate != NULL) {
94 entry_ref ref;
96 if (entry.GetRef(&ref) != B_OK || BLocaleRoster::Default()
97 ->GetLocalizedFileName(string, ref) != B_OK)
98 continue;
100 if (string.IFindFirst(predicate) < 0)
101 continue;
104 string = path.Path();
105 if (sEscapeMetaChars)
106 string.CharacterEscape(" ()?*&\"'[]^\\~|;!<>*$\t", '\\');
108 printf("%s\n", string.String());
114 main(int argc, char **argv)
116 // Make sure we have the minimum number of arguments.
117 if (argc < 2)
118 usage();
120 // Which volume do we make the query on?
121 // Default to the current volume.
122 char volumePath[B_FILE_NAME_LENGTH];
123 strcpy(volumePath, ".");
125 // Parse command-line arguments.
126 int opt;
127 while ((opt = getopt(argc, argv, "efalv:")) != -1) {
128 switch(opt) {
129 case 'e':
130 sEscapeMetaChars = false;
131 break;
132 case 'f':
133 sFilesOnly = true;
134 break;
135 case 'a':
136 sAllVolumes = true;
137 break;
138 case 'l':
139 sLocalizedAppNames = true;
140 break;
141 case 'v':
142 strlcpy(volumePath, optarg, B_FILE_NAME_LENGTH);
143 break;
145 default:
146 usage();
147 break;
151 BVolume volume;
153 if (!sAllVolumes) {
154 // Find the volume that the query should be performed on,
155 // and set the query to it.
156 BEntry entry(volumePath);
157 if (entry.InitCheck() != B_OK) {
158 fprintf(stderr, "%s: \"%s\" is not a valid file\n", kProgramName, volumePath);
159 exit(1);
162 status_t status = entry.GetVolume(&volume);
163 if (status != B_OK) {
164 fprintf(stderr, "%s: could not get volume: %s\n", kProgramName, strerror(status));
165 exit(1);
168 if (!volume.KnowsQuery())
169 fprintf(stderr, "%s: volume containing %s is not query-enabled\n", kProgramName, volumePath);
170 else
171 perform_query(volume, argv[optind]);
172 } else {
173 // Okay, we want to query all the disks -- so iterate over
174 // them, one by one, running the query.
175 BVolumeRoster volumeRoster;
176 while (volumeRoster.GetNextVolume(&volume) == B_OK) {
177 // We don't print errors here -- this will catch /pipe and
178 // other filesystems we don't care about.
179 if (volume.KnowsQuery())
180 perform_query(volume, argv[optind]);
184 return 0;