aboutsummaryrefslogtreecommitdiffstats
path: root/package/nvram/src/nvram.c
diff options
context:
space:
mode:
Diffstat (limited to 'package/nvram/src/nvram.c')
-rw-r--r--package/nvram/src/nvram.c189
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 0000000000..dbca8e058d
--- /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;
+}