]>
Commit | Line | Data |
---|---|---|
51410fc6 KZ |
1 | /* |
2 | * blkid.c - User command-line interface for libblkid | |
3 | * | |
4 | * Copyright (C) 2001 Andreas Dilger | |
5 | * | |
6 | * %Begin-Header% | |
7 | * This file may be redistributed under the terms of the | |
8 | * GNU Lesser General Public License. | |
9 | * %End-Header% | |
10 | */ | |
11 | ||
12 | #include <stdio.h> | |
13 | #include <stdlib.h> | |
14 | #include <unistd.h> | |
15 | #include <string.h> | |
5b6215b5 KZ |
16 | #include <sys/types.h> |
17 | #include <sys/stat.h> | |
18 | #include <fcntl.h> | |
4fc5d65b | 19 | #include <errno.h> |
51410fc6 | 20 | #include <getopt.h> |
51410fc6 | 21 | |
59b94cc0 | 22 | #define OUTPUT_FULL (1 << 0) |
ab978962 KZ |
23 | #define OUTPUT_VALUE_ONLY (1 << 1) |
24 | #define OUTPUT_DEVICE_ONLY (1 << 2) | |
24d741d8 KZ |
25 | #define OUTPUT_PRETTY_LIST (1 << 3) /* deprecated */ |
26 | #define OUTPUT_UDEV_LIST (1 << 4) /* deprecated */ | |
ab978962 | 27 | #define OUTPUT_EXPORT_LIST (1 << 5) |
51410fc6 | 28 | |
1578ddd6 PU |
29 | #define BLKID_EXIT_NOTFOUND 2 /* token or device not found */ |
30 | #define BLKID_EXIT_OTHER 4 /* bad usage or other error */ | |
31 | #define BLKID_EXIT_AMBIVAL 8 /* ambivalent low-level probing detected */ | |
32 | ||
51410fc6 KZ |
33 | #include <blkid.h> |
34 | ||
2d71a929 | 35 | #include "ismounted.h" |
3c2662d5 | 36 | |
8abcf290 | 37 | #include "strutils.h" |
72b99fc5 SK |
38 | #define OPTUTILS_EXIT_CODE BLKID_EXIT_OTHER /* exclusive_option() */ |
39 | #include "optutils.h" | |
090d8c76 | 40 | #define CLOSE_EXIT_CODE BLKID_EXIT_OTHER /* close_stdout() */ |
c05a80ca | 41 | #include "closestream.h" |
090d8c76 | 42 | |
f5a2b07e | 43 | #include "nls.h" |
597cfec5 | 44 | #include "ttyutils.h" |
778ca2a0 RM |
45 | |
46 | #define XALLOC_EXIT_CODE BLKID_EXIT_OTHER /* x.*alloc(), xstrndup() */ | |
fe20e5d1 | 47 | #include "xalloc.h" |
2d71a929 | 48 | |
64cfe6ac KZ |
49 | #include "sysfs.h" |
50 | ||
59b94cc0 SK |
51 | struct blkid_control { |
52 | int output; | |
53 | uintmax_t offset; | |
54 | uintmax_t size; | |
55 | char *show[128]; | |
56 | unsigned int | |
57 | eval:1, | |
58 | gc:1, | |
59 | lookup:1, | |
60 | lowprobe:1, | |
61 | lowprobe_superblocks:1, | |
62 | lowprobe_topology:1, | |
5e91d5dd | 63 | no_part_details:1, |
59b94cc0 SK |
64 | raw_chars:1; |
65 | }; | |
36a74e1b | 66 | |
fa2cd89a | 67 | static void __attribute__((__noreturn__)) usage(void) |
51410fc6 | 68 | { |
fa2cd89a | 69 | FILE *out = stdout; |
51410fc6 | 70 | |
f5a2b07e | 71 | fputs(USAGE_HEADER, out); |
15a74f75 SK |
72 | fprintf(out, _( " %s --label <label> | --uuid <uuid>\n\n"), program_invocation_short_name); |
73 | fprintf(out, _( " %s [--cache-file <file>] [-ghlLv] [--output <format>] [--match-tag <tag>] \n" | |
74 | " [--match-token <token>] [<dev> ...]\n\n"), program_invocation_short_name); | |
75 | fprintf(out, _( " %s -p [--match-tag <tag>] [--offset <offset>] [--size <size>] \n" | |
76 | " [--output <format>] <dev> ...\n\n"), program_invocation_short_name); | |
77 | fprintf(out, _( " %s -i [--match-tag <tag>] [--output <format>] <dev> ...\n"), program_invocation_short_name); | |
f5a2b07e | 78 | fputs(USAGE_OPTIONS, out); |
15a74f75 SK |
79 | fputs(_( " -c, --cache-file <file> read from <file> instead of reading from the default\n" |
80 | " cache file (-c /dev/null means no cache)\n"), out); | |
81 | fputs(_( " -d, --no-encoding don't encode non-printing characters\n"), out); | |
82 | fputs(_( " -g, --garbage-collect garbage collect the blkid cache\n"), out); | |
83 | fputs(_( " -o, --output <format> output format; can be one of:\n" | |
84 | " value, device, export or full; (default: full)\n"), out); | |
85 | fputs(_( " -k, --list-filesystems list all known filesystems/RAIDs and exit\n"), out); | |
86 | fputs(_( " -s, --match-tag <tag> show specified tag(s) (default show all tags)\n"), out); | |
87 | fputs(_( " -t, --match-token <token> find device with a specific token (NAME=value pair)\n"), out); | |
88 | fputs(_( " -l, --list-one look up only first device with token specified by -t\n"), out); | |
89 | fputs(_( " -L, --label <label> convert LABEL to device name\n"), out); | |
90 | fputs(_( " -U, --uuid <uuid> convert UUID to device name\n"), out); | |
f5a2b07e SK |
91 | fputs( "\n", out); |
92 | fputs(_( "Low-level probing options:\n"), out); | |
15a74f75 SK |
93 | fputs(_( " -p, --probe low-level superblocks probing (bypass cache)\n"), out); |
94 | fputs(_( " -i, --info gather information about I/O limits\n"), out); | |
27c4353b | 95 | fputs(_( " -H, --hint <value> set hint for probing function\n"), out); |
15a74f75 SK |
96 | fputs(_( " -S, --size <size> overwrite device size\n"), out); |
97 | fputs(_( " -O, --offset <offset> probe at the given offset\n"), out); | |
98 | fputs(_( " -u, --usages <list> filter by \"usage\" (e.g. -u filesystem,raid)\n"), out); | |
99 | fputs(_( " -n, --match-types <list> filter by filesystem type (e.g. -n vfat,ext3)\n"), out); | |
0ab08179 | 100 | fputs(_( " -D, --no-part-details don't print info from partition table\n"), out); |
15a74f75 SK |
101 | |
102 | fputs(USAGE_SEPARATOR, out); | |
f45f3ec3 | 103 | printf(USAGE_HELP_OPTIONS(28)); |
f1970cc5 KZ |
104 | |
105 | fputs(USAGE_ARGUMENTS, out); | |
106 | printf(USAGE_ARG_SIZE(_("<size> and <offset>"))); | |
107 | fputs(USAGE_ARG_SEPARATOR, out); | |
108 | fputs(_(" <dev> specify device(s) to probe (default: all devices)\n"), out); | |
109 | ||
f45f3ec3 | 110 | printf(USAGE_MAN_TAIL("blkid(8)")); |
fa2cd89a | 111 | exit(EXIT_SUCCESS); |
51410fc6 KZ |
112 | } |
113 | ||
114 | /* | |
115 | * This function does "safe" printing. It will convert non-printable | |
116 | * ASCII characters using '^' and M- notation. | |
1c9885cd KZ |
117 | * |
118 | * If 'esc' is defined then escape all chars from esc by \. | |
51410fc6 | 119 | */ |
59b94cc0 SK |
120 | static void safe_print(const struct blkid_control *ctl, const char *cp, int len, |
121 | const char *esc) | |
51410fc6 KZ |
122 | { |
123 | unsigned char ch; | |
124 | ||
125 | if (len < 0) | |
126 | len = strlen(cp); | |
127 | ||
128 | while (len--) { | |
129 | ch = *cp++; | |
59b94cc0 | 130 | if (!ctl->raw_chars) { |
305a6122 | 131 | if (ch >= 128) { |
36a74e1b KZ |
132 | fputs("M-", stdout); |
133 | ch -= 128; | |
134 | } | |
135 | if ((ch < 32) || (ch == 0x7f)) { | |
136 | fputc('^', stdout); | |
137 | ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */ | |
1c9885cd KZ |
138 | |
139 | } else if (esc && strchr(esc, ch)) | |
140 | fputc('\\', stdout); | |
51410fc6 KZ |
141 | } |
142 | fputc(ch, stdout); | |
143 | } | |
144 | } | |
145 | ||
51410fc6 KZ |
146 | static int pretty_print_word(const char *str, int max_len, |
147 | int left_len, int overflow_nl) | |
148 | { | |
149 | int len = strlen(str) + left_len; | |
150 | int ret = 0; | |
151 | ||
152 | fputs(str, stdout); | |
153 | if (overflow_nl && len > max_len) { | |
154 | fputc('\n', stdout); | |
155 | len = 0; | |
156 | } else if (len > max_len) | |
157 | ret = len - max_len; | |
126d8cf3 | 158 | do { |
51410fc6 | 159 | fputc(' ', stdout); |
126d8cf3 | 160 | } while (len++ < max_len); |
51410fc6 KZ |
161 | return ret; |
162 | } | |
163 | ||
164 | static void pretty_print_line(const char *device, const char *fs_type, | |
165 | const char *label, const char *mtpt, | |
166 | const char *uuid) | |
167 | { | |
168 | static int device_len = 10, fs_type_len = 7; | |
169 | static int label_len = 8, mtpt_len = 14; | |
170 | static int term_width = -1; | |
171 | int len, w; | |
172 | ||
7e9a9af1 | 173 | if (term_width < 0) { |
43b4f7ea | 174 | term_width = get_terminal_width(80); |
7e9a9af1 | 175 | } |
51410fc6 KZ |
176 | if (term_width > 80) { |
177 | term_width -= 80; | |
178 | w = term_width / 10; | |
179 | if (w > 8) | |
180 | w = 8; | |
181 | term_width -= 2*w; | |
182 | label_len += w; | |
183 | fs_type_len += w; | |
184 | w = term_width/2; | |
185 | device_len += w; | |
186 | mtpt_len +=w; | |
187 | } | |
188 | ||
189 | len = pretty_print_word(device, device_len, 0, 1); | |
190 | len = pretty_print_word(fs_type, fs_type_len, len, 0); | |
191 | len = pretty_print_word(label, label_len, len, 0); | |
fec1339f KZ |
192 | pretty_print_word(mtpt, mtpt_len, len, 0); |
193 | ||
51410fc6 KZ |
194 | fputs(uuid, stdout); |
195 | fputc('\n', stdout); | |
196 | } | |
197 | ||
198 | static void pretty_print_dev(blkid_dev dev) | |
199 | { | |
51410fc6 KZ |
200 | blkid_tag_iterate iter; |
201 | const char *type, *value, *devname; | |
202 | const char *uuid = "", *fs_type = "", *label = ""; | |
51410fc6 KZ |
203 | int len, mount_flags; |
204 | char mtpt[80]; | |
2d71a929 | 205 | int retval; |
51410fc6 KZ |
206 | |
207 | if (dev == NULL) { | |
208 | pretty_print_line("device", "fs_type", "label", | |
209 | "mount point", "UUID"); | |
43b4f7ea | 210 | for (len=get_terminal_width(0)-1; len > 0; len--) |
51410fc6 KZ |
211 | fputc('-', stdout); |
212 | fputc('\n', stdout); | |
213 | return; | |
214 | } | |
215 | ||
216 | devname = blkid_dev_devname(dev); | |
217 | if (access(devname, F_OK)) | |
218 | return; | |
219 | ||
220 | /* Get the uuid, label, type */ | |
221 | iter = blkid_tag_iterate_begin(dev); | |
222 | while (blkid_tag_next(iter, &type, &value) == 0) { | |
223 | if (!strcmp(type, "UUID")) | |
224 | uuid = value; | |
225 | if (!strcmp(type, "TYPE")) | |
226 | fs_type = value; | |
227 | if (!strcmp(type, "LABEL")) | |
228 | label = value; | |
229 | } | |
230 | blkid_tag_iterate_end(iter); | |
231 | ||
232 | /* Get the mount point */ | |
233 | mtpt[0] = 0; | |
2d71a929 | 234 | retval = check_mount_point(devname, &mount_flags, mtpt, sizeof(mtpt)); |
51410fc6 | 235 | if (retval == 0) { |
fa1b64da KZ |
236 | const char *msg = NULL; |
237 | ||
2d71a929 | 238 | if (mount_flags & MF_MOUNTED) { |
51410fc6 | 239 | if (!mtpt[0]) |
fa1b64da | 240 | msg = _("(mounted, mtpt unknown)"); |
2d71a929 | 241 | } else if (mount_flags & MF_BUSY) |
fa1b64da | 242 | msg = _("(in use)"); |
51410fc6 | 243 | else |
fa1b64da KZ |
244 | msg = _("(not mounted)"); |
245 | ||
246 | if (msg) | |
247 | xstrncpy(mtpt, msg, sizeof(mtpt)); | |
51410fc6 KZ |
248 | } |
249 | ||
250 | pretty_print_line(devname, fs_type, label, mtpt, uuid); | |
51410fc6 KZ |
251 | } |
252 | ||
525f3c28 | 253 | static void print_udev_format(const char *name, const char *value) |
b516dbe0 KZ |
254 | { |
255 | char enc[265], safe[256]; | |
09792910 | 256 | size_t namelen = strlen(name); |
b516dbe0 KZ |
257 | |
258 | *safe = *enc = '\0'; | |
259 | ||
15039460 KZ |
260 | if (!strcmp(name, "TYPE") |
261 | || !strcmp(name, "VERSION") | |
262 | || !strcmp(name, "SYSTEM_ID") | |
263 | || !strcmp(name, "PUBLISHER_ID") | |
264 | || !strcmp(name, "APPLICATION_ID") | |
265 | || !strcmp(name, "BOOT_SYSTEM_ID") | |
72ab7065 KZ |
266 | || !strcmp(name, "VOLUME_ID") |
267 | || !strcmp(name, "LOGICAL_VOLUME_ID") | |
15039460 KZ |
268 | || !strcmp(name, "VOLUME_SET_ID") |
269 | || !strcmp(name, "DATA_PREPARER_ID")) { | |
b516dbe0 | 270 | blkid_encode_string(value, enc, sizeof(enc)); |
d46c8ab3 | 271 | printf("ID_FS_%s=%s\n", name, enc); |
b516dbe0 | 272 | |
d46c8ab3 | 273 | } else if (!strcmp(name, "UUID") || |
0d2e8ff9 | 274 | !strncmp(name, "LABEL", 5) || |
b516dbe0 KZ |
275 | !strcmp(name, "UUID_SUB")) { |
276 | ||
277 | blkid_safe_string(value, safe, sizeof(safe)); | |
d46c8ab3 | 278 | printf("ID_FS_%s=%s\n", name, safe); |
b516dbe0 | 279 | |
d46c8ab3 | 280 | blkid_encode_string(value, enc, sizeof(enc)); |
b516dbe0 | 281 | printf("ID_FS_%s_ENC=%s\n", name, enc); |
e3d8933a | 282 | |
834eca4e KZ |
283 | } else if (!strcmp(name, "PTUUID")) { |
284 | printf("ID_PART_TABLE_UUID=%s\n", value); | |
285 | ||
4f74ffdb | 286 | } else if (!strcmp(name, "PTTYPE")) { |
e3d8933a KZ |
287 | printf("ID_PART_TABLE_TYPE=%s\n", value); |
288 | ||
dcc58f62 KZ |
289 | } else if (!strcmp(name, "PART_ENTRY_NAME") || |
290 | !strcmp(name, "PART_ENTRY_TYPE")) { | |
4f74ffdb | 291 | |
4f74ffdb | 292 | blkid_encode_string(value, enc, sizeof(enc)); |
0159857e | 293 | printf("ID_%s=%s\n", name, enc); |
4f74ffdb KZ |
294 | |
295 | } else if (!strncmp(name, "PART_ENTRY_", 11)) | |
296 | printf("ID_%s=%s\n", name, value); | |
e3d8933a | 297 | |
09792910 KZ |
298 | else if (namelen >= 15 && ( |
299 | !strcmp(name + (namelen - 12), "_SECTOR_SIZE") || | |
300 | !strcmp(name + (namelen - 8), "_IO_SIZE") || | |
301 | !strcmp(name, "ALIGNMENT_OFFSET"))) | |
302 | printf("ID_IOLIMIT_%s=%s\n", name, value); | |
d46c8ab3 KZ |
303 | else |
304 | printf("ID_FS_%s=%s\n", name, value); | |
b516dbe0 KZ |
305 | } |
306 | ||
071147ab | 307 | static int has_item(const struct blkid_control *ctl, const char *item) |
7711e215 | 308 | { |
071147ab | 309 | char * const *p; |
7711e215 | 310 | |
071147ab | 311 | for (p = ctl->show; *p != NULL; p++) |
7711e215 KZ |
312 | if (!strcmp(item, *p)) |
313 | return 1; | |
314 | return 0; | |
315 | } | |
316 | ||
59b94cc0 SK |
317 | static void print_value(const struct blkid_control *ctl, int num, |
318 | const char *devname, const char *value, | |
319 | const char *name, size_t valsz) | |
5b6215b5 | 320 | { |
59b94cc0 | 321 | if (ctl->output & OUTPUT_VALUE_ONLY) { |
5b6215b5 KZ |
322 | fputs(value, stdout); |
323 | fputc('\n', stdout); | |
324 | ||
59b94cc0 | 325 | } else if (ctl->output & OUTPUT_UDEV_LIST) { |
525f3c28 | 326 | print_udev_format(name, value); |
5b6215b5 | 327 | |
59b94cc0 | 328 | } else if (ctl->output & OUTPUT_EXPORT_LIST) { |
dab33573 KZ |
329 | if (num == 1 && devname) |
330 | printf("DEVNAME=%s\n", devname); | |
ab978962 KZ |
331 | fputs(name, stdout); |
332 | fputs("=", stdout); | |
59b94cc0 | 333 | safe_print(ctl, value, valsz, " \\\"'$`<>"); |
ab978962 KZ |
334 | fputs("\n", stdout); |
335 | ||
5b6215b5 | 336 | } else { |
cf778d68 | 337 | if (num == 1 && devname) |
16714abe KZ |
338 | printf("%s:", devname); |
339 | fputs(" ", stdout); | |
5b6215b5 KZ |
340 | fputs(name, stdout); |
341 | fputs("=\"", stdout); | |
59b94cc0 | 342 | safe_print(ctl, value, valsz, "\"\\"); |
16714abe | 343 | fputs("\"", stdout); |
5b6215b5 KZ |
344 | } |
345 | } | |
346 | ||
59b94cc0 | 347 | static void print_tags(const struct blkid_control *ctl, blkid_dev dev) |
51410fc6 KZ |
348 | { |
349 | blkid_tag_iterate iter; | |
cf778d68 | 350 | const char *type, *value, *devname; |
7711e215 | 351 | int num = 1; |
ab978962 | 352 | static int first = 1; |
51410fc6 KZ |
353 | |
354 | if (!dev) | |
355 | return; | |
356 | ||
59b94cc0 | 357 | if (ctl->output & OUTPUT_PRETTY_LIST) { |
51410fc6 KZ |
358 | pretty_print_dev(dev); |
359 | return; | |
360 | } | |
361 | ||
cf778d68 KZ |
362 | devname = blkid_dev_devname(dev); |
363 | ||
59b94cc0 | 364 | if (ctl->output & OUTPUT_DEVICE_ONLY) { |
cf778d68 | 365 | printf("%s\n", devname); |
51410fc6 KZ |
366 | return; |
367 | } | |
368 | ||
369 | iter = blkid_tag_iterate_begin(dev); | |
370 | while (blkid_tag_next(iter, &type, &value) == 0) { | |
071147ab | 371 | if (ctl->show[0] && !has_item(ctl, type)) |
7711e215 | 372 | continue; |
ab978962 KZ |
373 | |
374 | if (num == 1 && !first && | |
59b94cc0 | 375 | (ctl->output & (OUTPUT_UDEV_LIST | OUTPUT_EXPORT_LIST))) |
ab978962 KZ |
376 | /* add extra line between output from more devices */ |
377 | fputc('\n', stdout); | |
378 | ||
59b94cc0 | 379 | print_value(ctl, num++, devname, value, type, strlen(value)); |
51410fc6 KZ |
380 | } |
381 | blkid_tag_iterate_end(iter); | |
382 | ||
ab978962 | 383 | if (num > 1) { |
59b94cc0 | 384 | if (!(ctl->output & (OUTPUT_VALUE_ONLY | OUTPUT_UDEV_LIST | |
ab978962 KZ |
385 | OUTPUT_EXPORT_LIST))) |
386 | printf("\n"); | |
387 | first = 0; | |
388 | } | |
51410fc6 KZ |
389 | } |
390 | ||
c54670d5 KZ |
391 | |
392 | static int append_str(char **res, size_t *sz, const char *a, const char *b) | |
393 | { | |
293eef71 | 394 | char *str = *res; |
c54670d5 KZ |
395 | size_t asz = a ? strlen(a) : 0; |
396 | size_t bsz = b ? strlen(b) : 0; | |
397 | size_t len = *sz + asz + bsz; | |
398 | ||
399 | if (!len) | |
400 | return -1; | |
401 | ||
293eef71 | 402 | *res = str = xrealloc(str, len + 1); |
c54670d5 KZ |
403 | str += *sz; |
404 | ||
405 | if (a) { | |
406 | memcpy(str, a, asz); | |
407 | str += asz; | |
408 | } | |
409 | if (b) { | |
410 | memcpy(str, b, bsz); | |
411 | str += bsz; | |
412 | } | |
413 | *str = '\0'; | |
414 | *sz = len; | |
415 | return 0; | |
416 | } | |
417 | ||
418 | /* | |
419 | * Compose and print ID_FS_AMBIVALENT for udev | |
420 | */ | |
421 | static int print_udev_ambivalent(blkid_probe pr) | |
422 | { | |
423 | char *val = NULL; | |
424 | size_t valsz = 0; | |
425 | int count = 0, rc = -1; | |
426 | ||
427 | while (!blkid_do_probe(pr)) { | |
f5ee44b1 | 428 | const char *usage_txt = NULL, *type = NULL, *version = NULL; |
c54670d5 KZ |
429 | char enc[256]; |
430 | ||
f5ee44b1 | 431 | blkid_probe_lookup_value(pr, "USAGE", &usage_txt, NULL); |
c54670d5 KZ |
432 | blkid_probe_lookup_value(pr, "TYPE", &type, NULL); |
433 | blkid_probe_lookup_value(pr, "VERSION", &version, NULL); | |
434 | ||
f5ee44b1 | 435 | if (!usage_txt || !type) |
c54670d5 KZ |
436 | continue; |
437 | ||
f5ee44b1 | 438 | blkid_encode_string(usage_txt, enc, sizeof(enc)); |
c54670d5 KZ |
439 | if (append_str(&val, &valsz, enc, ":")) |
440 | goto done; | |
441 | ||
442 | blkid_encode_string(type, enc, sizeof(enc)); | |
443 | if (append_str(&val, &valsz, enc, version ? ":" : " ")) | |
444 | goto done; | |
445 | ||
446 | if (version) { | |
447 | blkid_encode_string(version, enc, sizeof(enc)); | |
448 | if (append_str(&val, &valsz, enc, " ")) | |
449 | goto done; | |
450 | } | |
451 | count++; | |
452 | } | |
453 | ||
454 | if (count > 1) { | |
455 | *(val + valsz - 1) = '\0'; /* rem tailing whitespace */ | |
08af448f | 456 | printf("ID_FS_AMBIVALENT=%s\n", val); |
c54670d5 KZ |
457 | rc = 0; |
458 | } | |
459 | done: | |
460 | free(val); | |
461 | return rc; | |
462 | } | |
463 | ||
5e91d5dd | 464 | static int lowprobe_superblocks(blkid_probe pr, struct blkid_control *ctl) |
5b6215b5 | 465 | { |
e3d8933a | 466 | struct stat st; |
d75bcac4 | 467 | int rc, fd = blkid_probe_get_fd(pr); |
e3d8933a | 468 | |
d75bcac4 | 469 | if (fd < 0 || fstat(fd, &st)) |
09792910 | 470 | return -1; |
e3d8933a KZ |
471 | |
472 | blkid_probe_enable_partitions(pr, 1); | |
4f74ffdb | 473 | |
6a2f2f58 KZ |
474 | if (!S_ISCHR(st.st_mode) && blkid_probe_get_size(pr) <= 1024 * 1440 && |
475 | blkid_probe_is_wholedisk(pr)) { | |
e3d8933a | 476 | /* |
cba1f975 KZ |
477 | * check if the small disk is partitioned, if yes then |
478 | * don't probe for filesystems. | |
e3d8933a | 479 | */ |
cba1f975 | 480 | blkid_probe_enable_superblocks(pr, 0); |
e3d8933a | 481 | |
cba1f975 | 482 | rc = blkid_do_fullprobe(pr); |
e3d8933a | 483 | if (rc < 0) |
9e930041 | 484 | return rc; /* -1 = error, 1 = nothing, 0 = success */ |
cba1f975 KZ |
485 | |
486 | if (blkid_probe_lookup_value(pr, "PTTYPE", NULL, NULL) == 0) | |
09792910 | 487 | return 0; /* partition table detected */ |
e3d8933a | 488 | } |
5b6215b5 | 489 | |
5e91d5dd KZ |
490 | if (!ctl->no_part_details) |
491 | blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS); | |
cba1f975 KZ |
492 | blkid_probe_enable_superblocks(pr, 1); |
493 | ||
09792910 KZ |
494 | return blkid_do_safeprobe(pr); |
495 | } | |
496 | ||
497 | static int lowprobe_topology(blkid_probe pr) | |
498 | { | |
499 | /* enable topology probing only */ | |
500 | blkid_probe_enable_topology(pr, 1); | |
501 | ||
502 | blkid_probe_enable_superblocks(pr, 0); | |
503 | blkid_probe_enable_partitions(pr, 0); | |
504 | ||
505 | return blkid_do_fullprobe(pr); | |
506 | } | |
507 | ||
508 | static int lowprobe_device(blkid_probe pr, const char *devname, | |
59b94cc0 | 509 | struct blkid_control *ctl) |
09792910 KZ |
510 | { |
511 | const char *data; | |
512 | const char *name; | |
513 | int nvals = 0, n, num = 1; | |
514 | size_t len; | |
515 | int fd; | |
516 | int rc = 0; | |
517 | static int first = 1; | |
518 | ||
39f5af25 | 519 | fd = open(devname, O_RDONLY|O_CLOEXEC|O_NONBLOCK); |
09792910 | 520 | if (fd < 0) { |
f5a2b07e | 521 | warn(_("error: %s"), devname); |
1578ddd6 | 522 | return BLKID_EXIT_NOTFOUND; |
09792910 | 523 | } |
dc30fd43 KZ |
524 | errno = 0; |
525 | if (blkid_probe_set_device(pr, fd, ctl->offset, ctl->size)) { | |
526 | if (errno) | |
527 | warn(_("error: %s"), devname); | |
09792910 | 528 | goto done; |
dc30fd43 | 529 | } |
09792910 | 530 | |
59b94cc0 | 531 | if (ctl->lowprobe_topology) |
09792910 | 532 | rc = lowprobe_topology(pr); |
59b94cc0 | 533 | if (rc >= 0 && ctl->lowprobe_superblocks) |
5e91d5dd | 534 | rc = lowprobe_superblocks(pr, ctl); |
cba1f975 KZ |
535 | if (rc < 0) |
536 | goto done; | |
09792910 | 537 | |
dbcafb87 KZ |
538 | if (!rc) |
539 | nvals = blkid_probe_numof_values(pr); | |
5b6215b5 | 540 | |
59b94cc0 | 541 | if (nvals && !first && ctl->output & (OUTPUT_UDEV_LIST | OUTPUT_EXPORT_LIST)) |
9eb44c28 KZ |
542 | /* add extra line between output from devices */ |
543 | fputc('\n', stdout); | |
544 | ||
59b94cc0 | 545 | if (nvals && (ctl->output & OUTPUT_DEVICE_ONLY)) { |
e88517b1 KZ |
546 | printf("%s\n", devname); |
547 | goto done; | |
548 | } | |
549 | ||
5b6215b5 KZ |
550 | for (n = 0; n < nvals; n++) { |
551 | if (blkid_probe_get_value(pr, n, &name, &data, &len)) | |
552 | continue; | |
071147ab | 553 | if (ctl->show[0] && !has_item(ctl, name)) |
7711e215 | 554 | continue; |
e736434b KZ |
555 | len = strnlen(data, len); |
556 | print_value(ctl, num++, devname, data, name, len); | |
5b6215b5 KZ |
557 | } |
558 | ||
9eb44c28 KZ |
559 | if (first) |
560 | first = 0; | |
59b94cc0 SK |
561 | |
562 | if (nvals >= 1 && !(ctl->output & (OUTPUT_VALUE_ONLY | | |
ab978962 | 563 | OUTPUT_UDEV_LIST | OUTPUT_EXPORT_LIST))) |
cf778d68 | 564 | printf("\n"); |
e88517b1 | 565 | done: |
c54670d5 | 566 | if (rc == -2) { |
59b94cc0 | 567 | if (ctl->output & OUTPUT_UDEV_LIST) |
c54670d5 KZ |
568 | print_udev_ambivalent(pr); |
569 | else | |
f5a2b07e | 570 | warnx(_("%s: ambivalent result (probably more " |
c54670d5 | 571 | "filesystems on the device, use wipefs(8) " |
f5a2b07e | 572 | "to see more details)"), |
a2f01a1c | 573 | devname); |
c54670d5 | 574 | } |
5b6215b5 | 575 | close(fd); |
68c88d94 KZ |
576 | |
577 | if (rc == -2) | |
1578ddd6 | 578 | return BLKID_EXIT_AMBIVAL; /* ambivalent probing result */ |
68c88d94 | 579 | if (!nvals) |
1578ddd6 | 580 | return BLKID_EXIT_NOTFOUND; /* nothing detected */ |
68c88d94 | 581 | |
455fe9a0 | 582 | return 0; /* success */ |
5b6215b5 KZ |
583 | } |
584 | ||
0bdd2f97 KZ |
585 | /* converts comma separated list to BLKID_USAGE_* mask */ |
586 | static int list_to_usage(const char *list, int *flag) | |
587 | { | |
588 | int mask = 0; | |
962496d4 | 589 | const char *word = NULL, *p = list; |
0bdd2f97 KZ |
590 | |
591 | if (p && strncmp(p, "no", 2) == 0) { | |
592 | *flag = BLKID_FLTR_NOTIN; | |
593 | p += 2; | |
594 | } | |
962496d4 KZ |
595 | if (!p || !*p) |
596 | goto err; | |
962496d4 KZ |
597 | while(p) { |
598 | word = p; | |
962496d4 KZ |
599 | p = strchr(p, ','); |
600 | if (p) | |
601 | p++; | |
962496d4 KZ |
602 | if (!strncmp(word, "filesystem", 10)) |
603 | mask |= BLKID_USAGE_FILESYSTEM; | |
604 | else if (!strncmp(word, "raid", 4)) | |
605 | mask |= BLKID_USAGE_RAID; | |
606 | else if (!strncmp(word, "crypto", 6)) | |
607 | mask |= BLKID_USAGE_CRYPTO; | |
608 | else if (!strncmp(word, "other", 5)) | |
609 | mask |= BLKID_USAGE_OTHER; | |
610 | else | |
611 | goto err; | |
0bdd2f97 KZ |
612 | } |
613 | return mask; | |
962496d4 KZ |
614 | err: |
615 | *flag = 0; | |
f5a2b07e | 616 | warnx(_("unknown keyword in -u <list> argument: '%s'"), |
962496d4 | 617 | word ? word : list); |
1578ddd6 | 618 | exit(BLKID_EXIT_OTHER); |
0bdd2f97 KZ |
619 | } |
620 | ||
4f946f53 KZ |
621 | /* converts comma separated list to types[] */ |
622 | static char **list_to_types(const char *list, int *flag) | |
623 | { | |
624 | int i; | |
625 | const char *p = list; | |
bc867ea3 | 626 | char **res = NULL; |
4f946f53 KZ |
627 | |
628 | if (p && strncmp(p, "no", 2) == 0) { | |
629 | *flag = BLKID_FLTR_NOTIN; | |
630 | p += 2; | |
631 | } | |
632 | if (!p || !*p) { | |
f5a2b07e | 633 | warnx(_("error: -u <list> argument is empty")); |
4f946f53 KZ |
634 | goto err; |
635 | } | |
636 | for (i = 1; p && (p = strchr(p, ',')); i++, p++); | |
637 | ||
5d00280c | 638 | res = xcalloc(i + 1, sizeof(char *)); |
4f946f53 KZ |
639 | p = *flag & BLKID_FLTR_NOTIN ? list + 2 : list; |
640 | i = 0; | |
641 | ||
642 | while(p) { | |
643 | const char *word = p; | |
644 | p = strchr(p, ','); | |
5d00280c | 645 | res[i++] = p ? xstrndup(word, p - word) : xstrdup(word); |
4f946f53 KZ |
646 | if (p) |
647 | p++; | |
648 | } | |
649 | res[i] = NULL; | |
650 | return res; | |
4f946f53 KZ |
651 | err: |
652 | *flag = 0; | |
653 | free(res); | |
1578ddd6 | 654 | exit(BLKID_EXIT_OTHER); |
4f946f53 KZ |
655 | } |
656 | ||
657 | static void free_types_list(char *list[]) | |
658 | { | |
659 | char **n; | |
660 | ||
661 | if (!list) | |
662 | return; | |
663 | for (n = list; *n; n++) | |
664 | free(*n); | |
665 | free(list); | |
666 | } | |
667 | ||
51410fc6 KZ |
668 | int main(int argc, char **argv) |
669 | { | |
59b94cc0 | 670 | struct blkid_control ctl = { .output = OUTPUT_FULL, 0 }; |
51410fc6 | 671 | blkid_cache cache = NULL; |
ea51c09c | 672 | char **devices = NULL; |
51410fc6 | 673 | char *search_type = NULL, *search_value = NULL; |
ac3a0fd9 | 674 | char *read = NULL, *hint = NULL; |
0bdd2f97 | 675 | int fltr_usage = 0; |
4f946f53 | 676 | char **fltr_type = NULL; |
0bdd2f97 | 677 | int fltr_flag = BLKID_FLTR_ONLYIN; |
51410fc6 | 678 | unsigned int numdev = 0, numtag = 0; |
1578ddd6 | 679 | int err = BLKID_EXIT_OTHER; |
51410fc6 | 680 | unsigned int i; |
51410fc6 KZ |
681 | int c; |
682 | ||
15a74f75 SK |
683 | static const struct option longopts[] = { |
684 | { "cache-file", required_argument, NULL, 'c' }, | |
685 | { "no-encoding", no_argument, NULL, 'd' }, | |
5e91d5dd | 686 | { "no-part-details", no_argument, NULL, 'D' }, |
15a74f75 SK |
687 | { "garbage-collect", no_argument, NULL, 'g' }, |
688 | { "output", required_argument, NULL, 'o' }, | |
689 | { "list-filesystems", no_argument, NULL, 'k' }, | |
690 | { "match-tag", required_argument, NULL, 's' }, | |
691 | { "match-token", required_argument, NULL, 't' }, | |
692 | { "list-one", no_argument, NULL, 'l' }, | |
693 | { "label", required_argument, NULL, 'L' }, | |
694 | { "uuid", required_argument, NULL, 'U' }, | |
695 | { "probe", no_argument, NULL, 'p' }, | |
ac3a0fd9 | 696 | { "hint", required_argument, NULL, 'H' }, |
15a74f75 SK |
697 | { "info", no_argument, NULL, 'i' }, |
698 | { "size", required_argument, NULL, 'S' }, | |
699 | { "offset", required_argument, NULL, 'O' }, | |
700 | { "usages", required_argument, NULL, 'u' }, | |
701 | { "match-types", required_argument, NULL, 'n' }, | |
702 | { "version", no_argument, NULL, 'V' }, | |
703 | { "help", no_argument, NULL, 'h' }, | |
704 | { NULL, 0, NULL, 0 } | |
705 | }; | |
706 | ||
a7349ee3 | 707 | static const ul_excl_t excl[] = { /* rows and cols in ASCII order */ |
a8e458b9 KZ |
708 | { 'n','u' }, |
709 | { 0 } | |
72b99fc5 | 710 | }; |
a8e458b9 | 711 | int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; |
72b99fc5 | 712 | |
f5a2b07e SK |
713 | setlocale(LC_ALL, ""); |
714 | bindtextdomain(PACKAGE, LOCALEDIR); | |
715 | textdomain(PACKAGE); | |
2c308875 | 716 | close_stdout_atexit(); |
7711e215 | 717 | |
9c8b9fba RM |
718 | strutils_set_exitcode(BLKID_EXIT_OTHER); |
719 | ||
15a74f75 | 720 | while ((c = getopt_long (argc, argv, |
ac3a0fd9 | 721 | "c:DdgH:hilL:n:ko:O:ps:S:t:u:U:w:Vv", longopts, NULL)) != -1) { |
a8e458b9 KZ |
722 | |
723 | err_exclusive_options(c, NULL, excl, excl_st); | |
724 | ||
51410fc6 KZ |
725 | switch (c) { |
726 | case 'c': | |
59b94cc0 | 727 | read = optarg; |
51410fc6 | 728 | break; |
36a74e1b | 729 | case 'd': |
59b94cc0 | 730 | ctl.raw_chars = 1; |
36a74e1b | 731 | break; |
5e91d5dd KZ |
732 | case 'D': |
733 | ctl.no_part_details = 1; | |
734 | break; | |
ac3a0fd9 KZ |
735 | case 'H': |
736 | hint = optarg; | |
737 | break; | |
4786921c | 738 | case 'L': |
59b94cc0 | 739 | ctl.eval = 1; |
fe20e5d1 SK |
740 | search_value = xstrdup(optarg); |
741 | search_type = xstrdup("LABEL"); | |
4786921c | 742 | break; |
4f946f53 | 743 | case 'n': |
4f946f53 KZ |
744 | fltr_type = list_to_types(optarg, &fltr_flag); |
745 | break; | |
0bdd2f97 KZ |
746 | case 'u': |
747 | fltr_usage = list_to_usage(optarg, &fltr_flag); | |
748 | break; | |
4786921c | 749 | case 'U': |
59b94cc0 | 750 | ctl.eval = 1; |
fe20e5d1 SK |
751 | search_value = xstrdup(optarg); |
752 | search_type = xstrdup("UUID"); | |
4786921c | 753 | break; |
09792910 | 754 | case 'i': |
59b94cc0 | 755 | ctl.lowprobe_topology = 1; |
09792910 | 756 | break; |
51410fc6 | 757 | case 'l': |
59b94cc0 | 758 | ctl.lookup = 1; |
51410fc6 | 759 | break; |
51410fc6 | 760 | case 'g': |
59b94cc0 | 761 | ctl.gc = 1; |
51410fc6 | 762 | break; |
70db6c7e KZ |
763 | case 'k': |
764 | { | |
765 | size_t idx = 0; | |
766 | const char *name = NULL; | |
767 | ||
768 | while (blkid_superblocks_get_name(idx++, &name, NULL) == 0) | |
769 | printf("%s\n", name); | |
a922091d | 770 | exit(EXIT_SUCCESS); |
70db6c7e | 771 | } |
51410fc6 KZ |
772 | case 'o': |
773 | if (!strcmp(optarg, "value")) | |
59b94cc0 | 774 | ctl.output = OUTPUT_VALUE_ONLY; |
51410fc6 | 775 | else if (!strcmp(optarg, "device")) |
59b94cc0 | 776 | ctl.output = OUTPUT_DEVICE_ONLY; |
51410fc6 | 777 | else if (!strcmp(optarg, "list")) |
59b94cc0 | 778 | ctl.output = OUTPUT_PRETTY_LIST; /* deprecated */ |
b516dbe0 | 779 | else if (!strcmp(optarg, "udev")) |
59b94cc0 | 780 | ctl.output = OUTPUT_UDEV_LIST; |
ab978962 | 781 | else if (!strcmp(optarg, "export")) |
59b94cc0 | 782 | ctl.output = OUTPUT_EXPORT_LIST; |
51410fc6 | 783 | else if (!strcmp(optarg, "full")) |
59b94cc0 | 784 | ctl.output = 0; |
f5a2b07e SK |
785 | else |
786 | errx(BLKID_EXIT_OTHER, _("unsupported output format %s"), optarg); | |
51410fc6 | 787 | break; |
5b6215b5 | 788 | case 'O': |
59b94cc0 | 789 | ctl.offset = strtosize_or_err(optarg, _("invalid offset argument")); |
5b6215b5 KZ |
790 | break; |
791 | case 'p': | |
59b94cc0 | 792 | ctl.lowprobe_superblocks = 1; |
5b6215b5 | 793 | break; |
51410fc6 | 794 | case 's': |
59b94cc0 | 795 | if (numtag + 1 >= sizeof(ctl.show) / sizeof(*ctl.show)) { |
f5a2b07e | 796 | warnx(_("Too many tags specified")); |
3b7693ca | 797 | errtryhelp(err); |
51410fc6 | 798 | } |
59b94cc0 | 799 | ctl.show[numtag++] = optarg; |
51410fc6 | 800 | break; |
5b6215b5 | 801 | case 'S': |
59b94cc0 | 802 | ctl.size = strtosize_or_err(optarg, _("invalid size argument")); |
5b6215b5 | 803 | break; |
51410fc6 KZ |
804 | case 't': |
805 | if (search_type) { | |
f5a2b07e SK |
806 | warnx(_("Can only search for " |
807 | "one NAME=value pair")); | |
3b7693ca | 808 | errtryhelp(err); |
51410fc6 KZ |
809 | } |
810 | if (blkid_parse_tag_string(optarg, | |
811 | &search_type, | |
812 | &search_value)) { | |
f5a2b07e | 813 | warnx(_("-t needs NAME=value pair")); |
3b7693ca | 814 | errtryhelp(err); |
51410fc6 KZ |
815 | } |
816 | break; | |
a9b2c52f | 817 | case 'V': |
51410fc6 | 818 | case 'v': |
68224d10 KZ |
819 | fprintf(stdout, _("%s from %s (libblkid %s, %s)\n"), |
820 | program_invocation_short_name, PACKAGE_STRING, | |
821 | LIBBLKID_VERSION, LIBBLKID_DATE); | |
dc46610b | 822 | err = 0; |
93bdbe19 | 823 | goto exit; |
51410fc6 | 824 | case 'w': |
077b15dc | 825 | /* ignore - backward compatibility */ |
51410fc6 KZ |
826 | break; |
827 | case 'h': | |
fa2cd89a | 828 | usage(); |
677ec86c | 829 | break; |
51410fc6 | 830 | default: |
3b7693ca | 831 | errtryhelp(EXIT_FAILURE); |
51410fc6 | 832 | } |
a8e458b9 | 833 | } |
51410fc6 | 834 | |
59b94cc0 SK |
835 | if (ctl.lowprobe_topology || ctl.lowprobe_superblocks) |
836 | ctl.lowprobe = 1; | |
ea51c09c ES |
837 | |
838 | /* The rest of the args are device names */ | |
839 | if (optind < argc) { | |
5d00280c | 840 | devices = xcalloc(argc - optind, sizeof(char *)); |
64cfe6ac KZ |
841 | while (optind < argc) { |
842 | char *dev = argv[optind++]; | |
843 | struct stat sb; | |
844 | ||
845 | if (stat(dev, &sb) != 0) | |
846 | continue; | |
847 | else if (S_ISBLK(sb.st_mode)) | |
848 | ; | |
849 | else if (S_ISREG(sb.st_mode)) | |
850 | ; | |
851 | else if (S_ISCHR(sb.st_mode)) { | |
852 | char buf[PATH_MAX]; | |
853 | ||
854 | if (!sysfs_chrdev_devno_to_devname( | |
855 | sb.st_rdev, buf, sizeof(buf))) | |
856 | continue; | |
857 | if (strncmp(buf, "ubi", 3) != 0) | |
858 | continue; | |
859 | } else | |
860 | continue; | |
861 | ||
862 | devices[numdev++] = dev; | |
863 | } | |
54a00b5c | 864 | } |
51410fc6 | 865 | |
4786921c | 866 | /* convert LABEL/UUID lookup to evaluate request */ |
59b94cc0 | 867 | if (ctl.lookup && ctl.output == OUTPUT_DEVICE_ONLY && search_type && |
4786921c | 868 | (!strcmp(search_type, "LABEL") || !strcmp(search_type, "UUID"))) { |
59b94cc0 SK |
869 | ctl.eval = 1; |
870 | ctl.lookup = 0; | |
4786921c | 871 | } |
872 | ||
59b94cc0 | 873 | if (!ctl.lowprobe && !ctl.eval && blkid_get_cache(&cache, read) < 0) |
51410fc6 KZ |
874 | goto exit; |
875 | ||
59b94cc0 | 876 | if (ctl.gc) { |
51410fc6 | 877 | blkid_gc_cache(cache); |
324759d6 | 878 | err = 0; |
51410fc6 KZ |
879 | goto exit; |
880 | } | |
1578ddd6 | 881 | err = BLKID_EXIT_NOTFOUND; |
324759d6 | 882 | |
59b94cc0 SK |
883 | if (ctl.eval == 0 && (ctl.output & OUTPUT_PRETTY_LIST)) { |
884 | if (ctl.lowprobe) | |
f5a2b07e SK |
885 | errx(BLKID_EXIT_OTHER, |
886 | _("The low-level probing mode does not " | |
887 | "support 'list' output format")); | |
51410fc6 | 888 | pretty_print_dev(NULL); |
2d71a929 | 889 | } |
51410fc6 | 890 | |
59b94cc0 | 891 | if (ctl.lowprobe) { |
4786921c | 892 | /* |
893 | * Low-level API | |
894 | */ | |
5b6215b5 KZ |
895 | blkid_probe pr; |
896 | ||
f5a2b07e SK |
897 | if (!numdev) |
898 | errx(BLKID_EXIT_OTHER, | |
899 | _("The low-level probing mode " | |
900 | "requires a device")); | |
ab978962 KZ |
901 | |
902 | /* automatically enable 'export' format for I/O Limits */ | |
59b94cc0 SK |
903 | if (!ctl.output && ctl.lowprobe_topology) |
904 | ctl.output = OUTPUT_EXPORT_LIST; | |
ab978962 | 905 | |
5b6215b5 KZ |
906 | pr = blkid_new_probe(); |
907 | if (!pr) | |
908 | goto exit; | |
ac3a0fd9 KZ |
909 | if (hint && blkid_probe_set_hint(pr, hint, 0) != 0) { |
910 | warn(_("Failed to use probing hint: %s"), hint); | |
911 | goto exit; | |
912 | } | |
1b780848 | 913 | |
59b94cc0 | 914 | if (ctl.lowprobe_superblocks) { |
09792910 | 915 | blkid_probe_set_superblocks_flags(pr, |
1b780848 KZ |
916 | BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | |
917 | BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE | | |
918 | BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION); | |
919 | ||
59b94cc0 SK |
920 | |
921 | if (fltr_usage && | |
922 | blkid_probe_filter_superblocks_usage(pr, fltr_flag, fltr_usage)) | |
09792910 KZ |
923 | goto exit; |
924 | ||
59b94cc0 SK |
925 | else if (fltr_type && |
926 | blkid_probe_filter_superblocks_type(pr, fltr_flag, fltr_type)) | |
09792910 KZ |
927 | goto exit; |
928 | } | |
5b6215b5 | 929 | |
078ad9bf | 930 | for (i = 0; i < numdev; i++) { |
59b94cc0 | 931 | err = lowprobe_device(pr, devices[i], &ctl); |
078ad9bf PU |
932 | if (err) |
933 | break; | |
934 | } | |
5b6215b5 | 935 | blkid_free_probe(pr); |
59b94cc0 | 936 | } else if (ctl.eval) { |
4786921c | 937 | /* |
938 | * Evaluate API | |
939 | */ | |
cee95a95 | 940 | char *res = blkid_evaluate_tag(search_type, search_value, NULL); |
324759d6 SJR |
941 | if (res) { |
942 | err = 0; | |
4786921c | 943 | printf("%s\n", res); |
324759d6 | 944 | } |
59b94cc0 | 945 | } else if (ctl.lookup) { |
4786921c | 946 | /* |
947 | * Classic (cache based) API | |
948 | */ | |
51410fc6 KZ |
949 | blkid_dev dev; |
950 | ||
f5a2b07e SK |
951 | if (!search_type) |
952 | errx(BLKID_EXIT_OTHER, | |
953 | _("The lookup option requires a " | |
954 | "search type specified using -t")); | |
51410fc6 KZ |
955 | /* Load any additional devices not in the cache */ |
956 | for (i = 0; i < numdev; i++) | |
957 | blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL); | |
958 | ||
959 | if ((dev = blkid_find_dev_with_tag(cache, search_type, | |
960 | search_value))) { | |
59b94cc0 | 961 | print_tags(&ctl, dev); |
51410fc6 KZ |
962 | err = 0; |
963 | } | |
964 | /* If we didn't specify a single device, show all available devices */ | |
965 | } else if (!numdev) { | |
966 | blkid_dev_iterate iter; | |
967 | blkid_dev dev; | |
968 | ||
969 | blkid_probe_all(cache); | |
970 | ||
971 | iter = blkid_dev_iterate_begin(cache); | |
972 | blkid_dev_set_search(iter, search_type, search_value); | |
973 | while (blkid_dev_next(iter, &dev) == 0) { | |
974 | dev = blkid_verify(cache, dev); | |
975 | if (!dev) | |
976 | continue; | |
59b94cc0 | 977 | print_tags(&ctl, dev); |
51410fc6 KZ |
978 | err = 0; |
979 | } | |
980 | blkid_dev_iterate_end(iter); | |
981 | /* Add all specified devices to cache (optionally display tags) */ | |
982 | } else for (i = 0; i < numdev; i++) { | |
983 | blkid_dev dev = blkid_get_dev(cache, devices[i], | |
984 | BLKID_DEV_NORMAL); | |
985 | ||
986 | if (dev) { | |
987 | if (search_type && | |
988 | !blkid_dev_has_tag(dev, search_type, | |
989 | search_value)) | |
990 | continue; | |
59b94cc0 | 991 | print_tags(&ctl, dev); |
51410fc6 KZ |
992 | err = 0; |
993 | } | |
994 | } | |
995 | ||
996 | exit: | |
4786921c | 997 | free(search_type); |
998 | free(search_value); | |
4f946f53 | 999 | free_types_list(fltr_type); |
59b94cc0 | 1000 | if (!ctl.lowprobe && !ctl.eval) |
5b6215b5 | 1001 | blkid_put_cache(cache); |
ea51c09c | 1002 | free(devices); |
51410fc6 KZ |
1003 | return err; |
1004 | } |