maininit(): print machine UUID under seabios version message

There are users who would like to see the UUID at startup, and it probably
won't bother others.

Related RHBZ: 876250.

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
diff --git a/src/post.c b/src/post.c
index 3705c3b..f3b56b8 100644
--- a/src/post.c
+++ b/src/post.c
@@ -261,6 +261,9 @@
     // Run vga option rom
     vga_setup();
 
+    // SMBIOS tables and VGA console are ready, print UUID
+    display_uuid();
+
     // Do hardware initialization (if running synchronously)
     if (!CONFIG_THREADS || !CONFIG_THREAD_OPTIONROMS) {
         init_hw();
diff --git a/src/smbios.c b/src/smbios.c
index fc84aad..aaa99bc 100644
--- a/src/smbios.c
+++ b/src/smbios.c
@@ -521,3 +521,71 @@
     smbios_entry_point_init(max_struct_size, p - start, start, nr_structs);
     free(start);
 }
+
+void
+display_uuid(void)
+{
+    u32 addr, end;
+    u8 *uuid;
+    u8 empty_uuid[16] = { 0 };
+
+    if (SMBiosAddr == NULL)
+        return;
+
+    addr =        SMBiosAddr->structure_table_address;
+    end  = addr + SMBiosAddr->structure_table_length;
+
+    /* the following takes care of any initial wraparound too */
+    while (addr < end) {
+        const struct smbios_structure_header *hdr;
+
+        /* partial structure header */
+        if (end - addr < sizeof(struct smbios_structure_header))
+            return;
+
+        hdr = (struct smbios_structure_header *)addr;
+
+        /* partial structure */
+        if (end - addr < hdr->length)
+            return;
+
+        /* any Type 1 structure version will do that has the UUID */
+        if (hdr->type == 1 &&
+            hdr->length >= offsetof(struct smbios_type_1, uuid) + 16)
+            break;
+
+        /* done with formatted area, skip string-set */
+        addr += hdr->length;
+
+        while (end - addr >= 2 &&
+               (*(u8 *)addr     != '\0' ||
+                *(u8 *)(addr+1) != '\0'))
+            ++addr;
+
+        /* structure terminator not found */
+        if (end - addr < 2)
+            return;
+
+        addr += 2;
+    }
+
+    /* parsing finished, UUID not found */
+    if (addr == end)
+        return;
+
+    uuid = (u8 *)(addr + offsetof(struct smbios_type_1, uuid));
+    if (memcmp(uuid, empty_uuid, sizeof empty_uuid) == 0)
+        return;
+
+    printf("Machine UUID"
+             " %02x%02x%02x%02x"
+             "-%02x%02x"
+             "-%02x%02x"
+             "-%02x%02x"
+             "-%02x%02x%02x%02x%02x%02x\n"
+           , uuid[ 0], uuid[ 1], uuid[ 2], uuid[ 3]
+           , uuid[ 4], uuid[ 5]
+           , uuid[ 6], uuid[ 7]
+           , uuid[ 8], uuid[ 9]
+           , uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
+}
diff --git a/src/smbios.h b/src/smbios.h
index 9d54e80..5bf0392 100644
--- a/src/smbios.h
+++ b/src/smbios.h
@@ -165,4 +165,5 @@
     struct smbios_structure_header header;
 } PACKED;
 
+void display_uuid(void);
 #endif // smbios.h