diff options
Diffstat (limited to 'daemon/base.c')
-rw-r--r-- | daemon/base.c | 331 |
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); +} |