diff options
Diffstat (limited to 'package/nvram/src/nvram.c')
| -rw-r--r-- | package/nvram/src/nvram.c | 189 | 
1 files changed, 189 insertions, 0 deletions
| diff --git a/package/nvram/src/nvram.c b/package/nvram/src/nvram.c new file mode 100644 index 000000000..dbca8e058 --- /dev/null +++ b/package/nvram/src/nvram.c @@ -0,0 +1,189 @@ +/* + * NVRAM variable manipulation (Linux user mode half) + * + * Copyright 2004, 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$ + */ + +#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 <typedefs.h> +#include <bcmnvram.h> +#include <shutils.h> + +#define PATH_DEV_NVRAM "/dev/nvram" + +/* Globals */ +static int nvram_fd = -1; +static char *nvram_buf = NULL; +int file_to_buf(char *path, char *buf, int len); + +int +nvram_init(void *unused) +{ +	if ((nvram_fd = open(PATH_DEV_NVRAM, O_RDWR)) < 0) +		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); +		nvram_fd = -1; +		goto err; +	} + +	return 0; + + err: +	perror(PATH_DEV_NVRAM); +	return errno; +} + +char * +nvram_get(const char *name) +{ +	size_t count = strlen(name) + 1; +	char tmp[100], *value; +	unsigned long *off = (unsigned long *) tmp; + +	if (nvram_fd < 0) +		if (nvram_init(NULL)) +			return NULL; + +	if (count > sizeof(tmp)) { +		if (!(off = malloc(count))) +			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; + +	if (count < 0) +		perror(PATH_DEV_NVRAM); + +	if (off != (unsigned long *) tmp) +		free(off); + +	return value; +} + +int +nvram_getall(char *buf, int count) +{ +	int ret; + +	if (nvram_fd < 0) +		if ((ret = nvram_init(NULL))) +			return ret; + +	if (count == 0) +		return 0; + +	/* Get all variables */ +	*buf = '\0'; + +	ret = read(nvram_fd, buf, count); + +	if (ret < 0) +		perror(PATH_DEV_NVRAM); + +	return (ret == count) ? 0 : ret; +} + +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; + +	/* Unset if value is NULL */ +	if (value) +		count += strlen(value) + 1; + +	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_unset(const char *name) +{ +	return nvram_set(name, NULL); +} + +int +nvram_commit(void) +{ +	int ret; +	 +	if (nvram_fd < 0) +		if ((ret = nvram_init(NULL))) +			return ret; + +	ret = ioctl(nvram_fd, NVRAM_MAGIC, NULL); + +	if (ret < 0) +		perror(PATH_DEV_NVRAM); + +	return ret; +} + +int +file_to_buf(char *path, char *buf, int len) +{ +	FILE *fp; + +	memset(buf, 0 , len); + +	if ((fp = fopen(path, "r"))) { +		fgets(buf, len, fp); +		fclose(fp); +		return 1; +	} + +	return 0; +} | 
