]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemd-id128: add new verb to print GPT partitions UUIDs 14594/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 17 Jan 2020 10:34:13 +0000 (11:34 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 23 Jan 2020 22:32:13 +0000 (23:32 +0100)
docs/DISCOVERABLE_PARTITIONS.md
man/systemd-id128.xml
src/id128/id128.c
src/shared/gpt.c
src/shared/gpt.h
src/shared/id128-print.c
src/shared/id128-print.h

index 8b1a7b46e3ef0ffa3b2cc723ae6fd89f5729308a..f1537b89399a5e180fa7f22da917d9f4676f1927 100644 (file)
@@ -64,6 +64,9 @@ Other GPT type IDs might be used on Linux, for example to mark software RAID or
 LVM partitions. The definitions of those GPT types is outside of the scope of
 this specification.
 
+[systemd-id128(1)](http://www.freedesktop.org/software/systemd/man/systemd-i128.html)
+may be used to list those UUIDs.
+
 ## Partition Names
 
 For partitions of the types listed above it is recommended to use
index a5ab31ad6dfe5276e0e2221528a952fd19e14e67..747b703653209cc1f9df20d9f15eaea9464b4f6e 100644 (file)
     will be printed. This is available in systemd services. See
     <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
     </para>
+
+    <para>With <command>show</command>, well-known UUIDs are printed. When no arguments are specified, all
+    known UUIDs are shown. When arguments are specified, they must be the names or values of one or more
+    known UUIDs, which are then printed.</para>
   </refsect1>
 
   <refsect1>
index cd4d5414503bbbbb0b220972a96f4561da528ccf..de74bac2c07c242e8c908cf184234085f3a38cf0 100644 (file)
@@ -4,9 +4,12 @@
 #include <stdio.h>
 
 #include "alloc-util.h"
+#include "gpt.h"
 #include "id128-print.h"
 #include "main-func.h"
 #include "pretty-print.h"
+#include "strv.h"
+#include "format-table.h"
 #include "terminal-util.h"
 #include "util.h"
 #include "verbs.h"
@@ -63,6 +66,85 @@ static int verb_invocation_id(int argc, char **argv, void *userdata) {
         return id128_pretty_print(id, arg_mode);
 }
 
+static int show_one(Table **table, const char *name, sd_id128_t uuid, bool first) {
+        int r;
+
+        if (arg_mode == ID128_PRINT_PRETTY) {
+                _cleanup_free_ char *id = NULL;
+
+                id = strreplace(name, "-", "_");
+                if (!id)
+                        return log_oom();
+
+                ascii_strupper(id);
+
+                r = id128_pretty_print_sample(id, uuid);
+                if (r < 0)
+                        return r;
+                if (!first)
+                        puts("");
+                return 0;
+
+        } else {
+                if (!*table) {
+                        *table = table_new("name", "uuid");
+                        if (!*table)
+                                return log_oom();
+                        table_set_width(*table, 0);
+                }
+
+                return table_add_many(*table,
+                                      TABLE_STRING, name,
+                                      arg_mode == ID128_PRINT_ID128 ? TABLE_ID128 : TABLE_UUID,
+                                      uuid);
+        }
+}
+
+static int verb_show(int argc, char **argv, void *userdata) {
+        _cleanup_(table_unrefp) Table *table = NULL;
+        char **p;
+        int r;
+
+        argv = strv_skip(argv, 1);
+        if (strv_isempty(argv))
+                for (const GptPartitionType *e = gpt_partition_type_table; e->name; e++) {
+                        r = show_one(&table, e->name, e->uuid, e == gpt_partition_type_table);
+                        if (r < 0)
+                                return r;
+                }
+        else
+                STRV_FOREACH(p, argv) {
+                        sd_id128_t uuid;
+                        bool have_uuid;
+                        const char *id;
+
+                        /* Check if the argument is an actual UUID first */
+                        have_uuid = sd_id128_from_string(*p, &uuid) >= 0;
+
+                        if (have_uuid)
+                                id = gpt_partition_type_uuid_to_string(uuid) ?: "XYZ";
+                        else {
+                                r = gpt_partition_type_uuid_from_string(*p, &uuid);
+                                if (r < 0)
+                                        return log_error_errno(r, "Unknown identifier \"%s\".", *p);
+
+                                id = *p;
+                        }
+
+                        r = show_one(&table, id, uuid, p == argv);
+                        if (r < 0)
+                                return r;
+                }
+
+        if (table) {
+                r = table_print(table, NULL);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to print table: %m");
+        }
+
+        return 0;
+}
+
 static int help(void) {
         _cleanup_free_ char *link = NULL;
         int r;
@@ -74,10 +156,11 @@ static int help(void) {
         printf("%s [OPTIONS...] COMMAND\n\n"
                "%sGenerate and print 128bit identifiers.%s\n"
                "\nCommands:\n"
-               "  new                     Generate a new id128 string\n"
+               "  new                     Generate a new ID\n"
                "  machine-id              Print the ID of current machine\n"
                "  boot-id                 Print the ID of current boot\n"
                "  invocation-id           Print the ID of current invocation\n"
+               "  show [NAME]             Print one or more well-known IDs\n"
                "  help                    Show this help\n"
                "\nOptions:\n"
                "  -h --help               Show this help\n"
@@ -155,6 +238,7 @@ static int id128_main(int argc, char *argv[]) {
                 { "machine-id",     VERB_ANY, 1,        0,  verb_machine_id    },
                 { "boot-id",        VERB_ANY, 1,        0,  verb_boot_id       },
                 { "invocation-id",  VERB_ANY, 1,        0,  verb_invocation_id },
+                { "show",           VERB_ANY, VERB_ANY, 0,  verb_show          },
                 { "help",           VERB_ANY, VERB_ANY, 0,  verb_help          },
                 {}
         };
index 024f4db515bbb6ef42940e4c9511b30bf38dc30c..e62f21e889ced2fdb7c29e3c4693dc667bc6ab41 100644 (file)
@@ -3,12 +3,7 @@
 #include "gpt.h"
 #include "string-util.h"
 
-typedef struct GptPartitionType {
-        sd_id128_t uuid;
-        const char *name;
-} GptPartitionType;
-
-static const GptPartitionType gpt_partition_type_table[] = {
+const GptPartitionType gpt_partition_type_table[] = {
         { GPT_ROOT_X86,              "root-x86"              },
         { GPT_ROOT_X86_VERITY,       "root-x86-verity"       },
         { GPT_ROOT_X86_64,           "root-x86-64"           },
@@ -35,10 +30,11 @@ static const GptPartitionType gpt_partition_type_table[] = {
         { GPT_VAR,                   "var"                   },
         { GPT_TMP,                   "tmp"                   },
         { GPT_LINUX_GENERIC,         "linux-generic",        },
+        {}
 };
 
 const char *gpt_partition_type_uuid_to_string(sd_id128_t id) {
-        for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table); i++)
+        for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++)
                 if (sd_id128_equal(id, gpt_partition_type_table[i].uuid))
                         return gpt_partition_type_table[i].name;
 
@@ -64,7 +60,7 @@ int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret) {
         assert(s);
         assert(ret);
 
-        for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table); i++)
+        for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++)
                 if (streq(s, gpt_partition_type_table[i].name)) {
                         *ret = gpt_partition_type_table[i].uuid;
                         return 0;
index a07bd630172501927a72178d9f843f6e1f567e98..dcceb076d6e7b72ef7d12470914e62cb14ac2603 100644 (file)
@@ -73,3 +73,10 @@ const char *gpt_partition_type_uuid_to_string_harder(
                 sd_id128_t id,
                 char buffer[static ID128_UUID_STRING_MAX]);
 int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret);
+
+typedef struct GptPartitionType {
+        sd_id128_t uuid;
+        const char *name;
+} GptPartitionType;
+
+extern const GptPartitionType gpt_partition_type_table[];
index 356f41050786ce67558db18e618039287f50f8d4..6237424e8243aec252eb4f33e973b22e32b6e08c 100644 (file)
 #include "pretty-print.h"
 #include "terminal-util.h"
 
-int id128_pretty_print(sd_id128_t id, Id128PrettyPrintMode mode) {
-        _cleanup_free_ char *man_link = NULL, *mod_link = NULL;
+int id128_pretty_print_sample(const char *name, sd_id128_t id) {
+       _cleanup_free_ char *man_link = NULL, *mod_link = NULL;
         const char *on, *off;
         unsigned i;
 
-        assert(mode >= 0);
-        assert(mode < _ID128_PRETTY_PRINT_MODE_MAX);
-
-        if (mode == ID128_PRINT_ID128) {
-                printf(SD_ID128_FORMAT_STR "\n",
-                       SD_ID128_FORMAT_VAL(id));
-                return 0;
-        } else if (mode == ID128_PRINT_UUID) {
-                printf(SD_ID128_UUID_FORMAT_STR "\n",
-                       SD_ID128_FORMAT_VAL(id));
-                return 0;
-        }
-
         on = ansi_highlight();
         off = ansi_normal();
 
@@ -42,24 +29,41 @@ int id128_pretty_print(sd_id128_t id, Id128PrettyPrintMode mode) {
                "As UUID:\n"
                "%s" SD_ID128_UUID_FORMAT_STR "%s\n\n"
                "As %s macro:\n"
-               "%s#define XYZ SD_ID128_MAKE(",
+               "%s#define %s SD_ID128_MAKE(",
                on, SD_ID128_FORMAT_VAL(id), off,
                on, SD_ID128_FORMAT_VAL(id), off,
                man_link,
-               on);
+               on, name);
         for (i = 0; i < 16; i++)
                 printf("%02x%s", id.bytes[i], i != 15 ? "," : "");
         printf(")%s\n\n", off);
 
         printf("As Python constant:\n"
                ">>> import %s\n"
-               ">>> %sXYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')%s\n",
+               ">>> %s%s = uuid.UUID('" SD_ID128_FORMAT_STR "')%s\n",
                mod_link,
-               on, SD_ID128_FORMAT_VAL(id), off);
+               on, name, SD_ID128_FORMAT_VAL(id), off);
 
         return 0;
 }
 
+
+int id128_pretty_print(sd_id128_t id, Id128PrettyPrintMode mode) {
+        assert(mode >= 0);
+        assert(mode < _ID128_PRETTY_PRINT_MODE_MAX);
+
+        if (mode == ID128_PRINT_ID128) {
+                printf(SD_ID128_FORMAT_STR "\n",
+                       SD_ID128_FORMAT_VAL(id));
+                return 0;
+        } else if (mode == ID128_PRINT_UUID) {
+                printf(SD_ID128_UUID_FORMAT_STR "\n",
+                       SD_ID128_FORMAT_VAL(id));
+                return 0;
+        } else
+                return id128_pretty_print_sample("XYZ", id);
+}
+
 int id128_print_new(Id128PrettyPrintMode mode) {
         sd_id128_t id;
         int r;
index 1dc5b6aae57b00b7d6b91ce3bc15fa425e718822..247558231c9a26c1eaeb382d0df03236817ebb65 100644 (file)
@@ -14,5 +14,6 @@ typedef enum Id128PrettyPrintMode {
         _ID128_PRETTY_PRINT_MODE_INVALID = -1
 } Id128PrettyPrintMode;
 
+int id128_pretty_print_sample(const char *name, sd_id128_t id);
 int id128_pretty_print(sd_id128_t id, Id128PrettyPrintMode mode);
 int id128_print_new(Id128PrettyPrintMode mode);