move package description to a separate definition, remove it when DESCRIPTION=TITLE
[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 * $Id$
13 */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18 #include <errno.h>
19 #include <error.h>
20 #include <string.h>
21 #include <sys/ioctl.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <sys/mman.h>
26
27 #include <typedefs.h>
28 #include <bcmnvram.h>
29 #include <shutils.h>
30
31 #define PATH_DEV_NVRAM "/dev/nvram"
32
33 /* Globals */
34 static int nvram_fd = -1;
35 static char *nvram_buf = NULL;
36 int file_to_buf(char *path, char *buf, int len);
37
38 int
39 nvram_init(void *unused)
40 {
41 if ((nvram_fd = open(PATH_DEV_NVRAM, O_RDWR)) < 0)
42 goto err;
43
44 /* Map kernel string buffer into user space */
45 if ((nvram_buf = mmap(NULL, NVRAM_SPACE, PROT_READ, MAP_SHARED, nvram_fd, 0)) == MAP_FAILED) {
46 close(nvram_fd);
47 nvram_fd = -1;
48 goto err;
49 }
50
51 return 0;
52
53 err:
54 perror(PATH_DEV_NVRAM);
55 return errno;
56 }
57
58 char *
59 nvram_get(const char *name)
60 {
61 size_t count = strlen(name) + 1;
62 char tmp[100], *value;
63 unsigned long *off = (unsigned long *) tmp;
64
65 if (nvram_fd < 0)
66 if (nvram_init(NULL))
67 return NULL;
68
69 if (count > sizeof(tmp)) {
70 if (!(off = malloc(count)))
71 return NULL;
72 }
73
74 /* Get offset into mmap() space */
75 strcpy((char *) off, name);
76
77 count = read(nvram_fd, off, count);
78
79 if (count == sizeof(unsigned long))
80 value = &nvram_buf[*off];
81 else
82 value = NULL;
83
84 if (count < 0)
85 perror(PATH_DEV_NVRAM);
86
87 if (off != (unsigned long *) tmp)
88 free(off);
89
90 return value;
91 }
92
93 int
94 nvram_getall(char *buf, int count)
95 {
96 int ret;
97
98 if (nvram_fd < 0)
99 if ((ret = nvram_init(NULL)))
100 return ret;
101
102 if (count == 0)
103 return 0;
104
105 /* Get all variables */
106 *buf = '\0';
107
108 ret = read(nvram_fd, buf, count);
109
110 if (ret < 0)
111 perror(PATH_DEV_NVRAM);
112
113 return (ret == count) ? 0 : ret;
114 }
115
116 int
117 nvram_set(const char *name, const char *value)
118 {
119 size_t count = strlen(name) + 1;
120 char tmp[100], *buf = tmp;
121 int ret;
122
123 if (nvram_fd < 0)
124 if ((ret = nvram_init(NULL)))
125 return ret;
126
127 /* Unset if value is NULL */
128 if (value)
129 count += strlen(value) + 1;
130
131 if (count > sizeof(tmp)) {
132 if (!(buf = malloc(count)))
133 return -ENOMEM;
134 }
135
136 if (value)
137 sprintf(buf, "%s=%s", name, value);
138 else
139 strcpy(buf, name);
140
141 ret = write(nvram_fd, buf, count);
142
143 if (ret < 0)
144 perror(PATH_DEV_NVRAM);
145
146 if (buf != tmp)
147 free(buf);
148
149 return (ret == count) ? 0 : ret;
150 }
151
152 int
153 nvram_unset(const char *name)
154 {
155 return nvram_set(name, NULL);
156 }
157
158 int
159 nvram_commit(void)
160 {
161 int ret;
162
163 if (nvram_fd < 0)
164 if ((ret = nvram_init(NULL)))
165 return ret;
166
167 ret = ioctl(nvram_fd, NVRAM_MAGIC, NULL);
168
169 if (ret < 0)
170 perror(PATH_DEV_NVRAM);
171
172 return ret;
173 }
174
175 int
176 file_to_buf(char *path, char *buf, int len)
177 {
178 FILE *fp;
179
180 memset(buf, 0 , len);
181
182 if ((fp = fopen(path, "r"))) {
183 fgets(buf, len, fp);
184 fclose(fp);
185 return 1;
186 }
187
188 return 0;
189 }