| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 | 
							- #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;
 
- }
 
 
  |