blob: c0fda73ccb92d6e18fb52be0fa9705d6cb8e0028 [file] [log] [blame]
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -05001/*
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>
Theodore Ts'o7a603aa2003-01-26 01:54:39 -050013#include <stdlib.h>
Theodore Ts'o48e6e812003-07-06 00:36:48 -040014#include <string.h>
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050015#ifdef HAVE_GETOPT_H
16#include <getopt.h>
17#else
Matthias Andreea6383022006-05-30 16:27:45 +020018extern int getopt(int argc, char * const argv[], const char *optstring);
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050019extern char *optarg;
20extern int optind;
21#endif
22
Theodore Ts'o89279982004-03-20 16:30:10 -050023#define OUTPUT_VALUE_ONLY 0x0001
24#define OUTPUT_DEVICE_ONLY 0x0002
25
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050026#include "blkid/blkid.h"
27
Theodore Ts'o7a603aa2003-01-26 01:54:39 -050028const char *progname = "blkid";
29
30static void print_version(FILE *out)
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050031{
Theodore Ts'o54434922003-12-07 01:28:50 -050032 fprintf(out, "%s %s (%s)\n", progname, BLKID_VERSION, BLKID_DATE);
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050033}
34
Theodore Ts'o7a603aa2003-01-26 01:54:39 -050035static void usage(int error)
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050036{
37 FILE *out = error ? stderr : stdout;
38
39 print_version(out);
40 fprintf(out,
Theodore Ts'o46100e32007-05-18 00:16:02 -040041 "usage:\t%s [-c <file>] [-ghl] [-o format] "
Theodore Ts'o9b2d5e92004-03-21 20:40:20 -050042 "[-s <tag>] [-t <token>]\n [-v] [-w <file>] [dev ...]\n"
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050043 "\t-c\tcache file (default: /etc/blkid.tab, /dev/null = none)\n"
44 "\t-h\tprint this usage message and exit\n"
Theodore Ts'o46100e32007-05-18 00:16:02 -040045 "\t-g\tgarbage collect the blkid cache\n"
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050046 "\t-s\tshow specified tag(s) (default show all tags)\n"
47 "\t-t\tfind device with a specific token (NAME=value pair)\n"
Theodore Ts'oed6acfa2005-05-07 17:06:27 -040048 "\t-l\tlookup the the first device with arguments specified by -t\n"
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050049 "\t-v\tprint version and exit\n"
50 "\t-w\twrite cache to different file (/dev/null = no write)\n"
51 "\tdev\tspecify device(s) to probe (default: all devices)\n",
52 progname);
53 exit(error);
54}
55
Theodore Ts'of8efcda2007-12-16 12:26:57 -050056/*
57 * This function does "safe" printing. It will convert non-printable
58 * ASCII characters using '^' and M- notation.
59 */
60static void safe_print(const char *cp, int len)
61{
62 unsigned char ch;
63
64 if (len < 0)
65 len = strlen(cp);
66
67 while (len--) {
68 ch = *cp++;
69 if (ch > 128) {
70 fputs("M-", stdout);
71 ch -= 128;
72 }
73 if ((ch < 32) || (ch == 0x7f)) {
74 fputc('^', stdout);
75 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
76 }
77 fputc(ch, stdout);
78 }
79}
80
Theodore Ts'o89279982004-03-20 16:30:10 -050081static void print_tags(blkid_dev dev, char *show[], int numtag, int output)
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050082{
Theodore Ts'o7a603aa2003-01-26 01:54:39 -050083 blkid_tag_iterate iter;
84 const char *type, *value;
Theodore Ts'oed1b33e2003-03-01 19:29:01 -050085 int i, first = 1;
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -050086
87 if (!dev)
88 return;
89
Theodore Ts'o89279982004-03-20 16:30:10 -050090 if (output & OUTPUT_DEVICE_ONLY) {
91 printf("%s\n", blkid_dev_devname(dev));
92 return;
93 }
94
Theodore Ts'o7a603aa2003-01-26 01:54:39 -050095 iter = blkid_tag_iterate_begin(dev);
96 while (blkid_tag_next(iter, &type, &value) == 0) {
97 if (numtag && show) {
98 for (i=0; i < numtag; i++)
99 if (!strcmp(type, show[i]))
100 break;
101 if (i >= numtag)
102 continue;
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500103 }
Theodore Ts'of8efcda2007-12-16 12:26:57 -0500104 if (output & OUTPUT_VALUE_ONLY) {
105 fputs(value, stdout);
106 fputc('\n', stdout);
107 } else {
108 if (first) {
109 printf("%s: ", blkid_dev_devname(dev));
110 first = 0;
111 }
112 fputs(type, stdout);
113 fputs("=\"", stdout);
114 safe_print(value, -1);
115 fputs("\" ", stdout);
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500116 }
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500117 }
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500118 blkid_tag_iterate_end(iter);
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500119
Theodore Ts'o89279982004-03-20 16:30:10 -0500120 if (!first && !(output & OUTPUT_VALUE_ONLY))
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500121 printf("\n");
122}
123
124int main(int argc, char **argv)
125{
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500126 blkid_cache cache = NULL;
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500127 char *devices[128] = { NULL, };
128 char *show[128] = { NULL, };
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500129 char *search_type = NULL, *search_value = NULL;
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500130 char *read = NULL;
131 char *write = NULL;
Theodore Ts'o54434922003-12-07 01:28:50 -0500132 unsigned int numdev = 0, numtag = 0;
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500133 int version = 0;
134 int err = 4;
Theodore Ts'o54434922003-12-07 01:28:50 -0500135 unsigned int i;
Theodore Ts'o89279982004-03-20 16:30:10 -0500136 int output_format = 0;
Theodore Ts'o46100e32007-05-18 00:16:02 -0400137 int lookup = 0, gc = 0;
Theodore Ts'o0af8c332005-05-06 00:10:52 -0400138 int c;
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500139
Theodore Ts'o46100e32007-05-18 00:16:02 -0400140 while ((c = getopt (argc, argv, "c:f:ghlo:s:t:w:v")) != EOF)
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500141 switch (c) {
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500142 case 'c':
143 if (optarg && !*optarg)
144 read = NULL;
145 else
146 read = optarg;
147 if (!write)
148 write = read;
149 break;
Theodore Ts'oed6acfa2005-05-07 17:06:27 -0400150 case 'l':
151 lookup++;
152 break;
Theodore Ts'o46100e32007-05-18 00:16:02 -0400153 case 'g':
154 gc = 1;
155 break;
Theodore Ts'o89279982004-03-20 16:30:10 -0500156 case 'o':
157 if (!strcmp(optarg, "value"))
158 output_format = OUTPUT_VALUE_ONLY;
159 else if (!strcmp(optarg, "device"))
160 output_format = OUTPUT_DEVICE_ONLY;
161 else if (!strcmp(optarg, "full"))
162 output_format = 0;
163 else {
164 fprintf(stderr, "Invalid output format %s. Chose from value, device, or full\n", optarg);
165 exit(1);
166 }
167 break;
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500168 case 's':
169 if (numtag >= sizeof(show) / sizeof(*show)) {
170 fprintf(stderr, "Too many tags specified\n");
171 usage(err);
172 }
173 show[numtag++] = optarg;
174 break;
175 case 't':
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500176 if (search_type) {
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500177 fprintf(stderr, "Can only search for "
178 "one NAME=value pair\n");
179 usage(err);
180 }
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500181 if (blkid_parse_tag_string(optarg,
182 &search_type,
183 &search_value)) {
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500184 fprintf(stderr, "-t needs NAME=value pair\n");
185 usage(err);
186 }
187 break;
188 case 'v':
189 version = 1;
190 break;
191 case 'w':
192 if (optarg && !*optarg)
193 write = NULL;
194 else
195 write = optarg;
196 break;
197 case 'h':
198 err = 0;
199 default:
200 usage(err);
201 }
202
203 while (optind < argc)
204 devices[numdev++] = argv[optind++];
205
206 if (version) {
207 print_version(stdout);
208 goto exit;
209 }
210
Theodore Ts'o50b380b2003-02-12 23:51:21 -0500211 if (blkid_get_cache(&cache, read) < 0)
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500212 goto exit;
213
214 err = 2;
Theodore Ts'o46100e32007-05-18 00:16:02 -0400215 if (gc) {
216 blkid_gc_cache(cache);
217 } else if (lookup) {
Theodore Ts'oed6acfa2005-05-07 17:06:27 -0400218 blkid_dev dev;
219
220 if (!search_type) {
221 fprintf(stderr, "The lookup option requires a "
222 "search type specified using -t\n");
223 exit(1);
224 }
225 /* Load any additional devices not in the cache */
226 for (i = 0; i < numdev; i++)
227 blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL);
228
229 if ((dev = blkid_find_dev_with_tag(cache, search_type,
230 search_value))) {
231 print_tags(dev, show, numtag, output_format);
232 err = 0;
233 }
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500234 /* If we didn't specify a single device, show all available devices */
Theodore Ts'oed6acfa2005-05-07 17:06:27 -0400235 } else if (!numdev) {
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500236 blkid_dev_iterate iter;
237 blkid_dev dev;
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500238
Theodore Ts'o50b380b2003-02-12 23:51:21 -0500239 blkid_probe_all(cache);
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500240
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500241 iter = blkid_dev_iterate_begin(cache);
Theodore Ts'oc37543d2005-05-07 13:32:47 -0400242 blkid_dev_set_search(iter, search_type, search_value);
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500243 while (blkid_dev_next(iter, &dev) == 0) {
Theodore Ts'o18d12962005-01-27 19:51:47 -0500244 dev = blkid_verify(cache, dev);
245 if (!dev)
246 continue;
Theodore Ts'o89279982004-03-20 16:30:10 -0500247 print_tags(dev, show, numtag, output_format);
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500248 err = 0;
249 }
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500250 blkid_dev_iterate_end(iter);
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500251 /* Add all specified devices to cache (optionally display tags) */
252 } else for (i = 0; i < numdev; i++) {
Theodore Ts'o98999c32003-02-16 00:47:07 -0500253 blkid_dev dev = blkid_get_dev(cache, devices[i],
Theodore Ts'o50b380b2003-02-12 23:51:21 -0500254 BLKID_DEV_NORMAL);
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500255
256 if (dev) {
Theodore Ts'oc37543d2005-05-07 13:32:47 -0400257 if (search_type &&
258 !blkid_dev_has_tag(dev, search_type,
259 search_value))
Theodore Ts'o18d12962005-01-27 19:51:47 -0500260 continue;
Theodore Ts'o89279982004-03-20 16:30:10 -0500261 print_tags(dev, show, numtag, output_format);
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500262 err = 0;
263 }
264 }
265
266exit:
Theodore Ts'o7a603aa2003-01-26 01:54:39 -0500267 if (search_type)
268 free(search_type);
269 if (search_value)
270 free(search_value);
Theodore Ts'o50b380b2003-02-12 23:51:21 -0500271 blkid_put_cache(cache);
Theodore Ts'oe12f2ae2003-01-23 16:45:16 -0500272 return err;
273}