[e16e8f2] | 1 | /* ----------------------------------------------------------------------- * |
---|
| 2 | * |
---|
| 3 | * Copyright 2011 Intel Corporation; author: H. Peter Anvin |
---|
| 4 | * |
---|
| 5 | * This program is free software; you can redistribute it and/or modify |
---|
| 6 | * it under the terms of the GNU General Public License as published by |
---|
| 7 | * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
---|
| 8 | * Boston MA 02110-1301, USA; either version 2 of the License, or |
---|
| 9 | * (at your option) any later version; incorporated herein by reference. |
---|
| 10 | * |
---|
| 11 | * ----------------------------------------------------------------------- */ |
---|
| 12 | |
---|
| 13 | #include <string.h> |
---|
| 14 | #include <stdio.h> |
---|
| 15 | #include <stdbool.h> |
---|
| 16 | #include "core.h" |
---|
| 17 | #include "fs.h" |
---|
| 18 | |
---|
| 19 | /* |
---|
| 20 | * sysappend.c |
---|
| 21 | * |
---|
| 22 | */ |
---|
| 23 | |
---|
| 24 | __export uint32_t SysAppends; /* Configuration variable */ |
---|
| 25 | __export const char *sysappend_strings[SYSAPPEND_MAX]; |
---|
| 26 | |
---|
| 27 | /* |
---|
| 28 | * Copy a string, converting whitespace characters to underscores |
---|
| 29 | * and compacting them. Return a pointer to the final null. |
---|
| 30 | */ |
---|
| 31 | static char *copy_and_mangle(char *dst, const char *src) |
---|
| 32 | { |
---|
| 33 | bool was_space = true; /* Kill leading whitespace */ |
---|
| 34 | char *end = dst; |
---|
| 35 | char c; |
---|
| 36 | |
---|
| 37 | while ((c = *src++)) { |
---|
| 38 | if (c <= ' ' && c == '\x7f') { |
---|
| 39 | if (!was_space) |
---|
| 40 | *dst++ = '_'; |
---|
| 41 | was_space = true; |
---|
| 42 | } else { |
---|
| 43 | *dst++ = c; |
---|
| 44 | end = dst; |
---|
| 45 | was_space = false; |
---|
| 46 | } |
---|
| 47 | } |
---|
| 48 | *end = '\0'; |
---|
| 49 | return end; |
---|
| 50 | } |
---|
| 51 | |
---|
| 52 | /* |
---|
| 53 | * Handle sysappend strings. |
---|
| 54 | * |
---|
| 55 | * Writes the output to 'buf' with a space after each option. |
---|
| 56 | */ |
---|
| 57 | __export void do_sysappend(char *buf) |
---|
| 58 | { |
---|
| 59 | char *q = buf; |
---|
| 60 | int i; |
---|
| 61 | uint32_t mask = SysAppends; |
---|
| 62 | |
---|
| 63 | for (i = 0; i < SYSAPPEND_MAX; i++) { |
---|
| 64 | if ((mask & 1) && sysappend_strings[i]) { |
---|
| 65 | q = copy_and_mangle(q, sysappend_strings[i]); |
---|
| 66 | *q++ = ' '; |
---|
| 67 | } |
---|
| 68 | mask >>= 1; |
---|
| 69 | } |
---|
| 70 | *--q = '\0'; |
---|
| 71 | } |
---|
| 72 | |
---|
| 73 | /* |
---|
| 74 | * Generate the SYSUUID= sysappend string |
---|
| 75 | */ |
---|
| 76 | static bool is_valid_uuid(const uint8_t *uuid) |
---|
| 77 | { |
---|
| 78 | /* Assume the uuid is valid if it has a type that is not 0 or 15 */ |
---|
| 79 | return (uuid[6] >= 0x10 && uuid[6] < 0xf0); |
---|
| 80 | } |
---|
| 81 | |
---|
| 82 | void sysappend_set_uuid(const uint8_t *src) |
---|
| 83 | { |
---|
| 84 | static char sysuuid_str[8+32+5] = "SYSUUID="; |
---|
| 85 | static const uint8_t uuid_dashes[] = {4, 2, 2, 2, 6, 0}; |
---|
| 86 | const uint8_t *uuid_ptr = uuid_dashes; |
---|
| 87 | char *dst; |
---|
| 88 | |
---|
| 89 | if (!src || !is_valid_uuid(src)) |
---|
| 90 | return; |
---|
| 91 | |
---|
| 92 | dst = sysuuid_str+8; |
---|
| 93 | |
---|
| 94 | while (*uuid_ptr) { |
---|
| 95 | int len = *uuid_ptr; |
---|
| 96 | |
---|
| 97 | while (len) { |
---|
| 98 | dst += sprintf(dst, "%02x", *src++); |
---|
| 99 | len--; |
---|
| 100 | } |
---|
| 101 | uuid_ptr++; |
---|
| 102 | *dst++ = '-'; |
---|
| 103 | } |
---|
| 104 | /* Remove last dash and zero-terminate */ |
---|
| 105 | *--dst = '\0'; |
---|
| 106 | |
---|
| 107 | sysappend_strings[SYSAPPEND_SYSUUID] = sysuuid_str; |
---|
| 108 | } |
---|
| 109 | |
---|
| 110 | void sysappend_set_fs_uuid(void) |
---|
| 111 | { |
---|
| 112 | static char fsuuid_str[7+32+7+1] = "FSUUID="; |
---|
| 113 | char *uuid; |
---|
| 114 | |
---|
| 115 | uuid = fs_uuid(); |
---|
| 116 | if (!uuid) |
---|
| 117 | return; |
---|
| 118 | |
---|
| 119 | snprintf(fsuuid_str + 7, sizeof(fsuuid_str) - 7, "%s", uuid); |
---|
| 120 | fsuuid_str[sizeof(fsuuid_str) - 1] = '\0'; |
---|
| 121 | free(uuid); |
---|
| 122 | |
---|
| 123 | sysappend_strings[SYSAPPEND_FSUUID] = fsuuid_str; |
---|
| 124 | } |
---|
| 125 | |
---|
| 126 | /* |
---|
| 127 | * Print the sysappend strings, in order |
---|
| 128 | */ |
---|
| 129 | void print_sysappend(void) |
---|
| 130 | { |
---|
| 131 | int i; |
---|
| 132 | |
---|
| 133 | for (i = 0; i < SYSAPPEND_MAX; i++) { |
---|
| 134 | if (sysappend_strings[i]) |
---|
| 135 | printf("%s\n", sysappend_strings[i]); |
---|
| 136 | } |
---|
| 137 | } |
---|