FreeCalypso > hg > freecalypso-tools
view ffstools/newcomp/compile-fc-chg.c @ 921:74d284add54d
fc-fsio: guard against bogus readdir results from the target
If the FFS being operated on contains SE K2x0 extended filenames,
readdir will return strings that are bad for printing. We need to
guard against this possibility, and also against possible other
bogosity that could be sent by other alien firmwares.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 31 Dec 2022 22:55:23 +0000 |
parents | 0937521ec2f4 |
children |
line wrap: on
line source
/* * This utility compiles a FreeCalypso battery charging configuration file * from ASCII source into the binary form suitable for uploading into * /etc/charging on a FreeCalypso device. */ #include <ctype.h> #include <string.h> #include <strings.h> #include <stdio.h> #include <stdlib.h> #include "../../rvinterf/include/exitcodes.h" char *infname; FILE *inf; char linebuf[256]; int lineno; struct setting { char *kw; int allow_always; int allow_never; int mandatory; unsigned default_value; unsigned set_value; int is_set; } settings[] = { {"start-delay", 0, 0, 0, 0, 0, 0}, {"start-threshold", 1, 1, 1, 0, 0, 0}, {"restart-threshold", 0, 1, 1, 0, 0, 0}, {"ci2cv-threshold", 0, 0, 1, 0, 0, 0}, {"cv-initial-setpoint", 0, 0, 1, 0, 0, 0}, {"cv-ctrl-loop-high", 0, 0, 1, 0, 0, 0}, {"cv-ctrl-loop-low", 0, 0, 1, 0, 0, 0}, {"cv-dac-max-incr", 0, 0, 1, 0, 0, 0}, {"cv-dac-max-decr", 0, 0, 1, 0, 0, 0}, {"cv-ctrl-loop-sample-count", 0, 0, 1, 0, 0, 0}, {"overvoltage", 0, 0, 0, 0xFFFF, 0, 0}, {"ci-current", 0, 0, 1, 0, 0, 0}, {"end-current", 0, 0, 1, 0, 0, 0}, {"ichg-max-spike", 0, 0, 0, 0x400, 0, 0}, {"ichg-low-samples-needed", 0, 0, 1, 0, 0, 0}, {"charging-time-limit", 0, 0, 0, 0xFFFF, 0, 0}, {"restart-delay", 0, 0, 0, 0, 0, 0}, {"i2v-offset", 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0} }; static void do_setting(tp, arg) struct setting *tp; char *arg; { char *endp; if (tp->allow_always && !strcmp(arg, "always")) { tp->set_value = 0xFFFF; return; } if (tp->allow_never && !strcmp(arg, "never")) { tp->set_value = 0; return; } tp->set_value = strtoul(arg, &endp, 0); if (*endp || tp->set_value > 0xFFFF) { fprintf(stderr, "%s line %d: invalid argument to %s\n", infname, lineno, tp->kw); exit(ERROR_USAGE); } } process_line() { char *cp, *kw, *arg; struct setting *tp; for (cp = linebuf; isspace(*cp); cp++) ; if (*cp == '\0' || *cp == '#') return(0); kw = cp; while (*cp && !isspace(*cp)) cp++; if (!*cp) { inv: fprintf(stderr, "%s line %d: invalid syntax\n", infname, lineno); exit(ERROR_USAGE); } *cp++ = '\0'; while (isspace(*cp)) cp++; if (*cp == '\0' || *cp == '#') goto inv; arg = cp; while (*cp && !isspace(*cp)) cp++; if (*cp) *cp++ = '\0'; while (isspace(*cp)) cp++; if (*cp != '\0' && *cp != '#') goto inv; for (tp = settings; tp->kw; tp++) if (!strcmp(tp->kw, kw)) break; if (!tp->kw) { fprintf(stderr, "%s line %d: setting \"%s\" not known\n", infname, lineno, kw); exit(ERROR_USAGE); } if (tp->is_set) { fprintf(stderr, "%s line %d: %s set more than once\n", infname, lineno, kw); exit(ERROR_USAGE); } do_setting(tp, arg); tp->is_set = 1; return(1); } set_defaults() { struct setting *tp; for (tp = settings; tp->kw; tp++) { if (tp->is_set) continue; if (tp->mandatory) { fprintf(stderr, "error: required setting %s is not set\n", tp->kw); exit(ERROR_USAGE); } tp->set_value = tp->default_value; } } write_output(filename) char *filename; { FILE *of; struct setting *tp; of = fopen(filename, "w"); if (!of) { perror(filename); exit(ERROR_UNIX); } for (tp = settings; tp->kw; tp++) { putc(tp->set_value, of); putc(tp->set_value >> 8, of); } fclose(of); } main(argc, argv) char **argv; { if (argc != 3) { fprintf(stderr, "usage: %s srcfile output-binfile\n", argv[0]); exit(ERROR_USAGE); } infname = argv[1]; inf = fopen(infname, "r"); if (!inf) { perror(infname); exit(ERROR_UNIX); } for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) process_line(); fclose(inf); set_defaults(); write_output(argv[2]); exit(0); }