~ubuntu-branches/ubuntu/lucid/loop-aes-utils/lucid-security

« back to all changes in this revision

Viewing changes to libs/blkid/bin/blkid.c

  • Committer: Bazaar Package Importer
  • Author(s): Max Vozeler
  • Date: 2009-07-06 02:08:18 UTC
  • mfrom: (1.3.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090706020818-11pxao7bhgjenfv9
Tags: 2.15.1~rc1-2
Disable ncurses (--without-ncurses), not used in
mount/. Fixes FTBFS (closes: #535676).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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>
 
16
#include <sys/types.h>
 
17
#include <sys/stat.h>
 
18
#include <fcntl.h>
 
19
#ifdef HAVE_TERMIOS_H
 
20
#include <termios.h>
 
21
#endif
 
22
#ifdef HAVE_TERMIO_H
 
23
#include <termio.h>
 
24
#endif
 
25
#ifdef HAVE_SYS_IOCTL_H
 
26
#include <sys/ioctl.h>
 
27
#endif
 
28
#ifdef HAVE_GETOPT_H
 
29
#include <getopt.h>
 
30
#else
 
31
extern int getopt(int argc, char * const argv[], const char *optstring);
 
32
extern char *optarg;
 
33
extern int optind;
 
34
#endif
 
35
 
 
36
#define OUTPUT_VALUE_ONLY       0x0001
 
37
#define OUTPUT_DEVICE_ONLY      0x0002
 
38
#define OUTPUT_PRETTY_LIST      0x0004
 
39
#define OUTPUT_UDEV_LIST        0x0008
 
40
 
 
41
#include <blkid.h>
 
42
 
 
43
const char *progname = "blkid";
 
44
 
 
45
static void print_version(FILE *out)
 
46
{
 
47
        fprintf(out, "%s from %s (libblkid %s, %s)\n",
 
48
                progname, PACKAGE_STRING, LIBBLKID_VERSION, LIBBLKID_DATE);
 
49
}
 
50
 
 
51
static void usage(int error)
 
52
{
 
53
        FILE *out = error ? stderr : stdout;
 
54
 
 
55
        print_version(out);
 
56
        fprintf(out,
 
57
                "Usage:\n"
 
58
                "  %1$s -L <label> | -U <uuid>\n\n"
 
59
                "  %1$s [-c <file>] [-ghlLv] [-o format] [-s <tag>] \n"
 
60
                "        [-t <token>] [-w <file>] [dev ...]\n\n"
 
61
                "  %1$s -p [-O <offset>] [-S <size>] [-o format] <dev> [dev ...]\n\n"
 
62
                "Options:\n"
 
63
                "  -c <file>   cache file (default: /etc/blkid.tab, /dev/null = none)\n"
 
64
                "  -h          print this usage message and exit\n"
 
65
                "  -g          garbage collect the blkid cache\n"
 
66
                "  -o <format> output format; can be one of:\n"
 
67
                "              value, device, list, udev or full; (default: full)\n"
 
68
                "  -s <tag>    show specified tag(s) (default show all tags)\n"
 
69
                "  -t <token>  find device with a specific token (NAME=value pair)\n"
 
70
                "  -l          lookup the the first device with arguments specified by -t\n"
 
71
                "  -L <label>  convert LABEL to device name\n"
 
72
                "  -U <uuid>   convert UUID to device name\n"
 
73
                "  -v          print version and exit\n"
 
74
                "  -w <file>   write cache to different file (/dev/null = no write)\n"
 
75
                "  <dev>       specify device(s) to probe (default: all devices)\n\n"
 
76
                "Low-level probing options:\n"
 
77
                "  -p          switch to low-level mode (bypass cache)\n"
 
78
                "  -S <bytes>  overwrite device size\n"
 
79
                "  -O <bytes>  probe at the given offset\n"
 
80
                "  -u <list>   filter by \"usage\" (e.g. -u filesystem,raid)\n"
 
81
                "\n",
 
82
                                progname);
 
83
 
 
84
        exit(error);
 
85
}
 
86
 
 
87
/*
 
88
 * This function does "safe" printing.  It will convert non-printable
 
89
 * ASCII characters using '^' and M- notation.
 
90
 */
 
91
static void safe_print(const char *cp, int len)
 
92
{
 
93
        unsigned char   ch;
 
94
 
 
95
        if (len < 0)
 
96
                len = strlen(cp);
 
97
 
 
98
        while (len--) {
 
99
                ch = *cp++;
 
100
                if (ch > 128) {
 
101
                        fputs("M-", stdout);
 
102
                        ch -= 128;
 
103
                }
 
104
                if ((ch < 32) || (ch == 0x7f)) {
 
105
                        fputc('^', stdout);
 
106
                        ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
 
107
                }
 
108
                fputc(ch, stdout);
 
109
        }
 
110
}
 
111
 
 
112
static int get_terminal_width(void)
 
113
{
 
114
#ifdef TIOCGSIZE
 
115
        struct ttysize  t_win;
 
116
#endif
 
117
#ifdef TIOCGWINSZ
 
118
        struct winsize  w_win;
 
119
#endif
 
120
        const char      *cp;
 
121
 
 
122
#ifdef TIOCGSIZE
 
123
        if (ioctl (0, TIOCGSIZE, &t_win) == 0)
 
124
                return (t_win.ts_cols);
 
125
#endif
 
126
#ifdef TIOCGWINSZ
 
127
        if (ioctl (0, TIOCGWINSZ, &w_win) == 0)
 
128
                return (w_win.ws_col);
 
129
#endif
 
130
        cp = getenv("COLUMNS");
 
131
        if (cp)
 
132
                return strtol(cp, NULL, 10);
 
133
        return 80;
 
134
}
 
135
 
 
136
static int pretty_print_word(const char *str, int max_len,
 
137
                             int left_len, int overflow_nl)
 
138
{
 
139
        int len = strlen(str) + left_len;
 
140
        int ret = 0;
 
141
 
 
142
        fputs(str, stdout);
 
143
        if (overflow_nl && len > max_len) {
 
144
                fputc('\n', stdout);
 
145
                len = 0;
 
146
        } else if (len > max_len)
 
147
                ret = len - max_len;
 
148
        do
 
149
                fputc(' ', stdout);
 
150
        while (len++ < max_len);
 
151
        return ret;
 
152
}
 
153
 
 
154
static void pretty_print_line(const char *device, const char *fs_type,
 
155
                              const char *label, const char *mtpt,
 
156
                              const char *uuid)
 
157
{
 
158
        static int device_len = 10, fs_type_len = 7;
 
159
        static int label_len = 8, mtpt_len = 14;
 
160
        static int term_width = -1;
 
161
        int len, w;
 
162
 
 
163
        if (term_width < 0)
 
164
                term_width = get_terminal_width();
 
165
 
 
166
        if (term_width > 80) {
 
167
                term_width -= 80;
 
168
                w = term_width / 10;
 
169
                if (w > 8)
 
170
                        w = 8;
 
171
                term_width -= 2*w;
 
172
                label_len += w;
 
173
                fs_type_len += w;
 
174
                w = term_width/2;
 
175
                device_len += w;
 
176
                mtpt_len +=w;
 
177
        }
 
178
 
 
179
        len = pretty_print_word(device, device_len, 0, 1);
 
180
        len = pretty_print_word(fs_type, fs_type_len, len, 0);
 
181
        len = pretty_print_word(label, label_len, len, 0);
 
182
        len = pretty_print_word(mtpt, mtpt_len, len, 0);
 
183
        fputs(uuid, stdout);
 
184
        fputc('\n', stdout);
 
185
}
 
186
 
 
187
static void pretty_print_dev(blkid_dev dev)
 
188
{
 
189
        fprintf(stderr, "pretty print not implemented yet\n");
 
190
 
 
191
#ifdef NOT_IMPLEMENTED
 
192
        blkid_tag_iterate       iter;
 
193
        const char              *type, *value, *devname;
 
194
        const char              *uuid = "", *fs_type = "", *label = "";
 
195
        char                    *cp;
 
196
        int                     len, mount_flags;
 
197
        char                    mtpt[80];
 
198
        errcode_t               retval;
 
199
 
 
200
        if (dev == NULL) {
 
201
                pretty_print_line("device", "fs_type", "label",
 
202
                                  "mount point", "UUID");
 
203
                for (len=get_terminal_width()-1; len > 0; len--)
 
204
                        fputc('-', stdout);
 
205
                fputc('\n', stdout);
 
206
                return;
 
207
        }
 
208
 
 
209
        devname = blkid_dev_devname(dev);
 
210
        if (access(devname, F_OK))
 
211
                return;
 
212
 
 
213
        /* Get the uuid, label, type */
 
214
        iter = blkid_tag_iterate_begin(dev);
 
215
        while (blkid_tag_next(iter, &type, &value) == 0) {
 
216
                if (!strcmp(type, "UUID"))
 
217
                        uuid = value;
 
218
                if (!strcmp(type, "TYPE"))
 
219
                        fs_type = value;
 
220
                if (!strcmp(type, "LABEL"))
 
221
                        label = value;
 
222
        }
 
223
        blkid_tag_iterate_end(iter);
 
224
 
 
225
        /* Get the mount point */
 
226
        mtpt[0] = 0;
 
227
        retval = ext2fs_check_mount_point(devname, &mount_flags,
 
228
                                          mtpt, sizeof(mtpt));
 
229
        if (retval == 0) {
 
230
                if (mount_flags & EXT2_MF_MOUNTED) {
 
231
                        if (!mtpt[0])
 
232
                                strcpy(mtpt, "(mounted, mtpt unknown)");
 
233
                } else if (mount_flags & EXT2_MF_BUSY)
 
234
                        strcpy(mtpt, "(in use)");
 
235
                else
 
236
                        strcpy(mtpt, "(not mounted)");
 
237
        }
 
238
 
 
239
        pretty_print_line(devname, fs_type, label, mtpt, uuid);
 
240
#endif
 
241
}
 
242
 
 
243
static void print_udev_format(const char *name, const char *value, size_t sz)
 
244
{
 
245
        char enc[265], safe[256];
 
246
 
 
247
        *safe = *enc = '\0';
 
248
 
 
249
        if (!strcmp(name, "TYPE") || !strcmp(name, "VERSION")) {
 
250
                blkid_encode_string(value, enc, sizeof(enc));
 
251
                printf("ID_FS_%s=%s\n", name, enc);
 
252
 
 
253
        } else if (!strcmp(name, "UUID") ||
 
254
                 !strcmp(name, "LABEL") ||
 
255
                 !strcmp(name, "UUID_SUB")) {
 
256
 
 
257
                blkid_safe_string(value, safe, sizeof(safe));
 
258
                printf("ID_FS_%s=%s\n", name, safe);
 
259
 
 
260
                blkid_encode_string(value, enc, sizeof(enc));
 
261
                printf("ID_FS_%s_ENC=%s\n", name, enc);
 
262
        }
 
263
        else
 
264
                printf("ID_FS_%s=%s\n", name, value);
 
265
}
 
266
 
 
267
static void print_value(int output, int num, const char *devname,
 
268
                        const char *value, const char *name, size_t valsz)
 
269
{
 
270
        if (output & OUTPUT_VALUE_ONLY) {
 
271
                fputs(value, stdout);
 
272
                fputc('\n', stdout);
 
273
 
 
274
        } else if (output & OUTPUT_UDEV_LIST) {
 
275
                print_udev_format(name, value, valsz);
 
276
 
 
277
        } else {
 
278
                if (num == 1 && devname)
 
279
                        printf("%s: ", devname);
 
280
                fputs(name, stdout);
 
281
                fputs("=\"", stdout);
 
282
                safe_print(value, valsz);
 
283
                fputs("\" ", stdout);
 
284
        }
 
285
}
 
286
 
 
287
static void print_tags(blkid_dev dev, char *show[], int numtag, int output)
 
288
{
 
289
        blkid_tag_iterate       iter;
 
290
        const char              *type, *value, *devname;
 
291
        int                     i, num = 1;
 
292
 
 
293
        if (!dev)
 
294
                return;
 
295
 
 
296
        if (output & OUTPUT_PRETTY_LIST) {
 
297
                pretty_print_dev(dev);
 
298
                return;
 
299
        }
 
300
 
 
301
        devname = blkid_dev_devname(dev);
 
302
 
 
303
        if (output & OUTPUT_DEVICE_ONLY) {
 
304
                printf("%s\n", devname);
 
305
                return;
 
306
        }
 
307
 
 
308
        iter = blkid_tag_iterate_begin(dev);
 
309
        while (blkid_tag_next(iter, &type, &value) == 0) {
 
310
                if (numtag && show) {
 
311
                        for (i=0; i < numtag; i++)
 
312
                                if (!strcmp(type, show[i]))
 
313
                                        break;
 
314
                        if (i >= numtag)
 
315
                                continue;
 
316
                }
 
317
                print_value(output, num++, devname, value, type, strlen(value));
 
318
        }
 
319
        blkid_tag_iterate_end(iter);
 
320
 
 
321
        if (num > 1 && !(output & (OUTPUT_VALUE_ONLY | OUTPUT_UDEV_LIST)))
 
322
                printf("\n");
 
323
}
 
324
 
 
325
static int lowprobe_device(blkid_probe pr, const char *devname, int output,
 
326
                blkid_loff_t offset, blkid_loff_t size)
 
327
{
 
328
        const char *data;
 
329
        const char *name;
 
330
        int nvals = 0, n;
 
331
        size_t len;
 
332
        int fd;
 
333
        int rc = 0;
 
334
 
 
335
        fd = open(devname, O_RDONLY);
 
336
        if (fd < 0)
 
337
                return 2;
 
338
 
 
339
        if (blkid_probe_set_device(pr, fd, offset, size))
 
340
                goto done;
 
341
        rc = blkid_do_safeprobe(pr);
 
342
        if (rc)
 
343
                goto done;
 
344
 
 
345
        nvals = blkid_probe_numof_values(pr);
 
346
 
 
347
        if (output & OUTPUT_DEVICE_ONLY) {
 
348
                printf("%s\n", devname);
 
349
                goto done;
 
350
        }
 
351
 
 
352
        for (n = 0; n < nvals; n++) {
 
353
                if (blkid_probe_get_value(pr, n, &name, &data, &len))
 
354
                        continue;
 
355
 
 
356
                len = strnlen((char *) data, len);
 
357
                print_value(output, n + 1, devname, (char *) data, name, len);
 
358
        }
 
359
 
 
360
        if (nvals > 1 && !(output & (OUTPUT_VALUE_ONLY | OUTPUT_UDEV_LIST)))
 
361
                printf("\n");
 
362
done:
 
363
        if (rc == -2)
 
364
                fprintf(stderr, "%s: ambivalent result "
 
365
                                "(probably more filesystems on the device)\n",
 
366
                                devname);
 
367
        close(fd);
 
368
        return !nvals ? 2 : 0;
 
369
}
 
370
 
 
371
/* converts comma separated list to BLKID_USAGE_* mask */
 
372
static int list_to_usage(const char *list, int *flag)
 
373
{
 
374
        int mask = 0;
 
375
        const char *word, *p = list;
 
376
 
 
377
        if (p && strncmp(p, "no", 2) == 0) {
 
378
                *flag = BLKID_FLTR_NOTIN;
 
379
                p += 2;
 
380
        }
 
381
 
 
382
        for (word = p; p && *p; p++) {
 
383
                if (*p == ',' || *(p + 1) == '\0') {
 
384
                        if (!strncmp(word, "filesystem", 10))
 
385
                                mask |= BLKID_USAGE_FILESYSTEM;
 
386
                        else if (!strncmp(word, "raid", 4))
 
387
                                mask |= BLKID_USAGE_RAID;
 
388
                        else if (!strncmp(word, "crypto", 6))
 
389
                                mask |= BLKID_USAGE_CRYPTO;
 
390
                        else if (!strncmp(word, "other", 5))
 
391
                                mask |= BLKID_USAGE_OTHER;
 
392
                        else {
 
393
                                fprintf(stderr, "unknown usage keyword '%*s'\n",
 
394
                                                (int) (p - word), word);
 
395
                                exit(4);
 
396
                        }
 
397
                        word = p + 1;
 
398
                }
 
399
        }
 
400
        return mask;
 
401
}
 
402
 
 
403
int main(int argc, char **argv)
 
404
{
 
405
        blkid_cache cache = NULL;
 
406
        char *devices[128] = { NULL, };
 
407
        char *show[128] = { NULL, };
 
408
        char *search_type = NULL, *search_value = NULL;
 
409
        char *read = NULL;
 
410
        char *write = NULL;
 
411
        int fltr_usage = 0;
 
412
        int fltr_flag = BLKID_FLTR_ONLYIN;
 
413
        unsigned int numdev = 0, numtag = 0;
 
414
        int version = 0;
 
415
        int err = 4;
 
416
        unsigned int i;
 
417
        int output_format = 0;
 
418
        int lookup = 0, gc = 0, lowprobe = 0, eval = 0;
 
419
        int c;
 
420
        blkid_loff_t offset = 0, size = 0;
 
421
 
 
422
        while ((c = getopt (argc, argv, "c:f:ghlL:o:O:ps:S:t:u:U:w:v")) != EOF)
 
423
                switch (c) {
 
424
                case 'c':
 
425
                        if (optarg && !*optarg)
 
426
                                read = NULL;
 
427
                        else
 
428
                                read = optarg;
 
429
                        if (!write)
 
430
                                write = read;
 
431
                        break;
 
432
                case 'L':
 
433
                        eval++;
 
434
                        search_value = strdup(optarg);
 
435
                        search_type = strdup("LABEL");
 
436
                        break;
 
437
                case 'u':
 
438
                        fltr_usage = list_to_usage(optarg, &fltr_flag);
 
439
                        break;
 
440
                case 'U':
 
441
                        eval++;
 
442
                        search_value = strdup(optarg);
 
443
                        search_type = strdup("UUID");
 
444
                        break;
 
445
                case 'l':
 
446
                        lookup++;
 
447
                        break;
 
448
                case 'g':
 
449
                        gc = 1;
 
450
                        break;
 
451
                case 'o':
 
452
                        if (!strcmp(optarg, "value"))
 
453
                                output_format = OUTPUT_VALUE_ONLY;
 
454
                        else if (!strcmp(optarg, "device"))
 
455
                                output_format = OUTPUT_DEVICE_ONLY;
 
456
                        else if (!strcmp(optarg, "list"))
 
457
                                output_format = OUTPUT_PRETTY_LIST;
 
458
                        else if (!strcmp(optarg, "udev"))
 
459
                                output_format = OUTPUT_UDEV_LIST;
 
460
                        else if (!strcmp(optarg, "full"))
 
461
                                output_format = 0;
 
462
                        else {
 
463
                                fprintf(stderr, "Invalid output format %s. "
 
464
                                        "Choose from value,\n\t"
 
465
                                        "device, list, udev or full\n", optarg);
 
466
                                exit(4);
 
467
                        }
 
468
                        break;
 
469
                case 'O':
 
470
                        offset = strtoll(optarg, NULL, 10);
 
471
                        break;
 
472
                case 'p':
 
473
                        lowprobe++;
 
474
                        break;
 
475
                case 's':
 
476
                        if (numtag >= sizeof(show) / sizeof(*show)) {
 
477
                                fprintf(stderr, "Too many tags specified\n");
 
478
                                usage(err);
 
479
                        }
 
480
                        show[numtag++] = optarg;
 
481
                        break;
 
482
                case 'S':
 
483
                        size = strtoll(optarg, NULL, 10);
 
484
                        break;
 
485
                case 't':
 
486
                        if (search_type) {
 
487
                                fprintf(stderr, "Can only search for "
 
488
                                                "one NAME=value pair\n");
 
489
                                usage(err);
 
490
                        }
 
491
                        if (blkid_parse_tag_string(optarg,
 
492
                                                   &search_type,
 
493
                                                   &search_value)) {
 
494
                                fprintf(stderr, "-t needs NAME=value pair\n");
 
495
                                usage(err);
 
496
                        }
 
497
                        break;
 
498
                case 'v':
 
499
                        version = 1;
 
500
                        break;
 
501
                case 'w':
 
502
                        if (optarg && !*optarg)
 
503
                                write = NULL;
 
504
                        else
 
505
                                write = optarg;
 
506
                        break;
 
507
                case 'h':
 
508
                        err = 0;
 
509
                default:
 
510
                        usage(err);
 
511
                }
 
512
 
 
513
        while (optind < argc)
 
514
                devices[numdev++] = argv[optind++];
 
515
 
 
516
        if (version) {
 
517
                print_version(stdout);
 
518
                goto exit;
 
519
        }
 
520
 
 
521
        /* convert LABEL/UUID lookup to evaluate request */
 
522
        if (lookup && output_format == OUTPUT_DEVICE_ONLY && search_type &&
 
523
            (!strcmp(search_type, "LABEL") || !strcmp(search_type, "UUID"))) {
 
524
                eval++;
 
525
                lookup = 0;
 
526
        }
 
527
 
 
528
        if (!lowprobe && !eval && blkid_get_cache(&cache, read) < 0)
 
529
                goto exit;
 
530
 
 
531
        if (gc) {
 
532
                blkid_gc_cache(cache);
 
533
                err = 0;
 
534
                goto exit;
 
535
        }
 
536
        err = 2;
 
537
 
 
538
        if (output_format & OUTPUT_PRETTY_LIST)
 
539
                pretty_print_dev(NULL);
 
540
 
 
541
        if (lowprobe) {
 
542
                /*
 
543
                 * Low-level API
 
544
                 */
 
545
                blkid_probe pr;
 
546
 
 
547
                if (!numdev) {
 
548
                        fprintf(stderr, "The low-probe option requires a device\n");
 
549
                        exit(4);
 
550
                }
 
551
                pr = blkid_new_probe();
 
552
                if (!pr)
 
553
                        goto exit;
 
554
                blkid_probe_set_request(pr,
 
555
                                BLKID_PROBREQ_LABEL | BLKID_PROBREQ_UUID |
 
556
                                BLKID_PROBREQ_TYPE | BLKID_PROBREQ_SECTYPE |
 
557
                                BLKID_PROBREQ_USAGE | BLKID_PROBREQ_VERSION);
 
558
                if (fltr_usage &&
 
559
                    blkid_probe_filter_usage(pr, fltr_flag, fltr_usage))
 
560
                        goto exit;
 
561
 
 
562
                for (i = 0; i < numdev; i++)
 
563
                        err = lowprobe_device(pr, devices[i],
 
564
                                        output_format, offset, size);
 
565
                blkid_free_probe(pr);
 
566
        } else if (eval) {
 
567
                /*
 
568
                 * Evaluate API
 
569
                 */
 
570
                char *res = blkid_evaluate_tag(search_type, search_value, NULL);
 
571
                if (res) {
 
572
                        err = 0;
 
573
                        printf("%s\n", res);
 
574
                }
 
575
        } else if (lookup) {
 
576
                /*
 
577
                 * Classic (cache based) API
 
578
                 */
 
579
                blkid_dev dev;
 
580
 
 
581
                if (!search_type) {
 
582
                        fprintf(stderr, "The lookup option requires a "
 
583
                                "search type specified using -t\n");
 
584
                        exit(4);
 
585
                }
 
586
                /* Load any additional devices not in the cache */
 
587
                for (i = 0; i < numdev; i++)
 
588
                        blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL);
 
589
 
 
590
                if ((dev = blkid_find_dev_with_tag(cache, search_type,
 
591
                                                   search_value))) {
 
592
                        print_tags(dev, show, numtag, output_format);
 
593
                        err = 0;
 
594
                }
 
595
        /* If we didn't specify a single device, show all available devices */
 
596
        } else if (!numdev) {
 
597
                blkid_dev_iterate       iter;
 
598
                blkid_dev               dev;
 
599
 
 
600
                blkid_probe_all(cache);
 
601
 
 
602
                iter = blkid_dev_iterate_begin(cache);
 
603
                blkid_dev_set_search(iter, search_type, search_value);
 
604
                while (blkid_dev_next(iter, &dev) == 0) {
 
605
                        dev = blkid_verify(cache, dev);
 
606
                        if (!dev)
 
607
                                continue;
 
608
                        print_tags(dev, show, numtag, output_format);
 
609
                        err = 0;
 
610
                }
 
611
                blkid_dev_iterate_end(iter);
 
612
        /* Add all specified devices to cache (optionally display tags) */
 
613
        } else for (i = 0; i < numdev; i++) {
 
614
                blkid_dev dev = blkid_get_dev(cache, devices[i],
 
615
                                                  BLKID_DEV_NORMAL);
 
616
 
 
617
                if (dev) {
 
618
                        if (search_type &&
 
619
                            !blkid_dev_has_tag(dev, search_type,
 
620
                                               search_value))
 
621
                                continue;
 
622
                        print_tags(dev, show, numtag, output_format);
 
623
                        err = 0;
 
624
                }
 
625
        }
 
626
 
 
627
exit:
 
628
        free(search_type);
 
629
        free(search_value);
 
630
        if (!lowprobe && !eval)
 
631
                blkid_put_cache(cache);
 
632
        return err;
 
633
}