2014-02-18 09:25:13 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2014 Sascha Hauer, Pengutronix
|
|
|
|
*
|
|
|
|
* See file CREDITS for list of people who contributed to this
|
|
|
|
* project.
|
|
|
|
*
|
|
|
|
* 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; either version 2 of
|
|
|
|
* the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include <common.h>
|
|
|
|
#include <envfs.h>
|
|
|
|
#include <filetype.h>
|
|
|
|
#include <uncompress.h>
|
|
|
|
#include <malloc.h>
|
|
|
|
#include <init.h>
|
|
|
|
#include <asm/unaligned.h>
|
|
|
|
#include "barebox_default_env.h"
|
|
|
|
|
|
|
|
static LIST_HEAD(defaultenv_list);
|
|
|
|
|
|
|
|
struct defaultenv {
|
|
|
|
struct list_head list;
|
|
|
|
const char *name;
|
|
|
|
void *buf;
|
|
|
|
size_t size;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void defaultenv_add_base(void)
|
|
|
|
{
|
|
|
|
static int base_added;
|
|
|
|
|
|
|
|
if (base_added)
|
|
|
|
return;
|
|
|
|
|
|
|
|
base_added = 1;
|
|
|
|
|
|
|
|
if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW))
|
|
|
|
defaultenv_append_directory(defaultenv_2_base);
|
|
|
|
if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW_MENU))
|
|
|
|
defaultenv_append_directory(defaultenv_2_menu);
|
2014-02-25 14:38:07 +00:00
|
|
|
if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW_DFU))
|
|
|
|
defaultenv_append_directory(defaultenv_2_dfu);
|
2014-02-18 09:25:13 +00:00
|
|
|
if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC))
|
|
|
|
defaultenv_append_directory(defaultenv_1);
|
2014-09-10 14:46:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void defaultenv_add_external(void)
|
|
|
|
{
|
|
|
|
static int external_added;
|
|
|
|
|
|
|
|
if (external_added)
|
|
|
|
return;
|
|
|
|
|
|
|
|
external_added = 1;
|
2014-02-18 09:25:13 +00:00
|
|
|
|
|
|
|
/*
|
2014-09-10 14:46:08 +00:00
|
|
|
* The traditional or external environment given with
|
|
|
|
* CONFIG_DEFAULT_ENVIRONMENT_PATH.
|
2014-02-18 09:25:13 +00:00
|
|
|
*/
|
|
|
|
defaultenv_append((void *)default_environment,
|
|
|
|
default_environment_size, "defaultenv");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* defaultenv_append - append a envfs buffer to the default environment
|
|
|
|
* @buf: The buffer containing the binary environment. If it is
|
|
|
|
* not a plain buffer it is assumed to be a compressed buffer.
|
|
|
|
* @size: The length of the buffer
|
|
|
|
*
|
|
|
|
* This adds an overlay to the default environment. New files will be created,
|
|
|
|
* existing files will be overwritten with the overlay.
|
|
|
|
*/
|
|
|
|
void defaultenv_append(void *buf, unsigned int size, const char *name)
|
|
|
|
{
|
|
|
|
struct defaultenv *df;
|
|
|
|
|
|
|
|
defaultenv_add_base();
|
|
|
|
|
|
|
|
df = xzalloc(sizeof(*df));
|
|
|
|
df->buf = buf;
|
|
|
|
df->size = size;
|
|
|
|
df->name = name;
|
|
|
|
|
|
|
|
list_add_tail(&df->list, &defaultenv_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int defaultenv_load_one(struct defaultenv *df, const char *dir,
|
|
|
|
unsigned flags)
|
|
|
|
{
|
|
|
|
void *freep = NULL;
|
|
|
|
void *buf;
|
|
|
|
enum filetype ft = file_detect_type(df->buf, df->size);
|
|
|
|
uint32_t size;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
pr_debug("loading %s\n", df->name);
|
|
|
|
|
|
|
|
if (!IS_ENABLED(CONFIG_DEFAULT_COMPRESSION_NONE) &&
|
|
|
|
ft != filetype_barebox_env) {
|
|
|
|
size = get_unaligned_le32(df->buf + df->size - 4);
|
|
|
|
freep = malloc(size);
|
|
|
|
if (!freep)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
ret = uncompress(df->buf, df->size,
|
|
|
|
NULL, NULL,
|
|
|
|
freep, NULL, uncompress_err_stdout);
|
|
|
|
if (ret) {
|
|
|
|
free(freep);
|
|
|
|
pr_err("Failed to uncompress: %s\n", strerror(-ret));
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf = freep;
|
|
|
|
} else {
|
|
|
|
buf = df->buf;
|
|
|
|
size = df->size;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = envfs_load_from_buf(buf, size, dir, flags);
|
|
|
|
|
|
|
|
free(freep);
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
pr_err("Failed to load defaultenv: %s\n", strerror(-ret));
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* defaultenv_load - load the default environment
|
|
|
|
* @dir: The directory the default environment should be loaded to.
|
|
|
|
*
|
|
|
|
* This loads all environment snippets previously registered with
|
|
|
|
* defaultenv_append to the directory given with @dir.
|
|
|
|
*
|
|
|
|
* Return: 0 for success, negative error code otherwise.
|
|
|
|
*/
|
|
|
|
int defaultenv_load(const char *dir, unsigned flags)
|
|
|
|
{
|
|
|
|
struct defaultenv *df;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
defaultenv_add_base();
|
|
|
|
|
2014-09-10 14:46:08 +00:00
|
|
|
defaultenv_add_external();
|
|
|
|
|
2014-02-18 09:25:13 +00:00
|
|
|
list_for_each_entry(df, &defaultenv_list, list) {
|
|
|
|
ret = defaultenv_load_one(df, dir, flags);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|