diff options
Diffstat (limited to 'daemon/wes.c')
-rw-r--r-- | daemon/wes.c | 131 |
1 files changed, 114 insertions, 17 deletions
diff --git a/daemon/wes.c b/daemon/wes.c index 1d34915..da260f4 100644 --- a/daemon/wes.c +++ b/daemon/wes.c @@ -30,6 +30,10 @@ #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 @@ -74,30 +78,123 @@ void set_obj_to_free(wes_t *wes, void *vobj) 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) { - size_t sz; 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); + } - if (*name) { - sz = strlen(name); - newname = malloc(sz + 1); - if (!newname) - return (WRALLOC); - - memcpy(newname, name, sz); - newname[sz] = '\0'; - } else - newname = empty_name; - - if (*wes->name) - free(wes->name); - wes->name = newname; - - return (0); + return (WROK); } |