netifd: update to latest git HEAD
[oweals/openwrt.git] / package / utils / nvram / src / cli.c
1 /*
2  * Command line interface for libnvram
3  *
4  * Copyright 2009, Jo-Philipp Wich <xm@subsignal.org>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  *
21  * The libnvram code is based on Broadcom code for Linux 2.4.x .
22  *
23  */
24
25 #include "nvram.h"
26
27
28 static nvram_handle_t * nvram_open_rdonly(void)
29 {
30         char *file = nvram_find_staging();
31
32         if( file == NULL )
33                 file = nvram_find_mtd();
34
35         if( file != NULL ) {
36                 nvram_handle_t *h = nvram_open(file, NVRAM_RO);
37                 if( strcmp(file, NVRAM_STAGING) )
38                         free(file);
39                 return h;
40         }
41
42         return NULL;
43 }
44
45 static nvram_handle_t * nvram_open_staging(void)
46 {
47         if( nvram_find_staging() != NULL || nvram_to_staging() == 0 )
48                 return nvram_open(NVRAM_STAGING, NVRAM_RW);
49
50         return NULL;
51 }
52
53 static int do_show(nvram_handle_t *nvram)
54 {
55         nvram_tuple_t *t;
56         int stat = 1;
57
58         if( (t = nvram_getall(nvram)) != NULL )
59         {
60                 while( t )
61                 {
62                         printf("%s=%s\n", t->name, t->value);
63                         t = t->next;
64                 }
65
66                 stat = 0;
67         }
68
69         return stat;
70 }
71
72 static int do_get(nvram_handle_t *nvram, const char *var)
73 {
74         const char *val;
75         int stat = 1;
76
77         if( (val = nvram_get(nvram, var)) != NULL )
78         {
79                 printf("%s\n", val);
80                 stat = 0;
81         }
82
83         return stat;
84 }
85
86 static int do_unset(nvram_handle_t *nvram, const char *var)
87 {
88         return nvram_unset(nvram, var);
89 }
90
91 static int do_set(nvram_handle_t *nvram, const char *pair)
92 {
93         char *val = strstr(pair, "=");
94         char var[strlen(pair)];
95         int stat = 1;
96
97         if( val != NULL )
98         {
99                 memset(var, 0, sizeof(var));
100                 strncpy(var, pair, (int)(val-pair));
101                 stat = nvram_set(nvram, var, (char *)(val + 1));
102         }
103
104         return stat;
105 }
106
107 static int do_info(nvram_handle_t *nvram)
108 {
109         nvram_header_t *hdr = nvram_header(nvram);
110
111         /* CRC8 over the last 11 bytes of the header and data bytes */
112         uint8_t crc = hndcrc8((unsigned char *) &hdr[0] + NVRAM_CRC_START_POSITION,
113                 hdr->len - NVRAM_CRC_START_POSITION, 0xff);
114
115         /* Show info */
116         printf("Magic:         0x%08X\n",   hdr->magic);
117         printf("Length:        0x%08X\n",   hdr->len);
118         printf("Offset:        0x%08X\n",   nvram->offset);
119
120         printf("CRC8:          0x%02X (calculated: 0x%02X)\n",
121                 hdr->crc_ver_init & 0xFF, crc);
122
123         printf("Version:       0x%02X\n",   (hdr->crc_ver_init >> 8) & 0xFF);
124         printf("SDRAM init:    0x%04X\n",   (hdr->crc_ver_init >> 16) & 0xFFFF);
125         printf("SDRAM config:  0x%04X\n",   hdr->config_refresh & 0xFFFF);
126         printf("SDRAM refresh: 0x%04X\n",   (hdr->config_refresh >> 16) & 0xFFFF);
127         printf("NCDL values:   0x%08X\n\n", hdr->config_ncdl);
128
129         printf("%i bytes used / %i bytes available (%.2f%%)\n",
130                 hdr->len, nvram->length - nvram->offset - hdr->len,
131                 (100.00 / (double)(nvram->length - nvram->offset)) * (double)hdr->len);
132
133         return 0;
134 }
135
136 static void usage(void)
137 {
138         fprintf(stderr,
139                 "Usage:\n"
140                 "       nvram show\n"
141                 "       nvram info\n"
142                 "       nvram get variable\n"
143                 "       nvram set variable=value [set ...]\n"
144                 "       nvram unset variable [unset ...]\n"
145                 "       nvram commit\n"
146         );
147 }
148
149 int main( int argc, const char *argv[] )
150 {
151         nvram_handle_t *nvram;
152         int commit = 0;
153         int write = 0;
154         int stat = 1;
155         int done = 0;
156         int i;
157
158         if( argc < 2 ) {
159                 usage();
160                 return 1;
161         }
162
163         /* Ugly... iterate over arguments to see whether we can expect a write */
164         if( ( !strcmp(argv[1], "set")  && 2 < argc ) ||
165                 ( !strcmp(argv[1], "unset") && 2 < argc ) ||
166                 !strcmp(argv[1], "commit") )
167                 write = 1;
168
169
170         nvram = write ? nvram_open_staging() : nvram_open_rdonly();
171
172         if( nvram != NULL && argc > 1 )
173         {
174                 for( i = 1; i < argc; i++ )
175                 {
176                         if( !strcmp(argv[i], "show") )
177                         {
178                                 stat = do_show(nvram);
179                                 done++;
180                         }
181                         else if( !strcmp(argv[i], "info") )
182                         {
183                                 stat = do_info(nvram);
184                                 done++;
185                         }
186                         else if( !strcmp(argv[i], "get") || !strcmp(argv[i], "unset") || !strcmp(argv[i], "set") )
187                         {
188                                 if( (i+1) < argc )
189                                 {
190                                         switch(argv[i++][0])
191                                         {
192                                                 case 'g':
193                                                         stat = do_get(nvram, argv[i]);
194                                                         break;
195
196                                                 case 'u':
197                                                         stat = do_unset(nvram, argv[i]);
198                                                         break;
199
200                                                 case 's':
201                                                         stat = do_set(nvram, argv[i]);
202                                                         break;
203                                         }
204                                         done++;
205                                 }
206                                 else
207                                 {
208                                         fprintf(stderr, "Command '%s' requires an argument!\n", argv[i]);
209                                         done = 0;
210                                         break;
211                                 }
212                         }
213                         else if( !strcmp(argv[i], "commit") )
214                         {
215                                 commit = 1;
216                                 done++;
217                         }
218                         else
219                         {
220                                 fprintf(stderr, "Unknown option '%s' !\n", argv[i]);
221                                 done = 0;
222                                 break;
223                         }
224                 }
225
226                 if( write )
227                         stat = nvram_commit(nvram);
228
229                 nvram_close(nvram);
230
231                 if( commit )
232                         stat = staging_to_nvram();
233         }
234
235         if( !nvram )
236         {
237                 fprintf(stderr,
238                         "Could not open nvram! Possible reasons are:\n"
239                         "       - No device found (/proc not mounted or no nvram present)\n"
240                         "       - Insufficient permissions to open mtd device\n"
241                         "       - Insufficient memory to complete operation\n"
242                         "       - Memory mapping failed or not supported\n"
243                         "       - Nvram magic not found in specific nvram partition\n"
244                 );
245
246                 stat = 1;
247         }
248         else if( !done )
249         {
250                 usage();
251                 stat = 1;
252         }
253
254         return stat;
255 }