Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / nvram / nvram.c
blob4afd737e85589f924f53731717af63cb3bb1344e
1 /*
3 NVRAM Utility
4 Copyright (C) 2006-2009 Jonathan Zarate
6 */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <unistd.h>
12 #include <ctype.h>
13 #include <sys/wait.h>
15 #include <bcmdevs.h>
16 #include <bcmnvram.h>
17 #include <utils.h>
18 #include <shutils.h>
19 #include <shared.h>
21 #include "nvram_convert.h"
22 #include "defaults.h"
25 __attribute__ ((noreturn))
26 static void help(void)
28 printf(
29 "NVRAM Utility\n"
30 "Copyright (C) 2006-2009 Jonathan Zarate\n\n"
31 "Usage: nvram set <key=value> | get <key> | unset <key> | default_get <key> [only work on K26AC routers]\n"
32 "ren <key> <key> | commit | erase | show [--nosort|--nostat] |\n"
33 "find <text> | defaults <--yes|--initcheck> | backup <filename> |\n"
34 "restore <filename> [--test] [--force] [--forceall] [--nocommit] |\n"
35 "export <--quote|--c|--set|--tab> [--nodefaults] |\n"
36 "export <--dump|--dump0> | import [--forceall] <filename> |\n"
37 "setfb64 <key> <filename> | getfb64 <key> <filename> |\n"
38 "setfile <key> <filename> | getfile <key> <filename> | setfile2nvram <filename>"
39 // "test"
40 "\n");
41 exit(1);
44 static void getall(char *buffer)
46 if (nvram_getall(buffer, NVRAM_SPACE) != 0) {
47 fprintf(stderr, "Error reading NVRAM\n");
48 exit(1);
52 static int set_main(int argc, char **argv)
54 char *b, *p;
56 if ((b = strdup(argv[1])) == NULL) {
57 fprintf(stderr, "Not enough memory");
58 return 1;
60 if ((p = strchr(b, '=')) != NULL) {
61 *p = 0;
62 nvram_set(b, p + 1);
63 return 0;
65 help();
68 static int get_main(int argc, char **argv)
70 char *p;
72 if ((p = nvram_get(argv[1])) != NULL) {
73 puts(p);
74 return 0;
76 return 1;
79 static int unset_main(int argc, char **argv)
81 nvram_unset(argv[1]);
82 return 0;
85 static int ren_main(int argc, char **argv)
87 char *p;
89 if ((p = nvram_get(argv[1])) == NULL) {
90 fprintf(stderr, "Unable to find %s\n", argv[1]);
91 return 1;
93 if (strcmp(argv[1], argv[2]) != 0) {
94 nvram_set(argv[2], p);
95 nvram_unset(argv[1]);
97 return 0;
100 extern int nvram_file2nvram(const char *name, const char *filename);
101 extern int nvram_nvram2file(const char *name, const char *filename);
103 static int f2n_main(int argc, char **argv)
105 return (nvram_file2nvram(argv[1], argv[2]));
109 static int n2f_main(int argc, char **argv)
111 return (nvram_nvram2file(argv[1], argv[2]));
114 static int save2f_main(int argc, char **argv)
116 char name[128] = "FILE:";
118 strcpy(name+5, argv[1]);
119 return (nvram_file2nvram(name, argv[1]));
121 static int default_get_main(int argc, char **argv){
122 char *p;
124 #ifdef CONFIG_BCMWL6
125 if ((p = nvram_default_get(argv[1])) != NULL) {
126 puts(p);
127 return 0;
129 #endif
130 return 1;
132 static int show_main(int argc, char **argv)
134 char *p, *q;
135 char buffer[NVRAM_SPACE];
136 int n;
137 int count;
138 int show = 1;
139 int stat = 1;
140 int sort = 1;
142 for (n = 1; n < argc; ++n) {
143 if (strcmp(argv[n], "--nostat") == 0) stat = 0;
144 else if (strcmp(argv[n], "--nosort") == 0) sort = 0;
145 else help();
148 if (sort) {
149 system("nvram show --nostat --nosort | sort"); // smallest and easiest way :)
150 show = 0;
153 getall(buffer);
154 count = 0;
155 for (p = buffer; *p; p += strlen(p) + 1) {
156 q = p;
157 while (*q) {
158 if (!isprint(*q)) *q = ' ';
159 ++q;
161 if (show) puts(p);
162 ++count;
164 if (stat) {
165 n = sizeof(struct nvram_header) + (p - buffer);
166 printf("---\n%d entries, %d bytes used, %d bytes free.\n", count, n, NVRAM_SPACE - n);
168 return 0;
171 static int find_main(int argc, char **argv)
173 char cmd[512];
174 int r;
176 snprintf(cmd, sizeof(cmd), "nvram show --nostat --nosort | sort | grep \"%s\"", argv[1]);
177 r = system(cmd);
178 return (r == -1) ? 1 : WEXITSTATUS(r);
181 static const char *nv_default_value(const defaults_t *t)
183 int model = get_model();
185 if (strcmp(t->key, "wl_txpwr") == 0) {
186 switch (model) {
187 case MODEL_WHRG54S:
188 return "28";
189 #ifdef CONFIG_BCMWL5
190 case MODEL_RTN10:
191 case MODEL_RTN12:
192 case MODEL_RTN16:
193 return "17";
194 #endif
197 #ifdef TCONFIG_USB
198 else if (strcmp(t->key, "usb_enable") == 0) {
199 switch (model) {
200 case MODEL_WRTSL54GS:
201 case MODEL_WL500W:
202 case MODEL_WL500GP:
203 case MODEL_WL500GPv2:
204 case MODEL_WL500GE:
205 case MODEL_WL500GD:
206 case MODEL_WL520GU:
207 case MODEL_DIR320:
208 case MODEL_H618B:
209 case MODEL_WNR3500L:
210 case MODEL_RTN16:
211 case MODEL_WRT610Nv2:
212 case MODEL_F7D3301:
213 case MODEL_F7D3302:
214 case MODEL_F7D4301:
215 case MODEL_F7D4302:
216 case MODEL_F5D8235v3:
217 return "1";
220 #endif
221 return t->value;
224 static void nv_fix_wl(const char *oldnv, const char *newnv)
226 char *p;
228 if (nvram_get(wl_nvname(newnv, 0, 0)) == NULL) {
229 p = nvram_get(oldnv);
230 if (p != NULL) nvram_set(wl_nvname(newnv, -1, 0), p);
231 nvram_unset(oldnv);
235 static int validate_main(int argc, char **argv)
237 const defaults_t *t;
238 char *p;
239 int i;
240 int force = 0;
241 int unit = 0;
243 for (i = 1; i < argc; ++i) {
244 if (strcmp(argv[i], "--restore") == 0) {
245 force = 1;
247 else if (strncmp(argv[i], "--wl", 4) == 0) {
248 unit = atoi(argv[i] + 4);
252 for (t = defaults; t->key; t++) {
253 if (strncmp(t->key, "wl_", 3) == 0) {
254 // sync wl_ and wlX_
255 p = wl_nvname(t->key + 3, unit, 0);
256 if (force || nvram_get(p) == NULL)
257 nvram_set(p, t->value);
260 return 0;
263 static int defaults_main(int argc, char **argv)
265 const defaults_t *t;
266 char *p;
267 char s[256];
268 int i, j;
269 int force = 0;
270 int commit = 0;
272 if (strcmp(argv[1], "--yes") == 0) {
273 force = 1;
275 else if (strcmp(argv[1], "--initcheck") != 0) {
276 help();
279 if ((!nvram_match("restore_defaults", "0")) || (!nvram_match("os_name", "linux"))) {
280 force = 1;
283 #if 0 // --need to test--
284 // prevent lockout if upgrading from DD-WRT v23 SP2+ w/ encrypted password
285 if (nvram_match("nvram_ver", "2")) {
286 nvram_unset("nvram_ver");
288 // If username is "", root or admin, then nvram_ver was probably a left-over
289 // from an old DD-WRT installation (ex: DD-WRT -> Linksys (reset) ->
290 // Tomato) and we don't need to do anything. Otherwise, reset.
291 if ((p = nvram_get("httpd_username")) != NULL) {
292 if ((*p != 0) && (strcmp(p, "root") != 0) && (strcmp(p, "admin") != 0)) {
293 nvram_unset("httpd_passwd");
294 nvram_unset("httpd_username"); // not used here, but dd will try to re-encrypt this
295 // filled below
299 #else
300 if (force) nvram_unset("nvram_ver"); // prep to prevent problems later
301 #endif
303 // keep the compatibility with old security_mode2, wds_enable, mac_wl - removeme after 1/1/2012
304 nv_fix_wl("security_mode2", "security_mode");
305 nv_fix_wl("wds_enable", "wds_enable");
306 nv_fix_wl("mac_wl", "macaddr");
308 for (t = defaults; t->key; t++) {
309 if (((p = nvram_get(t->key)) == NULL) || (force)) {
310 if (t->value == NULL) {
311 if (p != NULL) {
312 nvram_unset(t->key);
313 if (!force) _dprintf("%s=%s is not the default (NULL) - resetting\n", t->key, p);
314 commit = 1;
317 else {
318 nvram_set(t->key, nv_default_value(t));
319 if (!force) _dprintf("%s=%s is not the default (%s) - resetting\n", t->key, p ? p : "(NULL)", nv_default_value(t));
320 commit = 1;
323 else if (strncmp(t->key, "wl_", 3) == 0) {
324 // sync wl_ and wl0_
325 strcpy(s, "wl0_");
326 strcat(s, t->key + 3);
327 if (nvram_get(s) == NULL) nvram_set(s, nvram_safe_get(t->key));
331 // todo: moveme
332 if ((strtoul(nvram_safe_get("boardflags"), NULL, 0) & BFL_ENETVLAN) ||
333 (check_hw_type() == HW_BCM4712)) t = if_vlan;
334 else t = if_generic;
335 for (; t->key; t++) {
336 if (((p = nvram_get(t->key)) == NULL) || (*p == 0) || (force)) {
337 nvram_set(t->key, t->value);
338 commit = 1;
339 if (!force) _dprintf("%s=%s is not the default (%s) - resetting\n", t->key, p ? p : "(NULL)", t->value);
343 if (force) {
344 for (j = 0; j < 2; j++) {
345 for (i = 0; i < 20; i++) {
346 sprintf(s, "wl%d_wds%d", j, i);
347 nvram_unset(s);
351 for (i = 0; i < LED_COUNT; ++i) {
352 sprintf(s, "led_%s", led_names[i]);
353 nvram_unset(s);
356 // 0 = example
357 for (i = 1; i < 50; i++) {
358 sprintf(s, "rrule%d", i);
359 nvram_unset(s);
363 if (!nvram_match("boot_wait", "on")) {
364 nvram_set("boot_wait", "on");
365 commit = 1;
368 nvram_set("os_name", "linux");
369 nvram_set("os_version", tomato_version);
370 nvram_set("os_date", tomato_buildtime);
372 if ((commit) || (force)) {
373 printf("Saving...\n");
374 nvram_commit();
376 else {
377 printf("No change was necessary.\n");
379 return 0;
382 static int commit_main(int argc, char **argv)
384 int r;
386 printf("Commit... ");
387 fflush(stdout);
388 r = nvram_commit();
389 printf("done.\n");
390 return r ? 1 : 0;
393 static int erase_main(int argc, char **argv)
395 printf("Erasing nvram...\n");
396 return eval("mtd-erase", "-d", "nvram");
400 * Find nvram param name; return pointer which should be treated as const
401 * return NULL if not found.
403 * NOTE: This routine special-cases the variable wl_bss_enabled. It will
404 * return the normal default value if asked for wl_ or wl0_. But it will
405 * return 0 if asked for a virtual BSS reference like wl0.1_.
407 static const char *get_default_value(const char *name)
409 char *p;
410 const defaults_t *t;
411 char fixed_name[NVRAM_MAX_PARAM_LEN + 1];
413 if (strncmp(name, "wl", 2) == 0 && isdigit(name[2]) && ((p = strchr(name, '_'))))
414 snprintf(fixed_name, sizeof(fixed_name) - 1, "wl%s", p);
415 else
416 strncpy(fixed_name, name, sizeof(fixed_name));
418 if (strcmp(fixed_name, "wl_bss_enabled") == 0) {
419 if (name[3] == '.' || name[4] == '.') /* Virtual interface */
420 return "0";
423 for (t = defaults; t->key; t++) {
424 if (strcmp(t->key, name) == 0 || strcmp(t->key, fixed_name) == 0)
425 return (t->value ? : "");
428 return NULL;
431 #define X_QUOTE 0
432 #define X_SET 1
433 #define X_C 2
434 #define X_TAB 3
436 static int export_main(int argc, char **argv)
438 char *p;
439 char buffer[NVRAM_SPACE];
440 int eq;
441 int mode;
442 int all, n, skip;
443 char *bk, *bv, *v;
445 // C, set, quote
446 static const char *start[4] = { "\"", "nvram set ", "{ \"", "" };
447 static const char *stop[4] = { "\"", "\"", "\" },", "" };
450 getall(buffer);
451 p = buffer;
453 all = 1;
454 for (n = 1; n < argc; ++n) {
455 if (strcmp(argv[n], "--nodefaults") == 0) {
456 if (argc < 3) help();
457 all = 0;
458 if (n == 1) ++argv;
459 break;
463 if (strcmp(argv[1], "--dump") == 0) {
464 if (!all) help();
465 for (p = buffer; *p; p += strlen(p) + 1) {
466 puts(p);
468 return 0;
470 if (strcmp(argv[1], "--dump0") == 0) {
471 if (!all) help();
472 for (p = buffer; *p; p += strlen(p) + 1) { }
473 fwrite(buffer, p - buffer, 1, stdout);
474 return 0;
477 if (strcmp(argv[1], "--c") == 0) mode = X_C;
478 else if (strcmp(argv[1], "--set") == 0) mode = X_SET;
479 else if (strcmp(argv[1], "--tab") == 0) mode = X_TAB;
480 else if (strcmp(argv[1], "--quote") == 0) mode = X_QUOTE;
481 else help();
483 while (*p) {
484 eq = 0;
486 if (!all) {
487 skip = 0;
488 bk = p;
489 p += strlen(p) + 1;
490 bv = strchr(bk, '=');
491 *bv++ = 0;
493 if ((v = (char *)get_default_value(bk)) != NULL) {
494 skip = (strcmp(bv, v) == 0);
497 *(bv - 1) = '=';
498 if (skip)
499 continue;
500 else
501 p = bk;
504 printf("%s", start[mode]);
505 do {
506 switch (*p) {
507 case 9:
508 if (mode == X_SET) putchar(*p);
509 else printf("\\t");
510 break;
511 case 13:
512 if (mode == X_SET) putchar(*p);
513 else printf("\\r");
514 break;
515 case 10:
516 if (mode == X_SET) putchar(*p);
517 else printf("\\n");
518 break;
519 case '"':
520 case '\\':
521 printf("\\%c", *p);
522 break;
523 case '$':
524 case '`':
525 if (mode != X_SET) putchar(*p);
526 else printf("\\%c", *p);
527 break;
528 case '=':
529 if ((eq == 0) && (mode > X_QUOTE)) {
530 printf((mode == X_C) ? "\", \"" :
531 ((mode == X_SET) ? "=\"" : "\t"));
532 eq = 1;
533 break;
535 eq = 1;
536 default:
537 if (!isprint(*p)) printf("\\x%02x", *p);
538 else putchar(*p);
539 break;
541 ++p;
542 } while (*p);
543 printf("%s\n", stop[mode]);
544 ++p;
546 return 0;
549 static int in_defaults(const char *key)
551 const defaults_t *t;
552 int n;
554 for (t = defaults; t->key; t++) {
555 if (strcmp(t->key, key) == 0) return 1;
558 if ((strncmp(key, "rrule", 5) == 0) && ((n = atoi(key + 5)) > 0) && (n < 50)) return 1;
560 return 0;
563 static int import_main(int argc, char **argv)
565 FILE *f;
566 char s[10240];
567 int n;
568 char *k, *v;
569 char *p, *q;
570 int all;
571 int same, skip, set;
573 all = 0;
574 if (strcmp(argv[1], "--forceall") == 0) {
575 all = 1;
576 ++argv;
579 if ((f = fopen(argv[1], "r")) == NULL) {
580 printf("Error opening file.\n");
581 return 1;
584 same = skip = set = 0;
586 while (fgets(s, sizeof(s), f) != NULL) {
587 n = strlen(s);
588 while ((--n > 0) && (isspace(s[n]))) ;
589 if ((n <= 0) || (s[n] != '"')) continue;
590 s[n] = 0;
592 k = s;
593 while (isspace(*k)) ++k;
594 if (*k != '"') continue;
595 ++k;
597 if ((v = strchr(k, '=')) == NULL) continue;
598 *v++ = 0;
600 p = q = v;
601 while (*p) {
602 if (*p == '\\') {
603 ++p;
604 switch (*p) {
605 case 't':
606 *q++ = '\t';
607 break;
608 case 'r':
609 *q++ = '\n';
610 break;
611 case 'n':
612 *q++ = '\n';
613 break;
614 case '\\':
615 case '"':
616 *q++ = *p;
617 break;
618 default:
619 printf("Error unescaping %s=%s\n", k, v);
620 return 1;
623 else {
624 *q++ = *p;
626 ++p;
628 *q = 0;
630 if ((all) || (in_defaults(k))) {
631 if (nvram_match(k, v)) {
632 ++same;
633 // printf("SAME: %s=%s\n", k, v);
635 else {
636 ++set;
637 printf("%s=%s\n", k, v);
638 nvram_set(k, v);
641 else {
642 ++skip;
643 // printf("SKIP: %s=%s\n", k, v);
647 fclose(f);
649 printf("---\n%d skipped, %d same, %d set\n", skip, same, set);
650 return 0;
653 #define V1 0x31464354L
655 typedef struct {
656 unsigned long sig;
657 unsigned long hwid;
658 char buffer[NVRAM_SPACE];
659 } backup_t;
661 static int backup_main(int argc, char **argv)
663 backup_t data;
664 unsigned int size;
665 char *p;
666 char s[512];
667 char tmp[128];
668 int r;
670 getall(data.buffer);
672 data.sig = V1;
673 data.hwid = check_hw_type();
675 p = data.buffer;
676 while (*p != 0) p += strlen(p) + 1;
678 size = (sizeof(data) - sizeof(data.buffer)) + (p - data.buffer) + 1;
680 strcpy(tmp, "/tmp/nvramXXXXXX");
681 mktemp(tmp);
682 if (f_write(tmp, &data, size, 0, 0) != size) {
683 printf("Error saving file.\n");
684 return 1;
686 sprintf(s, "gzip < %s > %s", tmp, argv[1]);
687 r = system(s);
688 unlink(tmp);
690 if (r != 0) {
691 unlink(argv[1]);
692 printf("Error compressing file.\n");
693 return 1;
696 printf("Saved.\n");
697 return 0;
700 static int restore_main(int argc, char **argv)
702 char *name;
703 int test;
704 int force;
705 int commit;
706 backup_t data;
707 unsigned int size;
708 char s[512];
709 char tmp[128];
710 unsigned long hw;
711 char current[NVRAM_SPACE];
712 char *b, *bk, *bv;
713 char *c, *ck, *cv;
714 int nset;
715 int nunset;
716 int nsame;
717 int cmp;
718 int i;
720 test = 0;
721 force = 0;
722 commit = 1;
723 name = NULL;
724 for (i = 1; i < argc; ++i) {
725 if (argv[i][0] == '-') {
726 if (strcmp(argv[i], "--test") == 0) {
727 test = 1;
729 else if (strcmp(argv[i], "--force") == 0) {
730 force = 1;
732 else if (strcmp(argv[i], "--forceall") == 0) {
733 force = 2;
735 else if (strcmp(argv[i], "--nocommit") == 0) {
736 commit = 0;
738 else {
739 help();
742 else {
743 name = argv[i];
746 if (!name) help();
748 strcpy(tmp, "/tmp/nvramXXXXXX");
749 mktemp(tmp);
750 sprintf(s, "gzip -d < %s > %s", name, tmp);
751 if (system(s) != 0) {
752 unlink(tmp);
753 printf("Error decompressing file.\n");
754 return 1;
757 size = f_size(tmp);
758 if ((size <= (sizeof(data) - sizeof(data.buffer))) || (size > sizeof(data)) ||
759 (f_read(tmp, &data, sizeof(data)) != size)) {
760 unlink(tmp);
761 printf("Invalid data size or read error.\n");
762 return 1;
765 unlink(tmp);
767 if (data.sig != V1) {
768 printf("Invalid signature: %08lX / %08lX\n", data.sig, V1);
769 return 1;
772 hw = check_hw_type();
773 if ((data.hwid != hw) && (!force)) {
774 printf("Invalid hardware type: %08lX / %08lX\n", data.hwid, hw);
775 return 1;
778 // 1 - check data
780 size -= sizeof(data) - sizeof(data.buffer);
781 if ((data.buffer[size - 1] != 0) || (data.buffer[size - 2] != 0)) {
782 CORRUPT:
783 printf("Corrupted data area.\n");
784 return 1;
787 b = data.buffer;
788 while (*b) {
789 bk = b;
790 b += strlen(b) + 1;
791 if ((bv = strchr(bk, '=')) == NULL) {
792 goto CORRUPT;
794 *bv = 0;
795 if (strcmp(bk, "et0macaddr") == 0) {
796 if (!nvram_match(bk, bv + 1)) {
797 if (!force) {
798 printf("Cannot restore on a different router.\n");
799 return 1;
803 *bv = '=';
805 if (((b - data.buffer) + 1) != size) {
806 printf("Extra data found at the end.\n");
807 return 1;
811 // 2 - set
813 if (!test) {
814 if (!wait_action_idle(10)) {
815 printf("System busy.\n");
816 return 1;
818 set_action(ACT_SW_RESTORE);
819 led(LED_DIAG, 1);
822 nset = nunset = nsame = 0;
824 b = data.buffer;
825 while (*b) {
826 bk = b;
827 b += strlen(b) + 1;
828 bv = strchr(bk, '=');
829 *bv++ = 0;
831 if ((force != 1) || (in_defaults(bk))) {
832 if (!nvram_match(bk, bv)) {
833 if (test) printf("nvram set \"%s=%s\"\n", bk, bv);
834 else nvram_set(bk, bv);
835 ++nset;
837 else {
838 ++nsame;
842 *(bv - 1) = '=';
846 // 3 - unset
848 getall(current);
849 c = current;
850 while (*c) {
851 ck = c;
852 c += strlen(c) + 1;
853 if ((cv = strchr(ck, '=')) == NULL) {
854 printf("Invalid data in NVRAM: %s.", ck);
855 continue;
857 *cv++ = 0;
859 if ((force != 1) || (in_defaults(ck))) {
860 cmp = 1;
861 b = data.buffer;
862 while (*b) {
863 bk = b;
864 b += strlen(b) + 1;
865 bv = strchr(bk, '=');
866 *bv++ = 0;
867 cmp = strcmp(bk, ck);
868 *(bv - 1) = '=';
869 if (cmp == 0) break;
871 if (cmp != 0) {
872 ++nunset;
873 if (test) printf("nvram unset \"%s\"\n", ck);
874 else nvram_unset(ck);
880 if ((nset == 0) && (nunset == 0)) commit = 0;
881 printf("\nPerformed %d set and %d unset operations. %d required no changes.\n%s\n",
882 nset, nunset, nsame, commit ? "Committing..." : "Not commiting.");
883 fflush(stdout);
885 if (!test) {
886 set_action(ACT_IDLE);
887 if (commit) nvram_commit();
889 return 0;
892 #if 0
893 static int test_main(int argc, char **argv)
896 static const char *extra[] = {
897 "clkfreq", "pa0b0", "pa0b1", "pa0b2", "pa0itssit", "pa0maxpwr",
898 "sdram_config", "sdram_init", "sdram_ncdl", "vlan0ports", NULL };
899 const char **x;
901 char buffer[NVRAM_SPACE];
902 char *k, *v, *e;
903 const defaults_t *rest;
904 struct nvram_convert *conv;
906 printf("Unknown keys:\n");
908 getall(buffer);
909 k = buffer;
910 while (*k) {
911 e = k + strlen(k) + 1;
912 if ((v = strchr(k, '=')) != NULL) {
913 *v = 0;
914 for (rest = defaults; rest->key; ++rest) {
915 if (strcmp(k, rest->key) == 0) break;
917 if (rest->key == NULL) {
918 for (conv = nvram_converts; conv->name; ++conv) {
919 if ((strcmp(k, conv->name) == 0) || (strcmp(k, conv->wl0_name) == 0)) break;
921 if (conv->name == NULL) {
922 printf("%s=%s\n", k, v + 1);
924 for (x = extra; *x; ++x) {
925 if (strcmp(k, *x) == 0) break;
927 if (*x == NULL) {
928 printf("nvram unset \"%s\"\n", k);
934 else {
935 printf("WARNING: '%s' doesn't have a '=' delimiter\n", k);
937 k = e;
940 return 0;
942 #endif
945 static int setfb64_main(int argc, char **argv)
947 if (!nvram_set_file(argv[1], argv[2], 10240)) {
948 fprintf(stderr, "Unable to set %s or read %s\n", argv[1], argv[2]);
949 return 1;
951 return 0;
954 static int getfb64_main(int argc, char **argv)
956 if (!nvram_get_file(argv[1], argv[2], 10240)) {
957 fprintf(stderr, "Unable to get %s or write %s\n", argv[1], argv[2]);
958 return 1;
960 return 0;
963 // -----------------------------------------------------------------------------
965 typedef struct {
966 const char *name;
967 int args;
968 int (*main)(int argc, char *argv[]);
969 } applets_t;
971 static const applets_t applets[] = {
972 { "set", 3, set_main },
973 { "get", 3, get_main },
974 { "unset", 3, unset_main },
975 { "ren", 4, ren_main },
976 { "show", -2, show_main },
977 { "commit", 2, commit_main },
978 { "erase", 2, erase_main },
979 { "find", 3, find_main },
980 { "export", -3, export_main },
981 { "import", -3, import_main },
982 { "defaults", 3, defaults_main },
983 { "validate", -3, validate_main },
984 { "backup", 3, backup_main },
985 { "restore", -3, restore_main },
986 { "setfb64", 4, setfb64_main },
987 { "getfb64", 4, getfb64_main },
988 { "setfile", 4, f2n_main },
989 { "getfile", 4, n2f_main },
990 { "setfile2nvram", 3, save2f_main },
991 { "default_get", 3, default_get_main },
992 // { "test", 2, test_main },
993 { NULL, 0, NULL }
996 int main(int argc, char **argv)
998 const applets_t *a;
1000 if (argc >= 2) {
1001 a = applets;
1002 while (a->name) {
1003 if (strcmp(argv[1], a->name) == 0) {
1004 if ((argc != a->args) && ((a->args > 0) || (argc < -(a->args)))) help();
1005 return a->main(argc - 1, argv + 1);
1007 ++a;
1010 help();