master xplshn/aruu / cmd / extra / lsblk.c
  1/* See LICENSE file for copyright and license details. */
  2#include "util.h"
  3#include "diskutil.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(int name_pad, const char *name, int major, int minor, const char *size, const char *type, const char *fstype, const char *mountpoint)
 17{
 18	char linebuf[512];
 19	int len;
 20
 21	len = snprintf(linebuf, sizeof(linebuf), "%-*s %3d:%-3d %6s %-4s %-8s %s",
 22	               name_pad, name,
 23	               major, minor,
 24	               size,
 25	               type,
 26	               fstype,
 27	               mountpoint);
 28
 29	/* trim trailing spaces */
 30	while (len > 0 && linebuf[len - 1] == ' ') {
 31		linebuf[len - 1] = '\0';
 32		len--;
 33	}
 34	printf("%s\n", linebuf);
 35}
 36
 37// ?man lsblk: list block devices
 38// ?man lsblk lists information about all available block devices in a tree-like layout
 39int
 40main(int argc, char *argv[])
 41{
 42	struct BlockDevInfo *list, *curr, *part;
 43	char namebuf[64];
 44	char hdrbuf[512];
 45	int max_len = 4;
 46	int hdrlen;
 47
 48	ARGBEGIN {
 49	default:
 50		usage();
 51	} ARGEND
 52
 53	if (argc > 0)
 54		usage();
 55
 56	list = blockdev_get_list();
 57	if (!list)
 58		return 1;
 59
 60	/* calculate maximum display width of the name column */
 61	for (curr = list; curr; curr = curr->next) {
 62		int len = strlen(curr->name);
 63		if (len > max_len)
 64			max_len = len;
 65		for (part = curr->parts; part; part = part->next) {
 66			len = 2 + (int)strlen(part->name);
 67			if (len > max_len)
 68				max_len = len;
 69		}
 70	}
 71
 72	hdrlen = snprintf(hdrbuf, sizeof(hdrbuf), "%-*s %-7s %6s %-4s %-8s %s",
 73	                  max_len, "NAME", "MAJ:MIN", "SIZE", "TYPE", "FSTYPE", "MOUNTPOINT");
 74	while (hdrlen > 0 && hdrbuf[hdrlen - 1] == ' ') {
 75		hdrbuf[hdrlen - 1] = '\0';
 76		hdrlen--;
 77	}
 78	printf("%s\n", hdrbuf);
 79
 80	for (curr = list; curr; curr = curr->next) {
 81		print_line(max_len,
 82		           curr->name,
 83		           curr->major, curr->minor,
 84		           humansize(curr->size),
 85		           curr->type,
 86		           curr->fstype[0] ? curr->fstype : "",
 87		           curr->mountpoint[0] ? curr->mountpoint : "");
 88
 89		for (part = curr->parts; part; part = part->next) {
 90			int is_last = (part->next == NULL);
 91			snprintf(namebuf, sizeof(namebuf), "%s%s", is_last ? "└─" : "├─", part->name);
 92			print_line(max_len + 4,
 93			           namebuf,
 94			           part->major, part->minor,
 95			           humansize(part->size),
 96			           part->type,
 97			           part->fstype[0] ? part->fstype : "",
 98			           part->mountpoint[0] ? part->mountpoint : "");
 99		}
100	}
101
102	blockdev_free_list(list);
103	return 0;
104}