blkid.c revision 8927998f8229a103037ba5f49abe30c620ce322c
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
18extern char *optarg;
19extern int optind;
20#endif
21
22#define OUTPUT_VALUE_ONLY	0x0001
23#define OUTPUT_DEVICE_ONLY	0x0002
24
25#include "blkid/blkid.h"
26
27const char *progname = "blkid";
28
29static void print_version(FILE *out)
30{
31	fprintf(out, "%s %s (%s)\n", progname, BLKID_VERSION, BLKID_DATE);
32}
33
34static 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		"[-p] [-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
53static 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
91int main(int argc, char **argv)
92{
93	blkid_cache cache = NULL;
94	char *devices[128] = { NULL, };
95	char *show[128] = { NULL, };
96	char *search_type = NULL, *search_value = NULL;
97	char *read = NULL;
98	char *write = NULL;
99	unsigned int numdev = 0, numtag = 0;
100	int version = 0;
101	int err = 4;
102	unsigned int i;
103	int output_format = 0;
104	char c;
105
106	while ((c = getopt (argc, argv, "c:f:ho:ps:t:w:v")) != EOF)
107		switch (c) {
108		case 'c':
109			if (optarg && !*optarg)
110				read = NULL;
111			else
112				read = optarg;
113			if (!write)
114				write = read;
115			break;
116		case 'o':
117			if (!strcmp(optarg, "value"))
118				output_format = OUTPUT_VALUE_ONLY;
119			else if (!strcmp(optarg, "device"))
120				output_format = OUTPUT_DEVICE_ONLY;
121			else if (!strcmp(optarg, "full"))
122				output_format = 0;
123			else {
124				fprintf(stderr, "Invalid output format %s.  Chose from value, device, or full\n", optarg);
125				exit(1);
126			}
127			break;
128		case 's':
129			if (numtag >= sizeof(show) / sizeof(*show)) {
130				fprintf(stderr, "Too many tags specified\n");
131				usage(err);
132			}
133			show[numtag++] = optarg;
134			break;
135		case 't':
136			if (search_type) {
137				fprintf(stderr, "Can only search for "
138						"one NAME=value pair\n");
139				usage(err);
140			}
141			if (blkid_parse_tag_string(optarg,
142						   &search_type,
143						   &search_value)) {
144				fprintf(stderr, "-t needs NAME=value pair\n");
145				usage(err);
146			}
147			break;
148		case 'v':
149			version = 1;
150			break;
151		case 'w':
152			if (optarg && !*optarg)
153				write = NULL;
154			else
155				write = optarg;
156			break;
157		case 'h':
158			err = 0;
159		default:
160			usage(err);
161		}
162
163	while (optind < argc)
164		devices[numdev++] = argv[optind++];
165
166	if (version) {
167		print_version(stdout);
168		goto exit;
169	}
170
171	if (blkid_get_cache(&cache, read) < 0)
172		goto exit;
173
174	err = 2;
175	/* If looking for a specific NAME=value pair, print only that */
176	if (search_type) {
177		blkid_dev dev;
178
179		/* Load any additional devices not in the cache */
180		for (i = 0; i < numdev; i++)
181			blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL);
182
183		if ((dev = blkid_find_dev_with_tag(cache, search_type,
184						   search_value))) {
185			print_tags(dev, show, numtag, output_format);
186			err = 0;
187		}
188	/* If we didn't specify a single device, show all available devices */
189	} else if (!numdev) {
190		blkid_dev_iterate	iter;
191		blkid_dev		dev;
192
193		blkid_probe_all(cache);
194
195		iter = blkid_dev_iterate_begin(cache);
196		while (blkid_dev_next(iter, &dev) == 0) {
197			print_tags(dev, show, numtag, output_format);
198			err = 0;
199		}
200		blkid_dev_iterate_end(iter);
201	/* Add all specified devices to cache (optionally display tags) */
202	} else for (i = 0; i < numdev; i++) {
203		blkid_dev dev = blkid_get_dev(cache, devices[i],
204						  BLKID_DEV_NORMAL);
205
206		if (dev) {
207			print_tags(dev, show, numtag, output_format);
208			err = 0;
209		}
210	}
211
212exit:
213	if (search_type)
214		free(search_type);
215	if (search_value)
216		free(search_value);
217	blkid_put_cache(cache);
218	return err;
219}
220