1e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o/* 2e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * blkid.c - User command-line interface for libblkid 3e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * 4e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * Copyright (C) 2001 Andreas Dilger 5e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * 6e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * %Begin-Header% 7e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * This file may be redistributed under the terms of the 8e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * GNU Lesser General Public License. 9e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * %End-Header% 10e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o */ 11e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 12e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <stdio.h> 137a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o#include <stdlib.h> 143d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#include <unistd.h> 1548e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o#include <string.h> 163d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#ifdef HAVE_TERMIOS_H 173d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#include <termios.h> 183d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#endif 193d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#ifdef HAVE_TERMIO_H 203d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#include <termio.h> 213d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#endif 223d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#ifdef HAVE_SYS_IOCTL_H 233d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#include <sys/ioctl.h> 243d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#endif 25e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#ifdef HAVE_GETOPT_H 26e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <getopt.h> 27e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#else 28a63830271b5143416981f1171503e10bd6b6056fMatthias Andreeextern int getopt(int argc, char * const argv[], const char *optstring); 29e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'oextern char *optarg; 30e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'oextern int optind; 31e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#endif 32e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 338927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o#define OUTPUT_VALUE_ONLY 0x0001 348927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o#define OUTPUT_DEVICE_ONLY 0x0002 353d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#define OUTPUT_PRETTY_LIST 0x0004 368927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o 373d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#include "ext2fs/ext2fs.h" 38e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include "blkid/blkid.h" 39e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 407a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'oconst char *progname = "blkid"; 417a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o 427a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'ostatic void print_version(FILE *out) 43e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{ 44544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o fprintf(out, "%s %s (%s)\n", progname, BLKID_VERSION, BLKID_DATE); 45e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o} 46e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 477a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'ostatic void usage(int error) 48e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{ 49e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o FILE *out = error ? stderr : stdout; 50e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 51e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o print_version(out); 52e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o fprintf(out, 533d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o "usage:\t%s [-c <file>] [-ghlLv] [-o format] " 543d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o "[-s <tag>] [-t <token>]\n [-w <file>] [dev ...]\n" 55e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o "\t-c\tcache file (default: /etc/blkid.tab, /dev/null = none)\n" 56e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o "\t-h\tprint this usage message and exit\n" 5746100e3f6e21a5eb8fbb4d843d4c7fee368b31f5Theodore Ts'o "\t-g\tgarbage collect the blkid cache\n" 58e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o "\t-s\tshow specified tag(s) (default show all tags)\n" 59e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o "\t-t\tfind device with a specific token (NAME=value pair)\n" 60ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o "\t-l\tlookup the the first device with arguments specified by -t\n" 61e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o "\t-v\tprint version and exit\n" 62e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o "\t-w\twrite cache to different file (/dev/null = no write)\n" 63e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o "\tdev\tspecify device(s) to probe (default: all devices)\n", 64e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o progname); 65e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o exit(error); 66e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o} 67e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 68f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o/* 69f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o * This function does "safe" printing. It will convert non-printable 70f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o * ASCII characters using '^' and M- notation. 71f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o */ 72f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'ostatic void safe_print(const char *cp, int len) 73f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o{ 74f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o unsigned char ch; 75f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o 76f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o if (len < 0) 77f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o len = strlen(cp); 78f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o 79f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o while (len--) { 80f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o ch = *cp++; 81f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o if (ch > 128) { 82f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o fputs("M-", stdout); 83f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o ch -= 128; 84f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o } 85f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o if ((ch < 32) || (ch == 0x7f)) { 86f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o fputc('^', stdout); 87f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */ 88f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o } 89f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o fputc(ch, stdout); 90f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o } 91f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o} 92f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o 933d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'ostatic int get_terminal_width(void) 943d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o{ 953d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#ifdef TIOCGSIZE 9636f4c4080206f5ad4df37c3cb77f20df2f062266Theodore Ts'o struct ttysize t_win; 973d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#endif 983d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#ifdef TIOCGWINSZ 9936f4c4080206f5ad4df37c3cb77f20df2f062266Theodore Ts'o struct winsize w_win; 1003d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#endif 1013d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o const char *cp; 1023d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 1033d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#ifdef TIOCGSIZE 10436f4c4080206f5ad4df37c3cb77f20df2f062266Theodore Ts'o if (ioctl (0, TIOCGSIZE, &t_win) == 0) 10536f4c4080206f5ad4df37c3cb77f20df2f062266Theodore Ts'o return (t_win.ts_cols); 1063d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#endif 1073d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#ifdef TIOCGWINSZ 10836f4c4080206f5ad4df37c3cb77f20df2f062266Theodore Ts'o if (ioctl (0, TIOCGWINSZ, &w_win) == 0) 10936f4c4080206f5ad4df37c3cb77f20df2f062266Theodore Ts'o return (w_win.ws_col); 1103d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o#endif 1113d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o cp = getenv("COLUMNS"); 1123d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (cp) 1133d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o return strtol(cp, NULL, 10); 1143d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o return 80; 1153d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o} 1163d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 1173d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'ostatic int pretty_print_word(const char *str, int max_len, 1183d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o int left_len, int overflow_nl) 1193d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o{ 1203d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o int len = strlen(str) + left_len; 1213d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o int ret = 0; 1223d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 1233d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o fputs(str, stdout); 1243d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (overflow_nl && len > max_len) { 1253d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o fputc('\n', stdout); 1263d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o len = 0; 1273d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o } else if (len > max_len) 1283d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o ret = len - max_len; 1293d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o do 1303d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o fputc(' ', stdout); 1313d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o while (len++ < max_len); 1323d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o return ret; 1333d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o} 1343d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 1353d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'ostatic void pretty_print_line(const char *device, const char *fs_type, 1363d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o const char *label, const char *mtpt, 1373d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o const char *uuid) 1383d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o{ 1393d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o static int device_len = 10, fs_type_len = 7; 1403d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o static int label_len = 8, mtpt_len = 14; 1413d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o static int term_width = -1; 1423d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o int len, w; 1433d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 1443d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (term_width < 0) 1453d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o term_width = get_terminal_width(); 1463d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 1473d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (term_width > 80) { 1483d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o term_width -= 80; 1493d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o w = term_width / 10; 1503d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (w > 8) 1513d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o w = 8; 1523d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o term_width -= 2*w; 1533d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o label_len += w; 1543d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o fs_type_len += w; 1553d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o w = term_width/2; 1563d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o device_len += w; 1573d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o mtpt_len +=w; 1583d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o } 1593d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 1603d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o len = pretty_print_word(device, device_len, 0, 1); 1613d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o len = pretty_print_word(fs_type, fs_type_len, len, 0); 1623d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o len = pretty_print_word(label, label_len, len, 0); 1633d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o len = pretty_print_word(mtpt, mtpt_len, len, 0); 1643d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o fputs(uuid, stdout); 1653d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o fputc('\n', stdout); 1663d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o} 1673d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 1683d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'ostatic void pretty_print_dev(blkid_dev dev) 1693d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o{ 1703d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o blkid_tag_iterate iter; 1713d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o const char *type, *value, *devname; 1723d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o const char *uuid = "", *fs_type = "", *label = ""; 1733d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o int len, mount_flags; 1743d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o char mtpt[80]; 1753d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o errcode_t retval; 1763d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 1773d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (dev == NULL) { 1783d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o pretty_print_line("device", "fs_type", "label", 1793d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o "mount point", "UUID"); 1803d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o for (len=get_terminal_width()-1; len > 0; len--) 1813d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o fputc('-', stdout); 1823d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o fputc('\n', stdout); 1833d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o return; 1843d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o } 1853d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 1863d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o devname = blkid_dev_devname(dev); 1873d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (access(devname, F_OK)) 1883d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o return; 1893d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 1903d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o /* Get the uuid, label, type */ 1913d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o iter = blkid_tag_iterate_begin(dev); 1923d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o while (blkid_tag_next(iter, &type, &value) == 0) { 1933d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (!strcmp(type, "UUID")) 1943d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o uuid = value; 1953d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (!strcmp(type, "TYPE")) 1963d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o fs_type = value; 1973d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (!strcmp(type, "LABEL")) 1983d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o label = value; 1993d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o } 2003d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o blkid_tag_iterate_end(iter); 2013d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 2023d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o /* Get the mount point */ 2033d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o mtpt[0] = 0; 2043d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o retval = ext2fs_check_mount_point(devname, &mount_flags, 2053d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o mtpt, sizeof(mtpt)); 2063d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (retval == 0) { 2073d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (mount_flags & EXT2_MF_MOUNTED) { 2083d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (!mtpt[0]) 2093d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o strcpy(mtpt, "(mounted, mtpt unknown)"); 2103d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o } else if (mount_flags & EXT2_MF_BUSY) 2113d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o strcpy(mtpt, "(in use)"); 2123d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o else 2133d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o strcpy(mtpt, "(not mounted)"); 2143d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o } 2153d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 2163d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o pretty_print_line(devname, fs_type, label, mtpt, uuid); 2173d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o} 2183d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 2198927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'ostatic void print_tags(blkid_dev dev, char *show[], int numtag, int output) 220e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{ 2217a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o blkid_tag_iterate iter; 2227a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o const char *type, *value; 223ed1b33e8fb310641684d68a177c940b58f2f529dTheodore Ts'o int i, first = 1; 224e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 225e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o if (!dev) 226e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o return; 227e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 2283d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (output & OUTPUT_PRETTY_LIST) { 2293d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o pretty_print_dev(dev); 2303d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o return; 2313d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o } 2323d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 2338927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o if (output & OUTPUT_DEVICE_ONLY) { 2348927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o printf("%s\n", blkid_dev_devname(dev)); 2358927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o return; 2368927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o } 2378927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o 2387a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o iter = blkid_tag_iterate_begin(dev); 2397a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o while (blkid_tag_next(iter, &type, &value) == 0) { 2407a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o if (numtag && show) { 2417a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o for (i=0; i < numtag; i++) 2427a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o if (!strcmp(type, show[i])) 2437a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o break; 2447a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o if (i >= numtag) 2457a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o continue; 2467a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o } 247f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o if (output & OUTPUT_VALUE_ONLY) { 248f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o fputs(value, stdout); 249f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o fputc('\n', stdout); 250f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o } else { 251f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o if (first) { 252f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o printf("%s: ", blkid_dev_devname(dev)); 253f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o first = 0; 254f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o } 255f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o fputs(type, stdout); 256f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o fputs("=\"", stdout); 257f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o safe_print(value, -1); 258f8efcda2db612f6b6d33dc1a6ff78a1c048608f4Theodore Ts'o fputs("\" ", stdout); 259e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o } 260e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o } 2617a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o blkid_tag_iterate_end(iter); 262e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 2638927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o if (!first && !(output & OUTPUT_VALUE_ONLY)) 264e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o printf("\n"); 265e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o} 266e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 267e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'oint main(int argc, char **argv) 268e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{ 2697a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o blkid_cache cache = NULL; 270e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o char *devices[128] = { NULL, }; 271e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o char *show[128] = { NULL, }; 2727a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o char *search_type = NULL, *search_value = NULL; 273e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o char *read = NULL; 274e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o char *write = NULL; 275544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o unsigned int numdev = 0, numtag = 0; 276e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o int version = 0; 277e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o int err = 4; 278544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o unsigned int i; 2798927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o int output_format = 0; 28046100e3f6e21a5eb8fbb4d843d4c7fee368b31f5Theodore Ts'o int lookup = 0, gc = 0; 2810af8c33be075d7a989993bf2c159c640418b7ed4Theodore Ts'o int c; 282e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 2833d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o while ((c = getopt (argc, argv, "c:f:ghlLo:s:t:w:v")) != EOF) 284e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o switch (c) { 285e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o case 'c': 286e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o if (optarg && !*optarg) 287e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o read = NULL; 288e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o else 289e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o read = optarg; 290e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o if (!write) 291e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o write = read; 292e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o break; 293ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o case 'l': 294ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o lookup++; 295ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o break; 2963d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o case 'L': 2973d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o output_format = OUTPUT_PRETTY_LIST; 2983d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o break; 29946100e3f6e21a5eb8fbb4d843d4c7fee368b31f5Theodore Ts'o case 'g': 30046100e3f6e21a5eb8fbb4d843d4c7fee368b31f5Theodore Ts'o gc = 1; 30146100e3f6e21a5eb8fbb4d843d4c7fee368b31f5Theodore Ts'o break; 3028927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o case 'o': 3038927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o if (!strcmp(optarg, "value")) 3048927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o output_format = OUTPUT_VALUE_ONLY; 3058927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o else if (!strcmp(optarg, "device")) 3068927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o output_format = OUTPUT_DEVICE_ONLY; 3073d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o else if (!strcmp(optarg, "list")) 3083d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o output_format = OUTPUT_PRETTY_LIST; 3098927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o else if (!strcmp(optarg, "full")) 3108927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o output_format = 0; 3118927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o else { 3123d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o fprintf(stderr, "Invalid output format %s. " 3133d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o "Choose from value,\n\t" 3143d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o "device, list, or full\n", optarg); 3158927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o exit(1); 3168927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o } 3178927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o break; 318e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o case 's': 319e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o if (numtag >= sizeof(show) / sizeof(*show)) { 320e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o fprintf(stderr, "Too many tags specified\n"); 321e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o usage(err); 322e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o } 323e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o show[numtag++] = optarg; 324e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o break; 325e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o case 't': 3267a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o if (search_type) { 327e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o fprintf(stderr, "Can only search for " 328e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o "one NAME=value pair\n"); 329e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o usage(err); 330e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o } 3317a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o if (blkid_parse_tag_string(optarg, 3327a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o &search_type, 3337a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o &search_value)) { 334e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o fprintf(stderr, "-t needs NAME=value pair\n"); 335e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o usage(err); 336e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o } 337e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o break; 338e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o case 'v': 339e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o version = 1; 340e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o break; 341e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o case 'w': 342e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o if (optarg && !*optarg) 343e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o write = NULL; 344e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o else 345e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o write = optarg; 346e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o break; 347e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o case 'h': 348e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o err = 0; 349e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o default: 350e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o usage(err); 351e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o } 352e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 353e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o while (optind < argc) 354e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o devices[numdev++] = argv[optind++]; 355e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 356e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o if (version) { 357e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o print_version(stdout); 358e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o goto exit; 359e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o } 360e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 36150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o if (blkid_get_cache(&cache, read) < 0) 362e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o goto exit; 363e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 364e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o err = 2; 36546100e3f6e21a5eb8fbb4d843d4c7fee368b31f5Theodore Ts'o if (gc) { 36646100e3f6e21a5eb8fbb4d843d4c7fee368b31f5Theodore Ts'o blkid_gc_cache(cache); 3673d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o goto exit; 3683d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o } 3693d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (output_format & OUTPUT_PRETTY_LIST) 3703d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o pretty_print_dev(NULL); 3713d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o 3723d05802f925239f516f05b048809281e9e13b3a2Theodore Ts'o if (lookup) { 373ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o blkid_dev dev; 374ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o 375ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o if (!search_type) { 376ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o fprintf(stderr, "The lookup option requires a " 377ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o "search type specified using -t\n"); 378ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o exit(1); 379ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o } 380ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o /* Load any additional devices not in the cache */ 381ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o for (i = 0; i < numdev; i++) 382ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL); 383ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o 384ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o if ((dev = blkid_find_dev_with_tag(cache, search_type, 385ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o search_value))) { 386ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o print_tags(dev, show, numtag, output_format); 387ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o err = 0; 388ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o } 389e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o /* If we didn't specify a single device, show all available devices */ 390ed6acfa337ca74912079b85196cf1263f6daf1a2Theodore Ts'o } else if (!numdev) { 3917a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o blkid_dev_iterate iter; 3927a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o blkid_dev dev; 393e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 39450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o blkid_probe_all(cache); 395e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 3967a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o iter = blkid_dev_iterate_begin(cache); 397c37543df2f58f454c29fece5997bd0e9d6ee7533Theodore Ts'o blkid_dev_set_search(iter, search_type, search_value); 3987a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o while (blkid_dev_next(iter, &dev) == 0) { 39918d12963335b04a402d097af1d714e8708805adaTheodore Ts'o dev = blkid_verify(cache, dev); 40018d12963335b04a402d097af1d714e8708805adaTheodore Ts'o if (!dev) 40118d12963335b04a402d097af1d714e8708805adaTheodore Ts'o continue; 4028927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o print_tags(dev, show, numtag, output_format); 403e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o err = 0; 404e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o } 4057a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o blkid_dev_iterate_end(iter); 406e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o /* Add all specified devices to cache (optionally display tags) */ 407e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o } else for (i = 0; i < numdev; i++) { 40898999c399d563c248728bf217467a788cb0c1aadTheodore Ts'o blkid_dev dev = blkid_get_dev(cache, devices[i], 40950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o BLKID_DEV_NORMAL); 410e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 411e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o if (dev) { 412efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o if (search_type && 413efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o !blkid_dev_has_tag(dev, search_type, 414c37543df2f58f454c29fece5997bd0e9d6ee7533Theodore Ts'o search_value)) 41518d12963335b04a402d097af1d714e8708805adaTheodore Ts'o continue; 4168927998f8229a103037ba5f49abe30c620ce322cTheodore Ts'o print_tags(dev, show, numtag, output_format); 417e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o err = 0; 418e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o } 419e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o } 420e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o 421e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'oexit: 42245e338f5332a54295893dba2e32cc093d1316f60Jim Meyering free(search_type); 42345e338f5332a54295893dba2e32cc093d1316f60Jim Meyering free(search_value); 42450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o blkid_put_cache(cache); 425e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o return err; 426e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o} 427