blkid.c revision 8927998f8229a103037ba5f49abe30c620ce322c
1/* 2 * blkid.c - User command-line interface for libblkid 3 * 4 * Copyright (C) 2001 Andreas Dilger 5 * 6 * %Begin-Header% 7 * This file may be redistributed under the terms of the 8 * GNU Lesser General Public License. 9 * %End-Header% 10 */ 11 12#include <stdio.h> 13#include <stdlib.h> 14#include <string.h> 15#ifdef HAVE_GETOPT_H 16#include <getopt.h> 17#else 18extern char *optarg; 19extern int optind; 20#endif 21 22#define OUTPUT_VALUE_ONLY 0x0001 23#define OUTPUT_DEVICE_ONLY 0x0002 24 25#include "blkid/blkid.h" 26 27const char *progname = "blkid"; 28 29static void print_version(FILE *out) 30{ 31 fprintf(out, "%s %s (%s)\n", progname, BLKID_VERSION, BLKID_DATE); 32} 33 34static void usage(int error) 35{ 36 FILE *out = error ? stderr : stdout; 37 38 print_version(out); 39 fprintf(out, 40 "usage:\t%s [-c <file>] [-h] [-o format] " 41 "[-p] [-s <tag>] [-t <token>]\n [-v] [-w <file>] [dev ...]\n" 42 "\t-c\tcache file (default: /etc/blkid.tab, /dev/null = none)\n" 43 "\t-h\tprint this usage message and exit\n" 44 "\t-s\tshow specified tag(s) (default show all tags)\n" 45 "\t-t\tfind device with a specific token (NAME=value pair)\n" 46 "\t-v\tprint version and exit\n" 47 "\t-w\twrite cache to different file (/dev/null = no write)\n" 48 "\tdev\tspecify device(s) to probe (default: all devices)\n", 49 progname); 50 exit(error); 51} 52 53static void print_tags(blkid_dev dev, char *show[], int numtag, int output) 54{ 55 blkid_tag_iterate iter; 56 const char *type, *value; 57 int i, first = 1; 58 59 if (!dev) 60 return; 61 62 if (output & OUTPUT_DEVICE_ONLY) { 63 printf("%s\n", blkid_dev_devname(dev)); 64 return; 65 } 66 67 iter = blkid_tag_iterate_begin(dev); 68 while (blkid_tag_next(iter, &type, &value) == 0) { 69 if (numtag && show) { 70 for (i=0; i < numtag; i++) 71 if (!strcmp(type, show[i])) 72 break; 73 if (i >= numtag) 74 continue; 75 } 76 if (first && !(output & OUTPUT_VALUE_ONLY)) { 77 printf("%s: ", blkid_dev_devname(dev)); 78 first = 0; 79 } 80 if ((output & OUTPUT_VALUE_ONLY)) 81 printf("%s\n", value); 82 else 83 printf("%s=\"%s\" ", type, value); 84 } 85 blkid_tag_iterate_end(iter); 86 87 if (!first && !(output & OUTPUT_VALUE_ONLY)) 88 printf("\n"); 89} 90 91int main(int argc, char **argv) 92{ 93 blkid_cache cache = NULL; 94 char *devices[128] = { NULL, }; 95 char *show[128] = { NULL, }; 96 char *search_type = NULL, *search_value = NULL; 97 char *read = NULL; 98 char *write = NULL; 99 unsigned int numdev = 0, numtag = 0; 100 int version = 0; 101 int err = 4; 102 unsigned int i; 103 int output_format = 0; 104 char c; 105 106 while ((c = getopt (argc, argv, "c:f:ho:ps:t:w:v")) != EOF) 107 switch (c) { 108 case 'c': 109 if (optarg && !*optarg) 110 read = NULL; 111 else 112 read = optarg; 113 if (!write) 114 write = read; 115 break; 116 case 'o': 117 if (!strcmp(optarg, "value")) 118 output_format = OUTPUT_VALUE_ONLY; 119 else if (!strcmp(optarg, "device")) 120 output_format = OUTPUT_DEVICE_ONLY; 121 else if (!strcmp(optarg, "full")) 122 output_format = 0; 123 else { 124 fprintf(stderr, "Invalid output format %s. Chose from value, device, or full\n", optarg); 125 exit(1); 126 } 127 break; 128 case 's': 129 if (numtag >= sizeof(show) / sizeof(*show)) { 130 fprintf(stderr, "Too many tags specified\n"); 131 usage(err); 132 } 133 show[numtag++] = optarg; 134 break; 135 case 't': 136 if (search_type) { 137 fprintf(stderr, "Can only search for " 138 "one NAME=value pair\n"); 139 usage(err); 140 } 141 if (blkid_parse_tag_string(optarg, 142 &search_type, 143 &search_value)) { 144 fprintf(stderr, "-t needs NAME=value pair\n"); 145 usage(err); 146 } 147 break; 148 case 'v': 149 version = 1; 150 break; 151 case 'w': 152 if (optarg && !*optarg) 153 write = NULL; 154 else 155 write = optarg; 156 break; 157 case 'h': 158 err = 0; 159 default: 160 usage(err); 161 } 162 163 while (optind < argc) 164 devices[numdev++] = argv[optind++]; 165 166 if (version) { 167 print_version(stdout); 168 goto exit; 169 } 170 171 if (blkid_get_cache(&cache, read) < 0) 172 goto exit; 173 174 err = 2; 175 /* If looking for a specific NAME=value pair, print only that */ 176 if (search_type) { 177 blkid_dev dev; 178 179 /* Load any additional devices not in the cache */ 180 for (i = 0; i < numdev; i++) 181 blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL); 182 183 if ((dev = blkid_find_dev_with_tag(cache, search_type, 184 search_value))) { 185 print_tags(dev, show, numtag, output_format); 186 err = 0; 187 } 188 /* If we didn't specify a single device, show all available devices */ 189 } else if (!numdev) { 190 blkid_dev_iterate iter; 191 blkid_dev dev; 192 193 blkid_probe_all(cache); 194 195 iter = blkid_dev_iterate_begin(cache); 196 while (blkid_dev_next(iter, &dev) == 0) { 197 print_tags(dev, show, numtag, output_format); 198 err = 0; 199 } 200 blkid_dev_iterate_end(iter); 201 /* Add all specified devices to cache (optionally display tags) */ 202 } else for (i = 0; i < numdev; i++) { 203 blkid_dev dev = blkid_get_dev(cache, devices[i], 204 BLKID_DEV_NORMAL); 205 206 if (dev) { 207 print_tags(dev, show, numtag, output_format); 208 err = 0; 209 } 210 } 211 212exit: 213 if (search_type) 214 free(search_type); 215 if (search_value) 216 free(search_value); 217 blkid_put_cache(cache); 218 return err; 219} 220