xref: /aosp_15_r20/external/e2fsprogs/misc/blkid.c (revision 6a54128f25917bfc36a8a6e9d722c04a0b4641b6)
1*6a54128fSAndroid Build Coastguard Worker /*
2*6a54128fSAndroid Build Coastguard Worker  * blkid.c - User command-line interface for libblkid
3*6a54128fSAndroid Build Coastguard Worker  *
4*6a54128fSAndroid Build Coastguard Worker  * Copyright (C) 2001 Andreas Dilger
5*6a54128fSAndroid Build Coastguard Worker  *
6*6a54128fSAndroid Build Coastguard Worker  * %Begin-Header%
7*6a54128fSAndroid Build Coastguard Worker  * This file may be redistributed under the terms of the
8*6a54128fSAndroid Build Coastguard Worker  * GNU Lesser General Public License.
9*6a54128fSAndroid Build Coastguard Worker  * %End-Header%
10*6a54128fSAndroid Build Coastguard Worker  */
11*6a54128fSAndroid Build Coastguard Worker 
12*6a54128fSAndroid Build Coastguard Worker #include "config.h"
13*6a54128fSAndroid Build Coastguard Worker #include <stdio.h>
14*6a54128fSAndroid Build Coastguard Worker #include <stdlib.h>
15*6a54128fSAndroid Build Coastguard Worker #include <unistd.h>
16*6a54128fSAndroid Build Coastguard Worker #include <string.h>
17*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_TERMIOS_H
18*6a54128fSAndroid Build Coastguard Worker #include <termios.h>
19*6a54128fSAndroid Build Coastguard Worker #endif
20*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_TERMIO_H
21*6a54128fSAndroid Build Coastguard Worker #include <termio.h>
22*6a54128fSAndroid Build Coastguard Worker #endif
23*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_SYS_IOCTL_H
24*6a54128fSAndroid Build Coastguard Worker #include <sys/ioctl.h>
25*6a54128fSAndroid Build Coastguard Worker #endif
26*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_GETOPT_H
27*6a54128fSAndroid Build Coastguard Worker #include <getopt.h>
28*6a54128fSAndroid Build Coastguard Worker #else
29*6a54128fSAndroid Build Coastguard Worker extern int getopt(int argc, char * const argv[], const char *optstring);
30*6a54128fSAndroid Build Coastguard Worker extern char *optarg;
31*6a54128fSAndroid Build Coastguard Worker extern int optind;
32*6a54128fSAndroid Build Coastguard Worker #endif
33*6a54128fSAndroid Build Coastguard Worker 
34*6a54128fSAndroid Build Coastguard Worker #define OUTPUT_VALUE_ONLY	0x0001
35*6a54128fSAndroid Build Coastguard Worker #define OUTPUT_DEVICE_ONLY	0x0002
36*6a54128fSAndroid Build Coastguard Worker #define OUTPUT_PRETTY_LIST	0x0004
37*6a54128fSAndroid Build Coastguard Worker 
38*6a54128fSAndroid Build Coastguard Worker #include "ext2fs/ext2fs.h"
39*6a54128fSAndroid Build Coastguard Worker #include "blkid/blkid.h"
40*6a54128fSAndroid Build Coastguard Worker 
41*6a54128fSAndroid Build Coastguard Worker static const char *progname = "blkid";
42*6a54128fSAndroid Build Coastguard Worker 
print_version(FILE * out)43*6a54128fSAndroid Build Coastguard Worker static void print_version(FILE *out)
44*6a54128fSAndroid Build Coastguard Worker {
45*6a54128fSAndroid Build Coastguard Worker 	fprintf(out, "%s %s (%s)\n", progname, BLKID_VERSION, BLKID_DATE);
46*6a54128fSAndroid Build Coastguard Worker }
47*6a54128fSAndroid Build Coastguard Worker 
usage(int error)48*6a54128fSAndroid Build Coastguard Worker static void usage(int error)
49*6a54128fSAndroid Build Coastguard Worker {
50*6a54128fSAndroid Build Coastguard Worker 	FILE *out = error ? stderr : stdout;
51*6a54128fSAndroid Build Coastguard Worker 
52*6a54128fSAndroid Build Coastguard Worker 	print_version(out);
53*6a54128fSAndroid Build Coastguard Worker 	fprintf(out,
54*6a54128fSAndroid Build Coastguard Worker 		"usage:\t%s [-c <file>] [-ghlLv] [-o format] "
55*6a54128fSAndroid Build Coastguard Worker 		"[-s <tag>] [-t <token>]\n    [-w <file>] [dev ...]\n"
56*6a54128fSAndroid Build Coastguard Worker 		"\t-c\tcache file (default: /etc/blkid.tab, /dev/null = none)\n"
57*6a54128fSAndroid Build Coastguard Worker 		"\t-h\tprint this usage message and exit\n"
58*6a54128fSAndroid Build Coastguard Worker 		"\t-g\tgarbage collect the blkid cache\n"
59*6a54128fSAndroid Build Coastguard Worker 		"\t-s\tshow specified tag(s) (default show all tags)\n"
60*6a54128fSAndroid Build Coastguard Worker 		"\t-t\tfind device with a specific token (NAME=value pair)\n"
61*6a54128fSAndroid Build Coastguard Worker 		"\t-l\tlookup the the first device with arguments specified by -t\n"
62*6a54128fSAndroid Build Coastguard Worker 		"\t-v\tprint version and exit\n"
63*6a54128fSAndroid Build Coastguard Worker 		"\t-w\twrite cache to different file (/dev/null = no write)\n"
64*6a54128fSAndroid Build Coastguard Worker 		"\tdev\tspecify device(s) to probe (default: all devices)\n",
65*6a54128fSAndroid Build Coastguard Worker 		progname);
66*6a54128fSAndroid Build Coastguard Worker 	exit(error);
67*6a54128fSAndroid Build Coastguard Worker }
68*6a54128fSAndroid Build Coastguard Worker 
69*6a54128fSAndroid Build Coastguard Worker /*
70*6a54128fSAndroid Build Coastguard Worker  * This function does "safe" printing.  It will convert non-printable
71*6a54128fSAndroid Build Coastguard Worker  * ASCII characters using '^' and M- notation.
72*6a54128fSAndroid Build Coastguard Worker  */
safe_print(const char * cp,int len)73*6a54128fSAndroid Build Coastguard Worker static void safe_print(const char *cp, int len)
74*6a54128fSAndroid Build Coastguard Worker {
75*6a54128fSAndroid Build Coastguard Worker 	unsigned char	ch;
76*6a54128fSAndroid Build Coastguard Worker 
77*6a54128fSAndroid Build Coastguard Worker 	if (len < 0)
78*6a54128fSAndroid Build Coastguard Worker 		len = strlen(cp);
79*6a54128fSAndroid Build Coastguard Worker 
80*6a54128fSAndroid Build Coastguard Worker 	while (len--) {
81*6a54128fSAndroid Build Coastguard Worker 		ch = *cp++;
82*6a54128fSAndroid Build Coastguard Worker 		if (ch > 128) {
83*6a54128fSAndroid Build Coastguard Worker 			fputs("M-", stdout);
84*6a54128fSAndroid Build Coastguard Worker 			ch -= 128;
85*6a54128fSAndroid Build Coastguard Worker 		}
86*6a54128fSAndroid Build Coastguard Worker 		if ((ch < 32) || (ch == 0x7f)) {
87*6a54128fSAndroid Build Coastguard Worker 			fputc('^', stdout);
88*6a54128fSAndroid Build Coastguard Worker 			ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
89*6a54128fSAndroid Build Coastguard Worker 		}
90*6a54128fSAndroid Build Coastguard Worker 		if (ch != '"') {
91*6a54128fSAndroid Build Coastguard Worker 			fputc(ch, stdout);
92*6a54128fSAndroid Build Coastguard Worker 		}
93*6a54128fSAndroid Build Coastguard Worker 	}
94*6a54128fSAndroid Build Coastguard Worker }
95*6a54128fSAndroid Build Coastguard Worker 
get_terminal_width(void)96*6a54128fSAndroid Build Coastguard Worker static int get_terminal_width(void)
97*6a54128fSAndroid Build Coastguard Worker {
98*6a54128fSAndroid Build Coastguard Worker #ifdef TIOCGSIZE
99*6a54128fSAndroid Build Coastguard Worker 	struct ttysize	t_win;
100*6a54128fSAndroid Build Coastguard Worker #endif
101*6a54128fSAndroid Build Coastguard Worker #ifdef TIOCGWINSZ
102*6a54128fSAndroid Build Coastguard Worker 	struct winsize	w_win;
103*6a54128fSAndroid Build Coastguard Worker #endif
104*6a54128fSAndroid Build Coastguard Worker         const char	*cp;
105*6a54128fSAndroid Build Coastguard Worker 	int width = 80;
106*6a54128fSAndroid Build Coastguard Worker 
107*6a54128fSAndroid Build Coastguard Worker #ifdef TIOCGSIZE
108*6a54128fSAndroid Build Coastguard Worker 	if (ioctl (0, TIOCGSIZE, &t_win) == 0) {
109*6a54128fSAndroid Build Coastguard Worker 		width = t_win.ts_cols;
110*6a54128fSAndroid Build Coastguard Worker 		goto got_it;
111*6a54128fSAndroid Build Coastguard Worker 	}
112*6a54128fSAndroid Build Coastguard Worker #endif
113*6a54128fSAndroid Build Coastguard Worker #ifdef TIOCGWINSZ
114*6a54128fSAndroid Build Coastguard Worker 	if (ioctl (0, TIOCGWINSZ, &w_win) == 0) {
115*6a54128fSAndroid Build Coastguard Worker 		width = w_win.ws_col;
116*6a54128fSAndroid Build Coastguard Worker 		goto got_it;
117*6a54128fSAndroid Build Coastguard Worker 	}
118*6a54128fSAndroid Build Coastguard Worker #endif
119*6a54128fSAndroid Build Coastguard Worker         cp = getenv("COLUMNS");
120*6a54128fSAndroid Build Coastguard Worker 	if (cp)
121*6a54128fSAndroid Build Coastguard Worker 		width = atoi(cp);
122*6a54128fSAndroid Build Coastguard Worker got_it:
123*6a54128fSAndroid Build Coastguard Worker 	if (width > 4096)
124*6a54128fSAndroid Build Coastguard Worker 		return 4096;	/* sanity check */
125*6a54128fSAndroid Build Coastguard Worker 	return width;
126*6a54128fSAndroid Build Coastguard Worker }
127*6a54128fSAndroid Build Coastguard Worker 
pretty_print_word(const char * str,int max_len,int left_len,int overflow_nl)128*6a54128fSAndroid Build Coastguard Worker static int pretty_print_word(const char *str, int max_len,
129*6a54128fSAndroid Build Coastguard Worker 			     int left_len, int overflow_nl)
130*6a54128fSAndroid Build Coastguard Worker {
131*6a54128fSAndroid Build Coastguard Worker 	int len = strlen(str) + left_len;
132*6a54128fSAndroid Build Coastguard Worker 	int ret = 0;
133*6a54128fSAndroid Build Coastguard Worker 
134*6a54128fSAndroid Build Coastguard Worker 	fputs(str, stdout);
135*6a54128fSAndroid Build Coastguard Worker 	if (overflow_nl && len > max_len) {
136*6a54128fSAndroid Build Coastguard Worker 		fputc('\n', stdout);
137*6a54128fSAndroid Build Coastguard Worker 		len = 0;
138*6a54128fSAndroid Build Coastguard Worker 	} else if (len > max_len)
139*6a54128fSAndroid Build Coastguard Worker 		ret = len - max_len;
140*6a54128fSAndroid Build Coastguard Worker 	do {
141*6a54128fSAndroid Build Coastguard Worker 		fputc(' ', stdout);
142*6a54128fSAndroid Build Coastguard Worker 	} while (len++ < max_len);
143*6a54128fSAndroid Build Coastguard Worker 	return ret;
144*6a54128fSAndroid Build Coastguard Worker }
145*6a54128fSAndroid Build Coastguard Worker 
pretty_print_line(const char * device,const char * fs_type,const char * label,const char * mtpt,const char * uuid)146*6a54128fSAndroid Build Coastguard Worker static void pretty_print_line(const char *device, const char *fs_type,
147*6a54128fSAndroid Build Coastguard Worker 			      const char *label, const char *mtpt,
148*6a54128fSAndroid Build Coastguard Worker 			      const char *uuid)
149*6a54128fSAndroid Build Coastguard Worker {
150*6a54128fSAndroid Build Coastguard Worker 	static int device_len = 10, fs_type_len = 7;
151*6a54128fSAndroid Build Coastguard Worker 	static int label_len = 8, mtpt_len = 14;
152*6a54128fSAndroid Build Coastguard Worker 	static int term_width = -1;
153*6a54128fSAndroid Build Coastguard Worker 	int len, w;
154*6a54128fSAndroid Build Coastguard Worker 
155*6a54128fSAndroid Build Coastguard Worker 	if (term_width < 0) {
156*6a54128fSAndroid Build Coastguard Worker 		term_width = get_terminal_width();
157*6a54128fSAndroid Build Coastguard Worker 
158*6a54128fSAndroid Build Coastguard Worker 		if (term_width > 80) {
159*6a54128fSAndroid Build Coastguard Worker 			term_width -= 80;
160*6a54128fSAndroid Build Coastguard Worker 			w = term_width / 10;
161*6a54128fSAndroid Build Coastguard Worker 			if (w > 8)
162*6a54128fSAndroid Build Coastguard Worker 				w = 8;
163*6a54128fSAndroid Build Coastguard Worker 			term_width -= 2*w;
164*6a54128fSAndroid Build Coastguard Worker 			label_len += w;
165*6a54128fSAndroid Build Coastguard Worker 			fs_type_len += w;
166*6a54128fSAndroid Build Coastguard Worker 			w = term_width/2;
167*6a54128fSAndroid Build Coastguard Worker 			device_len += w;
168*6a54128fSAndroid Build Coastguard Worker 			mtpt_len +=w;
169*6a54128fSAndroid Build Coastguard Worker 		}
170*6a54128fSAndroid Build Coastguard Worker 	}
171*6a54128fSAndroid Build Coastguard Worker 
172*6a54128fSAndroid Build Coastguard Worker 	len = pretty_print_word(device, device_len, 0, 1);
173*6a54128fSAndroid Build Coastguard Worker 	len = pretty_print_word(fs_type, fs_type_len, len, 0);
174*6a54128fSAndroid Build Coastguard Worker 	len = pretty_print_word(label, label_len, len, 0);
175*6a54128fSAndroid Build Coastguard Worker 	len = pretty_print_word(mtpt, mtpt_len, len, 0);
176*6a54128fSAndroid Build Coastguard Worker 	fputs(uuid, stdout);
177*6a54128fSAndroid Build Coastguard Worker 	fputc('\n', stdout);
178*6a54128fSAndroid Build Coastguard Worker }
179*6a54128fSAndroid Build Coastguard Worker 
pretty_print_dev(blkid_dev dev)180*6a54128fSAndroid Build Coastguard Worker static void pretty_print_dev(blkid_dev dev)
181*6a54128fSAndroid Build Coastguard Worker {
182*6a54128fSAndroid Build Coastguard Worker 	blkid_tag_iterate	iter;
183*6a54128fSAndroid Build Coastguard Worker 	const char		*type, *value, *devname;
184*6a54128fSAndroid Build Coastguard Worker 	const char		*uuid = "", *fs_type = "", *label = "";
185*6a54128fSAndroid Build Coastguard Worker 	int			len, mount_flags;
186*6a54128fSAndroid Build Coastguard Worker 	char			mtpt[80];
187*6a54128fSAndroid Build Coastguard Worker 	errcode_t		retval;
188*6a54128fSAndroid Build Coastguard Worker 
189*6a54128fSAndroid Build Coastguard Worker 	if (dev == NULL) {
190*6a54128fSAndroid Build Coastguard Worker 		pretty_print_line("device", "fs_type", "label",
191*6a54128fSAndroid Build Coastguard Worker 				  "mount point", "UUID");
192*6a54128fSAndroid Build Coastguard Worker 		for (len=get_terminal_width()-1; len > 0; len--)
193*6a54128fSAndroid Build Coastguard Worker 			fputc('-', stdout);
194*6a54128fSAndroid Build Coastguard Worker 		fputc('\n', stdout);
195*6a54128fSAndroid Build Coastguard Worker 		return;
196*6a54128fSAndroid Build Coastguard Worker 	}
197*6a54128fSAndroid Build Coastguard Worker 
198*6a54128fSAndroid Build Coastguard Worker 	devname = blkid_dev_devname(dev);
199*6a54128fSAndroid Build Coastguard Worker 	if (access(devname, F_OK))
200*6a54128fSAndroid Build Coastguard Worker 		return;
201*6a54128fSAndroid Build Coastguard Worker 
202*6a54128fSAndroid Build Coastguard Worker 	/* Get the uuid, label, type */
203*6a54128fSAndroid Build Coastguard Worker 	iter = blkid_tag_iterate_begin(dev);
204*6a54128fSAndroid Build Coastguard Worker 	while (blkid_tag_next(iter, &type, &value) == 0) {
205*6a54128fSAndroid Build Coastguard Worker 		if (!strcmp(type, "UUID"))
206*6a54128fSAndroid Build Coastguard Worker 			uuid = value;
207*6a54128fSAndroid Build Coastguard Worker 		if (!strcmp(type, "TYPE"))
208*6a54128fSAndroid Build Coastguard Worker 			fs_type = value;
209*6a54128fSAndroid Build Coastguard Worker 		if (!strcmp(type, "LABEL"))
210*6a54128fSAndroid Build Coastguard Worker 			label = value;
211*6a54128fSAndroid Build Coastguard Worker 	}
212*6a54128fSAndroid Build Coastguard Worker 	blkid_tag_iterate_end(iter);
213*6a54128fSAndroid Build Coastguard Worker 
214*6a54128fSAndroid Build Coastguard Worker 	/* Get the mount point */
215*6a54128fSAndroid Build Coastguard Worker 	mtpt[0] = 0;
216*6a54128fSAndroid Build Coastguard Worker 	retval = ext2fs_check_mount_point(devname, &mount_flags,
217*6a54128fSAndroid Build Coastguard Worker 					  mtpt, sizeof(mtpt));
218*6a54128fSAndroid Build Coastguard Worker 	if (retval == 0) {
219*6a54128fSAndroid Build Coastguard Worker 		if (mount_flags & EXT2_MF_MOUNTED) {
220*6a54128fSAndroid Build Coastguard Worker 			if (!mtpt[0])
221*6a54128fSAndroid Build Coastguard Worker 				strcpy(mtpt, "(mounted, mtpt unknown)");
222*6a54128fSAndroid Build Coastguard Worker 		} else if (mount_flags & EXT2_MF_BUSY)
223*6a54128fSAndroid Build Coastguard Worker 			strcpy(mtpt, "(in use)");
224*6a54128fSAndroid Build Coastguard Worker 		else
225*6a54128fSAndroid Build Coastguard Worker 			strcpy(mtpt, "(not mounted)");
226*6a54128fSAndroid Build Coastguard Worker 	}
227*6a54128fSAndroid Build Coastguard Worker 
228*6a54128fSAndroid Build Coastguard Worker 	pretty_print_line(devname, fs_type, label, mtpt, uuid);
229*6a54128fSAndroid Build Coastguard Worker }
230*6a54128fSAndroid Build Coastguard Worker 
print_tags(blkid_dev dev,char * show[],int numtag,int output)231*6a54128fSAndroid Build Coastguard Worker static void print_tags(blkid_dev dev, char *show[], int numtag, int output)
232*6a54128fSAndroid Build Coastguard Worker {
233*6a54128fSAndroid Build Coastguard Worker 	blkid_tag_iterate	iter;
234*6a54128fSAndroid Build Coastguard Worker 	const char		*type, *value;
235*6a54128fSAndroid Build Coastguard Worker 	int 			i, first = 1;
236*6a54128fSAndroid Build Coastguard Worker 
237*6a54128fSAndroid Build Coastguard Worker 	if (!dev)
238*6a54128fSAndroid Build Coastguard Worker 		return;
239*6a54128fSAndroid Build Coastguard Worker 
240*6a54128fSAndroid Build Coastguard Worker 	if (output & OUTPUT_PRETTY_LIST) {
241*6a54128fSAndroid Build Coastguard Worker 		pretty_print_dev(dev);
242*6a54128fSAndroid Build Coastguard Worker 		return;
243*6a54128fSAndroid Build Coastguard Worker 	}
244*6a54128fSAndroid Build Coastguard Worker 
245*6a54128fSAndroid Build Coastguard Worker 	if (output & OUTPUT_DEVICE_ONLY) {
246*6a54128fSAndroid Build Coastguard Worker 		printf("%s\n", blkid_dev_devname(dev));
247*6a54128fSAndroid Build Coastguard Worker 		return;
248*6a54128fSAndroid Build Coastguard Worker 	}
249*6a54128fSAndroid Build Coastguard Worker 
250*6a54128fSAndroid Build Coastguard Worker 	iter = blkid_tag_iterate_begin(dev);
251*6a54128fSAndroid Build Coastguard Worker 	while (blkid_tag_next(iter, &type, &value) == 0) {
252*6a54128fSAndroid Build Coastguard Worker 		if (numtag && show) {
253*6a54128fSAndroid Build Coastguard Worker 			for (i=0; i < numtag; i++)
254*6a54128fSAndroid Build Coastguard Worker 				if (!strcmp(type, show[i]))
255*6a54128fSAndroid Build Coastguard Worker 					break;
256*6a54128fSAndroid Build Coastguard Worker 			if (i >= numtag)
257*6a54128fSAndroid Build Coastguard Worker 				continue;
258*6a54128fSAndroid Build Coastguard Worker 		}
259*6a54128fSAndroid Build Coastguard Worker 		if (output & OUTPUT_VALUE_ONLY) {
260*6a54128fSAndroid Build Coastguard Worker 			fputs(value, stdout);
261*6a54128fSAndroid Build Coastguard Worker 			fputc('\n', stdout);
262*6a54128fSAndroid Build Coastguard Worker 		} else {
263*6a54128fSAndroid Build Coastguard Worker 			if (first) {
264*6a54128fSAndroid Build Coastguard Worker 				printf("%s: ", blkid_dev_devname(dev));
265*6a54128fSAndroid Build Coastguard Worker 				first = 0;
266*6a54128fSAndroid Build Coastguard Worker 			}
267*6a54128fSAndroid Build Coastguard Worker 			fputs(type, stdout);
268*6a54128fSAndroid Build Coastguard Worker 			fputs("=\"", stdout);
269*6a54128fSAndroid Build Coastguard Worker 			safe_print(value, -1);
270*6a54128fSAndroid Build Coastguard Worker 			fputs("\" ", stdout);
271*6a54128fSAndroid Build Coastguard Worker 		}
272*6a54128fSAndroid Build Coastguard Worker 	}
273*6a54128fSAndroid Build Coastguard Worker 	blkid_tag_iterate_end(iter);
274*6a54128fSAndroid Build Coastguard Worker 
275*6a54128fSAndroid Build Coastguard Worker 	if (!first && !(output & OUTPUT_VALUE_ONLY))
276*6a54128fSAndroid Build Coastguard Worker 		printf("\n");
277*6a54128fSAndroid Build Coastguard Worker }
278*6a54128fSAndroid Build Coastguard Worker 
main(int argc,char ** argv)279*6a54128fSAndroid Build Coastguard Worker int main(int argc, char **argv)
280*6a54128fSAndroid Build Coastguard Worker {
281*6a54128fSAndroid Build Coastguard Worker 	blkid_cache cache = NULL;
282*6a54128fSAndroid Build Coastguard Worker 	char *devices[128] = { NULL, };
283*6a54128fSAndroid Build Coastguard Worker 	char *show[128] = { NULL, };
284*6a54128fSAndroid Build Coastguard Worker 	char *search_type = NULL, *search_value = NULL;
285*6a54128fSAndroid Build Coastguard Worker 	char *read = NULL;
286*6a54128fSAndroid Build Coastguard Worker 	char *write = NULL;
287*6a54128fSAndroid Build Coastguard Worker 	unsigned int numdev = 0, numtag = 0;
288*6a54128fSAndroid Build Coastguard Worker 	int version = 0;
289*6a54128fSAndroid Build Coastguard Worker 	int err = 4;
290*6a54128fSAndroid Build Coastguard Worker 	unsigned int i;
291*6a54128fSAndroid Build Coastguard Worker 	int output_format = 0;
292*6a54128fSAndroid Build Coastguard Worker 	int lookup = 0, gc = 0;
293*6a54128fSAndroid Build Coastguard Worker 	int c;
294*6a54128fSAndroid Build Coastguard Worker 
295*6a54128fSAndroid Build Coastguard Worker 	while ((c = getopt (argc, argv, "c:f:ghlLo:s:t:w:v")) != EOF)
296*6a54128fSAndroid Build Coastguard Worker 		switch (c) {
297*6a54128fSAndroid Build Coastguard Worker 		case 'c':
298*6a54128fSAndroid Build Coastguard Worker 			read = optarg;
299*6a54128fSAndroid Build Coastguard Worker 			if (!write)
300*6a54128fSAndroid Build Coastguard Worker 				write = read;
301*6a54128fSAndroid Build Coastguard Worker 			break;
302*6a54128fSAndroid Build Coastguard Worker 		case 'l':
303*6a54128fSAndroid Build Coastguard Worker 			lookup++;
304*6a54128fSAndroid Build Coastguard Worker 			break;
305*6a54128fSAndroid Build Coastguard Worker 		case 'L':
306*6a54128fSAndroid Build Coastguard Worker 			output_format = OUTPUT_PRETTY_LIST;
307*6a54128fSAndroid Build Coastguard Worker 			break;
308*6a54128fSAndroid Build Coastguard Worker 		case 'g':
309*6a54128fSAndroid Build Coastguard Worker 			gc = 1;
310*6a54128fSAndroid Build Coastguard Worker 			break;
311*6a54128fSAndroid Build Coastguard Worker 		case 'o':
312*6a54128fSAndroid Build Coastguard Worker 			if (!strcmp(optarg, "value"))
313*6a54128fSAndroid Build Coastguard Worker 				output_format = OUTPUT_VALUE_ONLY;
314*6a54128fSAndroid Build Coastguard Worker 			else if (!strcmp(optarg, "device"))
315*6a54128fSAndroid Build Coastguard Worker 				output_format = OUTPUT_DEVICE_ONLY;
316*6a54128fSAndroid Build Coastguard Worker 			else if (!strcmp(optarg, "list"))
317*6a54128fSAndroid Build Coastguard Worker 				output_format = OUTPUT_PRETTY_LIST;
318*6a54128fSAndroid Build Coastguard Worker 			else if (!strcmp(optarg, "full"))
319*6a54128fSAndroid Build Coastguard Worker 				output_format = 0;
320*6a54128fSAndroid Build Coastguard Worker 			else {
321*6a54128fSAndroid Build Coastguard Worker 				fprintf(stderr, "Invalid output format %s. "
322*6a54128fSAndroid Build Coastguard Worker 					"Choose from value,\n\t"
323*6a54128fSAndroid Build Coastguard Worker 					"device, list, or full\n", optarg);
324*6a54128fSAndroid Build Coastguard Worker 				exit(1);
325*6a54128fSAndroid Build Coastguard Worker 			}
326*6a54128fSAndroid Build Coastguard Worker 			break;
327*6a54128fSAndroid Build Coastguard Worker 		case 's':
328*6a54128fSAndroid Build Coastguard Worker 			if (numtag >= sizeof(show) / sizeof(*show)) {
329*6a54128fSAndroid Build Coastguard Worker 				fprintf(stderr, "Too many tags specified\n");
330*6a54128fSAndroid Build Coastguard Worker 				usage(err);
331*6a54128fSAndroid Build Coastguard Worker 			}
332*6a54128fSAndroid Build Coastguard Worker 			show[numtag++] = optarg;
333*6a54128fSAndroid Build Coastguard Worker 			break;
334*6a54128fSAndroid Build Coastguard Worker 		case 't':
335*6a54128fSAndroid Build Coastguard Worker 			if (search_type) {
336*6a54128fSAndroid Build Coastguard Worker 				fprintf(stderr, "Can only search for "
337*6a54128fSAndroid Build Coastguard Worker 						"one NAME=value pair\n");
338*6a54128fSAndroid Build Coastguard Worker 				usage(err);
339*6a54128fSAndroid Build Coastguard Worker 			}
340*6a54128fSAndroid Build Coastguard Worker 			if (blkid_parse_tag_string(optarg,
341*6a54128fSAndroid Build Coastguard Worker 						   &search_type,
342*6a54128fSAndroid Build Coastguard Worker 						   &search_value)) {
343*6a54128fSAndroid Build Coastguard Worker 				fprintf(stderr, "-t needs NAME=value pair\n");
344*6a54128fSAndroid Build Coastguard Worker 				usage(err);
345*6a54128fSAndroid Build Coastguard Worker 			}
346*6a54128fSAndroid Build Coastguard Worker 			break;
347*6a54128fSAndroid Build Coastguard Worker 		case 'v':
348*6a54128fSAndroid Build Coastguard Worker 			version = 1;
349*6a54128fSAndroid Build Coastguard Worker 			break;
350*6a54128fSAndroid Build Coastguard Worker 		case 'w':
351*6a54128fSAndroid Build Coastguard Worker 			write = optarg;
352*6a54128fSAndroid Build Coastguard Worker 			break;
353*6a54128fSAndroid Build Coastguard Worker 		case 'h':
354*6a54128fSAndroid Build Coastguard Worker 			err = 0;
355*6a54128fSAndroid Build Coastguard Worker 			/* fallthrough */
356*6a54128fSAndroid Build Coastguard Worker 		default:
357*6a54128fSAndroid Build Coastguard Worker 			usage(err);
358*6a54128fSAndroid Build Coastguard Worker 		}
359*6a54128fSAndroid Build Coastguard Worker 
360*6a54128fSAndroid Build Coastguard Worker 	while (optind < argc)
361*6a54128fSAndroid Build Coastguard Worker 		devices[numdev++] = argv[optind++];
362*6a54128fSAndroid Build Coastguard Worker 
363*6a54128fSAndroid Build Coastguard Worker 	if (version) {
364*6a54128fSAndroid Build Coastguard Worker 		print_version(stdout);
365*6a54128fSAndroid Build Coastguard Worker 		goto exit;
366*6a54128fSAndroid Build Coastguard Worker 	}
367*6a54128fSAndroid Build Coastguard Worker 
368*6a54128fSAndroid Build Coastguard Worker 	if (blkid_get_cache(&cache, read) < 0)
369*6a54128fSAndroid Build Coastguard Worker 		goto exit;
370*6a54128fSAndroid Build Coastguard Worker 
371*6a54128fSAndroid Build Coastguard Worker 	err = 2;
372*6a54128fSAndroid Build Coastguard Worker 	if (gc) {
373*6a54128fSAndroid Build Coastguard Worker 		blkid_gc_cache(cache);
374*6a54128fSAndroid Build Coastguard Worker 		goto exit;
375*6a54128fSAndroid Build Coastguard Worker 	}
376*6a54128fSAndroid Build Coastguard Worker 	if (output_format & OUTPUT_PRETTY_LIST)
377*6a54128fSAndroid Build Coastguard Worker 		pretty_print_dev(NULL);
378*6a54128fSAndroid Build Coastguard Worker 
379*6a54128fSAndroid Build Coastguard Worker 	if (lookup) {
380*6a54128fSAndroid Build Coastguard Worker 		blkid_dev dev;
381*6a54128fSAndroid Build Coastguard Worker 
382*6a54128fSAndroid Build Coastguard Worker 		if (!search_type) {
383*6a54128fSAndroid Build Coastguard Worker 			fprintf(stderr, "The lookup option requires a "
384*6a54128fSAndroid Build Coastguard Worker 				"search type specified using -t\n");
385*6a54128fSAndroid Build Coastguard Worker 			exit(1);
386*6a54128fSAndroid Build Coastguard Worker 		}
387*6a54128fSAndroid Build Coastguard Worker 		/* Load any additional devices not in the cache */
388*6a54128fSAndroid Build Coastguard Worker 		for (i = 0; i < numdev; i++)
389*6a54128fSAndroid Build Coastguard Worker 			blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL);
390*6a54128fSAndroid Build Coastguard Worker 
391*6a54128fSAndroid Build Coastguard Worker 		if ((dev = blkid_find_dev_with_tag(cache, search_type,
392*6a54128fSAndroid Build Coastguard Worker 						   search_value))) {
393*6a54128fSAndroid Build Coastguard Worker 			print_tags(dev, show, numtag, output_format);
394*6a54128fSAndroid Build Coastguard Worker 			err = 0;
395*6a54128fSAndroid Build Coastguard Worker 		}
396*6a54128fSAndroid Build Coastguard Worker 	/* If we didn't specify a single device, show all available devices */
397*6a54128fSAndroid Build Coastguard Worker 	} else if (!numdev) {
398*6a54128fSAndroid Build Coastguard Worker 		blkid_dev_iterate	iter;
399*6a54128fSAndroid Build Coastguard Worker 		blkid_dev		dev;
400*6a54128fSAndroid Build Coastguard Worker 
401*6a54128fSAndroid Build Coastguard Worker 		blkid_probe_all(cache);
402*6a54128fSAndroid Build Coastguard Worker 
403*6a54128fSAndroid Build Coastguard Worker 		iter = blkid_dev_iterate_begin(cache);
404*6a54128fSAndroid Build Coastguard Worker 		blkid_dev_set_search(iter, search_type, search_value);
405*6a54128fSAndroid Build Coastguard Worker 		while (blkid_dev_next(iter, &dev) == 0) {
406*6a54128fSAndroid Build Coastguard Worker 			dev = blkid_verify(cache, dev);
407*6a54128fSAndroid Build Coastguard Worker 			if (!dev)
408*6a54128fSAndroid Build Coastguard Worker 				continue;
409*6a54128fSAndroid Build Coastguard Worker 			print_tags(dev, show, numtag, output_format);
410*6a54128fSAndroid Build Coastguard Worker 			err = 0;
411*6a54128fSAndroid Build Coastguard Worker 		}
412*6a54128fSAndroid Build Coastguard Worker 		blkid_dev_iterate_end(iter);
413*6a54128fSAndroid Build Coastguard Worker 	/* Add all specified devices to cache (optionally display tags) */
414*6a54128fSAndroid Build Coastguard Worker 	} else for (i = 0; i < numdev; i++) {
415*6a54128fSAndroid Build Coastguard Worker 		blkid_dev dev = blkid_get_dev(cache, devices[i],
416*6a54128fSAndroid Build Coastguard Worker 						  BLKID_DEV_NORMAL);
417*6a54128fSAndroid Build Coastguard Worker 
418*6a54128fSAndroid Build Coastguard Worker 		if (dev) {
419*6a54128fSAndroid Build Coastguard Worker 			if (search_type &&
420*6a54128fSAndroid Build Coastguard Worker 			    !blkid_dev_has_tag(dev, search_type,
421*6a54128fSAndroid Build Coastguard Worker 					       search_value))
422*6a54128fSAndroid Build Coastguard Worker 				continue;
423*6a54128fSAndroid Build Coastguard Worker 			print_tags(dev, show, numtag, output_format);
424*6a54128fSAndroid Build Coastguard Worker 			err = 0;
425*6a54128fSAndroid Build Coastguard Worker 		}
426*6a54128fSAndroid Build Coastguard Worker 	}
427*6a54128fSAndroid Build Coastguard Worker 
428*6a54128fSAndroid Build Coastguard Worker exit:
429*6a54128fSAndroid Build Coastguard Worker 	free(search_type);
430*6a54128fSAndroid Build Coastguard Worker 	free(search_value);
431*6a54128fSAndroid Build Coastguard Worker 	blkid_put_cache(cache);
432*6a54128fSAndroid Build Coastguard Worker 	return err;
433*6a54128fSAndroid Build Coastguard Worker }
434