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 | } |
---|