mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 18:58:40 +00:00
Compare commits
2 commits
e48f3674c7
...
ed5f10eb7d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed5f10eb7d | ||
|
|
a01a34b7f2 |
7 changed files with 481 additions and 40 deletions
106
docs/usage/commands/lsblk.md
Normal file
106
docs/usage/commands/lsblk.md
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
# lsblk
|
||||||
|
|
||||||
|
`lsblk` lists the block devices detected by BoredOS, including whole disks and their partitions.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```sh
|
||||||
|
lsblk
|
||||||
|
lsblk /dev/sda
|
||||||
|
lsblk -r
|
||||||
|
lsblk --json
|
||||||
|
```
|
||||||
|
|
||||||
|
## Output
|
||||||
|
|
||||||
|
By default, `lsblk` prints a compact tree view:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/dev/sda 2 GB disk
|
||||||
|
└─ sda1 2 GB part FAT32 BOREDOS
|
||||||
|
```
|
||||||
|
|
||||||
|
Fields shown by the default output:
|
||||||
|
|
||||||
|
- device name, such as `/dev/sda` or `sda1`
|
||||||
|
- human-readable size, such as `512 MB` or `2 GB`
|
||||||
|
- device type, either `disk` or `part`
|
||||||
|
- filesystem type, currently `FAT32` when detected
|
||||||
|
- volume label when available
|
||||||
|
- `[ESP]` flag for EFI System Partitions
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Mount points are not shown yet because BoredOS does not currently expose mountpoint information through the disk info syscall.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
| Option | Description |
|
||||||
|
| :--- | :--- |
|
||||||
|
| `-r` | Print raw output without tree characters. |
|
||||||
|
| `--json` | Print machine-readable JSON output. |
|
||||||
|
| `/dev/DEVICE` | Show only one disk or partition. |
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
List all block devices:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
lsblk
|
||||||
|
```
|
||||||
|
|
||||||
|
Example output:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/dev/sda 2 GB disk
|
||||||
|
└─ sda1 2 GB part FAT32 BOREDOS
|
||||||
|
/dev/sdb 16 GB disk
|
||||||
|
```
|
||||||
|
|
||||||
|
Show one disk and its partitions:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
lsblk /dev/sda
|
||||||
|
```
|
||||||
|
|
||||||
|
Example output:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/dev/sda 2 GB disk
|
||||||
|
└─ sda1 2 GB part FAT32 BOREDOS
|
||||||
|
```
|
||||||
|
|
||||||
|
Print raw output for scripts:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
lsblk -r
|
||||||
|
```
|
||||||
|
|
||||||
|
Example output:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/dev/sda 2GB disk
|
||||||
|
/dev/sda1 2GB part FAT32 BOREDOS
|
||||||
|
```
|
||||||
|
|
||||||
|
Print JSON output:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
lsblk --json
|
||||||
|
```
|
||||||
|
|
||||||
|
Example output:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"devices":[{"name":"/dev/sda","size":"2 GB","type":"disk","fstype":"","label":"","flags":[],"children":[{"name":"/dev/sda1","size":"2 GB","type":"part","fstype":"FAT32","label":"BOREDOS","flags":[]}]}]}
|
||||||
|
```
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
`lsblk` reads disk metadata through the disk syscalls exposed by BoredOS:
|
||||||
|
|
||||||
|
- `sys_disk_get_count()` gets the number of registered block devices.
|
||||||
|
- `sys_disk_get_info()` reads each device's name, size, type, FAT32 status, label, and flags.
|
||||||
|
|
||||||
|
The command treats non-partition entries as parent disks, then groups partition entries under the matching disk name. For example, `sda1` is displayed under `/dev/sda`.
|
||||||
|
|
||||||
|
Sizes are calculated from sector counts using 512-byte sectors, then formatted as `KB`, `MB`, or `GB`.
|
||||||
|
|
@ -53,6 +53,7 @@ Below are some of the most used commands available in `/bin`:
|
||||||
| `rm` | Remove a file. |
|
| `rm` | Remove a file. |
|
||||||
| `mkdir` | Create a new directory. |
|
| `mkdir` | Create a new directory. |
|
||||||
| `man` | View the manual for a specific command (e.g., `man ls`). |
|
| `man` | View the manual for a specific command (e.g., `man ls`). |
|
||||||
|
| `lsblk` | List block devices and partitions with size, type, filesystem, label, and flags. |
|
||||||
| `sysfetch` | Display system and hardware information. |
|
| `sysfetch` | Display system and hardware information. |
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,32 @@ static int dm_strlen(const char *s) {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dm_copy_fat_label(char *dst, const uint8_t *src) {
|
||||||
|
int end = 11;
|
||||||
|
while (end > 0 && src[end - 1] == ' ') end--;
|
||||||
|
for (int i = 0; i < end && i < 31; i++) dst[i] = (char)src[i];
|
||||||
|
dst[end < 31 ? end : 31] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void disk_load_fat32_label(Disk *disk) {
|
||||||
|
uint8_t *buffer;
|
||||||
|
FAT32_BootSector *bpb;
|
||||||
|
char label[32];
|
||||||
|
|
||||||
|
if (!disk || !disk->read_sector) return;
|
||||||
|
|
||||||
|
buffer = (uint8_t*)kmalloc(512);
|
||||||
|
if (!buffer) return;
|
||||||
|
|
||||||
|
if (disk->read_sector(disk, 0, buffer) == 0 && buffer[510] == 0x55 && buffer[511] == 0xAA) {
|
||||||
|
bpb = (FAT32_BootSector*)buffer;
|
||||||
|
dm_copy_fat_label(label, bpb->volume_label);
|
||||||
|
if (label[0]) dm_strcpy(disk->label, label);
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
// === ATA Definitions (Legacy IDE PIO — kept as fallback) ===
|
// === ATA Definitions (Legacy IDE PIO — kept as fallback) ===
|
||||||
|
|
||||||
#define ATA_PRIMARY_IO 0x1F0
|
#define ATA_PRIMARY_IO 0x1F0
|
||||||
|
|
@ -387,6 +413,8 @@ void disk_register_partition(Disk *parent, uint32_t lba_offset, uint32_t sector_
|
||||||
part->is_partition = true;
|
part->is_partition = true;
|
||||||
part->registered = true;
|
part->registered = true;
|
||||||
|
|
||||||
|
if (is_fat32) disk_load_fat32_label(part);
|
||||||
|
|
||||||
disks[disk_count++] = part;
|
disks[disk_count++] = part;
|
||||||
|
|
||||||
serial_write("[DISK] Registered /dev/");
|
serial_write("[DISK] Registered /dev/");
|
||||||
|
|
@ -567,6 +595,7 @@ static void parse_mbr_partitions(Disk *disk) {
|
||||||
serial_write("\n");
|
serial_write("\n");
|
||||||
disk->is_fat32 = true;
|
disk->is_fat32 = true;
|
||||||
disk->partition_lba_offset = 0;
|
disk->partition_lba_offset = 0;
|
||||||
|
disk_load_fat32_label(disk);
|
||||||
} else if (part_count == 0) {
|
} else if (part_count == 0) {
|
||||||
serial_write("[DISK] No MBR partitions found on /dev/");
|
serial_write("[DISK] No MBR partitions found on /dev/");
|
||||||
serial_write(disk->devname);
|
serial_write(disk->devname);
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,13 @@ static void mf_strncpy(char *dst, const char *src, int n) {
|
||||||
while (i < n) { dst[i++] = ' '; } /* FAT labels are space-padded */
|
while (i < n) { dst[i++] = ' '; } /* FAT labels are space-padded */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mf_set_disk_label(Disk *disk, const char *label) {
|
||||||
|
int end = 11;
|
||||||
|
while (end > 0 && label[end - 1] == ' ') end--;
|
||||||
|
for (int i = 0; i < end && i < 31; i++) disk->label[i] = label[i];
|
||||||
|
disk->label[end < 31 ? end : 31] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// On-disk BPB structures
|
// On-disk BPB structures
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) {
|
typedef struct __attribute__((packed)) {
|
||||||
|
|
@ -269,13 +276,15 @@ int mkfs_fat32_format(Disk *disk, uint32_t sector_count, const char *label) {
|
||||||
|
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
|
|
||||||
|
disk->is_fat32 = true;
|
||||||
|
mf_set_disk_label(disk, upper_label);
|
||||||
|
|
||||||
serial_write("[MKFS] FAT32 formatted: ");
|
serial_write("[MKFS] FAT32 formatted: ");
|
||||||
serial_write(disk->devname);
|
serial_write(disk->devname);
|
||||||
serial_write(" label=");
|
serial_write(" label=");
|
||||||
char lb[12];
|
char lb[12];
|
||||||
mf_memcpy(lb, vol_label, 11);
|
mf_memcpy(lb, upper_label, 11);
|
||||||
lb[11] = 0;
|
lb[11] = 0;
|
||||||
for (int i = 0; i < 11; i++) lb[i] = (lb[i] >= 'a' && lb[i] <= 'z') ? lb[i] - 32 : lb[i];
|
|
||||||
for (int i = 10; i >= 0 && lb[i] == ' '; i--) lb[i] = 0;
|
for (int i = 10; i >= 0 && lb[i] == ' '; i--) lb[i] = 0;
|
||||||
serial_write(lb);
|
serial_write(lb);
|
||||||
serial_write(" spc=");
|
serial_write(" spc=");
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ int main(int argc, char **argv) {
|
||||||
printf("date - Print current date and time\n");
|
printf("date - Print current date and time\n");
|
||||||
printf("uptime - Print system uptime\n");
|
printf("uptime - Print system uptime\n");
|
||||||
printf("meminfo - Print memory information\n");
|
printf("meminfo - Print memory information\n");
|
||||||
|
printf("lsblk - List block devices and partitions\n");
|
||||||
printf("cowsay [msg] - Fun cow says something\n");
|
printf("cowsay [msg] - Fun cow says something\n");
|
||||||
printf("beep - Make a beep sound\n");
|
printf("beep - Make a beep sound\n");
|
||||||
printf("reboot - Reboot the system\n");
|
printf("reboot - Reboot the system\n");
|
||||||
|
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
|
||||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
|
||||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
|
||||||
// BOREDOS_APP_DESC: Manual pages CLI utility
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <syscall.h>
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
if (argc < 2) {
|
|
||||||
printf("What manual page do you want?\nExample: man ls\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char path[128];
|
|
||||||
printf("Manual for: %s\n", argv[1]);
|
|
||||||
printf("---------------------------\n");
|
|
||||||
|
|
||||||
strcpy(path, "/Library/man/");
|
|
||||||
strcat(path, argv[1]);
|
|
||||||
strcat(path, ".txt");
|
|
||||||
|
|
||||||
int fd = sys_open(path, "r");
|
|
||||||
if (fd < 0) {
|
|
||||||
printf("No manual entry for %s\n", argv[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char buffer[4096];
|
|
||||||
int bytes;
|
|
||||||
while ((bytes = sys_read(fd, buffer, sizeof(buffer))) > 0) {
|
|
||||||
sys_write(1, buffer, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
sys_close(fd);
|
|
||||||
printf("\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
332
src/userland/sys/lsblk.c
Normal file
332
src/userland/sys/lsblk.c
Normal file
|
|
@ -0,0 +1,332 @@
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syscall.h>
|
||||||
|
|
||||||
|
#define LSBLK_MAX_DISKS 32
|
||||||
|
#define LSBLK_SECTOR_SIZE 512ULL
|
||||||
|
#define LSBLK_KB 1024ULL
|
||||||
|
#define LSBLK_MB (1024ULL * 1024ULL)
|
||||||
|
#define LSBLK_GB (1024ULL * 1024ULL * 1024ULL)
|
||||||
|
|
||||||
|
static int streq(const char *a, const char *b) {
|
||||||
|
return strcmp(a, b) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int starts_with(const char *s, const char *prefix) {
|
||||||
|
while (*prefix) {
|
||||||
|
if (*s++ != *prefix++) return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *display_label(const disk_info_t *d) {
|
||||||
|
if (!d->label[0]) return "";
|
||||||
|
if (streq(d->label, "Unknown Partition")) return "";
|
||||||
|
if (streq(d->label, "FAT32 Partition")) return "";
|
||||||
|
if (streq(d->label, "EFI System Partition")) return "EFI";
|
||||||
|
return d->label;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *device_name_arg(const char *arg) {
|
||||||
|
if (starts_with(arg, "/dev/")) return arg + 5;
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void format_size(uint64_t bytes, char *out, size_t out_len, int compact) {
|
||||||
|
const char *sep = compact ? "" : " ";
|
||||||
|
uint64_t unit = 1;
|
||||||
|
const char *suffix = "B";
|
||||||
|
|
||||||
|
if (bytes >= LSBLK_GB) {
|
||||||
|
unit = LSBLK_GB;
|
||||||
|
suffix = "GB";
|
||||||
|
} else if (bytes >= LSBLK_MB) {
|
||||||
|
unit = LSBLK_MB;
|
||||||
|
suffix = "MB";
|
||||||
|
} else if (bytes >= LSBLK_KB) {
|
||||||
|
unit = LSBLK_KB;
|
||||||
|
suffix = "KB";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unit == 1) {
|
||||||
|
snprintf(out, out_len, "%llu%s%s", (unsigned long long)bytes, sep, suffix);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t whole = bytes / unit;
|
||||||
|
uint64_t rem = bytes % unit;
|
||||||
|
uint64_t tenth = (rem * 10ULL + unit / 2ULL) / unit;
|
||||||
|
|
||||||
|
if (tenth >= 10ULL) {
|
||||||
|
whole++;
|
||||||
|
tenth = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tenth == 0) {
|
||||||
|
snprintf(out, out_len, "%llu%s%s", (unsigned long long)whole, sep, suffix);
|
||||||
|
} else {
|
||||||
|
snprintf(out, out_len, "%llu.%llu%s%s", (unsigned long long)whole, (unsigned long long)tenth, sep, suffix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t disk_size_bytes(const disk_info_t *d) {
|
||||||
|
return (uint64_t)d->total_sectors * LSBLK_SECTOR_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_child_partition(const disk_info_t *disk, const disk_info_t *part) {
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (disk->is_partition || !part->is_partition) return 0;
|
||||||
|
|
||||||
|
len = strlen(disk->devname);
|
||||||
|
if (strncmp(part->devname, disk->devname, len) != 0) return 0;
|
||||||
|
|
||||||
|
return part->devname[len] >= '0' && part->devname[len] <= '9';
|
||||||
|
}
|
||||||
|
|
||||||
|
static int child_count(const disk_info_t *disk, disk_info_t *items, int count) {
|
||||||
|
int children = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (is_child_partition(disk, &items[i])) children++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_tree_device(const disk_info_t *d, const char *branch) {
|
||||||
|
char size[24];
|
||||||
|
const char *type = d->is_partition ? "part" : "disk";
|
||||||
|
|
||||||
|
format_size(disk_size_bytes(d), size, sizeof(size), 0);
|
||||||
|
|
||||||
|
if (d->is_partition) {
|
||||||
|
const char *label = display_label(d);
|
||||||
|
if (branch[0]) printf("%s %-8s %8s %s", branch, d->devname, size, type);
|
||||||
|
else printf("/dev/%-8s %8s %s", d->devname, size, type);
|
||||||
|
if (d->is_fat32) printf(" FAT32");
|
||||||
|
if (label[0]) printf(" %s", label);
|
||||||
|
if (d->is_esp) printf(" [ESP]");
|
||||||
|
printf("\n");
|
||||||
|
} else {
|
||||||
|
printf("/dev/%-8s %8s %s\n", d->devname, size, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_tree_disk(const disk_info_t *disk, disk_info_t *items, int count) {
|
||||||
|
int children = child_count(disk, items, count);
|
||||||
|
int seen = 0;
|
||||||
|
|
||||||
|
print_tree_device(disk, "");
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (!is_child_partition(disk, &items[i])) continue;
|
||||||
|
seen++;
|
||||||
|
print_tree_device(&items[i], seen == children ? "└─" : "├─");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_raw_device(const disk_info_t *d) {
|
||||||
|
char size[24];
|
||||||
|
|
||||||
|
format_size(disk_size_bytes(d), size, sizeof(size), 1);
|
||||||
|
printf("/dev/%s %s %s", d->devname, size, d->is_partition ? "part" : "disk");
|
||||||
|
|
||||||
|
if (d->is_partition) {
|
||||||
|
const char *label = display_label(d);
|
||||||
|
if (d->is_fat32) printf(" FAT32");
|
||||||
|
if (label[0]) printf(" %s", label);
|
||||||
|
if (d->is_esp) printf(" ESP");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_raw_disk(const disk_info_t *disk, disk_info_t *items, int count) {
|
||||||
|
print_raw_device(disk);
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (is_child_partition(disk, &items[i])) print_raw_device(&items[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void json_string(const char *s) {
|
||||||
|
putchar('"');
|
||||||
|
|
||||||
|
while (*s) {
|
||||||
|
if (*s == '"' || *s == '\\') {
|
||||||
|
putchar('\\');
|
||||||
|
putchar(*s);
|
||||||
|
} else if (*s == '\n') {
|
||||||
|
printf("\\n");
|
||||||
|
} else {
|
||||||
|
putchar(*s);
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
putchar('"');
|
||||||
|
}
|
||||||
|
|
||||||
|
static void json_device_fields(const disk_info_t *d) {
|
||||||
|
char size[24];
|
||||||
|
char name[24];
|
||||||
|
|
||||||
|
format_size(disk_size_bytes(d), size, sizeof(size), 0);
|
||||||
|
snprintf(name, sizeof(name), "/dev/%s", d->devname);
|
||||||
|
|
||||||
|
printf("\"name\":");
|
||||||
|
json_string(name);
|
||||||
|
printf(",\"size\":");
|
||||||
|
json_string(size);
|
||||||
|
printf(",\"type\":");
|
||||||
|
json_string(d->is_partition ? "part" : "disk");
|
||||||
|
printf(",\"fstype\":");
|
||||||
|
json_string(d->is_fat32 ? "FAT32" : "");
|
||||||
|
printf(",\"label\":");
|
||||||
|
json_string(display_label(d));
|
||||||
|
printf(",\"flags\":[");
|
||||||
|
if (d->is_esp) json_string("ESP");
|
||||||
|
printf("]");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_json_partition(const disk_info_t *d) {
|
||||||
|
printf("{");
|
||||||
|
json_device_fields(d);
|
||||||
|
printf("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_json_disk(const disk_info_t *disk, disk_info_t *items, int count) {
|
||||||
|
int seen = 0;
|
||||||
|
|
||||||
|
printf("{");
|
||||||
|
json_device_fields(disk);
|
||||||
|
printf(",\"children\":[");
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (!is_child_partition(disk, &items[i])) continue;
|
||||||
|
if (seen > 0) printf(",");
|
||||||
|
print_json_partition(&items[i]);
|
||||||
|
seen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("]}");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int load_disks(disk_info_t *items, int max) {
|
||||||
|
int total = sys_disk_get_count();
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < total && count < max; i++) {
|
||||||
|
if (sys_disk_get_info(i, &items[count]) == 0) count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usage(void) {
|
||||||
|
printf("Usage: lsblk [-r] [--json] [/dev/DEVICE]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
disk_info_t items[LSBLK_MAX_DISKS];
|
||||||
|
const char *filter = NULL;
|
||||||
|
int raw = 0;
|
||||||
|
int json = 0;
|
||||||
|
int count;
|
||||||
|
int printed = 0;
|
||||||
|
|
||||||
|
for (int i = 1; i < argc; i++) {
|
||||||
|
if (streq(argv[i], "-r")) {
|
||||||
|
raw = 1;
|
||||||
|
} else if (streq(argv[i], "--json")) {
|
||||||
|
json = 1;
|
||||||
|
} else if (streq(argv[i], "-h") || streq(argv[i], "--help")) {
|
||||||
|
usage();
|
||||||
|
return 0;
|
||||||
|
} else if (argv[i][0] == '-') {
|
||||||
|
printf("lsblk: unknown option: %s\n", argv[i]);
|
||||||
|
usage();
|
||||||
|
return 1;
|
||||||
|
} else if (!filter) {
|
||||||
|
filter = device_name_arg(argv[i]);
|
||||||
|
} else {
|
||||||
|
printf("lsblk: only one device filter is supported\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (raw && json) {
|
||||||
|
printf("lsblk: -r and --json cannot be used together\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
count = load_disks(items, LSBLK_MAX_DISKS);
|
||||||
|
|
||||||
|
if (json) {
|
||||||
|
printf("{\"devices\":[");
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (items[i].is_partition) continue;
|
||||||
|
if (filter && !streq(items[i].devname, filter)) continue;
|
||||||
|
if (printed > 0) printf(",");
|
||||||
|
print_json_disk(&items[i], items, count);
|
||||||
|
printed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter && printed == 0) {
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (!items[i].is_partition || !streq(items[i].devname, filter)) continue;
|
||||||
|
print_json_partition(&items[i]);
|
||||||
|
printed++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("]}\n");
|
||||||
|
} else if (raw) {
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (items[i].is_partition) continue;
|
||||||
|
if (filter && !streq(items[i].devname, filter)) continue;
|
||||||
|
print_raw_disk(&items[i], items, count);
|
||||||
|
printed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter && printed == 0) {
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (!items[i].is_partition || !streq(items[i].devname, filter)) continue;
|
||||||
|
print_raw_device(&items[i]);
|
||||||
|
printed++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (items[i].is_partition) continue;
|
||||||
|
if (filter && !streq(items[i].devname, filter)) continue;
|
||||||
|
print_tree_disk(&items[i], items, count);
|
||||||
|
printed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter && printed == 0) {
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
if (!items[i].is_partition || !streq(items[i].devname, filter)) continue;
|
||||||
|
print_tree_device(&items[i], "");
|
||||||
|
printed++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (printed == 0 && !json) {
|
||||||
|
if (filter) printf("lsblk: /dev/%s not found\n", filter);
|
||||||
|
else printf("lsblk: no block devices found\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (printed == 0 && filter) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue