lsscsi: new applet
authorMarkus Gothe <nietzsche@lysator.liu.se>
Tue, 18 Apr 2017 17:25:49 +0000 (19:25 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Tue, 18 Apr 2017 17:26:26 +0000 (19:26 +0200)
function                                             old     new   delta
lsscsi_main                                            -     326    +326
applet_names                                        2613    2620      +7
applet_main                                         1512    1516      +4
applet_install_loc                                   189     190      +1
packed_usage                                       31566   31560      -6
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 3/1 up/down: 338/-6)            Total: 332 bytes

Signed-off-by: Markus Gothe <nietzsche@lysator.liu.se>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
miscutils/lsscsi.c [new file with mode: 0644]

diff --git a/miscutils/lsscsi.c b/miscutils/lsscsi.c
new file mode 100644 (file)
index 0000000..1521680
--- /dev/null
@@ -0,0 +1,123 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * lsscsi implementation for busybox
+ *
+ * Copyright (C) 2017 Markus Gothe <nietzsche@lysator.liu.se>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+//config:config LSSCSI
+//config:      bool "lsscsi"
+//config:      default y
+//config:      #select PLATFORM_LINUX
+//config:      help
+//config:        lsscsi is a utility for displaying information about SCSI buses in the
+//config:        system and devices connected to them.
+//config:
+//config:        This version uses sysfs (/sys/bus/scsi/devices) only.
+
+//applet:IF_LSSCSI(APPLET(lsscsi, BB_DIR_USR_BIN, BB_SUID_DROP))
+
+//kbuild:lib-$(CONFIG_LSSCSI) += lsscsi.o
+
+//usage:#define lsscsi_trivial_usage NOUSAGE_STR
+//usage:#define lsscsi_full_usage ""
+
+#include "libbb.h"
+
+static char *get_line(const char *filename, char *buf, unsigned *bufsize_p)
+{
+       unsigned bufsize = *bufsize_p;
+       ssize_t sz;
+
+       if ((int)(bufsize - 2) <= 0)
+               return buf;
+
+       sz = open_read_close(filename, buf, bufsize - 2);
+       if (sz < 0)
+               sz = 0;
+       buf[sz] = '\0';
+       trim(buf);
+
+       sz = strlen(buf) + 1;
+       bufsize -= sz;
+       buf += sz;
+       buf[0] = '\0';
+
+       *bufsize_p = bufsize;
+       return buf;
+}
+
+int lsscsi_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int lsscsi_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
+{
+       struct dirent *de;
+       DIR *dir;
+
+       xchdir("/sys/bus/scsi/devices");
+
+       dir = xopendir(".");
+       while ((de = readdir(dir)) != NULL) {
+               char buf[256];
+               char *ptr;
+               unsigned bufsize;
+               const char *vendor;
+               const char *type_str;
+               const char *type_name;
+               const char *model;
+               const char *rev;
+               unsigned type;
+
+               if (!isdigit(de->d_name[0]))
+                       continue;
+               if (!strchr(de->d_name, ':'))
+                       continue;
+               if (chdir(de->d_name) != 0)
+                       continue;
+
+               bufsize = sizeof(buf);
+               vendor = buf;
+               ptr = get_line("vendor", buf, &bufsize);
+               type_str = ptr;
+               ptr = get_line("type", ptr, &bufsize);
+               model = ptr;
+               ptr = get_line("model", ptr, &bufsize);
+               rev = ptr;
+               ptr = get_line("rev", ptr, &bufsize);
+
+               printf("[%s]\t", de->d_name);
+
+#define scsi_device_types \
+       "disk\0"    "tape\0"    "printer\0" "process\0" \
+       "worm\0"    "\0"        "scanner\0" "optical\0" \
+       "mediumx\0" "comms\0"   "\0"        "\0"        \
+       "storage\0" "enclosu\0" "sim dsk\0" "opti rd\0" \
+       "bridge\0"  "osd\0"     "adi\0"     "\0"        \
+       "\0"        "\0"        "\0"        "\0"        \
+       "\0"        "\0"        "\0"        "\0"        \
+       "\0"        "\0"        "wlun\0"    "no dev"
+               type = bb_strtou(type_str, NULL, 10);
+               if (errno
+                || type >= 0x20
+                || (type_name = nth_string(scsi_device_types, type))[0] == '\0'
+               ) {
+                       printf("(%s)\t", type_str);
+               } else {
+                       printf("%s\t", type_name);
+               }
+
+               printf("%s\t""%s\t""%s\n",
+                       vendor,
+                       model,
+                       rev
+               );
+               /* TODO: also output device column, e.g. "/dev/sdX" */
+
+               xchdir("..");
+       }
+
+       if (ENABLE_FEATURE_CLEAN_UP)
+               closedir(dir);
+
+       return EXIT_SUCCESS;
+}