/*
* NVRAM variable manipulation (Linux user mode half)
*
* Copyright 2001-2003, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: nvram_linux.c,v 1.9 2003/12/03 10:14:06 honor Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <error.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <syslog.h>
//#include <typedefs.h>
#include <nvram.h>
#include <nvram_convert.h>
#include "nvram_generics.h"
#define PATH_DEV_NVRAM "/dev/nvram"
#define PATH_BIN_NVRAM "/root/nvram.bin"
/* Globals */
static int nvram_fd = -1;
static char *nvram_buf = NULL;
void do_nvram_set(char *buf)
{
char *name;
char *val;
char *ptr;
ptr=strstr(buf,"=");
if(ptr)
{
name = buf;
*ptr='\0';
val = ptr+1;
nvram_set(name,val);
}
}
int __nvram_init()
{
FILE *fp = NULL;
char tmp_buf[NVRAM_SPACE];
char tmp_val[256];
char *ptr;
struct nvram_header *header;
fp = fopen(PATH_BIN_NVRAM,"rb");
if(fp)
{
fread(tmp_buf,1,NVRAM_SPACE,fp);
fclose(fp);
fp = NULL;
header = tmp_buf;
ptr = tmp_buf;//+sizeof(struct nvram_header);
while(1)
{
memset(tmp_val,0,sizeof(tmp_val));
sprintf(tmp_val,"%s",ptr);
do_nvram_set(tmp_val);
ptr += strlen(ptr)+1;
if(strlen(ptr)==0)
break;
}
}
else
{
printf("file:%s on exist!\n",PATH_BIN_NVRAM);
return -1;
}
return 0;
}
int nvram_init(void *unused)
{
syslog(LOG_USER|LOG_DEBUG, "nvram_init-----------");
if ((nvram_fd = open(PATH_DEV_NVRAM, O_RDWR)) < 0)
{
syslog(LOG_USER|LOG_DEBUG, "open nvram fail:");
goto err;
}
/* Map kernel string buffer into user space */
if ((nvram_buf =
mmap(NULL, NVRAM_SPACE, PROT_READ, MAP_SHARED, nvram_fd,
0)) == MAP_FAILED) {
close(nvram_fd);
fprintf(stderr, "nvram_init(): failed\n");
syslog(LOG_USER|LOG_DEBUG, "nvram_init(): failed\n");
nvram_fd = -1;
goto err;
}
return 0;
err:
return errno;
}
void lock(void)
{
FILE *in;
int lockwait = 0;
while ((in = fopen("/tmp/.nvlock", "rb")) != NULL) {
fclose(in);
fprintf(stderr, "nvram lock, waiting....\n");
lockwait++;
if (lockwait == 3)
unlink("/tmp/.nvlock"); //something crashed, we fix it
sleep(1);
}
in = fopen("/tmp/.nvlock", "wb");
fprintf(in, "lock");
fclose(in);
}
void unlock(void)
{
unlink("/tmp/.nvlock");
}
char *nvram_get(const char *name)
{
//lock();
size_t count = strlen(name) + 1;
char tmp[100], *value;
unsigned long *off = (unsigned long *)tmp;
if (nvram_fd < 0)
if (nvram_init(NULL)) {
//unlock();
return NULL;
}
if (count > sizeof(tmp)) {
if (!(off = malloc(count))) {
//unlock();
return NULL;
}
}
/* Get offset into mmap() space */
strcpy((char *)off, name);
count = read(nvram_fd, off, count);
if (count == sizeof(unsigned long))
value = &nvram_buf[*off];
else
value = NULL;
#ifndef HAVE_MICRO
if (value)
msync(nvram_buf, NVRAM_SPACE, MS_INVALIDATE);
#endif
if (count < 0)
perror(PATH_DEV_NVRAM);
if (off != (unsigned long *)tmp)
free(off);
//unlock();
return value;
}
int nvram_getall(char *buf, int count)
{
//lock();
int ret;
if (nvram_fd < 0)
if ((ret = nvram_init(NULL))) {
//unlock();
return ret;
}
if (count == 0) {
//unlock();
return 0;
}
/* Get all variables */
*buf = '\0';
ret = read(nvram_fd, buf, count);
if (ret < 0)
perror(PATH_DEV_NVRAM);
//unlock();
return (ret == count) ? 0 : ret;
}
void nvram_open(void) // dummy
{
}
void nvram_close(void) //dummy
{
}
static int _nvram_set(const char *name, const char *value)
{
size_t count = strlen(name) + 1;
char tmp[100], *buf = tmp;
int ret;
if (nvram_fd < 0)
if ((ret = nvram_init(NULL)))
return ret;
syslog(LOG_USER|LOG_DEBUG, "nvram_set %s = %s", name, value);
/* Wolf add - keep nvram varname to sane len - may prevent corruption */
if (strlen(name) > 64)
return -ENOMEM;
/* Unset if value is NULL */
if (value)
count += strlen(value) + 2;
if (count > sizeof(tmp)) {
if (!(buf = malloc(count)))
return -ENOMEM;
}
if (value)
sprintf(buf, "%s=%s", name, value);
else
strcpy(buf, name);
ret = write(nvram_fd, buf, count);
if (ret < 0)
perror(PATH_DEV_NVRAM);
if (buf != tmp)
free(buf);
return (ret == count) ? 0 : ret;
}
int nvram_set(const char *name, const char *value)
{
int ret;
ret = _nvram_set(name, value);
return ret;
}
int nvram_immed_set(const char *name, const char *value)
{
return nvram_set(name, value);
}
int nvram_unset(const char *name)
{
//lock();
int v = _nvram_set(name, NULL);
//unlock();
return v;
}
int nvram_commit(void)
{
FILE *fp;
char buffer[NVRAM_SPACE];
memset(buffer,0,sizeof(buffer));
printf("sizeof buffer=%d\n",sizeof(buffer));
syslog(LOG_USER|LOG_DEBUG, "nvram_commit sizeof buffer=%d\n",sizeof(buffer));
#if 0
if (nvram_match("flash_active", "1")) {
fprintf(stderr, "not allowed, flash process in progress");
exit(1);
}
#endif
lock();
#if 0
int ret;
if (nvram_fd < 0) {
if ((ret = nvram_init(NULL))) {
fprintf(stderr, "nvram_commit(): failed\n");
unlock();
return ret;
}
}
ret = ioctl(nvram_fd, NVRAM_MAGIC, NULL);
if (ret < 0) {
fprintf(stderr, "nvram_commit(): failed\n");
perror(PATH_DEV_NVRAM);
}
#endif
nvram_getall(buffer, sizeof(buffer));
fp = fopen(PATH_BIN_NVRAM,"wb");
if(fp)
{
fwrite(buffer,1,sizeof(buffer),fp);
fclose(fp);
fp = NULL;
}
unlock();
sync();
return 0;
}
int file2nvram(char *filename, char *varname)
{
FILE *fp;
int c, count;
int i = 0, j = 0;
char mem[10000], buf[30000];
if (!(fp = fopen(filename, "rb")))
return 0;
count = fread(mem, 1, sizeof(mem), fp);
fclose(fp);
for (j = 0; j < count; j++) {
if (i > sizeof(buf) - 3)
break;
c = mem[j];
if (c >= 32 && c <= 126 && c != '~') {
buf[i++] = (unsigned char)c;
} else if (c == 13) {
buf[i++] = (unsigned char)c;
} else if (c == 0) {
buf[i++] = '~';
} else if (c == 10) {
buf[i++] = (unsigned char)c;
} else {
buf[i++] = '\\';
sprintf(buf + i, "%02X", c);
i += 2;
}
}
if (i == 0)
return 0;
buf[i] = 0;
nvram_set(varname, buf);
}
int nvram2file(char *varname, char *filename)
{
FILE *fp;
int i = 0, j = 0;
char *buf;
char mem[10000];
if (!(fp = fopen(filename, "wb")))
return 0;
buf = strdup(nvram_safe_get(varname));
while (buf[i] && j < sizeof(mem) - 3) {
if (buf[i] == '~') {
mem[j] = 0;
j++;
i++;
} else {
mem[j] = buf[i];
j++;
i++;
}
}
if (j <= 0)
return j;
j = fwrite(mem, 1, j, fp);
fclose(fp);
free(buf);
return j;
}
- 1
- 2
前往页