|
@@ -1,432 +0,0 @@
|
|
|
-#include "common.h"
|
|
|
-#include "sysvars.h"
|
|
|
-
|
|
|
-#include <stdlib.h>
|
|
|
-#include <string.h>
|
|
|
-#include <stdio.h>
|
|
|
-#include <time.h>
|
|
|
-
|
|
|
-bool sysvar_print_updates;
|
|
|
-
|
|
|
-#ifndef DEBUG
|
|
|
-# ifdef ON_FPGA
|
|
|
-# define DEBUG 0
|
|
|
-# else
|
|
|
-# define DEBUG sysvar_print_updates
|
|
|
-# endif
|
|
|
-#endif
|
|
|
-
|
|
|
-static const char *sysvar_bool_tostr(sysvar_t from, char *buf)
|
|
|
-{
|
|
|
- buf[0] = '0' + from.v_bool;
|
|
|
- buf[1] = '\0';
|
|
|
- return buf;
|
|
|
-}
|
|
|
-
|
|
|
-static bool sysvar_bool_fromstr(sysvar_t *to, const char *from)
|
|
|
-{
|
|
|
- char c = from[0] | 0x20;
|
|
|
- switch (c) {
|
|
|
- case '1':
|
|
|
- case 't':
|
|
|
- case 'y':
|
|
|
- case 'j':
|
|
|
- case 's':
|
|
|
- to->v_bool = true;
|
|
|
- return true;
|
|
|
- case ' ': /* Blank or null */
|
|
|
- case '0':
|
|
|
- case 'f':
|
|
|
- case 'n':
|
|
|
- to->v_bool = false;
|
|
|
- return true;
|
|
|
- default:
|
|
|
- return false;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const struct sysvar_ops sysvar_bool_ops = {
|
|
|
- .tostr = sysvar_bool_tostr,
|
|
|
- .fromstr = sysvar_bool_fromstr,
|
|
|
- .buflen = BOOL_BUFLEN
|
|
|
-};
|
|
|
-
|
|
|
-static const char *sysvar_int_tostr(sysvar_t from, char *buf)
|
|
|
-{
|
|
|
- snprintf(buf, INT_BUFLEN, "%ld", from.v_int);
|
|
|
- return buf;
|
|
|
-}
|
|
|
-
|
|
|
-static bool sysvar_int_fromstr(sysvar_t *to, const char *from)
|
|
|
-{
|
|
|
- char *ep;
|
|
|
- long v = strtol(from, &ep, 0);
|
|
|
- if (ep == from || *ep)
|
|
|
- return false;
|
|
|
- to->v_int = v;
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-const struct sysvar_ops sysvar_int_ops = {
|
|
|
- .tostr = sysvar_int_tostr,
|
|
|
- .fromstr = sysvar_int_fromstr,
|
|
|
- .buflen = INT_BUFLEN
|
|
|
-};
|
|
|
-
|
|
|
-static const char *sysvar_uint_tostr(sysvar_t from, char *buf)
|
|
|
-{
|
|
|
- snprintf(buf, UINT_BUFLEN, "%lu", from.v_uint);
|
|
|
- return buf;
|
|
|
-}
|
|
|
-
|
|
|
-static bool sysvar_uint_fromstr(sysvar_t *to, const char *from)
|
|
|
-{
|
|
|
- char *ep;
|
|
|
- unsigned long v = strtoul(from, &ep, 0);
|
|
|
- if (ep == from || *ep)
|
|
|
- return false;
|
|
|
- to->v_uint = v;
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-const struct sysvar_ops sysvar_uint_ops = {
|
|
|
- .tostr = sysvar_uint_tostr,
|
|
|
- .fromstr = sysvar_uint_fromstr,
|
|
|
- .buflen = UINT_BUFLEN
|
|
|
-};
|
|
|
-
|
|
|
-static const char *sysvar_str_tostr(sysvar_t from, char *buf)
|
|
|
-{
|
|
|
- (void)buf;
|
|
|
- return from.v_str;
|
|
|
-}
|
|
|
-
|
|
|
-static bool sysvar_str_fromstr(sysvar_t *to, const char *from)
|
|
|
-{
|
|
|
- char *ns;
|
|
|
-
|
|
|
- if (!from) {
|
|
|
- ns = NULL;
|
|
|
- } else {
|
|
|
- ns = strdup(from);
|
|
|
- if (!ns)
|
|
|
- return false;
|
|
|
- }
|
|
|
- to->v_str = ns;
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-static bool sysvar_str_set(sysvar_t *to, sysvar_t from)
|
|
|
-{
|
|
|
- return sysvar_str_fromstr(to, from.v_str);
|
|
|
-}
|
|
|
-
|
|
|
-static size_t sysvar_str_datasize(sysvar_t val)
|
|
|
-{
|
|
|
- return (val.v_str ? strlen(val.v_str) : 0) + 1;
|
|
|
-}
|
|
|
-
|
|
|
-const struct sysvar_ops sysvar_str_ops = {
|
|
|
- .set = sysvar_str_set,
|
|
|
- .tostr = sysvar_str_tostr,
|
|
|
- .fromstr = sysvar_str_fromstr,
|
|
|
- .datasize = sysvar_str_datasize
|
|
|
-};
|
|
|
-
|
|
|
-static void sysvar_tz_update(sysvar_t val, bool isset)
|
|
|
-{
|
|
|
- if (isset)
|
|
|
- setenv("TZ", val.v_tz, 1);
|
|
|
- else
|
|
|
- unsetenv("TZ");
|
|
|
- tzset();
|
|
|
-}
|
|
|
-
|
|
|
-const struct sysvar_ops sysvar_tz_ops = {
|
|
|
- .set = sysvar_str_set,
|
|
|
- .tostr = sysvar_str_tostr,
|
|
|
- .fromstr = sysvar_str_fromstr,
|
|
|
- .update = sysvar_tz_update,
|
|
|
- .datasize = sysvar_str_datasize
|
|
|
-};
|
|
|
-
|
|
|
-static const char *sysvar_ip_tostr(sysvar_t from, char *buf)
|
|
|
-{
|
|
|
- union ip_bytes {
|
|
|
- uint8_t b[4];
|
|
|
- uint32_t l;
|
|
|
- } ip;
|
|
|
-
|
|
|
- ip.l = from.v_ip;
|
|
|
- snprintf(buf, IP_BUFLEN,
|
|
|
- "%u.%u.%u.%u", ip.b[0], ip.b[1], ip.b[2], ip.b[3]);
|
|
|
- return buf;
|
|
|
-}
|
|
|
-
|
|
|
-static bool sysvar_ip_fromstr(sysvar_t *to, const char *str)
|
|
|
-{
|
|
|
- union ip_bytes {
|
|
|
- uint8_t b[4];
|
|
|
- uint32_t l;
|
|
|
- } ip;
|
|
|
-
|
|
|
- ip.l = 0;
|
|
|
- for (int i = 0; i < 4; i++) {
|
|
|
- char *ep;
|
|
|
- unsigned long v = strtoul(str, &ep, 10);
|
|
|
- if (ep == str || *ep != (i == 3) ? '\0' : '.' || v > 255)
|
|
|
- return false;
|
|
|
- str = ep + 1;
|
|
|
- ip.b[i] = v;
|
|
|
- }
|
|
|
-
|
|
|
- to->v_ip = ip.l;
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-const struct sysvar_ops sysvar_ip_ops = {
|
|
|
- .tostr = sysvar_ip_tostr,
|
|
|
- .fromstr = sysvar_ip_fromstr,
|
|
|
- .buflen = IP_BUFLEN
|
|
|
-};
|
|
|
-
|
|
|
-static bool sysvar_mac_set(sysvar_t *to, sysvar_t from)
|
|
|
-{
|
|
|
- uint8_t *buf;
|
|
|
-
|
|
|
- if (!from.v_mac) {
|
|
|
- buf = NULL;
|
|
|
- } else {
|
|
|
- buf = malloc(6);
|
|
|
- if (!buf)
|
|
|
- return false;
|
|
|
-
|
|
|
- memcpy(buf, from.v_mac, 6);
|
|
|
- }
|
|
|
- to->v_mac = buf;
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-static const char *sysvar_mac_tostr(sysvar_t from, char *buf)
|
|
|
-{
|
|
|
- const uint8_t *m = from.v_mac;
|
|
|
- if (!m)
|
|
|
- return NULL;
|
|
|
-
|
|
|
- snprintf(buf, MAC_BUFLEN, "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
|
- m[0], m[1], m[2], m[3], m[4], m[5]);
|
|
|
- return buf;
|
|
|
-}
|
|
|
-
|
|
|
-static bool sysvar_mac_fromstr(sysvar_t *to, const char *str)
|
|
|
-{
|
|
|
- sysvar_t from;
|
|
|
- uint8_t m[6];
|
|
|
-
|
|
|
- if (!str) {
|
|
|
- from.v_mac = NULL;
|
|
|
- } else {
|
|
|
- for (int i = 0; i < 6; i++) {
|
|
|
- char *ep;
|
|
|
- unsigned long v = strtoul(str, &ep, 16);
|
|
|
- if (ep == str || *ep != (i == 5) ? '\0' : ':' || v > 255)
|
|
|
- return false;
|
|
|
- str = ep + 1;
|
|
|
- m[i] = v;
|
|
|
- }
|
|
|
-
|
|
|
- from.v_mac = m;
|
|
|
- }
|
|
|
-
|
|
|
- return sysvar_mac_set(to, from);
|
|
|
-}
|
|
|
-
|
|
|
-static size_t sysvar_mac_datasize(sysvar_t val)
|
|
|
-{
|
|
|
- (void)val;
|
|
|
- return 6;
|
|
|
-}
|
|
|
-
|
|
|
-const struct sysvar_ops sysvar_mac_ops = {
|
|
|
- .set = sysvar_mac_set,
|
|
|
- .tostr = sysvar_mac_tostr,
|
|
|
- .fromstr = sysvar_mac_fromstr,
|
|
|
- .buflen = MAC_BUFLEN,
|
|
|
- .datasize = sysvar_mac_datasize
|
|
|
-};
|
|
|
-
|
|
|
-/* --- Generic getters/setters --- */
|
|
|
-
|
|
|
-/* Contains the lowest numbered sysvar changed; or sysvar_count if nothing */
|
|
|
-enum sysvar_enum sysvar_changed;
|
|
|
-
|
|
|
-sysvar_t getvar(size_t var)
|
|
|
-{
|
|
|
- if (var >= (size_t)sysvar_count)
|
|
|
- return sysvar_defval[sysvar_null];
|
|
|
-
|
|
|
- return sysvar_val[var];
|
|
|
-}
|
|
|
-
|
|
|
-static bool do_setvar(size_t var, sysvar_t val, bool is_set)
|
|
|
-{
|
|
|
- const struct sysvar_ops *type = sysvar_types[var];
|
|
|
- sysvar_t *to = &sysvar_val[var];
|
|
|
- void *free_ptr = NULL;
|
|
|
-
|
|
|
- if (type->datasize)
|
|
|
- free_ptr = to->v_ptr;
|
|
|
-
|
|
|
- if (DEBUG) {
|
|
|
- char tostr_buf[SYSVAR_BUFLEN];
|
|
|
- printf("%ssetvar %zu %s <- %s\n", is_set ? "" : "un",
|
|
|
- var, sysvar_name[var],
|
|
|
- notempty(type->tostr(val, tostr_buf)));
|
|
|
- }
|
|
|
-
|
|
|
- if (!type->set || (type->datasize && !val.v_ptr)) {
|
|
|
- sysvar_val[var] = val;
|
|
|
- } else {
|
|
|
- if (!type->set(to, val))
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (free_ptr)
|
|
|
- free(free_ptr);
|
|
|
-
|
|
|
- if (var < (size_t)sysvar_changed)
|
|
|
- sysvar_changed = (enum sysvar_enum)var;
|
|
|
-
|
|
|
- sysvar_isset[var] = is_set;
|
|
|
- if (type->update)
|
|
|
- type->update(*to, is_set);
|
|
|
-
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-bool setvar(size_t var, sysvar_t val)
|
|
|
-{
|
|
|
- if (var >= (size_t)sysvar_count)
|
|
|
- return false;
|
|
|
-
|
|
|
- return do_setvar(var, val, true);
|
|
|
-}
|
|
|
-
|
|
|
-bool unsetvar(size_t var)
|
|
|
-{
|
|
|
- if (var >= (size_t)sysvar_count)
|
|
|
- return false;
|
|
|
-
|
|
|
- return do_setvar(var, sysvar_defval[var], false);
|
|
|
-}
|
|
|
-
|
|
|
-/* --- Getters/setters converting to/from strings --- */
|
|
|
-
|
|
|
-const char *getvar_tostr(size_t var)
|
|
|
-{
|
|
|
- static char buf[SYSVAR_BUFLEN];
|
|
|
- return getvar_tostr_r(var, buf);
|
|
|
-}
|
|
|
-
|
|
|
-const char *getvar_tostr_r(size_t var, char *buf)
|
|
|
-{
|
|
|
- if (var >= (size_t)sysvar_count)
|
|
|
- return NULL;
|
|
|
-
|
|
|
- const struct sysvar_ops *type = sysvar_types[var];
|
|
|
-
|
|
|
- /* A tostr method is required */
|
|
|
- return type->tostr(sysvar_val[var], buf);
|
|
|
-}
|
|
|
-
|
|
|
-bool setvar_fromstr(size_t var, const char *str)
|
|
|
-{
|
|
|
- if (var >= (size_t)sysvar_count)
|
|
|
- return NULL;
|
|
|
-
|
|
|
- if (!str)
|
|
|
- return unsetvar(var);
|
|
|
-
|
|
|
- const struct sysvar_ops *type = sysvar_types[var];
|
|
|
- sysvar_t *to = &sysvar_val[var];
|
|
|
- void *free_ptr = NULL;
|
|
|
-
|
|
|
- if (type->datasize)
|
|
|
- free_ptr = to->v_ptr;
|
|
|
-
|
|
|
- if (DEBUG) {
|
|
|
- printf("setvar_fromstr %zu %s <- %s\n", var, sysvar_name[var], str);
|
|
|
- }
|
|
|
-
|
|
|
- /* A fromstr method is required */
|
|
|
- if (!type->fromstr(to, str))
|
|
|
- return false;
|
|
|
-
|
|
|
- if (free_ptr)
|
|
|
- free(free_ptr);
|
|
|
-
|
|
|
- if (var < (size_t)sysvar_changed)
|
|
|
- sysvar_changed = (enum sysvar_enum)var;
|
|
|
-
|
|
|
- sysvar_isset[var] = true;
|
|
|
- if (type->update)
|
|
|
- type->update(*to, true);
|
|
|
-
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-/* --- Find the index of a specific variable --- */
|
|
|
-
|
|
|
-static int string_ptr_compare(const void *a, const void *b)
|
|
|
-{
|
|
|
- const char * const *aa = a;
|
|
|
- const char * const *bb = b;
|
|
|
- return strcmp(*aa, *bb);
|
|
|
-}
|
|
|
-
|
|
|
-size_t sysvar_find(size_t ns, const char *name)
|
|
|
-{
|
|
|
- if (ns >= (size_t)sysvar_nscount)
|
|
|
- return 0;
|
|
|
-
|
|
|
- const sysvar_ns_t *nsi = &sysvar_ns[ns];
|
|
|
- const char * const *varname;
|
|
|
- const size_t count = nsi[1].first - nsi->first;
|
|
|
-
|
|
|
- varname = bsearch(&name, sysvar_name + nsi->first,
|
|
|
- count, sizeof *sysvar_name,
|
|
|
- string_ptr_compare);
|
|
|
- if (!varname)
|
|
|
- return 0;
|
|
|
-
|
|
|
- return varname - sysvar_name;
|
|
|
-}
|
|
|
-
|
|
|
-/* --- Initialization/reset to defaults --- */
|
|
|
-
|
|
|
-void sysvar_reset(size_t ns)
|
|
|
-{
|
|
|
- if (ns >= (size_t)sysvar_nscount)
|
|
|
- return;
|
|
|
-
|
|
|
- bool print_updates = sysvar_print_updates;
|
|
|
-
|
|
|
- enum sysvar_enum i;
|
|
|
- for (i = sysvar_ns[ns].first; i < sysvar_ns[ns+1].first; i++)
|
|
|
- unsetvar(i);
|
|
|
-
|
|
|
- sysvar_print_updates = print_updates;
|
|
|
-
|
|
|
- if (sysvar_changed < i)
|
|
|
- sysvar_changed = i;
|
|
|
-}
|
|
|
-
|
|
|
-void sysvar_init(void)
|
|
|
-{
|
|
|
- sysvar_print_updates = false;
|
|
|
-
|
|
|
- for (enum sysvar_enum i = sysvar_null+1; i < sysvar_count; i++)
|
|
|
- unsetvar(i);
|
|
|
-
|
|
|
- sysvar_changed = sysvar_count;
|
|
|
-}
|