get rid of $Id$ - it has never helped us and it has broken too many patches ;)
[openwrt-10.03/.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 }