Whamcloud - gitweb
ecbf8cf52767394082a86249b04dbab7dfd2e596
[tools/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>] [-h] [-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-v\tprint version and exit\n"
47                 "\t-w\twrite cache to different file (/dev/null = no write)\n"
48                 "\tdev\tspecify device(s) to probe (default: all devices)\n",
49                 progname);
50         exit(error);
51 }
52
53 static void print_tags(blkid_dev dev, char *show[], int numtag, int output)
54 {
55         blkid_tag_iterate       iter;
56         const char              *type, *value;
57         int                     i, first = 1;
58
59         if (!dev)
60                 return;
61
62         if (output & OUTPUT_DEVICE_ONLY) {
63                 printf("%s\n", blkid_dev_devname(dev));
64                 return;
65         }
66
67         iter = blkid_tag_iterate_begin(dev);
68         while (blkid_tag_next(iter, &type, &value) == 0) {
69                 if (numtag && show) {
70                         for (i=0; i < numtag; i++)
71                                 if (!strcmp(type, show[i]))
72                                         break;
73                         if (i >= numtag)
74                                 continue;
75                 }
76                 if (first && !(output & OUTPUT_VALUE_ONLY)) {
77                         printf("%s: ", blkid_dev_devname(dev));
78                         first = 0;
79                 }
80                 if ((output & OUTPUT_VALUE_ONLY))
81                         printf("%s\n", value);
82                 else
83                         printf("%s=\"%s\" ", type, value);
84         }
85         blkid_tag_iterate_end(iter);
86
87         if (!first && !(output & OUTPUT_VALUE_ONLY))
88                 printf("\n");
89 }
90
91 int compare_search_type(blkid_dev dev, const char *search_type, 
92                         const char *search_value)
93 {
94         blkid_tag_iterate       tag_iter;
95         const char              *type, *value;
96         int                     found = 0;
97
98         tag_iter = blkid_tag_iterate_begin(dev);
99         while (blkid_tag_next(tag_iter, &type, &value) == 0) {
100                 if (!strcmp(type, search_type) &&
101                     !strcmp(value, search_value)) {
102                         found++;
103                         break;
104                 }
105         }
106         blkid_tag_iterate_end(tag_iter);
107
108         return found;
109 }
110
111 int main(int argc, char **argv)
112 {
113         blkid_cache cache = NULL;
114         char *devices[128] = { NULL, };
115         char *show[128] = { NULL, };
116         char *search_type = NULL, *search_value = NULL;
117         char *read = NULL;
118         char *write = NULL;
119         unsigned int numdev = 0, numtag = 0;
120         int version = 0;
121         int err = 4;
122         unsigned int i;
123         int output_format = 0;
124         char c;
125
126         while ((c = getopt (argc, argv, "c:f:ho:s:t:w:v")) != EOF)
127                 switch (c) {
128                 case 'c':
129                         if (optarg && !*optarg)
130                                 read = NULL;
131                         else
132                                 read = optarg;
133                         if (!write)
134                                 write = read;
135                         break;
136                 case 'o':
137                         if (!strcmp(optarg, "value"))
138                                 output_format = OUTPUT_VALUE_ONLY;
139                         else if (!strcmp(optarg, "device"))
140                                 output_format = OUTPUT_DEVICE_ONLY;
141                         else if (!strcmp(optarg, "full"))
142                                 output_format = 0;
143                         else {
144                                 fprintf(stderr, "Invalid output format %s.  Chose from value, device, or full\n", optarg);
145                                 exit(1);
146                         }
147                         break;
148                 case 's':
149                         if (numtag >= sizeof(show) / sizeof(*show)) {
150                                 fprintf(stderr, "Too many tags specified\n");
151                                 usage(err);
152                         }
153                         show[numtag++] = optarg;
154                         break;
155                 case 't':
156                         if (search_type) {
157                                 fprintf(stderr, "Can only search for "
158                                                 "one NAME=value pair\n");
159                                 usage(err);
160                         }
161                         if (blkid_parse_tag_string(optarg,
162                                                    &search_type,
163                                                    &search_value)) {
164                                 fprintf(stderr, "-t needs NAME=value pair\n");
165                                 usage(err);
166                         }
167                         break;
168                 case 'v':
169                         version = 1;
170                         break;
171                 case 'w':
172                         if (optarg && !*optarg)
173                                 write = NULL;
174                         else
175                                 write = optarg;
176                         break;
177                 case 'h':
178                         err = 0;
179                 default:
180                         usage(err);
181                 }
182
183         while (optind < argc)
184                 devices[numdev++] = argv[optind++];
185
186         if (version) {
187                 print_version(stdout);
188                 goto exit;
189         }
190
191         if (blkid_get_cache(&cache, read) < 0)
192                 goto exit;
193
194         err = 2;
195         /* If we didn't specify a single device, show all available devices */
196         if (!numdev) {
197                 blkid_dev_iterate       iter;
198                 blkid_dev               dev;
199
200                 blkid_probe_all(cache);
201
202                 iter = blkid_dev_iterate_begin(cache);
203                 while (blkid_dev_next(iter, &dev) == 0) {
204                         dev = blkid_verify(cache, dev);
205                         if (!dev)
206                                 continue;
207                         if (search_type &&
208                             !compare_search_type(dev, search_type, 
209                                                  search_value))
210                                 continue;
211                         print_tags(dev, show, numtag, output_format);
212                         err = 0;
213                 }
214                 blkid_dev_iterate_end(iter);
215         /* Add all specified devices to cache (optionally display tags) */
216         } else for (i = 0; i < numdev; i++) {
217                 blkid_dev dev = blkid_get_dev(cache, devices[i],
218                                                   BLKID_DEV_NORMAL);
219
220                 if (dev) {
221                         if (search_type &&
222                             !compare_search_type(dev, search_type, 
223                                                  search_value))
224                                 continue;
225                         print_tags(dev, show, numtag, output_format);
226                         err = 0;
227                 }
228         }
229
230 exit:
231         if (search_type)
232                 free(search_type);
233         if (search_value)
234                 free(search_value);
235         blkid_put_cache(cache);
236         return err;
237 }