/src/barebox/defaultenv/defaultenv.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2014 Sascha Hauer, Pengutronix |
3 | | * |
4 | | * This program is free software; you can redistribute it and/or |
5 | | * modify it under the terms of the GNU General Public License as |
6 | | * published by the Free Software Foundation; either version 2 of |
7 | | * the License, or (at your option) any later version. |
8 | | * |
9 | | * This program is distributed in the hope that it will be useful, |
10 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | * GNU General Public License for more details. |
13 | | * |
14 | | */ |
15 | | #include <common.h> |
16 | | #include <envfs.h> |
17 | | #include <filetype.h> |
18 | | #include <uncompress.h> |
19 | | #include <malloc.h> |
20 | | #include <init.h> |
21 | | #include <libfile.h> |
22 | | #include <asm/unaligned.h> |
23 | | #include "barebox_default_env.h" |
24 | | |
25 | | static LIST_HEAD(defaultenv_list); |
26 | | |
27 | | struct defaultenv { |
28 | | struct list_head list; |
29 | | const char *srcdir; |
30 | | const char *name; |
31 | | void *buf; |
32 | | size_t size; |
33 | | }; |
34 | | |
35 | | /* |
36 | | * defaultenv_append - append a envfs buffer to the default environment |
37 | | * @buf: The buffer containing the binary environment. If it is |
38 | | * not a plain buffer it is assumed to be a compressed buffer. |
39 | | * @size: The length of the buffer |
40 | | * |
41 | | * This adds an overlay to the default environment. New files will be created, |
42 | | * existing files will be overwritten with the overlay. |
43 | | */ |
44 | | void defaultenv_append(void *buf, unsigned int size, const char *name) |
45 | 130 | { |
46 | 130 | struct defaultenv *df; |
47 | | |
48 | 130 | df = xzalloc(sizeof(*df)); |
49 | 130 | df->buf = buf; |
50 | 130 | df->size = size; |
51 | 130 | df->name = name; |
52 | | |
53 | 130 | list_add_tail(&df->list, &defaultenv_list); |
54 | 130 | } |
55 | | |
56 | | void defaultenv_append_runtime_directory(const char *srcdir) |
57 | 0 | { |
58 | 0 | struct defaultenv *df; |
59 | |
|
60 | 0 | df = xzalloc(sizeof(*df)); |
61 | 0 | df->srcdir = srcdir; |
62 | 0 | df->name = srcdir; |
63 | |
|
64 | 0 | list_add_tail(&df->list, &defaultenv_list); |
65 | 0 | } |
66 | | |
67 | | static int defaultenv_load_one(struct defaultenv *df, const char *dir, |
68 | | unsigned flags) |
69 | 130 | { |
70 | 130 | void *freep = NULL; |
71 | 130 | void *buf; |
72 | 130 | enum filetype ft = file_detect_type(df->buf, df->size); |
73 | 130 | uint32_t size; |
74 | 130 | int ret; |
75 | | |
76 | 130 | pr_debug("loading %s\n", df->name); |
77 | | |
78 | 130 | if (df->srcdir) { |
79 | 0 | int cpflags = 0; |
80 | 0 | if (flags & ENV_FLAG_NO_OVERWRITE) |
81 | 0 | cpflags |= COPY_FILE_NO_OVERWRITE; |
82 | 0 | return copy_recursive(df->srcdir, dir, cpflags); |
83 | 0 | } |
84 | | |
85 | 130 | if (!IS_ENABLED(CONFIG_DEFAULT_COMPRESSION_NONE) && |
86 | 0 | ft != filetype_barebox_env) { |
87 | 0 | size = get_unaligned_le32(df->buf + df->size - 4); |
88 | 0 | freep = malloc(size); |
89 | 0 | if (!freep) |
90 | 0 | return -ENOMEM; |
91 | | |
92 | 0 | ret = uncompress(df->buf, df->size, |
93 | 0 | NULL, NULL, |
94 | 0 | freep, NULL, uncompress_err_stdout); |
95 | 0 | if (ret) { |
96 | 0 | free(freep); |
97 | 0 | pr_err("Failed to uncompress: %pe\n", ERR_PTR(ret)); |
98 | 0 | return ret; |
99 | 0 | } |
100 | | |
101 | 0 | buf = freep; |
102 | 130 | } else { |
103 | 130 | buf = df->buf; |
104 | 130 | size = df->size; |
105 | 130 | } |
106 | | |
107 | 130 | ret = envfs_load_from_buf(buf, size, dir, flags); |
108 | | |
109 | 130 | free(freep); |
110 | | |
111 | 130 | if (ret) |
112 | 130 | pr_err("Failed to load defaultenv: %pe\n", ERR_PTR(ret)); |
113 | | |
114 | 130 | return ret; |
115 | 130 | } |
116 | | |
117 | | /* |
118 | | * defaultenv_load - load the default environment |
119 | | * @dir: The directory the default environment should be loaded to. |
120 | | * |
121 | | * This loads all environment snippets previously registered with |
122 | | * defaultenv_append to the directory given with @dir. |
123 | | * |
124 | | * Return: 0 for success, negative error code otherwise. |
125 | | */ |
126 | | int defaultenv_load(const char *dir, unsigned flags) |
127 | 26 | { |
128 | 26 | struct defaultenv *df; |
129 | 26 | int err = 0; |
130 | | |
131 | 130 | list_for_each_entry(df, &defaultenv_list, list) { |
132 | 130 | int ret = defaultenv_load_one(df, dir, flags); |
133 | 130 | if (ret) |
134 | 0 | err = ret; |
135 | 130 | } |
136 | | |
137 | 26 | return err; |
138 | 26 | } |
139 | | |
140 | | static int defaultenv_init(void) |
141 | 26 | { |
142 | 26 | if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW)) |
143 | 26 | defaultenv_append_directory(defaultenv_2_base); |
144 | 26 | if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW_MENU)) |
145 | 26 | defaultenv_append_directory(defaultenv_2_menu); |
146 | 26 | if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW_DFU)) |
147 | 0 | defaultenv_append_directory(defaultenv_2_dfu); |
148 | 26 | if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW_REBOOT_MODE)) |
149 | 26 | defaultenv_append_directory(defaultenv_2_reboot_mode); |
150 | 26 | if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW_SECURITY_POLICY)) |
151 | 0 | defaultenv_append_directory(defaultenv_2_security_policy); |
152 | 26 | if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW_DEVBOOT)) |
153 | 0 | defaultenv_append_directory(defaultenv_2_devboot); |
154 | 26 | if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW_IKCONFIG)) |
155 | 0 | defaultenv_append_directory(defaultenv_2_ikconfig); |
156 | 26 | if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC)) |
157 | 0 | defaultenv_append_directory(defaultenv_1); |
158 | | |
159 | | /* |
160 | | * The traditional or external environment given with |
161 | | * CONFIG_DEFAULT_ENVIRONMENT_PATH. |
162 | | */ |
163 | 26 | defaultenv_append((void *)default_environment, |
164 | 26 | default_environment_size, "defaultenv"); |
165 | | |
166 | 26 | return 0; |
167 | 26 | } |
168 | | pure_initcall(defaultenv_init); |