aboutsummaryrefslogtreecommitdiff
path: root/daemon/wes.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/wes.c')
-rw-r--r--daemon/wes.c131
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);
}