aboutsummaryrefslogtreecommitdiff
path: root/daemon/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/base.c')
-rw-r--r--daemon/base.c331
1 files changed, 331 insertions, 0 deletions
diff --git a/daemon/base.c b/daemon/base.c
new file mode 100644
index 0000000..eb0275f
--- /dev/null
+++ b/daemon/base.c
@@ -0,0 +1,331 @@
+/* ****************************************************************************
+ * base.c -- initialisation, gestion, utilisation des types de base.
+ * Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
+ *
+ * This project is governed by the CeCILL license under French law and
+ * abiding by the rules of distribution of free software. You can use,
+ * modify and/or redistribute the software under the terms of the
+ * CeCILL license as circulated by CEA, CNRS and INRIA at the
+ * following URL: "http://www.cecill.info".
+ *
+ * As a counterpart to the access to the source code and rights to copy,
+ * modify and redistribute granted by the license, users are provided only
+ * with a limited warranty and the project's author, the holder of the
+ * economic rights, and the successive licensors have only limited liability.
+ *
+ * In this respect, the user's attention is drawn to the risks associated
+ * with loading, using, modifying and/or developing or reproducing the
+ * software by the user in light of its specific status of free software,
+ * that may mean that it is complicated to manipulate, and that also therefore
+ * means that it is reserved for developers and experienced professionals
+ * having in-depth computer knowledge. Users are therefore encouraged to load
+ * and test the software's suitability as regards their requirements in
+ * conditions enabling the security of their systems and/or data to be
+ * ensured and, more generally, to use and operate it in the same conditions
+ * as regards security.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL license and that you accept its terms.
+ * ************************************************************************* */
+#include "internals.h"
+#include <unistd.h>
+
+/* Nom vide, afin d'éviter à avoir à allouer une chaîne vide pour avoir
+ * quelque chose de « mutable » globalement (en vrai on fait le maximum pour
+ * ne pas y toucher). */
+
+static char *empty_name = "";
+
+/* `init_wes_base()`: Initialiser les composants de base d'une ressource de
+ * type serveur WES. */
+
+int init_wes_base(wes_t *wes, wesif_t const *iface)
+{
+ wes->valid = 1;
+ wes->id = 0;
+ wes->next = NULL;
+ wes->prev = NULL;
+ wes->iface = iface;
+ wes->lastobj = NULL;
+ wes->name = empty_name;
+
+ return (WROK);
+}
+
+/* `deinit_wes_base()`: Supprimer les composants d'une ressource de
+ * type serveur WES. */
+
+int deinit_wes_base(wes_t *wes)
+{
+ set_name(wes, "");
+ set_obj_to_free(wes, NULL);
+
+ return (WROK);
+}
+
+/* `set_obj_to_free()`: faire en sorte qu'un objet soit libéré tantôt. */
+
+void set_obj_to_free(wes_t *wes, void *vobj)
+{
+ wesfreemem_t **obj = (void*)vobj;
+
+ if (wes->lastobj) {
+ (**wes->lastobj)((void*)*wes->lastobj);
+ wes->lastobj = NULL;
+ }
+
+ if (obj && *obj)
+ wes->lastobj = (wesfreemem_t **)obj;
+}
+
+/* ---
+ * Gestion d'un nom de serveur WES.
+ * --- */
+
+#define MAX_NAME_SIZE 16
+#define VALIDCAR(C) \
+ !!strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" \
+ "0123456789-", (C))
+
+/* `name_valid_length()`: Longueur d'un nom après sanitization (prédiction). */
+
+static size_t name_valid_length(const char *s)
+{
+ size_t len = 0;
+
+ for (; *s && len < MAX_NAME_SIZE; s++)
+ len += VALIDCAR(*s);
+
+ return (len);
+}
+
+/* `prep_name()`: Duplication d'un nom en sanitizant. */
+
+int prep_name(char **dst, const char *src)
+{
+ char *name, *buf;
+ size_t len;
+
+ *dst = NULL;
+ len = name_valid_length(src);
+
+ if (!len) {
+ *dst = empty_name;
+ return (WROK);
+ }
+ if (!(name = malloc(len + 1)))
+ return (WRALLOC);
+ buf = name;
+
+ for (; len; len--, src++)
+ if (VALIDCAR(*src))
+ *buf++ = *src;
+ *buf = '\0';
+
+ *dst = name;
+ return (WROK);
+}
+
+/* `prep_valid_name()`: Duplication d'un nom avec _validation_, et non
+ * sanitization comme la fonction précédente. */
+
+int prep_valid_name(char **dst, const char *src)
+{
+ char *name, *s;
+ size_t len = 0;
+
+ *dst = NULL;
+
+ if (!(name = memchr(src, '\0', MAX_NAME_SIZE)))
+ return (WRVAL);
+ len = (size_t)(name - src);
+
+ if (!len) {
+ *dst = empty_name;
+ return (WROK);
+ }
+
+ if (!(name = malloc(len + 1)))
+ return (WRALLOC);
+ s = name;
+
+ for (; len; len--) {
+ if (!strchr("abcdefghijklmnopqrstuvwxyz0123456789-", *src)) {
+ free(name);
+ return (WRVAL);
+ }
+
+ *s++ = *src++;
+ }
+ *s = '\0';
+
+ *dst = name;
+ return (WROK);
+}
+
+/* `free_name()`: Suppression d'un nom. */
+
+void free_name(char *name)
+{
+ if (name != empty_name)
+ free(name);
+}
+
+/* `assign_name()`: Assigner un nom à un serveur WES. */
+
+int assign_name(wes_t *wes, char *name)
+{
+ free_name(wes->name);
+ wes->name = name;
+ return (WROK);
+}
+
+/* `set_name()`: Définir le nom d'un serveur WES. */
+
+int set_name(wes_t *wes, const char *name)
+{
+ char *newname;
+ int err;
+
+ if (!strcmp(name, wes->name))
+ return (WROK);
+ if ((err = prep_name(&newname, name)))
+ return (err);
+ if ((err = assign_name(wes, newname))) {
+ free_name(newname);
+ return (err);
+ }
+
+ return (WROK);
+}
+
+/* ---
+ * Correction de structures de données.
+ * --- */
+
+/* `correct_cfg()`: correction de la configuration d'un WES. */
+
+int correct_cfg(wes_t *wes, wescfg_t *cfg, wescfgflags_t flags)
+{
+ flags = ~flags;
+
+ if (flags & WESCFG_NAME)
+ cfg->name = "";
+ if (flags & WESCFG_TIME) {
+ cfg->current_time.year = 1970;
+ cfg->current_time.mon = 1;
+ cfg->current_time.dom = 1;
+ cfg->current_time.hour = 0;
+ cfg->current_time.min = 0;
+ cfg->current_time.sec = 0;
+ cfg->current_time.dow = 3; /* jeudi */
+ cfg->current_time.tzhour = 0;
+ cfg->current_time.tzmin = 0;
+ cfg->current_time.sum = 0;
+ }
+
+ switch (wes->iface->type) {
+ case WESTYPE_IP:
+ {
+ const unsigned char fixed_ip[4] = {0, 0, 0, 0};
+ const unsigned char fixed_mask[4] = {255, 255, 255, 255};
+ const unsigned char fixed_mac[6] = {0, 0, 0, 0, 0, 0};
+
+ if (flags & WESCFG_DHCP)
+ cfg->more.ip.dhcp_enabled = 0;
+ if (flags & WESCFG_IP)
+ memcpy(cfg->more.ip.ip, fixed_ip, 4);
+ if (flags & WESCFG_MASK)
+ memcpy(cfg->more.ip.mask, fixed_mask, 4);
+ if (flags & WESCFG_GW)
+ memcpy(cfg->more.ip.gw, fixed_ip, 4);
+ if (flags & WESCFG_DNS1)
+ memcpy(cfg->more.ip.dns1, fixed_ip, 4);
+ if (flags & WESCFG_DNS2)
+ memcpy(cfg->more.ip.dns2, fixed_ip, 4);
+ if (flags & WESCFG_MAC)
+ memcpy(cfg->more.ip.mac, fixed_mac, 6);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return (WROK);
+}
+
+/* `correct_meter()`: correction d'un compteur. */
+
+int correct_meter(wes_t *wes, wesmetercfg_t *meter, wesmetertype_t type,
+ wesmeterflags_t flags)
+{
+ (void)wes;
+ flags = ~flags;
+
+ if (flags & WESMETER_NAME)
+ meter->name = "";
+ if (flags & WESMETER_READ)
+ meter->is_read = 0;
+ if (flags & WESMETER_MODE)
+ meter->mode = WESMETERMODE_CONSO;
+ if (flags & WESMETER_WHAT)
+ meter->what = WESMETERWHAT_UNKNOWN;
+ if (flags & WESMETER_FIXED_COSTS)
+ meter->fixed_cost = 0.0;
+ if (flags & WESMETER_PRORATA)
+ meter->prorata = 0;
+ if (flags & WESMETER_TYPE)
+ meter->type = WESMETERTYPE_NONE;
+
+ switch (type) {
+ case WESMETERTYPE_AMPER:
+ if (flags & WESMETER_COST)
+ meter->more.amper.cost = 0.0;
+ if (flags & WESMETER_VOLTAGE)
+ meter->more.amper.voltage = 0;
+ break;
+ case WESMETERTYPE_PULSE:
+ if (flags & WESMETER_COST)
+ meter->more.pulse.cost = 0.0;
+ if (flags & WESMETER_METHOD)
+ meter->more.pulse.method = WESPLSMETHOD_ELEC;
+ if (flags & WESMETER_GROUP)
+ meter->more.pulse.group_size = 1;
+ break;
+ case WESMETERTYPE_TELEINFO:
+ if (flags & WESMETER_COSTS_BASE)
+ meter->more.teleinfo.cost_base_th = 0;
+ if (flags & WESMETER_COSTS_HCHP) {
+ meter->more.teleinfo.cost_hchp_hc = 0;
+ meter->more.teleinfo.cost_hchp_hp = 0;
+ }
+ if (flags & WESMETER_COSTS_TEMPO) {
+ meter->more.teleinfo.cost_tempo_hcjb = 0;
+ meter->more.teleinfo.cost_tempo_hpjb = 0;
+ meter->more.teleinfo.cost_tempo_hcjw = 0;
+ meter->more.teleinfo.cost_tempo_hpjw = 0;
+ meter->more.teleinfo.cost_tempo_hcjr = 0;
+ meter->more.teleinfo.cost_tempo_hpjr = 0;
+ }
+ if (flags & WESMETER_COSTS_EJP) {
+ meter->more.teleinfo.cost_ejp_hn = 0;
+ meter->more.teleinfo.cost_ejp_pm = 0;
+ }
+
+ if (flags & WESMETER_BDPV_ENABLED)
+ meter->more.teleinfo.bdpv_enabled = 0;
+ if (flags & WESMETER_BDPV_IDS) {
+ meter->more.teleinfo.bdpv_username = "";
+ meter->more.teleinfo.bdpv_password = "";
+ }
+ if (flags & WESMETER_BDPV_TIME) {
+ meter->more.teleinfo.bdpv_hour = 0;
+ meter->more.teleinfo.bdpv_min = 0;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return (WROK);
+}