| /* ----------------------------------------------------------------------- * |
| * |
| * Copyright 2011 Intel Corporation; author: H. Peter Anvin |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
| * Boston MA 02110-1301, USA; either version 2 of the License, or |
| * (at your option) any later version; incorporated herein by reference. |
| * |
| * ----------------------------------------------------------------------- */ |
| |
| #include <string.h> |
| #include <stdio.h> |
| #include <stdbool.h> |
| #include "core.h" |
| #include "fs.h" |
| |
| /* |
| * sysappend.c |
| * |
| */ |
| |
| __export uint32_t SysAppends; /* Configuration variable */ |
| __export const char *sysappend_strings[SYSAPPEND_MAX]; |
| |
| /* |
| * Copy a string, converting whitespace characters to underscores |
| * and compacting them. Return a pointer to the final null. |
| */ |
| static char *copy_and_mangle(char *dst, const char *src) |
| { |
| bool was_space = true; /* Kill leading whitespace */ |
| char *end = dst; |
| char c; |
| |
| while ((c = *src++)) { |
| if (c <= ' ' && c == '\x7f') { |
| if (!was_space) |
| *dst++ = '_'; |
| was_space = true; |
| } else { |
| *dst++ = c; |
| end = dst; |
| was_space = false; |
| } |
| } |
| *end = '\0'; |
| return end; |
| } |
| |
| /* |
| * Handle sysappend strings. |
| * |
| * Writes the output to 'buf' with a space after each option. |
| */ |
| __export void do_sysappend(char *buf) |
| { |
| char *q = buf; |
| int i; |
| uint32_t mask = SysAppends; |
| |
| for (i = 0; i < SYSAPPEND_MAX; i++) { |
| if ((mask & 1) && sysappend_strings[i]) { |
| q = copy_and_mangle(q, sysappend_strings[i]); |
| *q++ = ' '; |
| } |
| mask >>= 1; |
| } |
| *--q = '\0'; |
| } |
| |
| /* |
| * Generate the SYSUUID= sysappend string |
| */ |
| static bool is_valid_uuid(const uint8_t *uuid) |
| { |
| /* Assume the uuid is valid if it has a type that is not 0 or 15 */ |
| return (uuid[6] >= 0x10 && uuid[6] < 0xf0); |
| } |
| |
| void sysappend_set_uuid(const uint8_t *src) |
| { |
| static char sysuuid_str[8+32+5] = "SYSUUID="; |
| static const uint8_t uuid_dashes[] = {4, 2, 2, 2, 6, 0}; |
| const uint8_t *uuid_ptr = uuid_dashes; |
| char *dst; |
| |
| if (!src || !is_valid_uuid(src)) |
| return; |
| |
| dst = sysuuid_str+8; |
| |
| while (*uuid_ptr) { |
| int len = *uuid_ptr; |
| |
| while (len) { |
| dst += sprintf(dst, "%02x", *src++); |
| len--; |
| } |
| uuid_ptr++; |
| *dst++ = '-'; |
| } |
| /* Remove last dash and zero-terminate */ |
| *--dst = '\0'; |
| |
| sysappend_strings[SYSAPPEND_SYSUUID] = sysuuid_str; |
| } |
| |
| void sysappend_set_fs_uuid(void) |
| { |
| static char fsuuid_str[7+32+7+1] = "FSUUID="; |
| char *uuid; |
| |
| uuid = fs_uuid(); |
| if (!uuid) |
| return; |
| |
| snprintf(fsuuid_str + 7, sizeof(fsuuid_str) - 7, "%s", uuid); |
| fsuuid_str[sizeof(fsuuid_str) - 1] = '\0'; |
| free(uuid); |
| |
| sysappend_strings[SYSAPPEND_FSUUID] = fsuuid_str; |
| } |
| |
| /* |
| * Print the sysappend strings, in order |
| */ |
| void print_sysappend(void) |
| { |
| int i; |
| |
| for (i = 0; i < SYSAPPEND_MAX; i++) { |
| if (sysappend_strings[i]) |
| printf("%s\n", sysappend_strings[i]); |
| } |
| } |