source: src/router/nvram/nvram_linux.c @ 17874

Last change on this file since 17874 was 17874, checked in by BrainSlayer, 19 months ago

typo

File size: 6.7 KB
Line 
1/*
2 * NVRAM variable manipulation (Linux user mode half)
3 *
4 * Copyright 2001-2003, 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: nvram_linux.c,v 1.9 2003/12/03 10:14:06 honor Exp $
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 <nvram_convert.h>
30
31#define PATH_DEV_NVRAM "/dev/nvram"
32
33/* Globals */
34static int nvram_fd = -1;
35static char *nvram_buf = NULL;
36
37int nvram_init(void *unused)
38{
39#ifdef HAVE_X86
40        FILE *in = fopen("/usr/local/nvram/nvram.bin", "rb");
41        if (in==NULL)
42            return -1;
43        fclose(in);
44#endif
45        if ((nvram_fd = open(PATH_DEV_NVRAM, O_RDWR)) < 0)
46                goto err;
47
48        /* Map kernel string buffer into user space */
49        if ((nvram_buf =
50             mmap(NULL, NVRAM_SPACE, PROT_READ, MAP_SHARED, nvram_fd,
51                  0)) == MAP_FAILED) {
52                close(nvram_fd);
53                fprintf(stderr, "nvram_init(): failed\n");
54                nvram_fd = -1;
55                goto err;
56        }
57
58        return 0;
59
60err:
61        return errno;
62}
63
64void lock(void)
65{
66        FILE *in;
67        int lockwait = 0;
68        while ((in = fopen("/tmp/.nvlock", "rb")) != NULL) {
69                fclose(in);
70                fprintf(stderr, "nvram lock, waiting....\n");
71                lockwait++;
72                if (lockwait == 3)
73                        unlink("/tmp/.nvlock"); //something crashed, we fix it
74                sleep(1);
75        }
76        in = fopen("/tmp/.nvlock", "wb");
77        fprintf(in, "lock");
78        fclose(in);
79}
80
81void unlock(void)
82{
83        unlink("/tmp/.nvlock");
84}
85
86char *nvram_get(const char *name)
87{
88//lock();
89        size_t count = strlen(name) + 1;
90        char tmp[100], *value;
91        unsigned long *off = (unsigned long *)tmp;
92
93        if (nvram_fd < 0)
94                if (nvram_init(NULL)) {
95                        //unlock();
96                        return NULL;
97                }
98        if (count > sizeof(tmp)) {
99                if (!(off = malloc(count))) {
100                        //unlock();
101                        return NULL;
102                }
103        }
104
105        /* Get offset into mmap() space */
106        strcpy((char *)off, name);
107
108        count = read(nvram_fd, off, count);
109
110        if (count == sizeof(unsigned long))
111                value = &nvram_buf[*off];
112        else
113                value = NULL;
114       
115#ifndef HAVE_MICRO
116        if (value)
117            msync(nvram_buf, NVRAM_SPACE, MS_INVALIDATE);
118#endif
119        if (count < 0)
120                perror(PATH_DEV_NVRAM);
121
122        if (off != (unsigned long *)tmp)
123                free(off);
124        //unlock();
125
126
127        return value;
128}
129
130int nvram_getall(char *buf, int count)
131{
132//lock();
133        int ret;
134
135        if (nvram_fd < 0)
136                if ((ret = nvram_init(NULL))) {
137                        //unlock();
138                        return ret;
139                }
140        if (count == 0) {
141                //unlock();
142                return 0;
143        }
144        /* Get all variables */
145        *buf = '\0';
146
147        ret = read(nvram_fd, buf, count);
148
149        if (ret < 0)
150                perror(PATH_DEV_NVRAM);
151        //unlock();
152        return (ret == count) ? 0 : ret;
153}
154
155void nvram_open(void)           // dummy
156{
157}
158
159void nvram_close(void)          //dummy
160{
161}
162
163static int _nvram_set(const char *name, const char *value)
164{
165        size_t count = strlen(name) + 1;
166        char tmp[100], *buf = tmp;
167        int ret;
168
169        if (nvram_fd < 0)
170                if ((ret = nvram_init(NULL)))
171                        return ret;
172
173        /* Wolf add - keep nvram varname to sane len - may prevent corruption */
174        if (strlen(name) > 64)
175                return -ENOMEM;
176
177        /* Unset if value is NULL */
178        if (value)
179                count += strlen(value) + 2;
180
181        if (count > sizeof(tmp)) {
182                if (!(buf = malloc(count)))
183                        return -ENOMEM;
184        }
185
186        if (value)
187                sprintf(buf, "%s=%s", name, value);
188        else
189                strcpy(buf, name);
190
191        ret = write(nvram_fd, buf, count);
192
193        if (ret < 0)
194                perror(PATH_DEV_NVRAM);
195
196        if (buf != tmp)
197                free(buf);
198
199        return (ret == count) ? 0 : ret;
200}
201
202int nvram_set(const char *name, const char *value)
203{
204        extern struct nvram_convert nvram_converts[];
205        struct nvram_convert *v;
206        int ret;
207#ifdef HAVE_NOWIFI
208        if (!strcmp(name, "ip_conntrack_max") && value != NULL) {
209                int val = atoi(value);
210                if (val > 4096) {
211                        return _nvram_set(name, "4096");
212                }
213
214        }
215#endif
216        ret = _nvram_set(name, value);
217
218        for (v = nvram_converts; v->name; v++) {
219                if (!strcmp(v->name, name)) {
220                        if (strcmp(v->wl0_name, ""))
221                                _nvram_set(v->wl0_name, value);
222                }
223        }
224        return ret;
225}
226
227int nvram_immed_set(const char *name, const char *value)
228{
229        return nvram_set(name, value);
230}
231
232int nvram_unset(const char *name)
233{
234//lock();
235        int v = _nvram_set(name, NULL);
236//unlock();
237        return v;
238}
239
240int nvram_commit(void)
241{
242        if (nvram_match("flash_active", "1")) {
243                fprintf(stderr, "not allowed, flash process in progress");
244                exit(1);
245        }
246#if defined(HAVE_WZRHPG300NH) || defined(HAVE_WHRHPGN) || defined(HAVE_WZRHPAG300NH) || defined(HAVE_DIR825) || defined(HAVE_TEW632BRP) || defined(HAVE_TG2521) || defined(HAVE_WR1043)  || defined(HAVE_WRT400) || defined(HAVE_WZRHPAG300NH) || defined(HAVE_WZRG450) || defined(HAVE_DANUBE)
247        system("/sbin/ledtool 1");
248#elif HAVE_LSX
249        //nothing
250#else
251        system("/sbin/ledtool 1");
252#endif
253        lock();
254        int ret;
255        if (nvram_fd < 0) {
256                if ((ret = nvram_init(NULL))) {
257                        fprintf(stderr, "nvram_commit(): failed\n");
258                        unlock();
259                        return ret;
260                }
261        }
262        ret = ioctl(nvram_fd, NVRAM_MAGIC, NULL);
263
264        if (ret < 0) {
265                fprintf(stderr, "nvram_commit(): failed\n");
266                perror(PATH_DEV_NVRAM);
267        }
268        unlock();
269        sync();
270        return ret;
271}
272
273int file2nvram(char *filename, char *varname)
274{
275        FILE *fp;
276        int c, count;
277        int i = 0, j = 0;
278        char mem[10000], buf[30000];
279
280        if (!(fp = fopen(filename, "rb")))
281                return 0;
282
283        count = fread(mem, 1, sizeof(mem), fp);
284        fclose(fp);
285        for (j = 0; j < count; j++) {
286                if (i > sizeof(buf) - 3)
287                        break;
288                c = mem[j];
289                if (c >= 32 && c <= 126 && c != '~') {
290                        buf[i++] = (unsigned char)c;
291                } else if (c == 13) {
292                        buf[i++] = (unsigned char)c;
293                } else if (c == 0) {
294                        buf[i++] = '~';
295                } else if (c == 10) {
296                        buf[i++] = (unsigned char)c;
297                } else {
298                        buf[i++] = '\\';
299                        sprintf(buf + i, "%02X", c);
300                        i += 2;
301                }
302        }
303        if (i == 0)
304                return 0;
305        buf[i] = 0;
306        //fprintf(stderr,"================ > file2nvram %s = [%s] \n",varname,buf);
307        nvram_set(varname, buf);
308        return 0;
309
310}
311
312int nvram2file(char *varname, char *filename)
313{
314        FILE *fp;
315        int c, tmp;
316        int i = 0, j = 0;
317        char *buf;
318        char mem[10000];
319
320        if (!(fp = fopen(filename, "wb")))
321                return 0;
322
323        buf = strdup(nvram_safe_get(varname));
324        //fprintf(stderr,"=================> nvram2file %s = [%s] \n",varname,buf);
325        while (buf[i] && j < sizeof(mem) - 3) {
326/*        if (buf[i] == '\\')  {
327                i++;
328                tmp=buf[i+2];
329                buf[i+2]=0;
330                sscanf(buf+i,"%02X",&c);
331                buf[i+2]=tmp;
332                i+=2;
333                mem[j]=c;j++;
334        } else */
335                if (buf[i] == '~') {
336                        mem[j] = 0;
337                        j++;
338                        i++;
339                } else {
340                        mem[j] = buf[i];
341                        j++;
342                        i++;
343                }
344        }
345        if (j <= 0)
346                return j;
347        j = fwrite(mem, 1, j, fp);
348        fclose(fp);
349        free(buf);
350        return j;
351}
352
353#include "nvram_generics.h"
Note: See TracBrowser for help on using the repository browser.