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