Whamcloud - gitweb
Integrate new blkid library.
[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 #ifdef HAVE_GETOPT_H
14 #include <getopt.h>
15 #else
16 extern char *optarg;
17 extern int optind;
18 #endif
19
20 #include "blkid/blkid.h"
21
22 char *progname = "blkid";
23 void print_version(FILE *out)
24 {
25         fprintf(stderr, "%s %s (%s)\n", progname, BLKID_VERSION, BLKID_DATE);
26 }
27
28 void usage(int error)
29 {
30         FILE *out = error ? stderr : stdout;
31
32         print_version(out);
33         fprintf(out,
34                 "usage:\t%s [-c <file>] [-h] "
35                 "[-p] [-s <tag>] [-t <token>] [-v] [-w <file>] [dev ...]\n"
36                 "\t-c\tcache file (default: /etc/blkid.tab, /dev/null = none)\n"
37                 "\t-h\tprint this usage message and exit\n"
38                 "\t-s\tshow specified tag(s) (default show all tags)\n"
39                 "\t-t\tfind device with a specific token (NAME=value pair)\n"
40                 "\t-v\tprint version and exit\n"
41                 "\t-w\twrite cache to different file (/dev/null = no write)\n"
42                 "\tdev\tspecify device(s) to probe (default: all devices)\n",
43                 progname);
44         exit(error);
45 }
46
47 #define PT_FL_START     0x0001
48 #define PT_FL_TYPE      0x0002
49
50 static void print_tag(blkid_dev *dev, blkid_tag *tag, int *flags)
51 {
52         /* Print only one "dev:" per device */
53         if (!*flags & PT_FL_START) {
54                 printf("%s: ", dev->bid_name);
55                 *flags |= PT_FL_START;
56         }
57         /* Print only the primary TYPE per device */
58         if (!strcmp(tag->bit_name, "TYPE")) {
59                 if (*flags & PT_FL_TYPE)
60                         return;
61                 *flags |= PT_FL_TYPE;
62         }
63         printf("%s=\"%s\" ", tag->bit_name, tag->bit_val);
64 }
65
66 void print_tags(blkid_dev *dev, char *show[], int numtag)
67 {
68         struct list_head *p;
69         int flags = 0;
70
71         if (!dev)
72                 return;
73
74         list_for_each(p, &dev->bid_tags) {
75                 blkid_tag *tag = list_entry(p, blkid_tag, bit_tags);
76                 int i;
77
78                 /* Print all tokens if none is specified */
79                 if (numtag == 0 || !show) {
80                         print_tag(dev, tag, &flags);
81                 /* Otherwise, only print specific tokens */
82                 } else for (i = 0; i < numtag; i++) {
83                         if (!strcmp(tag->bit_name, show[i]))
84                                 print_tag(dev, tag, &flags);
85                 }
86         }
87
88         if (flags)
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         blkid_tag *tag = NULL;
98         char *read = NULL;
99         char *write = NULL;
100         int numdev = 0, numtag = 0;
101         int version = 0;
102         int err = 4;
103         int i;
104         char c;
105
106         while ((c = getopt (argc, argv, "c:d:f:hps:t:w:v")) != EOF)
107                 switch (c) {
108                 case 'd':       /* deprecated */
109                         if (numdev >= sizeof(devices) / sizeof(*devices)) {
110                                 fprintf(stderr,
111                                         "Too many devices specified\n");
112                                 usage(err);
113                         }
114                         devices[numdev++] = optarg;
115                         break;
116                 case 'c':
117                         if (optarg && !*optarg)
118                                 read = NULL;
119                         else
120                                 read = optarg;
121                         if (!write)
122                                 write = read;
123                         break;
124                 case 's':
125                         if (numtag >= sizeof(show) / sizeof(*show)) {
126                                 fprintf(stderr, "Too many tags specified\n");
127                                 usage(err);
128                         }
129                         show[numtag++] = optarg;
130                         break;
131                 case 't':
132                         if (tag) {
133                                 fprintf(stderr, "Can only search for "
134                                                 "one NAME=value pair\n");
135                                 usage(err);
136                         }
137                         if (!(tag = blkid_token_to_tag(optarg))) {
138                                 fprintf(stderr, "-t needs NAME=value pair\n");
139                                 usage(err);
140                         }
141                         break;
142                 case 'v':
143                         version = 1;
144                         break;
145                 case 'w':
146                         if (optarg && !*optarg)
147                                 write = NULL;
148                         else
149                                 write = optarg;
150                         break;
151                 case 'h':
152                         err = 0;
153                 default:
154                         usage(err);
155                 }
156
157         while (optind < argc)
158                 devices[numdev++] = argv[optind++];
159
160         if (version) {
161                 print_version(stdout);
162                 goto exit;
163         }
164
165         if (blkid_read_cache(&cache, read) < 0)
166                 goto exit;
167
168         err = 2;
169         /* If looking for a specific NAME=value pair, print only that */
170         if (tag) {
171                 blkid_tag *found = NULL;
172
173                 /* Load any additional devices not in the cache */
174                 for (i = 0; i < numdev; i++)
175                         blkid_get_devname(cache, devices[i]);
176
177                 if ((found = blkid_get_tag_cache(cache, tag))) {
178                         print_tags(found->bit_dev, show, numtag);
179                         err = 0;
180                 }
181         /* If we didn't specify a single device, show all available devices */
182         } else if (!numdev) {
183                 struct list_head *p;
184
185                 blkid_probe_all(&cache);
186
187                 list_for_each(p, &cache->bic_devs) {
188                         blkid_dev *dev = list_entry(p, blkid_dev, bid_devs);
189                         print_tags(dev, show, numtag);
190                         err = 0;
191                 }
192         /* Add all specified devices to cache (optionally display tags) */
193         } else for (i = 0; i < numdev; i++) {
194                 blkid_dev *dev = blkid_get_devname(cache, devices[i]);
195
196                 if (dev) {
197                         print_tags(dev, show, numtag);
198                         err = 0;
199                 }
200         }
201
202 exit:
203         blkid_free_tag(tag);
204         blkid_save_cache(cache, write);
205         blkid_free_cache(cache);
206         return err;
207 }