2007-07-05 16:02:19 +00:00
|
|
|
/*
|
|
|
|
* ubootenv.c - generate or read a U-Boot environment archive
|
|
|
|
*
|
|
|
|
* Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, 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 version 2
|
|
|
|
* as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
2007-07-05 16:01:52 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <getopt.h>
|
2007-09-25 10:58:52 +00:00
|
|
|
#include <libgen.h>
|
2007-07-05 16:01:52 +00:00
|
|
|
|
2007-09-27 10:04:17 +00:00
|
|
|
#define debug(...)
|
|
|
|
|
2007-07-05 16:01:52 +00:00
|
|
|
void *xmalloc(size_t size)
|
|
|
|
{
|
|
|
|
void *p = NULL;
|
|
|
|
|
|
|
|
if (!(p = malloc(size))) {
|
|
|
|
printf("ERROR: out of memory\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
2007-07-05 16:01:52 +00:00
|
|
|
|
2007-09-25 10:58:52 +00:00
|
|
|
void *xzalloc(size_t size)
|
|
|
|
{
|
|
|
|
void *p = xmalloc(size);
|
|
|
|
memset(p, 0, size);
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find out if the last character of a string matches the one given.
|
|
|
|
* Don't underrun the buffer if the string length is 0.
|
|
|
|
*/
|
|
|
|
char* last_char_is(const char *s, int c)
|
|
|
|
{
|
|
|
|
if (s && *s) {
|
|
|
|
size_t sz = strlen(s) - 1;
|
|
|
|
s += sz;
|
|
|
|
if ( (unsigned char)*s == c)
|
|
|
|
return (char*)s;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum {
|
|
|
|
ACTION_RECURSE = (1 << 0),
|
|
|
|
/* ACTION_FOLLOWLINKS = (1 << 1), - unused */
|
|
|
|
ACTION_DEPTHFIRST = (1 << 2),
|
|
|
|
/*ACTION_REVERSE = (1 << 3), - unused */
|
|
|
|
};
|
|
|
|
|
|
|
|
int recursive_action(const char *fileName, unsigned flags,
|
|
|
|
int (*fileAction) (const char *fileName, struct stat* statbuf, void* userData, int depth),
|
|
|
|
int (*dirAction) (const char *fileName, struct stat* statbuf, void* userData, int depth),
|
|
|
|
void* userData, const unsigned depth);
|
|
|
|
|
|
|
|
#define DOT_OR_DOTDOT(s) ((s)[0] == '.' && (!(s)[1] || ((s)[1] == '.' && !(s)[2])))
|
|
|
|
|
|
|
|
/* concatenate path and file name to new allocation buffer,
|
|
|
|
* not adding '/' if path name already has '/'
|
|
|
|
*/
|
|
|
|
char *concat_path_file(const char *path, const char *filename)
|
|
|
|
{
|
|
|
|
char *lc, *str;
|
|
|
|
|
|
|
|
if (!path)
|
|
|
|
path = "";
|
|
|
|
lc = last_char_is(path, '/');
|
|
|
|
while (*filename == '/')
|
|
|
|
filename++;
|
|
|
|
|
|
|
|
str = xmalloc(strlen(path) + (lc==0 ? 1 : 0) + strlen(filename) + 1);
|
|
|
|
sprintf(str, "%s%s%s", path, (lc==NULL ? "/" : ""), filename);
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This function make special for recursive actions with usage
|
|
|
|
* concat_path_file(path, filename)
|
|
|
|
* and skipping "." and ".." directory entries
|
|
|
|
*/
|
|
|
|
|
|
|
|
char *concat_subpath_file(const char *path, const char *f)
|
|
|
|
{
|
|
|
|
if (f && DOT_OR_DOTDOT(f))
|
|
|
|
return NULL;
|
|
|
|
return concat_path_file(path, f);
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "../lib/recursive_action.c"
|
2007-07-05 16:01:52 +00:00
|
|
|
#include "../include/envfs.h"
|
2007-09-27 10:04:17 +00:00
|
|
|
#include "../lib/crc32.c"
|
|
|
|
#include "../lib/make_directory.c"
|
2007-11-09 22:19:54 +00:00
|
|
|
#include "../include/environment.h"
|
|
|
|
#include "../common/environment.c"
|
2007-07-05 16:01:52 +00:00
|
|
|
|
|
|
|
void usage(char *prgname)
|
|
|
|
{
|
|
|
|
printf( "Usage : %s [OPTION] DIRECTORY FILE\n"
|
|
|
|
"Load an u-boot environment sector into a directory or\n"
|
|
|
|
"save a directory into an u-boot environment sector\n"
|
|
|
|
"\n"
|
|
|
|
"options:\n"
|
|
|
|
" -s save (directory -> environment sector)\n"
|
2007-07-05 19:36:32 +00:00
|
|
|
" -l load (environment sector -> directory)\n"
|
|
|
|
" -p <size> pad output file to given size\n",
|
2007-07-05 16:01:52 +00:00
|
|
|
prgname);
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
int opt;
|
2007-07-05 19:36:32 +00:00
|
|
|
int save = 0, load = 0, pad = 0, fd;
|
2007-07-05 16:01:52 +00:00
|
|
|
char *filename = NULL, *dirname = NULL;
|
|
|
|
|
2007-07-05 19:36:32 +00:00
|
|
|
while((opt = getopt(argc, argv, "slp:")) != -1) {
|
2007-07-05 16:01:52 +00:00
|
|
|
switch (opt) {
|
|
|
|
case 's':
|
|
|
|
save = 1;
|
|
|
|
break;
|
|
|
|
case 'l':
|
|
|
|
load = 1;
|
|
|
|
break;
|
2007-07-05 19:36:32 +00:00
|
|
|
case 'p':
|
|
|
|
pad = strtoul(optarg, NULL, 0);
|
|
|
|
break;
|
2007-07-05 16:01:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (optind + 1 >= argc) {
|
|
|
|
usage(argv[0]);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
dirname = argv[optind];
|
|
|
|
filename = argv[optind + 1];
|
|
|
|
|
|
|
|
if ((!load && !save) || (load && save) || !filename || !dirname) {
|
|
|
|
usage(argv[0]);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2007-07-05 19:36:32 +00:00
|
|
|
if (save) {
|
|
|
|
fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0644);
|
|
|
|
if (fd < 0) {
|
|
|
|
perror("open");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
close(fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (save && pad) {
|
|
|
|
if (truncate(filename, pad)) {
|
|
|
|
perror("truncate");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-05 16:01:52 +00:00
|
|
|
if (load) {
|
|
|
|
printf("loading env from file %s to %s\n", filename, dirname);
|
|
|
|
envfs_load(filename, dirname);
|
|
|
|
}
|
|
|
|
if (save) {
|
|
|
|
printf("saving contents of %s to file %s\n", dirname, filename);
|
|
|
|
envfs_save(filename, dirname);
|
|
|
|
}
|
|
|
|
exit(0);
|
|
|
|
}
|