119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * blkid.c - User command-line interface for libblkid
319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 2001 Andreas Dilger
519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %Begin-Header%
719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This file may be redistributed under the terms of the
819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * GNU Lesser General Public License.
919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %End-Header%
1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h>
1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdlib.h>
143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <unistd.h>
1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h>
163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef HAVE_TERMIOS_H
173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <termios.h>
183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef HAVE_TERMIO_H
203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <termio.h>
213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef HAVE_SYS_IOCTL_H
233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <sys/ioctl.h>
243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_GETOPT_H
2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <getopt.h>
2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else
2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern int getopt(int argc, char * const argv[], const char *optstring);
2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern char *optarg;
3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern int optind;
3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define OUTPUT_VALUE_ONLY	0x0001
3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define OUTPUT_DEVICE_ONLY	0x0002
353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define OUTPUT_PRETTY_LIST	0x0004
3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include "ext2fs/ext2fs.h"
3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "blkid/blkid.h"
3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectconst char *progname = "blkid";
4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void print_version(FILE *out)
4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fprintf(out, "%s %s (%s)\n", progname, BLKID_VERSION, BLKID_DATE);
4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void usage(int error)
4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	FILE *out = error ? stderr : stdout;
5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	print_version(out);
5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fprintf(out,
533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		"usage:\t%s [-c <file>] [-ghlLv] [-o format] "
543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		"[-s <tag>] [-t <token>]\n    [-w <file>] [dev ...]\n"
5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		"\t-c\tcache file (default: /etc/blkid.tab, /dev/null = none)\n"
5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		"\t-h\tprint this usage message and exit\n"
5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		"\t-g\tgarbage collect the blkid cache\n"
5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		"\t-s\tshow specified tag(s) (default show all tags)\n"
5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		"\t-t\tfind device with a specific token (NAME=value pair)\n"
6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		"\t-l\tlookup the the first device with arguments specified by -t\n"
6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		"\t-v\tprint version and exit\n"
6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		"\t-w\twrite cache to different file (/dev/null = no write)\n"
6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		"\tdev\tspecify device(s) to probe (default: all devices)\n",
6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		progname);
6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	exit(error);
6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function does "safe" printing.  It will convert non-printable
7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * ASCII characters using '^' and M- notation.
7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void safe_print(const char *cp, int len)
7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned char	ch;
7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (len < 0)
7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		len = strlen(cp);
7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (len--) {
8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ch = *cp++;
8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (ch > 128) {
8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fputs("M-", stdout);
8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ch -= 128;
8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((ch < 32) || (ch == 0x7f)) {
8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fputc('^', stdout);
8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fputc(ch, stdout);
9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic int get_terminal_width(void)
943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef TIOCGSIZE
963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct ttysize	t_win;
973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef TIOCGWINSZ
993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct winsize	w_win;
1003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
1013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt        const char	*cp;
1023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef TIOCGSIZE
1043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (ioctl (0, TIOCGSIZE, &t_win) == 0)
1053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return (t_win.ts_cols);
1063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
1073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef TIOCGWINSZ
1083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (ioctl (0, TIOCGWINSZ, &w_win) == 0)
1093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return (w_win.ws_col);
1103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
1113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt        cp = getenv("COLUMNS");
1123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (cp)
1133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return strtol(cp, NULL, 10);
1143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return 80;
1153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
1163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic int pretty_print_word(const char *str, int max_len,
1183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			     int left_len, int overflow_nl)
1193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
1203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int len = strlen(str) + left_len;
1213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int ret = 0;
1223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	fputs(str, stdout);
1243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (overflow_nl && len > max_len) {
1253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fputc('\n', stdout);
1263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		len = 0;
1273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	} else if (len > max_len)
1283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		ret = len - max_len;
1293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	do
1303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fputc(' ', stdout);
1313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	while (len++ < max_len);
1323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return ret;
1333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
1343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic void pretty_print_line(const char *device, const char *fs_type,
1363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			      const char *label, const char *mtpt,
1373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			      const char *uuid)
1383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
1393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	static int device_len = 10, fs_type_len = 7;
1403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	static int label_len = 8, mtpt_len = 14;
1413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	static int term_width = -1;
1423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int len, w;
1433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (term_width < 0)
1453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		term_width = get_terminal_width();
1463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (term_width > 80) {
1483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		term_width -= 80;
1493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		w = term_width / 10;
1503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (w > 8)
1513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			w = 8;
1523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		term_width -= 2*w;
1533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		label_len += w;
1543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fs_type_len += w;
1553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		w = term_width/2;
1563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		device_len += w;
1573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		mtpt_len +=w;
1583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
1593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	len = pretty_print_word(device, device_len, 0, 1);
1613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	len = pretty_print_word(fs_type, fs_type_len, len, 0);
1623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	len = pretty_print_word(label, label_len, len, 0);
1633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	len = pretty_print_word(mtpt, mtpt_len, len, 0);
1643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	fputs(uuid, stdout);
1653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	fputc('\n', stdout);
1663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
1673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic void pretty_print_dev(blkid_dev dev)
1693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
1703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	blkid_tag_iterate	iter;
1713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	const char		*type, *value, *devname;
1723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	const char		*uuid = "", *fs_type = "", *label = "";
1733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int			len, mount_flags;
1743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	char			mtpt[80];
1753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	errcode_t		retval;
1763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (dev == NULL) {
1783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		pretty_print_line("device", "fs_type", "label",
1793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				  "mount point", "UUID");
1803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		for (len=get_terminal_width()-1; len > 0; len--)
1813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			fputc('-', stdout);
1823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fputc('\n', stdout);
1833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return;
1843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
1853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	devname = blkid_dev_devname(dev);
1873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (access(devname, F_OK))
1883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return;
1893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	/* Get the uuid, label, type */
1913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	iter = blkid_tag_iterate_begin(dev);
1923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	while (blkid_tag_next(iter, &type, &value) == 0) {
1933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (!strcmp(type, "UUID"))
1943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			uuid = value;
1953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (!strcmp(type, "TYPE"))
1963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			fs_type = value;
1973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (!strcmp(type, "LABEL"))
1983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			label = value;
1993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
2003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	blkid_tag_iterate_end(iter);
2013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
2023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	/* Get the mount point */
2033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	mtpt[0] = 0;
2043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	retval = ext2fs_check_mount_point(devname, &mount_flags,
2053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt					  mtpt, sizeof(mtpt));
2063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (retval == 0) {
2073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (mount_flags & EXT2_MF_MOUNTED) {
2083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (!mtpt[0])
2093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				strcpy(mtpt, "(mounted, mtpt unknown)");
2103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		} else if (mount_flags & EXT2_MF_BUSY)
2113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			strcpy(mtpt, "(in use)");
2123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		else
2133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			strcpy(mtpt, "(not mounted)");
2143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
2153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
2163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	pretty_print_line(devname, fs_type, label, mtpt, uuid);
2173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
2183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
21919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void print_tags(blkid_dev dev, char *show[], int numtag, int output)
22019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
22119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_tag_iterate	iter;
22219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char		*type, *value;
22319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int 			i, first = 1;
22419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
22519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!dev)
22619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
22719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
2283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (output & OUTPUT_PRETTY_LIST) {
2293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		pretty_print_dev(dev);
2303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return;
2313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
2323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
23319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (output & OUTPUT_DEVICE_ONLY) {
23419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf("%s\n", blkid_dev_devname(dev));
23519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
23619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
23719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
23819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	iter = blkid_tag_iterate_begin(dev);
23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (blkid_tag_next(iter, &type, &value) == 0) {
24019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (numtag && show) {
24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			for (i=0; i < numtag; i++)
24219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				if (!strcmp(type, show[i]))
24319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					break;
24419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (i >= numtag)
24519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				continue;
24619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
24719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (output & OUTPUT_VALUE_ONLY) {
24819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fputs(value, stdout);
24919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fputc('\n', stdout);
25019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		} else {
25119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (first) {
25219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				printf("%s: ", blkid_dev_devname(dev));
25319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				first = 0;
25419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
25519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fputs(type, stdout);
25619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fputs("=\"", stdout);
25719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			safe_print(value, -1);
25819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fputs("\" ", stdout);
25919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
26019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
26119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_tag_iterate_end(iter);
26219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
26319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!first && !(output & OUTPUT_VALUE_ONLY))
26419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf("\n");
26519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
26619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
26719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint main(int argc, char **argv)
26819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
26919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_cache cache = NULL;
27019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char *devices[128] = { NULL, };
27119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char *show[128] = { NULL, };
27219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char *search_type = NULL, *search_value = NULL;
27319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char *read = NULL;
27419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char *write = NULL;
27519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned int numdev = 0, numtag = 0;
27619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int version = 0;
27719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int err = 4;
27819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned int i;
27919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int output_format = 0;
28019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int lookup = 0, gc = 0;
28119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int c;
28219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
2833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	while ((c = getopt (argc, argv, "c:f:ghlLo:s:t:w:v")) != EOF)
28419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		switch (c) {
28519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'c':
28619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (optarg && !*optarg)
28719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				read = NULL;
28819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			else
28919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				read = optarg;
29019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (!write)
29119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				write = read;
29219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
29319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'l':
29419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			lookup++;
29519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
2963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		case 'L':
2973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			output_format = OUTPUT_PRETTY_LIST;
2983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			break;
29919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'g':
30019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			gc = 1;
30119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
30219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'o':
30319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (!strcmp(optarg, "value"))
30419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				output_format = OUTPUT_VALUE_ONLY;
30519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			else if (!strcmp(optarg, "device"))
30619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				output_format = OUTPUT_DEVICE_ONLY;
3073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			else if (!strcmp(optarg, "list"))
3083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				output_format = OUTPUT_PRETTY_LIST;
30919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			else if (!strcmp(optarg, "full"))
31019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				output_format = 0;
31119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			else {
3123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				fprintf(stderr, "Invalid output format %s. "
3133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt					"Choose from value,\n\t"
3143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt					"device, list, or full\n", optarg);
31519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				exit(1);
31619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
31719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
31819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 's':
31919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (numtag >= sizeof(show) / sizeof(*show)) {
32019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				fprintf(stderr, "Too many tags specified\n");
32119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				usage(err);
32219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
32319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			show[numtag++] = optarg;
32419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
32519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 't':
32619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (search_type) {
32719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				fprintf(stderr, "Can only search for "
32819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project						"one NAME=value pair\n");
32919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				usage(err);
33019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
33119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (blkid_parse_tag_string(optarg,
33219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project						   &search_type,
33319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project						   &search_value)) {
33419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				fprintf(stderr, "-t needs NAME=value pair\n");
33519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				usage(err);
33619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
33719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
33819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'v':
33919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			version = 1;
34019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
34119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'w':
34219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (optarg && !*optarg)
34319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				write = NULL;
34419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			else
34519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				write = optarg;
34619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
34719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'h':
34819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			err = 0;
34919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		default:
35019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			usage(err);
35119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
35219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
35319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (optind < argc)
35419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		devices[numdev++] = argv[optind++];
35519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
35619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (version) {
35719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		print_version(stdout);
35819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		goto exit;
35919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
36019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
36119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (blkid_get_cache(&cache, read) < 0)
36219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		goto exit;
36319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
36419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	err = 2;
36519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (gc) {
36619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_gc_cache(cache);
3673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		goto exit;
3683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
3693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (output_format & OUTPUT_PRETTY_LIST)
3703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		pretty_print_dev(NULL);
3713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
3723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (lookup) {
37319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_dev dev;
37419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
37519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!search_type) {
37619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fprintf(stderr, "The lookup option requires a "
37719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				"search type specified using -t\n");
37819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			exit(1);
37919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
38019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		/* Load any additional devices not in the cache */
38119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		for (i = 0; i < numdev; i++)
38219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL);
38319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
38419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((dev = blkid_find_dev_with_tag(cache, search_type,
38519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project						   search_value))) {
38619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			print_tags(dev, show, numtag, output_format);
38719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			err = 0;
38819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
38919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* If we didn't specify a single device, show all available devices */
39019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	} else if (!numdev) {
39119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_dev_iterate	iter;
39219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_dev		dev;
39319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
39419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_probe_all(cache);
39519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
39619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		iter = blkid_dev_iterate_begin(cache);
39719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_dev_set_search(iter, search_type, search_value);
39819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		while (blkid_dev_next(iter, &dev) == 0) {
39919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			dev = blkid_verify(cache, dev);
40019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (!dev)
40119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				continue;
40219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			print_tags(dev, show, numtag, output_format);
40319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			err = 0;
40419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
40519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_dev_iterate_end(iter);
40619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Add all specified devices to cache (optionally display tags) */
40719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	} else for (i = 0; i < numdev; i++) {
40819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_dev dev = blkid_get_dev(cache, devices[i],
40919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project						  BLKID_DEV_NORMAL);
41019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
41119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (dev) {
4123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (search_type &&
4133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			    !blkid_dev_has_tag(dev, search_type,
41419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					       search_value))
41519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				continue;
41619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			print_tags(dev, show, numtag, output_format);
41719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			err = 0;
41819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
41919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
42019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
42119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectexit:
4223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	free(search_type);
4233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	free(search_value);
42419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_put_cache(cache);
42519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return err;
42619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
427