get rid of $Id$ - it has never helped us and it has broken too many patches ;)
[openwrt/svn-archive/archive.git] / package / nvram / src / nvram.c
1 /*
2 * NVRAM variable manipulation (Linux user mode half)
3 *
4 * Copyright 2004, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
11 *
12 */
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17 #include <errno.h>
18 #include <error.h>
19 #include <string.h>
20 #include <sys/ioctl.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 #include <sys/mman.h>
25
26 #include <typedefs.h>
27 #include <bcmnvram.h>
28 #include <shutils.h>
29
30 #define PATH_DEV_NVRAM "/dev/nvram"
31
32 /* Globals */
33 static int nvram_fd = -1;
34 static char *nvram_buf = NULL;
35 int file_to_buf(char *path, char *buf, int len);
36
37 int
38 nvram_init(void *unused)
39 {
40 if ((nvram_fd = open(PATH_DEV_NVRAM, O_RDWR)) < 0)
41 goto err;
42
43 /* Map kernel string buffer into user space */
44 if ((nvram_buf = mmap(NULL, NVRAM_SPACE, PROT_READ, MAP_SHARED, nvram_fd, 0)) == MAP_FAILED) {
45 close(nvram_fd);
46 nvram_fd = -1;
47 goto err;
48 }
49
50 return 0;
51
52 err:
53 perror(PATH_DEV_NVRAM);
54 return errno;
55 }
56
57 char *
58 nvram_get(const char *name)
59 {
60 size_t count = strlen(name) + 1;
61 char tmp[100], *value;
62 unsigned long *off = (unsigned long *) tmp;
63
64 if (nvram_fd < 0)
65 if (nvram_init(NULL))
66 return NULL;
67
68 if (count > sizeof(tmp)) {
69 if (!(off = malloc(count)))
70 return NULL;
71 }
72
73 /* Get offset into mmap() space */
74 strcpy((char *) off, name);
75
76 count = read(nvram_fd, off, count);
77
78 if (count == sizeof(unsigned long))
79 value = &nvram_buf[*off];
80 else
81 value = NULL;
82
83 if (count < 0)
84 perror(PATH_DEV_NVRAM);
85
86 if (off != (unsigned long *) tmp)
87 free(off);
88
89 return value;
90 }
91
92 int
93 nvram_getall(char *buf, int count)
94 {
95 int ret;
96
97 if (nvram_fd < 0)
98 if ((ret = nvram_init(NULL)))
99 return ret;
100
101 if (count == 0)
102 return 0;
103
104 /* Get all variables */
105 *buf = '\0';
106
107 ret = read(nvram_fd, buf, count);
108
109 if (ret < 0)
110 perror(PATH_DEV_NVRAM);
111
112 return (ret == count) ? 0 : ret;
113 }
114
115 int
116 nvram_set(const char *name, const char *value)
117 {
118 size_t count = strlen(name) + 1;
119 char tmp[100], *buf = tmp;
120 int ret;
121
122 if (nvram_fd < 0)
123 if ((ret = nvram_init(NULL)))
124 return ret;
125
126 /* Unset if value is NULL */
127 if (value)
128 count += strlen(value) + 1;
129
130 if (count > sizeof(tmp)) {
131 if (!(buf = malloc(count)))
132 return -ENOMEM;
133 }
134
135 if (value)
136 sprintf(buf, "%s=%s", name, value);
137 else
138 strcpy(buf, name);
139
140 ret = write(nvram_fd, buf, count);
141
142 if (ret < 0)
143 perror(PATH_DEV_NVRAM);
144
145 if (buf != tmp)
146 free(buf);
147
148 return (ret == count) ? 0 : ret;
149 }
150
151 int
152 nvram_unset(const char *name)
153 {
154 return nvram_set(name, NULL);
155 }
156
157 int
158 nvram_commit(void)
159 {
160 int ret;
161
162 if (nvram_fd < 0)
163 if ((ret = nvram_init(NULL)))
164 return ret;
165
166 ret = ioctl(nvram_fd, NVRAM_MAGIC, NULL);
167
168 if (ret < 0)
169 perror(PATH_DEV_NVRAM);
170
171 return ret;
172 }
173
174 int
175 file_to_buf(char *path, char *buf, int len)
176 {
177 FILE *fp;
178
179 memset(buf, 0 , len);
180
181 if ((fp = fopen(path, "r"))) {
182 fgets(buf, len, fp);
183 fclose(fp);
184 return 1;
185 }
186
187 return 0;
188 }