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

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

block only get functions until nvram is available

File size: 6.9 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#ifdef HAVE_X86
95                FILE *in = fopen("/usr/local/nvram/nvram.bin", "rb");
96                if (in == NULL)
97                        return NULL;
98                fclose(in);
99#endif
100                if (nvram_init(NULL)) {
101                        //unlock();
102                        return NULL;
103                }
104        }
105        if (count > sizeof(tmp)) {
106                if (!(off = malloc(count))) {
107                        //unlock();
108                        return NULL;
109                }
110        }
111
112        /* Get offset into mmap() space */
113        strcpy((char *)off, name);
114
115        count = read(nvram_fd, off, count);
116
117        if (count == sizeof(unsigned long))
118                value = &nvram_buf[*off];
119        else
120                value = NULL;
121
122#ifndef HAVE_MICRO
123        if (value)
124                msync(nvram_buf, NVRAM_SPACE, MS_INVALIDATE);
125#endif
126        if (count < 0)
127                perror(PATH_DEV_NVRAM);
128
129        if (off != (unsigned long *)tmp)
130                free(off);
131        //unlock();
132
133        return value;
134}
135
136int nvram_getall(char *buf, int count)
137{
138//lock();
139        int ret;
140
141        if (nvram_fd < 0) {
142#ifdef HAVE_X86
143                FILE *in = fopen("/usr/local/nvram/nvram.bin", "rb");
144                if (in == NULL)
145                        return 0;
146                fclose(in);
147#endif
148                if ((ret = nvram_init(NULL))) {
149                        //unlock();
150                        return ret;
151                }
152        }
153        if (count == 0) {
154                //unlock();
155                return 0;
156        }
157        /* Get all variables */
158        *buf = '\0';
159
160        ret = read(nvram_fd, buf, count);
161
162        if (ret < 0)
163                perror(PATH_DEV_NVRAM);
164        //unlock();
165        return (ret == count) ? 0 : ret;
166}
167
168void nvram_open(void)           // dummy
169{
170}
171
172void nvram_close(void)          //dummy
173{
174}
175
176static int _nvram_set(const char *name, const char *value)
177{
178        size_t count = strlen(name) + 1;
179        char tmp[100], *buf = tmp;
180        int ret;
181
182        if (nvram_fd < 0)
183                if ((ret = nvram_init(NULL)))
184                        return ret;
185
186        /* Wolf add - keep nvram varname to sane len - may prevent corruption */
187        if (strlen(name) > 64)
188                return -ENOMEM;
189
190        /* Unset if value is NULL */
191        if (value)
192                count += strlen(value) + 2;
193
194        if (count > sizeof(tmp)) {
195                if (!(buf = malloc(count)))
196                        return -ENOMEM;
197        }
198
199        if (value)
200                sprintf(buf, "%s=%s", name, value);
201        else
202                strcpy(buf, name);
203
204        ret = write(nvram_fd, buf, count);
205
206        if (ret < 0)
207                perror(PATH_DEV_NVRAM);
208
209        if (buf != tmp)
210                free(buf);
211
212        return (ret == count) ? 0 : ret;
213}
214
215int nvram_set(const char *name, const char *value)
216{
217        extern struct nvram_convert nvram_converts[];
218        struct nvram_convert *v;
219        int ret;
220#ifdef HAVE_NOWIFI
221        if (!strcmp(name, "ip_conntrack_max") && value != NULL) {
222                int val = atoi(value);
223                if (val > 4096) {
224                        return _nvram_set(name, "4096");
225                }
226
227        }
228#endif
229        ret = _nvram_set(name, value);
230
231        for (v = nvram_converts; v->name; v++) {
232                if (!strcmp(v->name, name)) {
233                        if (strcmp(v->wl0_name, ""))
234                                _nvram_set(v->wl0_name, value);
235                }
236        }
237        return ret;
238}
239
240int nvram_immed_set(const char *name, const char *value)
241{
242        return nvram_set(name, value);
243}
244
245int nvram_unset(const char *name)
246{
247//lock();
248        int v = _nvram_set(name, NULL);
249//unlock();
250        return v;
251}
252
253int nvram_commit(void)
254{
255        if (nvram_match("flash_active", "1")) {
256                fprintf(stderr, "not allowed, flash process in progress");
257                exit(1);
258        }
259#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)
260        system("/sbin/ledtool 1");
261#elif HAVE_LSX
262        //nothing
263#else
264        system("/sbin/ledtool 1");
265#endif
266        lock();
267        int ret;
268        if (nvram_fd < 0) {
269                if ((ret = nvram_init(NULL))) {
270                        fprintf(stderr, "nvram_commit(): failed\n");
271                        unlock();
272                        return ret;
273                }
274        }
275        ret = ioctl(nvram_fd, NVRAM_MAGIC, NULL);
276
277        if (ret < 0) {
278                fprintf(stderr, "nvram_commit(): failed\n");
279                perror(PATH_DEV_NVRAM);
280        }
281        unlock();
282        sync();
283        return ret;
284}
285
286int file2nvram(char *filename, char *varname)
287{
288        FILE *fp;
289        int c, count;
290        int i = 0, j = 0;
291        char mem[10000], buf[30000];
292
293        if (!(fp = fopen(filename, "rb")))
294                return 0;
295
296        count = fread(mem, 1, sizeof(mem), fp);
297        fclose(fp);
298        for (j = 0; j < count; j++) {
299                if (i > sizeof(buf) - 3)
300                        break;
301                c = mem[j];
302                if (c >= 32 && c <= 126 && c != '~') {
303                        buf[i++] = (unsigned char)c;
304                } else if (c == 13) {
305                        buf[i++] = (unsigned char)c;
306                } else if (c == 0) {
307                        buf[i++] = '~';
308                } else if (c == 10) {
309                        buf[i++] = (unsigned char)c;
310                } else {
311                        buf[i++] = '\\';
312                        sprintf(buf + i, "%02X", c);
313                        i += 2;
314                }
315        }
316        if (i == 0)
317                return 0;
318        buf[i] = 0;
319        //fprintf(stderr,"================ > file2nvram %s = [%s] \n",varname,buf);
320        nvram_set(varname, buf);
321        return 0;
322
323}
324
325int nvram2file(char *varname, char *filename)
326{
327        FILE *fp;
328        int c, tmp;
329        int i = 0, j = 0;
330        char *buf;
331        char mem[10000];
332
333        if (!(fp = fopen(filename, "wb")))
334                return 0;
335
336        buf = strdup(nvram_safe_get(varname));
337        //fprintf(stderr,"=================> nvram2file %s = [%s] \n",varname,buf);
338        while (buf[i] && j < sizeof(mem) - 3) {
339/*        if (buf[i] == '\\')  {
340                i++;
341                tmp=buf[i+2];
342                buf[i+2]=0;
343                sscanf(buf+i,"%02X",&c);
344                buf[i+2]=tmp;
345                i+=2;
346                mem[j]=c;j++;
347        } else */
348                if (buf[i] == '~') {
349                        mem[j] = 0;
350                        j++;
351                        i++;
352                } else {
353                        mem[j] = buf[i];
354                        j++;
355                        i++;
356                }
357        }
358        if (j <= 0)
359                return j;
360        j = fwrite(mem, 1, j, fp);
361        fclose(fp);
362        free(buf);
363        return j;
364}
365
366#include "nvram_generics.h"
Note: See TracBrowser for help on using the repository browser.