0001
0002
0003
0004
0005 #include <linux/fs.h>
0006 #include <linux/init.h>
0007 #include <linux/printk.h>
0008 #include <linux/proc_fs.h>
0009 #include <linux/seq_file.h>
0010 #include <linux/bootconfig.h>
0011 #include <linux/slab.h>
0012
0013 static char *saved_boot_config;
0014
0015 static int boot_config_proc_show(struct seq_file *m, void *v)
0016 {
0017 if (saved_boot_config)
0018 seq_puts(m, saved_boot_config);
0019 return 0;
0020 }
0021
0022
0023 #define rest(dst, end) ((end) > (dst) ? (end) - (dst) : 0)
0024
0025
0026 static int __init copy_xbc_key_value_list(char *dst, size_t size)
0027 {
0028 struct xbc_node *leaf, *vnode;
0029 char *key, *end = dst + size;
0030 const char *val;
0031 char q;
0032 int ret = 0;
0033
0034 key = kzalloc(XBC_KEYLEN_MAX, GFP_KERNEL);
0035 if (!key)
0036 return -ENOMEM;
0037
0038 xbc_for_each_key_value(leaf, val) {
0039 ret = xbc_node_compose_key(leaf, key, XBC_KEYLEN_MAX);
0040 if (ret < 0)
0041 break;
0042 ret = snprintf(dst, rest(dst, end), "%s = ", key);
0043 if (ret < 0)
0044 break;
0045 dst += ret;
0046 vnode = xbc_node_get_child(leaf);
0047 if (vnode) {
0048 xbc_array_for_each_value(vnode, val) {
0049 if (strchr(val, '"'))
0050 q = '\'';
0051 else
0052 q = '"';
0053 ret = snprintf(dst, rest(dst, end), "%c%s%c%s",
0054 q, val, q, xbc_node_is_array(vnode) ? ", " : "\n");
0055 if (ret < 0)
0056 goto out;
0057 dst += ret;
0058 }
0059 } else {
0060 ret = snprintf(dst, rest(dst, end), "\"\"\n");
0061 if (ret < 0)
0062 break;
0063 dst += ret;
0064 }
0065 }
0066 out:
0067 kfree(key);
0068
0069 return ret < 0 ? ret : dst - (end - size);
0070 }
0071
0072 static int __init proc_boot_config_init(void)
0073 {
0074 int len;
0075
0076 len = copy_xbc_key_value_list(NULL, 0);
0077 if (len < 0)
0078 return len;
0079
0080 if (len > 0) {
0081 saved_boot_config = kzalloc(len + 1, GFP_KERNEL);
0082 if (!saved_boot_config)
0083 return -ENOMEM;
0084
0085 len = copy_xbc_key_value_list(saved_boot_config, len + 1);
0086 if (len < 0) {
0087 kfree(saved_boot_config);
0088 return len;
0089 }
0090 }
0091
0092 proc_create_single("bootconfig", 0, NULL, boot_config_proc_show);
0093
0094 return 0;
0095 }
0096 fs_initcall(proc_boot_config_init);