master xplshn/aruu / cmd / extra / lsblk.c
  1/* See LICENSE file for copyright and license details. */
  2#include "diskutil.h"
  3#include "util.h"
  4
  5#include <stdio.h>
  6#include <stdlib.h>
  7#include <string.h>
  8
  9static void
 10usage(void)
 11{
 12  eprintf("usage: %s\n", argv0);
 13}
 14
 15static void
 16print_line(
 17    int         name_pad,
 18    const char *name,
 19    int         major,
 20    int         minor,
 21    const char *size,
 22    const char *type,
 23    const char *fstype,
 24    const char *mountpoint
 25)
 26{
 27  char linebuf[512];
 28  int  len;
 29
 30  len = snprintf(
 31      linebuf,
 32      sizeof(linebuf),
 33      "%-*s %3d:%-3d %6s %-4s %-8s %s",
 34      name_pad,
 35      name,
 36      major,
 37      minor,
 38      size,
 39      type,
 40      fstype,
 41      mountpoint
 42  );
 43
 44  /* trim trailing spaces */
 45  while (len > 0 && linebuf[len - 1] == ' ') {
 46    linebuf[len - 1] = '\0';
 47    len--;
 48  }
 49  printf("%s\n", linebuf);
 50}
 51
 52// ?man lsblk: list block devices
 53// ?man lsblk lists information about all available block devices in a tree-like
 54// layout
 55int
 56main(int argc, char *argv[])
 57{
 58  struct BlockDevInfo *list, *curr, *part;
 59  char                 namebuf[64];
 60  char                 hdrbuf[512];
 61  int                  max_len = 4;
 62  int                  hdrlen;
 63
 64  ARGBEGIN
 65  {
 66    default:
 67      usage();
 68  }
 69  ARGEND
 70
 71  if (argc > 0)
 72    usage();
 73
 74  list = blockdev_get_list();
 75  if (!list)
 76    return 1;
 77
 78  /* calculate maximum display width of the name column */
 79  for (curr = list; curr; curr = curr->next) {
 80    int len = strlen(curr->name);
 81    if (len > max_len)
 82      max_len = len;
 83    for (part = curr->parts; part; part = part->next) {
 84      len = 2 + (int)strlen(part->name);
 85      if (len > max_len)
 86        max_len = len;
 87    }
 88  }
 89
 90  hdrlen = snprintf(
 91      hdrbuf,
 92      sizeof(hdrbuf),
 93      "%-*s %-7s %6s %-4s %-8s %s",
 94      max_len,
 95      "NAME",
 96      "MAJ:MIN",
 97      "SIZE",
 98      "TYPE",
 99      "FSTYPE",
100      "MOUNTPOINT"
101  );
102  while (hdrlen > 0 && hdrbuf[hdrlen - 1] == ' ') {
103    hdrbuf[hdrlen - 1] = '\0';
104    hdrlen--;
105  }
106  printf("%s\n", hdrbuf);
107
108  for (curr = list; curr; curr = curr->next) {
109    if (strncmp(curr->name, "ram", 3) == 0)
110      continue;
111
112    print_line(
113        max_len,
114        curr->name,
115        curr->major,
116        curr->minor,
117        humansize(curr->size),
118        curr->type,
119        curr->fstype[0] ? curr->fstype : "",
120        curr->mountpoint[0] ? curr->mountpoint : ""
121    );
122
123    for (part = curr->parts; part; part = part->next) {
124      int is_last = (part->next == NULL);
125      snprintf(namebuf, sizeof(namebuf), "%s%s", is_last ? "└─" : "├─", part->name);
126      print_line(
127          max_len + 4,
128          namebuf,
129          part->major,
130          part->minor,
131          humansize(part->size),
132          part->type,
133          part->fstype[0] ? part->fstype : "",
134          part->mountpoint[0] ? part->mountpoint : ""
135      );
136    }
137  }
138
139  blockdev_free_list(list);
140  return 0;
141}