master xplshn/aruu / cmd / extra / blkid.c
  1/* See LICENSE file for copyright and license details. */
  2#include "diskutil.h"
  3#include "util.h"
  4
  5#include <fcntl.h>
  6#include <stdio.h>
  7#include <stdlib.h>
  8#include <string.h>
  9#include <unistd.h>
 10
 11static char *oflag = "full";
 12static char *sflag = NULL;
 13static int   Uflag = 0;
 14static int   Lflag = 0;
 15
 16static void
 17usage(void)
 18{
 19  eprintf("usage: %s [-o format] [-s tag] [-U] [-L] [device ...]\n", argv0);
 20}
 21
 22static void
 23print_tag(const char *devname, const char *tag, const char *value)
 24{
 25  (void)devname;
 26  if (sflag && strcasecmp(sflag, tag) != 0)
 27    return;
 28
 29  if (strcmp(oflag, "value") == 0) {
 30    printf("%s\n", value);
 31  } else if (strcmp(oflag, "export") == 0) {
 32    printf("%s=%s\n", tag, value);
 33  } else {
 34    printf(" %s=\"%s\"", tag, value);
 35  }
 36}
 37
 38static int
 39do_blkid(const char *path)
 40{
 41  struct BlockDev dev;
 42  char            type[64]   = {0};
 43  char            label[256] = {0};
 44  char            uuid[256]  = {0};
 45  int             res;
 46
 47  if (blockdev_open(&dev, path, 0) < 0)
 48    return -1;
 49
 50  res = blockdev_detect_fs(&dev, type, sizeof(type), label, sizeof(label), uuid, sizeof(uuid));
 51  if (res == 0) {
 52    if (Uflag || Lflag) {
 53      if (Uflag) {
 54        printf("%s\n", uuid);
 55      } else {
 56        printf("%s\n", label);
 57      }
 58    } else {
 59      if (strcmp(oflag, "export") == 0) {
 60        printf("DEVNAME=%s\n", path);
 61      } else if (strcmp(oflag, "value") != 0) {
 62        printf("%s:", path);
 63      }
 64
 65      if (label[0])
 66        print_tag(path, "LABEL", label);
 67      if (uuid[0])
 68        print_tag(path, "UUID", uuid);
 69      print_tag(path, "TYPE", type);
 70
 71      if (strcmp(oflag, "full") == 0)
 72        printf("\n");
 73    }
 74  }
 75
 76  blockdev_close(&dev);
 77  return res == 0 ? 0 : -2;
 78}
 79
 80// ?man blkid: print block device attributes
 81// ?man arguments: [device ...]
 82// ?man blkid locates and prints attributes (such as uuid, volume label, and
 83// filesystem type) ?man of block devices or partition images
 84int
 85main(int argc, char *argv[])
 86{
 87  int ret = 0;
 88
 89  ARGBEGIN
 90  {
 91    // ?man -o:specify output format (full, value, export)
 92    case 'o':
 93      oflag = EARGF(usage());
 94      break;
 95    // ?man -s:only show specified tag (e.g. UUID, LABEL, TYPE)
 96    case 's':
 97      sflag = EARGF(usage());
 98      break;
 99    // ?man -U:print UUID only
100    case 'U':
101      Uflag = 1;
102      break;
103    // ?man -L:print volume label only
104    case 'L':
105      Lflag = 1;
106      break;
107    default:
108      usage();
109  }
110  ARGEND
111
112  if (argc > 0) {
113    for (; *argv; argv++) {
114      if (do_blkid(*argv) < 0)
115        ret = 1;
116    }
117  } else {
118    struct BlockDevInfo *list = blockdev_get_list();
119    struct BlockDevInfo *curr;
120    if (!list) {
121      return 1;
122    }
123    for (curr = list; curr; curr = curr->next) {
124      do_blkid(curr->path);
125      struct BlockDevInfo *part;
126      for (part = curr->parts; part; part = part->next) {
127        do_blkid(part->path);
128      }
129    }
130    blockdev_free_list(list);
131  }
132
133  if (fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>"))
134    ret = 2;
135
136  return ret;
137}