OSDN Git Service

Add a new option to the blkid program, -l, which will more efficiently search
[android-x86/external-e2fsprogs.git] / misc / blkid.c
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 <string.h>
15 #ifdef HAVE_GETOPT_H
16 #include <getopt.h>
17 #else
18 extern char *optarg;
19 extern int optind;
20 #endif
21
22 #define OUTPUT_VALUE_ONLY       0x0001
23 #define OUTPUT_DEVICE_ONLY      0x0002
24
25 #include "blkid/blkid.h"
26
27 const char *progname = "blkid";
28
29 static void print_version(FILE *out)
30 {
31         fprintf(out, "%s %s (%s)\n", progname, BLKID_VERSION, BLKID_DATE);
32 }
33
34 static void usage(int error)
35 {
36         FILE *out = error ? stderr : stdout;
37
38         print_version(out);
39         fprintf(out,
40                 "usage:\t%s [-c <file>] [-hl] [-o format] "
41                 "[-s <tag>] [-t <token>]\n    [-v] [-w <file>] [dev ...]\n"
42                 "\t-c\tcache file (default: /etc/blkid.tab, /dev/null = none)\n"
43                 "\t-h\tprint this usage message and exit\n"
44                 "\t-s\tshow specified tag(s) (default show all tags)\n"
45                 "\t-t\tfind device with a specific token (NAME=value pair)\n"
46                 "\t-l\tlookup the the first device with arguments specified by -t\n"
47                 "\t-v\tprint version and exit\n"
48                 "\t-w\twrite cache to different file (/dev/null = no write)\n"
49                 "\tdev\tspecify device(s) to probe (default: all devices)\n",
50                 progname);
51         exit(error);
52 }
53
54 static void print_tags(blkid_dev dev, char *show[], int numtag, int output)
55 {
56         blkid_tag_iterate       iter;
57         const char              *type, *value;
58         int                     i, first = 1;
59
60         if (!dev)
61                 return;
62
63         if (output & OUTPUT_DEVICE_ONLY) {
64                 printf("%s\n", blkid_dev_devname(dev));
65                 return;
66         }
67
68         iter = blkid_tag_iterate_begin(dev);
69         while (blkid_tag_next(iter, &type, &value) == 0) {
70                 if (numtag && show) {
71                         for (i=0; i < numtag; i++)
72                                 if (!strcmp(type, show[i]))
73                                         break;
74                         if (i >= numtag)
75                                 continue;
76                 }
77                 if (first && !(output & OUTPUT_VALUE_ONLY)) {
78                         printf("%s: ", blkid_dev_devname(dev));
79                         first = 0;
80                 }
81                 if ((output & OUTPUT_VALUE_ONLY))
82                         printf("%s\n", value);
83                 else
84                         printf("%s=\"%s\" ", type, value);
85         }
86         blkid_tag_iterate_end(iter);
87
88         if (!first && !(output & OUTPUT_VALUE_ONLY))
89                 printf("\n");
90 }
91
92 int main(int argc, char **argv)
93 {
94         blkid_cache cache = NULL;
95         char *devices[128] = { NULL, };
96         char *show[128] = { NULL, };
97         char *search_type = NULL, *search_value = NULL;
98         char *read = NULL;
99         char *write = NULL;
100         unsigned int numdev = 0, numtag = 0;
101         int version = 0;
102         int err = 4;
103         unsigned int i;
104         int output_format = 0;
105         int lookup = 0;
106         int c;
107
108         while ((c = getopt (argc, argv, "c:f:hlo:s:t:w:v")) != EOF)
109                 switch (c) {
110                 case 'c':
111                         if (optarg && !*optarg)
112                                 read = NULL;
113                         else
114                                 read = optarg;
115                         if (!write)
116                                 write = read;
117                         break;
118                 case 'l':
119                         lookup++;
120                         break;
121                 case 'o':
122                         if (!strcmp(optarg, "value"))
123                                 output_format = OUTPUT_VALUE_ONLY;
124                         else if (!strcmp(optarg, "device"))
125                                 output_format = OUTPUT_DEVICE_ONLY;
126                         else if (!strcmp(optarg, "full"))
127                                 output_format = 0;
128                         else {
129                                 fprintf(stderr, "Invalid output format %s.  Chose from value, device, or full\n", optarg);
130                                 exit(1);
131                         }
132                         break;
133                 case 's':
134                         if (numtag >= sizeof(show) / sizeof(*show)) {
135                                 fprintf(stderr, "Too many tags specified\n");
136                                 usage(err);
137                         }
138                         show[numtag++] = optarg;
139                         break;
140                 case 't':
141                         if (search_type) {
142                                 fprintf(stderr, "Can only search for "
143                                                 "one NAME=value pair\n");
144                                 usage(err);
145                         }
146                         if (blkid_parse_tag_string(optarg,
147                                                    &search_type,
148                                                    &search_value)) {
149                                 fprintf(stderr, "-t needs NAME=value pair\n");
150                                 usage(err);
151                         }
152                         break;
153                 case 'v':
154                         version = 1;
155                         break;
156                 case 'w':
157                         if (optarg && !*optarg)
158                                 write = NULL;
159                         else
160                                 write = optarg;
161                         break;
162                 case 'h':
163                         err = 0;
164                 default:
165                         usage(err);
166                 }
167
168         while (optind < argc)
169                 devices[numdev++] = argv[optind++];
170
171         if (version) {
172                 print_version(stdout);
173                 goto exit;
174         }
175
176         if (blkid_get_cache(&cache, read) < 0)
177                 goto exit;
178
179         err = 2;
180         if (lookup) {
181                 blkid_dev dev;
182
183                 if (!search_type) {
184                         fprintf(stderr, "The lookup option requires a "
185                                 "search type specified using -t\n");
186                         exit(1);
187                 }
188                 /* Load any additional devices not in the cache */
189                 for (i = 0; i < numdev; i++)
190                         blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL);
191
192                 if ((dev = blkid_find_dev_with_tag(cache, search_type,
193                                                    search_value))) {
194                         print_tags(dev, show, numtag, output_format);
195                         err = 0;
196                 }
197         /* If we didn't specify a single device, show all available devices */
198         } else if (!numdev) {
199                 blkid_dev_iterate       iter;
200                 blkid_dev               dev;
201
202                 blkid_probe_all(cache);
203
204                 iter = blkid_dev_iterate_begin(cache);
205                 blkid_dev_set_search(iter, search_type, search_value);
206                 while (blkid_dev_next(iter, &dev) == 0) {
207                         dev = blkid_verify(cache, dev);
208                         if (!dev)
209                                 continue;
210                         print_tags(dev, show, numtag, output_format);
211                         err = 0;
212                 }
213                 blkid_dev_iterate_end(iter);
214         /* Add all specified devices to cache (optionally display tags) */
215         } else for (i = 0; i < numdev; i++) {
216                 blkid_dev dev = blkid_get_dev(cache, devices[i],
217                                                   BLKID_DEV_NORMAL);
218
219                 if (dev) {
220                         if (search_type && 
221                             !blkid_dev_has_tag(dev, search_type, 
222                                                search_value))
223                                 continue;
224                         print_tags(dev, show, numtag, output_format);
225                         err = 0;
226                 }
227         }
228
229 exit:
230         if (search_type)
231                 free(search_type);
232         if (search_value)
233                 free(search_value);
234         blkid_put_cache(cache);
235         return err;
236 }