]>
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); | |
bad4c729 | 103 | fprintf(out, USAGE_HELP_OPTIONS(28)); |
f1970cc5 KZ |
104 | |
105 | fputs(USAGE_ARGUMENTS, out); | |
bad4c729 | 106 | fprintf(out, USAGE_ARG_SIZE(_("<size> and <offset>"))); |
f1970cc5 KZ |
107 | fputs(USAGE_ARG_SEPARATOR, out); |
108 | fputs(_(" <dev> specify device(s) to probe (default: all devices)\n"), out); | |
109 | ||
bad4c729 | 110 | fprintf(out, 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 | ||
7165c9bb | 405 | if (a) |
cba33452 | 406 | str = mempcpy(str, a, asz); |
7165c9bb | 407 | if (b) |
cba33452 | 408 | str = mempcpy(str, b, bsz); |
7165c9bb | 409 | |
c54670d5 KZ |
410 | *str = '\0'; |
411 | *sz = len; | |
412 | return 0; | |
413 | } | |
414 | ||
415 | /* | |
416 | * Compose and print ID_FS_AMBIVALENT for udev | |
417 | */ | |
418 | static int print_udev_ambivalent(blkid_probe pr) | |
419 | { | |
420 | char *val = NULL; | |
421 | size_t valsz = 0; | |
422 | int count = 0, rc = -1; | |
423 | ||
424 | while (!blkid_do_probe(pr)) { | |
f5ee44b1 | 425 | const char *usage_txt = NULL, *type = NULL, *version = NULL; |
c54670d5 KZ |
426 | char enc[256]; |
427 | ||
f5ee44b1 | 428 | blkid_probe_lookup_value(pr, "USAGE", &usage_txt, NULL); |
c54670d5 KZ |
429 | blkid_probe_lookup_value(pr, "TYPE", &type, NULL); |
430 | blkid_probe_lookup_value(pr, "VERSION", &version, NULL); | |
431 | ||
f5ee44b1 | 432 | if (!usage_txt || !type) |
c54670d5 KZ |
433 | continue; |
434 | ||
f5ee44b1 | 435 | blkid_encode_string(usage_txt, enc, sizeof(enc)); |
c54670d5 KZ |
436 | if (append_str(&val, &valsz, enc, ":")) |
437 | goto done; | |
438 | ||
439 | blkid_encode_string(type, enc, sizeof(enc)); | |
440 | if (append_str(&val, &valsz, enc, version ? ":" : " ")) | |
441 | goto done; | |
442 | ||
443 | if (version) { | |
444 | blkid_encode_string(version, enc, sizeof(enc)); | |
445 | if (append_str(&val, &valsz, enc, " ")) | |
446 | goto done; | |
447 | } | |
448 | count++; | |
449 | } | |
450 | ||
451 | if (count > 1) { | |
452 | *(val + valsz - 1) = '\0'; /* rem tailing whitespace */ | |
08af448f | 453 | printf("ID_FS_AMBIVALENT=%s\n", val); |
c54670d5 KZ |
454 | rc = 0; |
455 | } | |
456 | done: | |
457 | free(val); | |
458 | return rc; | |
459 | } | |
460 | ||
5e91d5dd | 461 | static int lowprobe_superblocks(blkid_probe pr, struct blkid_control *ctl) |
5b6215b5 | 462 | { |
e3d8933a | 463 | struct stat st; |
d75bcac4 | 464 | int rc, fd = blkid_probe_get_fd(pr); |
e3d8933a | 465 | |
d75bcac4 | 466 | if (fd < 0 || fstat(fd, &st)) |
09792910 | 467 | return -1; |
e3d8933a KZ |
468 | |
469 | blkid_probe_enable_partitions(pr, 1); | |
4f74ffdb | 470 | |
6a2f2f58 KZ |
471 | if (!S_ISCHR(st.st_mode) && blkid_probe_get_size(pr) <= 1024 * 1440 && |
472 | blkid_probe_is_wholedisk(pr)) { | |
e3d8933a | 473 | /* |
cba1f975 KZ |
474 | * check if the small disk is partitioned, if yes then |
475 | * don't probe for filesystems. | |
e3d8933a | 476 | */ |
cba1f975 | 477 | blkid_probe_enable_superblocks(pr, 0); |
e3d8933a | 478 | |
cba1f975 | 479 | rc = blkid_do_fullprobe(pr); |
e3d8933a | 480 | if (rc < 0) |
9e930041 | 481 | return rc; /* -1 = error, 1 = nothing, 0 = success */ |
cba1f975 KZ |
482 | |
483 | if (blkid_probe_lookup_value(pr, "PTTYPE", NULL, NULL) == 0) | |
09792910 | 484 | return 0; /* partition table detected */ |
e3d8933a | 485 | } |
5b6215b5 | 486 | |
5e91d5dd KZ |
487 | if (!ctl->no_part_details) |
488 | blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS); | |
cba1f975 KZ |
489 | blkid_probe_enable_superblocks(pr, 1); |
490 | ||
09792910 KZ |
491 | return blkid_do_safeprobe(pr); |
492 | } | |
493 | ||
494 | static int lowprobe_topology(blkid_probe pr) | |
495 | { | |
496 | /* enable topology probing only */ | |
497 | blkid_probe_enable_topology(pr, 1); | |
498 | ||
499 | blkid_probe_enable_superblocks(pr, 0); | |
500 | blkid_probe_enable_partitions(pr, 0); | |
501 | ||
502 | return blkid_do_fullprobe(pr); | |
503 | } | |
504 | ||
505 | static int lowprobe_device(blkid_probe pr, const char *devname, | |
59b94cc0 | 506 | struct blkid_control *ctl) |
09792910 KZ |
507 | { |
508 | const char *data; | |
509 | const char *name; | |
510 | int nvals = 0, n, num = 1; | |
511 | size_t len; | |
512 | int fd; | |
513 | int rc = 0; | |
514 | static int first = 1; | |
515 | ||
39f5af25 | 516 | fd = open(devname, O_RDONLY|O_CLOEXEC|O_NONBLOCK); |
09792910 | 517 | if (fd < 0) { |
f5a2b07e | 518 | warn(_("error: %s"), devname); |
1578ddd6 | 519 | return BLKID_EXIT_NOTFOUND; |
09792910 | 520 | } |
dc30fd43 KZ |
521 | errno = 0; |
522 | if (blkid_probe_set_device(pr, fd, ctl->offset, ctl->size)) { | |
523 | if (errno) | |
524 | warn(_("error: %s"), devname); | |
09792910 | 525 | goto done; |
dc30fd43 | 526 | } |
09792910 | 527 | |
59b94cc0 | 528 | if (ctl->lowprobe_topology) |
09792910 | 529 | rc = lowprobe_topology(pr); |
59b94cc0 | 530 | if (rc >= 0 && ctl->lowprobe_superblocks) |
5e91d5dd | 531 | rc = lowprobe_superblocks(pr, ctl); |
cba1f975 KZ |
532 | if (rc < 0) |
533 | goto done; | |
09792910 | 534 | |
dbcafb87 KZ |
535 | if (!rc) |
536 | nvals = blkid_probe_numof_values(pr); | |
5b6215b5 | 537 | |
59b94cc0 | 538 | if (nvals && !first && ctl->output & (OUTPUT_UDEV_LIST | OUTPUT_EXPORT_LIST)) |
9eb44c28 KZ |
539 | /* add extra line between output from devices */ |
540 | fputc('\n', stdout); | |
541 | ||
59b94cc0 | 542 | if (nvals && (ctl->output & OUTPUT_DEVICE_ONLY)) { |
e88517b1 KZ |
543 | printf("%s\n", devname); |
544 | goto done; | |
545 | } | |
546 | ||
5b6215b5 KZ |
547 | for (n = 0; n < nvals; n++) { |
548 | if (blkid_probe_get_value(pr, n, &name, &data, &len)) | |
549 | continue; | |
071147ab | 550 | if (ctl->show[0] && !has_item(ctl, name)) |
7711e215 | 551 | continue; |
e736434b KZ |
552 | len = strnlen(data, len); |
553 | print_value(ctl, num++, devname, data, name, len); | |
5b6215b5 KZ |
554 | } |
555 | ||
9eb44c28 KZ |
556 | if (first) |
557 | first = 0; | |
59b94cc0 SK |
558 | |
559 | if (nvals >= 1 && !(ctl->output & (OUTPUT_VALUE_ONLY | | |
ab978962 | 560 | OUTPUT_UDEV_LIST | OUTPUT_EXPORT_LIST))) |
cf778d68 | 561 | printf("\n"); |
e88517b1 | 562 | done: |
c54670d5 | 563 | if (rc == -2) { |
59b94cc0 | 564 | if (ctl->output & OUTPUT_UDEV_LIST) |
c54670d5 KZ |
565 | print_udev_ambivalent(pr); |
566 | else | |
f5a2b07e | 567 | warnx(_("%s: ambivalent result (probably more " |
c54670d5 | 568 | "filesystems on the device, use wipefs(8) " |
f5a2b07e | 569 | "to see more details)"), |
a2f01a1c | 570 | devname); |
c54670d5 | 571 | } |
5b6215b5 | 572 | close(fd); |
68c88d94 KZ |
573 | |
574 | if (rc == -2) | |
1578ddd6 | 575 | return BLKID_EXIT_AMBIVAL; /* ambivalent probing result */ |
68c88d94 | 576 | if (!nvals) |
1578ddd6 | 577 | return BLKID_EXIT_NOTFOUND; /* nothing detected */ |
68c88d94 | 578 | |
455fe9a0 | 579 | return 0; /* success */ |
5b6215b5 KZ |
580 | } |
581 | ||
0bdd2f97 KZ |
582 | /* converts comma separated list to BLKID_USAGE_* mask */ |
583 | static int list_to_usage(const char *list, int *flag) | |
584 | { | |
585 | int mask = 0; | |
962496d4 | 586 | const char *word = NULL, *p = list; |
0bdd2f97 KZ |
587 | |
588 | if (p && strncmp(p, "no", 2) == 0) { | |
589 | *flag = BLKID_FLTR_NOTIN; | |
590 | p += 2; | |
591 | } | |
962496d4 KZ |
592 | if (!p || !*p) |
593 | goto err; | |
962496d4 KZ |
594 | while(p) { |
595 | word = p; | |
962496d4 KZ |
596 | p = strchr(p, ','); |
597 | if (p) | |
598 | p++; | |
962496d4 KZ |
599 | if (!strncmp(word, "filesystem", 10)) |
600 | mask |= BLKID_USAGE_FILESYSTEM; | |
601 | else if (!strncmp(word, "raid", 4)) | |
602 | mask |= BLKID_USAGE_RAID; | |
603 | else if (!strncmp(word, "crypto", 6)) | |
604 | mask |= BLKID_USAGE_CRYPTO; | |
605 | else if (!strncmp(word, "other", 5)) | |
606 | mask |= BLKID_USAGE_OTHER; | |
607 | else | |
608 | goto err; | |
0bdd2f97 KZ |
609 | } |
610 | return mask; | |
962496d4 KZ |
611 | err: |
612 | *flag = 0; | |
f5a2b07e | 613 | warnx(_("unknown keyword in -u <list> argument: '%s'"), |
962496d4 | 614 | word ? word : list); |
1578ddd6 | 615 | exit(BLKID_EXIT_OTHER); |
0bdd2f97 KZ |
616 | } |
617 | ||
4f946f53 KZ |
618 | /* converts comma separated list to types[] */ |
619 | static char **list_to_types(const char *list, int *flag) | |
620 | { | |
621 | int i; | |
622 | const char *p = list; | |
bc867ea3 | 623 | char **res = NULL; |
4f946f53 KZ |
624 | |
625 | if (p && strncmp(p, "no", 2) == 0) { | |
626 | *flag = BLKID_FLTR_NOTIN; | |
627 | p += 2; | |
628 | } | |
629 | if (!p || !*p) { | |
f5a2b07e | 630 | warnx(_("error: -u <list> argument is empty")); |
4f946f53 KZ |
631 | goto err; |
632 | } | |
633 | for (i = 1; p && (p = strchr(p, ',')); i++, p++); | |
634 | ||
5d00280c | 635 | res = xcalloc(i + 1, sizeof(char *)); |
4f946f53 KZ |
636 | p = *flag & BLKID_FLTR_NOTIN ? list + 2 : list; |
637 | i = 0; | |
638 | ||
639 | while(p) { | |
640 | const char *word = p; | |
641 | p = strchr(p, ','); | |
5d00280c | 642 | res[i++] = p ? xstrndup(word, p - word) : xstrdup(word); |
4f946f53 KZ |
643 | if (p) |
644 | p++; | |
645 | } | |
646 | res[i] = NULL; | |
647 | return res; | |
4f946f53 KZ |
648 | err: |
649 | *flag = 0; | |
650 | free(res); | |
1578ddd6 | 651 | exit(BLKID_EXIT_OTHER); |
4f946f53 KZ |
652 | } |
653 | ||
654 | static void free_types_list(char *list[]) | |
655 | { | |
656 | char **n; | |
657 | ||
658 | if (!list) | |
659 | return; | |
660 | for (n = list; *n; n++) | |
661 | free(*n); | |
662 | free(list); | |
663 | } | |
664 | ||
51410fc6 KZ |
665 | int main(int argc, char **argv) |
666 | { | |
59b94cc0 | 667 | struct blkid_control ctl = { .output = OUTPUT_FULL, 0 }; |
51410fc6 | 668 | blkid_cache cache = NULL; |
ea51c09c | 669 | char **devices = NULL; |
51410fc6 | 670 | char *search_type = NULL, *search_value = NULL; |
ac3a0fd9 | 671 | char *read = NULL, *hint = NULL; |
0bdd2f97 | 672 | int fltr_usage = 0; |
4f946f53 | 673 | char **fltr_type = NULL; |
0bdd2f97 | 674 | int fltr_flag = BLKID_FLTR_ONLYIN; |
51410fc6 | 675 | unsigned int numdev = 0, numtag = 0; |
1578ddd6 | 676 | int err = BLKID_EXIT_OTHER; |
51410fc6 | 677 | unsigned int i; |
51410fc6 KZ |
678 | int c; |
679 | ||
15a74f75 SK |
680 | static const struct option longopts[] = { |
681 | { "cache-file", required_argument, NULL, 'c' }, | |
682 | { "no-encoding", no_argument, NULL, 'd' }, | |
5e91d5dd | 683 | { "no-part-details", no_argument, NULL, 'D' }, |
15a74f75 SK |
684 | { "garbage-collect", no_argument, NULL, 'g' }, |
685 | { "output", required_argument, NULL, 'o' }, | |
686 | { "list-filesystems", no_argument, NULL, 'k' }, | |
687 | { "match-tag", required_argument, NULL, 's' }, | |
688 | { "match-token", required_argument, NULL, 't' }, | |
689 | { "list-one", no_argument, NULL, 'l' }, | |
690 | { "label", required_argument, NULL, 'L' }, | |
691 | { "uuid", required_argument, NULL, 'U' }, | |
692 | { "probe", no_argument, NULL, 'p' }, | |
ac3a0fd9 | 693 | { "hint", required_argument, NULL, 'H' }, |
15a74f75 SK |
694 | { "info", no_argument, NULL, 'i' }, |
695 | { "size", required_argument, NULL, 'S' }, | |
696 | { "offset", required_argument, NULL, 'O' }, | |
697 | { "usages", required_argument, NULL, 'u' }, | |
698 | { "match-types", required_argument, NULL, 'n' }, | |
699 | { "version", no_argument, NULL, 'V' }, | |
700 | { "help", no_argument, NULL, 'h' }, | |
701 | { NULL, 0, NULL, 0 } | |
702 | }; | |
703 | ||
a7349ee3 | 704 | static const ul_excl_t excl[] = { /* rows and cols in ASCII order */ |
a8e458b9 KZ |
705 | { 'n','u' }, |
706 | { 0 } | |
72b99fc5 | 707 | }; |
a8e458b9 | 708 | int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; |
72b99fc5 | 709 | |
f5a2b07e SK |
710 | setlocale(LC_ALL, ""); |
711 | bindtextdomain(PACKAGE, LOCALEDIR); | |
712 | textdomain(PACKAGE); | |
2c308875 | 713 | close_stdout_atexit(); |
7711e215 | 714 | |
9c8b9fba RM |
715 | strutils_set_exitcode(BLKID_EXIT_OTHER); |
716 | ||
15a74f75 | 717 | while ((c = getopt_long (argc, argv, |
ac3a0fd9 | 718 | "c:DdgH:hilL:n:ko:O:ps:S:t:u:U:w:Vv", longopts, NULL)) != -1) { |
a8e458b9 | 719 | |
ee84a3bf | 720 | err_exclusive_options(c, longopts, excl, excl_st); |
a8e458b9 | 721 | |
51410fc6 KZ |
722 | switch (c) { |
723 | case 'c': | |
59b94cc0 | 724 | read = optarg; |
51410fc6 | 725 | break; |
36a74e1b | 726 | case 'd': |
59b94cc0 | 727 | ctl.raw_chars = 1; |
36a74e1b | 728 | break; |
5e91d5dd KZ |
729 | case 'D': |
730 | ctl.no_part_details = 1; | |
731 | break; | |
ac3a0fd9 KZ |
732 | case 'H': |
733 | hint = optarg; | |
734 | break; | |
4786921c | 735 | case 'L': |
59b94cc0 | 736 | ctl.eval = 1; |
fe20e5d1 SK |
737 | search_value = xstrdup(optarg); |
738 | search_type = xstrdup("LABEL"); | |
4786921c | 739 | break; |
4f946f53 | 740 | case 'n': |
4f946f53 KZ |
741 | fltr_type = list_to_types(optarg, &fltr_flag); |
742 | break; | |
0bdd2f97 KZ |
743 | case 'u': |
744 | fltr_usage = list_to_usage(optarg, &fltr_flag); | |
745 | break; | |
4786921c | 746 | case 'U': |
59b94cc0 | 747 | ctl.eval = 1; |
fe20e5d1 SK |
748 | search_value = xstrdup(optarg); |
749 | search_type = xstrdup("UUID"); | |
4786921c | 750 | break; |
09792910 | 751 | case 'i': |
59b94cc0 | 752 | ctl.lowprobe_topology = 1; |
09792910 | 753 | break; |
51410fc6 | 754 | case 'l': |
59b94cc0 | 755 | ctl.lookup = 1; |
51410fc6 | 756 | break; |
51410fc6 | 757 | case 'g': |
59b94cc0 | 758 | ctl.gc = 1; |
51410fc6 | 759 | break; |
70db6c7e KZ |
760 | case 'k': |
761 | { | |
762 | size_t idx = 0; | |
763 | const char *name = NULL; | |
764 | ||
765 | while (blkid_superblocks_get_name(idx++, &name, NULL) == 0) | |
766 | printf("%s\n", name); | |
a922091d | 767 | exit(EXIT_SUCCESS); |
70db6c7e | 768 | } |
51410fc6 KZ |
769 | case 'o': |
770 | if (!strcmp(optarg, "value")) | |
59b94cc0 | 771 | ctl.output = OUTPUT_VALUE_ONLY; |
51410fc6 | 772 | else if (!strcmp(optarg, "device")) |
59b94cc0 | 773 | ctl.output = OUTPUT_DEVICE_ONLY; |
51410fc6 | 774 | else if (!strcmp(optarg, "list")) |
59b94cc0 | 775 | ctl.output = OUTPUT_PRETTY_LIST; /* deprecated */ |
b516dbe0 | 776 | else if (!strcmp(optarg, "udev")) |
59b94cc0 | 777 | ctl.output = OUTPUT_UDEV_LIST; |
ab978962 | 778 | else if (!strcmp(optarg, "export")) |
59b94cc0 | 779 | ctl.output = OUTPUT_EXPORT_LIST; |
51410fc6 | 780 | else if (!strcmp(optarg, "full")) |
59b94cc0 | 781 | ctl.output = 0; |
f5a2b07e SK |
782 | else |
783 | errx(BLKID_EXIT_OTHER, _("unsupported output format %s"), optarg); | |
51410fc6 | 784 | break; |
5b6215b5 | 785 | case 'O': |
59b94cc0 | 786 | ctl.offset = strtosize_or_err(optarg, _("invalid offset argument")); |
5b6215b5 KZ |
787 | break; |
788 | case 'p': | |
59b94cc0 | 789 | ctl.lowprobe_superblocks = 1; |
5b6215b5 | 790 | break; |
51410fc6 | 791 | case 's': |
59b94cc0 | 792 | if (numtag + 1 >= sizeof(ctl.show) / sizeof(*ctl.show)) { |
f5a2b07e | 793 | warnx(_("Too many tags specified")); |
3b7693ca | 794 | errtryhelp(err); |
51410fc6 | 795 | } |
59b94cc0 | 796 | ctl.show[numtag++] = optarg; |
51410fc6 | 797 | break; |
5b6215b5 | 798 | case 'S': |
59b94cc0 | 799 | ctl.size = strtosize_or_err(optarg, _("invalid size argument")); |
5b6215b5 | 800 | break; |
51410fc6 KZ |
801 | case 't': |
802 | if (search_type) { | |
f5a2b07e SK |
803 | warnx(_("Can only search for " |
804 | "one NAME=value pair")); | |
3b7693ca | 805 | errtryhelp(err); |
51410fc6 KZ |
806 | } |
807 | if (blkid_parse_tag_string(optarg, | |
808 | &search_type, | |
809 | &search_value)) { | |
f5a2b07e | 810 | warnx(_("-t needs NAME=value pair")); |
3b7693ca | 811 | errtryhelp(err); |
51410fc6 KZ |
812 | } |
813 | break; | |
a9b2c52f | 814 | case 'V': |
51410fc6 | 815 | case 'v': |
68224d10 KZ |
816 | fprintf(stdout, _("%s from %s (libblkid %s, %s)\n"), |
817 | program_invocation_short_name, PACKAGE_STRING, | |
818 | LIBBLKID_VERSION, LIBBLKID_DATE); | |
dc46610b | 819 | err = 0; |
93bdbe19 | 820 | goto exit; |
51410fc6 | 821 | case 'w': |
077b15dc | 822 | /* ignore - backward compatibility */ |
51410fc6 KZ |
823 | break; |
824 | case 'h': | |
fa2cd89a | 825 | usage(); |
677ec86c | 826 | break; |
51410fc6 | 827 | default: |
3b7693ca | 828 | errtryhelp(EXIT_FAILURE); |
51410fc6 | 829 | } |
a8e458b9 | 830 | } |
51410fc6 | 831 | |
59b94cc0 SK |
832 | if (ctl.lowprobe_topology || ctl.lowprobe_superblocks) |
833 | ctl.lowprobe = 1; | |
ea51c09c ES |
834 | |
835 | /* The rest of the args are device names */ | |
836 | if (optind < argc) { | |
5d00280c | 837 | devices = xcalloc(argc - optind, sizeof(char *)); |
64cfe6ac KZ |
838 | while (optind < argc) { |
839 | char *dev = argv[optind++]; | |
840 | struct stat sb; | |
841 | ||
842 | if (stat(dev, &sb) != 0) | |
843 | continue; | |
844 | else if (S_ISBLK(sb.st_mode)) | |
845 | ; | |
846 | else if (S_ISREG(sb.st_mode)) | |
847 | ; | |
848 | else if (S_ISCHR(sb.st_mode)) { | |
849 | char buf[PATH_MAX]; | |
850 | ||
851 | if (!sysfs_chrdev_devno_to_devname( | |
852 | sb.st_rdev, buf, sizeof(buf))) | |
853 | continue; | |
854 | if (strncmp(buf, "ubi", 3) != 0) | |
855 | continue; | |
856 | } else | |
857 | continue; | |
858 | ||
859 | devices[numdev++] = dev; | |
860 | } | |
9e882685 KZ |
861 | |
862 | if (!numdev) { | |
863 | /* only unsupported devices specified */ | |
864 | err = BLKID_EXIT_NOTFOUND; | |
865 | goto exit; | |
866 | } | |
54a00b5c | 867 | } |
51410fc6 | 868 | |
4786921c | 869 | /* convert LABEL/UUID lookup to evaluate request */ |
59b94cc0 | 870 | if (ctl.lookup && ctl.output == OUTPUT_DEVICE_ONLY && search_type && |
4786921c | 871 | (!strcmp(search_type, "LABEL") || !strcmp(search_type, "UUID"))) { |
59b94cc0 SK |
872 | ctl.eval = 1; |
873 | ctl.lookup = 0; | |
4786921c | 874 | } |
875 | ||
59b94cc0 | 876 | if (!ctl.lowprobe && !ctl.eval && blkid_get_cache(&cache, read) < 0) |
51410fc6 KZ |
877 | goto exit; |
878 | ||
59b94cc0 | 879 | if (ctl.gc) { |
51410fc6 | 880 | blkid_gc_cache(cache); |
324759d6 | 881 | err = 0; |
51410fc6 KZ |
882 | goto exit; |
883 | } | |
1578ddd6 | 884 | err = BLKID_EXIT_NOTFOUND; |
324759d6 | 885 | |
59b94cc0 SK |
886 | if (ctl.eval == 0 && (ctl.output & OUTPUT_PRETTY_LIST)) { |
887 | if (ctl.lowprobe) | |
f5a2b07e SK |
888 | errx(BLKID_EXIT_OTHER, |
889 | _("The low-level probing mode does not " | |
890 | "support 'list' output format")); | |
51410fc6 | 891 | pretty_print_dev(NULL); |
2d71a929 | 892 | } |
51410fc6 | 893 | |
59b94cc0 | 894 | if (ctl.lowprobe) { |
4786921c | 895 | /* |
896 | * Low-level API | |
897 | */ | |
5b6215b5 KZ |
898 | blkid_probe pr; |
899 | ||
f5a2b07e SK |
900 | if (!numdev) |
901 | errx(BLKID_EXIT_OTHER, | |
902 | _("The low-level probing mode " | |
903 | "requires a device")); | |
ab978962 KZ |
904 | |
905 | /* automatically enable 'export' format for I/O Limits */ | |
59b94cc0 SK |
906 | if (!ctl.output && ctl.lowprobe_topology) |
907 | ctl.output = OUTPUT_EXPORT_LIST; | |
ab978962 | 908 | |
5b6215b5 KZ |
909 | pr = blkid_new_probe(); |
910 | if (!pr) | |
911 | goto exit; | |
ac3a0fd9 KZ |
912 | if (hint && blkid_probe_set_hint(pr, hint, 0) != 0) { |
913 | warn(_("Failed to use probing hint: %s"), hint); | |
914 | goto exit; | |
915 | } | |
1b780848 | 916 | |
59b94cc0 | 917 | if (ctl.lowprobe_superblocks) { |
09792910 | 918 | blkid_probe_set_superblocks_flags(pr, |
1b780848 KZ |
919 | BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | |
920 | BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE | | |
60cedc92 | 921 | BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION | |
c9b2297e | 922 | BLKID_SUBLKS_FSINFO); |
59b94cc0 SK |
923 | |
924 | if (fltr_usage && | |
925 | blkid_probe_filter_superblocks_usage(pr, fltr_flag, fltr_usage)) | |
09792910 KZ |
926 | goto exit; |
927 | ||
59b94cc0 SK |
928 | else if (fltr_type && |
929 | blkid_probe_filter_superblocks_type(pr, fltr_flag, fltr_type)) | |
09792910 KZ |
930 | goto exit; |
931 | } | |
5b6215b5 | 932 | |
078ad9bf | 933 | for (i = 0; i < numdev; i++) { |
59b94cc0 | 934 | err = lowprobe_device(pr, devices[i], &ctl); |
078ad9bf PU |
935 | if (err) |
936 | break; | |
937 | } | |
5b6215b5 | 938 | blkid_free_probe(pr); |
59b94cc0 | 939 | } else if (ctl.eval) { |
4786921c | 940 | /* |
941 | * Evaluate API | |
942 | */ | |
cee95a95 | 943 | char *res = blkid_evaluate_tag(search_type, search_value, NULL); |
324759d6 SJR |
944 | if (res) { |
945 | err = 0; | |
4786921c | 946 | printf("%s\n", res); |
324759d6 | 947 | } |
59b94cc0 | 948 | } else if (ctl.lookup) { |
4786921c | 949 | /* |
950 | * Classic (cache based) API | |
951 | */ | |
51410fc6 KZ |
952 | blkid_dev dev; |
953 | ||
f5a2b07e SK |
954 | if (!search_type) |
955 | errx(BLKID_EXIT_OTHER, | |
956 | _("The lookup option requires a " | |
957 | "search type specified using -t")); | |
51410fc6 KZ |
958 | /* Load any additional devices not in the cache */ |
959 | for (i = 0; i < numdev; i++) | |
960 | blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL); | |
961 | ||
962 | if ((dev = blkid_find_dev_with_tag(cache, search_type, | |
963 | search_value))) { | |
59b94cc0 | 964 | print_tags(&ctl, dev); |
51410fc6 KZ |
965 | err = 0; |
966 | } | |
967 | /* If we didn't specify a single device, show all available devices */ | |
968 | } else if (!numdev) { | |
969 | blkid_dev_iterate iter; | |
970 | blkid_dev dev; | |
971 | ||
972 | blkid_probe_all(cache); | |
973 | ||
974 | iter = blkid_dev_iterate_begin(cache); | |
975 | blkid_dev_set_search(iter, search_type, search_value); | |
976 | while (blkid_dev_next(iter, &dev) == 0) { | |
977 | dev = blkid_verify(cache, dev); | |
978 | if (!dev) | |
979 | continue; | |
59b94cc0 | 980 | print_tags(&ctl, dev); |
51410fc6 KZ |
981 | err = 0; |
982 | } | |
983 | blkid_dev_iterate_end(iter); | |
984 | /* Add all specified devices to cache (optionally display tags) */ | |
985 | } else for (i = 0; i < numdev; i++) { | |
986 | blkid_dev dev = blkid_get_dev(cache, devices[i], | |
987 | BLKID_DEV_NORMAL); | |
988 | ||
989 | if (dev) { | |
990 | if (search_type && | |
991 | !blkid_dev_has_tag(dev, search_type, | |
992 | search_value)) | |
993 | continue; | |
59b94cc0 | 994 | print_tags(&ctl, dev); |
51410fc6 KZ |
995 | err = 0; |
996 | } | |
997 | } | |
998 | ||
999 | exit: | |
4786921c | 1000 | free(search_type); |
1001 | free(search_value); | |
4f946f53 | 1002 | free_types_list(fltr_type); |
59b94cc0 | 1003 | if (!ctl.lowprobe && !ctl.eval) |
5b6215b5 | 1004 | blkid_put_cache(cache); |
ea51c09c | 1005 | free(devices); |
51410fc6 KZ |
1006 | return err; |
1007 | } |