sysvars.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #ifndef SYSVARS_H
  2. #define SYSVARS_H
  3. #include <stddef.h>
  4. #include <stdbool.h>
  5. #include <inttypes.h>
  6. #ifndef extern_c
  7. # ifdef __cplusplus
  8. # define extern_c extern "C"
  9. # else
  10. # define extern_c extern
  11. # endif
  12. #endif
  13. typedef union sysvar_value {
  14. bool v_bool;
  15. long int v_int;
  16. unsigned long int v_uint;
  17. const char *v_str;
  18. const char *v_tz; /* Timezone */
  19. uint32_t v_ip; /* IPv4 address */
  20. const uint8_t *v_mac; /* MAC address */
  21. void *v_ptr;
  22. } sysvar_t;
  23. struct sysvar_ops {
  24. bool (*set)(sysvar_t *, sysvar_t);
  25. /* bool (*unset)(sysvar_t *); - not used */
  26. const char * (*tostr)(sysvar_t, char *);
  27. bool (*fromstr)(sysvar_t *, const char *);
  28. void (*update)(sysvar_t, bool); /* Called after set or fromstr; bool = isset */
  29. size_t (*datasize)(sysvar_t); /* If pointer, return size of data */
  30. size_t buflen; /* Minimal buffer size for string if needed */
  31. };
  32. typedef const struct sysvar_ops *sysvar_type_t;
  33. extern_c const struct sysvar_ops sysvar_bool_ops;
  34. extern_c const struct sysvar_ops sysvar_int_ops;
  35. extern_c const struct sysvar_ops sysvar_uint_ops;
  36. extern_c const struct sysvar_ops sysvar_str_ops;
  37. extern_c const struct sysvar_ops sysvar_tz_ops;
  38. extern_c const struct sysvar_ops sysvar_ip_ops;
  39. extern_c const struct sysvar_ops sysvar_mac_ops;
  40. #define SYSVAR_NULLTYPE NULL
  41. #define SYSVAR_TYPE(x) (&sysvar ## x ## _ops)
  42. #include "sysvars_gen.h"
  43. typedef struct sysvar_namespace {
  44. const char *name;
  45. enum sysvar_enum first;
  46. } sysvar_ns_t;
  47. extern_c const sysvar_ns_t sysvar_ns[(size_t)sysvar_nscount+1];
  48. extern_c enum sysvar_enum sysvar_changed;
  49. extern_c bool sysvar_print_updates;
  50. /* Buffer size needed to represent some data types */
  51. #define BOOL_BUFLEN 2
  52. #define INT_BUFLEN (3*sizeof(unsigned int)+2)
  53. #define UINT_BUFLEN INT_BUFLEN
  54. #define IP_BUFLEN (4*4)
  55. #define MAC_BUFLEN (3*6)
  56. #define SYSVAR_BUFLEN 32 /* Conservative minimum */
  57. extern_c sysvar_t getvar(size_t var);
  58. extern_c bool setvar(size_t var, sysvar_t val);
  59. extern_c bool unsetvar(size_t var);
  60. extern_c const char *getvar_tostr(size_t var);
  61. extern_c const char *getvar_tostr_r(size_t var, char *buf);
  62. extern_c bool setvar_fromstr(size_t var, const char *str);
  63. extern_c void sysvar_init(void);
  64. extern_c void sysvar_reset(size_t ns);
  65. extern_c size_t sysvar_find(size_t ns, const char *name);
  66. extern_c size_t sysvar_marshall(enum sysvar_enum first, size_t count,
  67. void *buf, size_t *buflen, uintptr_t extaddr);
  68. /* Type-specific definitions/getters/setters */
  69. /* Note that t contains a leading underscore to avoid bool/_Bool issues */
  70. #define const_assert(cond, str) \
  71. do { \
  72. extern void fail(void) __attribute__((error(str))); \
  73. if (__builtin_constant_p(cond) && !(cond)) \
  74. fail(); \
  75. } while (0)
  76. #define TRY_ASSERT_TYPE(var,t) \
  77. const_assert(sysvar_type(var) == SYSVAR_TYPE(t), \
  78. "invalid type for sysvar " #var)
  79. #define SYSVAR_MKTYPE(t,c_type) \
  80. static inline c_type getvar ## t (size_t var) \
  81. { \
  82. TRY_ASSERT_TYPE(var,t); \
  83. /* If var is constant and >= sysvar_count, TRY_ASSERT_TYPE() fails */ \
  84. if (__builtin_constant_p(var < (size_t)sysvar_count)) \
  85. return sysvar_val[var].v ## t; \
  86. return getvar(var).v ## t ; \
  87. } \
  88. static inline bool setvar ## t (size_t var, c_type v) \
  89. { \
  90. sysvar_t vv; \
  91. TRY_ASSERT_TYPE(var,t); \
  92. vv.v ## t = v; \
  93. return setvar(var, vv); \
  94. }
  95. SYSVAR_MKTYPE(_bool, bool);
  96. SYSVAR_MKTYPE(_int, long int);
  97. SYSVAR_MKTYPE(_uint, unsigned long int);
  98. SYSVAR_MKTYPE(_str, const char *);
  99. SYSVAR_MKTYPE(_tz, const char *);
  100. SYSVAR_MKTYPE(_ip, uint32_t);
  101. SYSVAR_MKTYPE(_mac, const uint8_t *);
  102. #endif /* SYSVARS_H */