2 * Copyright 2005, Haiku Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT license.
6 * Ficus Kirkpatrick (ficus@ior.com)
8 * Axel Dörfler, axeld@pinc-software.de
11 /* A shell utility for somewhat emulating the Tracker's "Find By Formula"
17 #include <LocaleRoster.h>
22 #include <VolumeRoster.h>
30 extern const char *__progname
;
31 static const char *kProgramName
= __progname
;
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
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
);
57 perform_query(BVolume
&volume
, const char *predicate
)
60 query
.SetVolume(&volume
);
62 if (sLocalizedAppNames
)
63 query
.SetPredicate("BEOS:APP_SIG=*");
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=";
73 query
.SetPredicate(string
.String());
74 status
= query
.Fetch();
77 fprintf(stderr
, "%s: bad query expression\n", kProgramName
);
83 while (query
.GetNextEntry(&entry
) == B_OK
) {
84 if (sFilesOnly
&& !entry
.IsFile())
87 if (entry
.GetPath(&path
) < B_OK
) {
88 fprintf(stderr
, "%s: could not get path for entry\n", kProgramName
);
93 if (sLocalizedAppNames
&& predicate
!= NULL
) {
96 if (entry
.GetRef(&ref
) != B_OK
|| BLocaleRoster::Default()
97 ->GetLocalizedFileName(string
, ref
) != B_OK
)
100 if (string
.IFindFirst(predicate
) < 0)
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.
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.
127 while ((opt
= getopt(argc
, argv
, "efalv:")) != -1) {
130 sEscapeMetaChars
= false;
139 sLocalizedAppNames
= true;
142 strlcpy(volumePath
, optarg
, B_FILE_NAME_LENGTH
);
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
);
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
));
168 if (!volume
.KnowsQuery())
169 fprintf(stderr
, "%s: volume containing %s is not query-enabled\n", kProgramName
, volumePath
);
171 perform_query(volume
, argv
[optind
]);
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
]);