aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2018-03-20 15:59:30 +0100
committerThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2018-03-20 15:59:30 +0100
commit7621e2010121af73a0c5e6956487d459e6129324 (patch)
tree11ab1d6a3b4fc374678b113c029d37334e7955b8
parent94f683d97f19bbbc8e29842a48b28061ab1e89c8 (diff)
Ajouté multi-usage du même handle curl, corrigé quelques lectures dangereuses.
-rw-r--r--daemon/cfg.c42
-rw-r--r--daemon/cgi.c77
-rw-r--r--daemon/error.c3
-rw-r--r--daemon/internals.h13
-rw-r--r--daemon/main.c7
-rw-r--r--daemon/wes.c89
6 files changed, 149 insertions, 82 deletions
diff --git a/daemon/cfg.c b/daemon/cfg.c
index 5ae5702..2bbf965 100644
--- a/daemon/cfg.c
+++ b/daemon/cfg.c
@@ -41,23 +41,14 @@
* Utilitaires.
* --- */
-/* `prepare_request()`: Préparation d'une requête, avec URL et identifiants. */
+/* `get_request()`: Préparation d'une requête, avec URL et identifiants. */
-static int prepare_request(CURL *curl, wes_t *wes, const char *section)
+static int get_request(wes_t *wes, CURL **handlep, const char *section)
{
- char url[40 + SECSIZE];
- const unsigned char *ip;
+ char path[10 + SECSIZE];
- ip = wes->addr.data.inet.ipv4;
- sprintf(url, "ftp://%d.%d.%d.%d/CFG/%s.CFG", ip[0], ip[1], ip[2], ip[3],
- section);
-
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_USERNAME, wes->ftp_name);
- curl_easy_setopt(curl, CURLOPT_PASSWORD, wes->ftp_pass);
- curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
-
- return (WROK);
+ sprintf(path, "/CFG/%s.CFG", section);
+ return (open_http_handle(wes, handlep, path));
}
/* `normalize_section()`: Normalisation du nom de section. */
@@ -137,11 +128,10 @@ static int normalize_value(char *buf, const char *src)
static int emptysection(wescfgsec_t *sec)
{
- wescfg_t *cfg, **cfgp;
+ wescfg_t *cfg;
- cfgp = &sec->child;
- while ((cfg = *cfgp)) {
- cfgp = &cfg->next;
+ while ((cfg = sec->child)) {
+ sec->child = cfg->next;
free(cfg);
}
@@ -286,6 +276,7 @@ static int gathersection(wes_t *wes, wescfgsec_t *sec)
struct getcookie cookie;
CURL *curl; CURLcode cres;
const char *section;
+ int err;
section = sec->data;
@@ -295,9 +286,8 @@ static int gathersection(wes_t *wes, wescfgsec_t *sec)
/* On initialise la requête. */
- curl = curl_easy_init();
- if (!curl)
- return (WRUNKNOWN);
+ if ((err = get_request(wes, &curl, section)))
+ return (err);
cookie.sec = sec;
cookie.step = SG_KEY;
@@ -305,12 +295,10 @@ static int gathersection(wes_t *wes, wescfgsec_t *sec)
cookie.hadval = 0;
cookie.err = WROK;
- prepare_request(curl, wes, section);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, getsection_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &cookie);
cres = curl_easy_perform(curl);
- curl_easy_cleanup(curl);
if (cres != CURLE_OK) {
emptysection(sec);
@@ -446,6 +434,7 @@ static int sendsection(wes_t *wes, wescfgsec_t *sec)
struct sendcookie cookie;
curl_off_t fsize;
wescfg_t *cfg;
+ int err;
/* On calcule le nombre total de bytes que cela va prendre. */
@@ -459,14 +448,15 @@ static int sendsection(wes_t *wes, wescfgsec_t *sec)
if (!curl)
return (WRUNKNOWN);
- prepare_request(curl, wes, &sec->data[sec->keysz]);
- curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
+ if ((err = get_request(wes, &curl, &sec->data[sec->keysz])))
+ return (err);
+
+ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(curl, CURLOPT_READDATA, &cookie);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, sendsection_callback);
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fsize);
cres = curl_easy_perform(curl);
- curl_easy_cleanup(curl);
switch (cres) {
case CURLE_OK:
diff --git a/daemon/cgi.c b/daemon/cgi.c
index 02c157b..4e953e2 100644
--- a/daemon/cgi.c
+++ b/daemon/cgi.c
@@ -213,17 +213,16 @@ static curl_off_t estimatescriptsize(int num, const wescgi_t *blocks)
static int sendscript(wes_t *wes, int num, const wescgi_t *blocks)
{
- CURL *curl;
- CURLcode cres;
- char url[50];
- const unsigned char *ip;
+ CURL *curl; CURLcode cres;
+ char path[50];
struct ucookie cookie;
+ int err;
/* Initialisation du handle de la libcurl. */
- curl = curl_easy_init();
- if (!curl)
- return (WRUNKNOWN);
+ sprintf(path, "/WH%d.CGI", wes->id);
+ if ((err = open_ftp_handle(wes, &curl, path)))
+ return (err);
/* Initialisation du cookie. */
@@ -240,13 +239,6 @@ static int sendscript(wes_t *wes, int num, const wescgi_t *blocks)
/* Définition des méta-informations. */
- ip = wes->addr.data.inet.ipv4;
- sprintf(url, "ftp://%d.%d.%d.%d/WH%d.CGI", ip[0], ip[1], ip[2], ip[3],
- wes->id);
-
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_USERNAME, wes->ftp_name);
- curl_easy_setopt(curl, CURLOPT_PASSWORD, wes->ftp_pass);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
@@ -260,7 +252,6 @@ static int sendscript(wes_t *wes, int num, const wescgi_t *blocks)
/* Exécution de la requête. */
cres = curl_easy_perform(curl);
- curl_easy_cleanup(curl);
switch (cres) {
case CURLE_OK:
@@ -314,30 +305,22 @@ static size_t delscript_write(char *buffer, size_t blksize, size_t nmemb,
static int delscript(wes_t *wes)
{
- char url[50], hdr[20];
- const unsigned char *ip;
+ char hdr[20];
CURL *curl; CURLcode cres;
struct curl_slist *headerlist = NULL;
+ int err;
/* Initialisation du handle de la libcurl. */
- curl = curl_easy_init();
- if (!curl)
- return (WRUNKNOWN);
+ if ((err = open_ftp_handle(wes, &curl, "/")))
+ return (err);
/* Préparation des méta-informations. */
- ip = wes->addr.data.inet.ipv4;
- sprintf(url, "ftp://%d.%d.%d.%d/", ip[0], ip[1], ip[2], ip[3]);
sprintf(hdr, "DELE WH%d.CGI", wes->id);
headerlist = curl_slist_append(headerlist, hdr);
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_USERNAME, wes->ftp_name);
- curl_easy_setopt(curl, CURLOPT_PASSWORD, wes->ftp_pass);
- curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
-
curl_easy_setopt(curl, CURLOPT_QUOTE, headerlist);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, delscript_write);
@@ -345,8 +328,6 @@ static int delscript(wes_t *wes)
/* Exécution de la requête. */
cres = curl_easy_perform(curl);
- curl_easy_cleanup(curl);
-
curl_slist_free_all(headerlist);
switch (cres) {
@@ -581,17 +562,16 @@ static size_t execscript_write(char *buffer, size_t blksize, size_t nmemb,
static int execscript(wes_t *wes, int num, wescgi_t *blocks)
{
- CURL *curl;
- CURLcode cres;
- char url[50], sepbuf[sizeof(REQSEP) + 1];
- const unsigned char *ip;
+ CURL *curl; CURLcode cres;
+ char path[20], sepbuf[sizeof(REQSEP) + 1];
struct ecookie cookie;
+ int err;
/* Initialisation du handle de la libcurl. */
- curl = curl_easy_init();
- if (!curl)
- return (WRUNKNOWN);
+ sprintf(path, "/WH%d.CGI", wes->id);
+ if ((err = open_http_handle(wes, &curl, path)))
+ return (err);
/* Initialisation du cookie. */
@@ -614,17 +594,6 @@ static int execscript(wes_t *wes, int num, wescgi_t *blocks)
blocks[0].full = 1; /* NUL character */
}
- /* Définition des méta-informations. */
-
- ip = wes->addr.data.inet.ipv4;
- sprintf(url, "http://%d.%d.%d.%d/WH%d.CGI", ip[0], ip[1], ip[2], ip[3],
- wes->id);
-
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_USERNAME, wes->http_name);
- curl_easy_setopt(curl, CURLOPT_PASSWORD, wes->http_pass);
- curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
-
/* Définition du fichier à envoyer. */
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &cookie);
@@ -633,7 +602,6 @@ static int execscript(wes_t *wes, int num, wescgi_t *blocks)
/* Exécution de la requête. */
cres = curl_easy_perform(curl);
- curl_easy_cleanup(curl);
switch (cres) {
case CURLE_OK:
@@ -689,14 +657,21 @@ int get_cgi(wes_t *wes, int num, wescgi_t *blocks)
/* `get_cgi_var()`: Récupération de valeurs par CGI. */
int get_cgi_var(wes_t *wes, const char *var, const char *format,
- char *buffer, size_t len)
+ char *buffer, size_t *len)
{
wescgi_t cgi;
+ int err;
cgi.var = var;
cgi.format = format;
cgi.buffer = buffer;
- cgi.len = len;
+ cgi.len = *len;
- return (get_cgi(wes, 1, &cgi));
+ if ((err = get_cgi(wes, 1, &cgi)))
+ return (err);
+
+ *len = cgi.full;
+ if (cgi.full > cgi.len)
+ return (WRSPACE);
+ return (WROK);
}
diff --git a/daemon/error.c b/daemon/error.c
index 5581069..07eefbb 100644
--- a/daemon/error.c
+++ b/daemon/error.c
@@ -34,7 +34,8 @@ static const char *error_strings[] = {
"une erreur inconnue s'est produite",
"cette opération est interdite",
"une allocation mémoire a échoué",
- NULL, NULL, NULL, NULL, NULL, NULL,
+ "espace insuffisant pour stocker la réponse",
+ NULL, NULL, NULL, NULL, NULL,
"le serveur n'a pas pu être atteint",
"un élément n'a pas été trouvé",
diff --git a/daemon/internals.h b/daemon/internals.h
index 96d4652..1e1ab4f 100644
--- a/daemon/internals.h
+++ b/daemon/internals.h
@@ -45,6 +45,7 @@
# define WRUNKNOWN 1 /* Une erreur inconnue s'est produite. */
# define WROP 2 /* Cette opération est interdite. */
# define WRALLOC 3 /* Une allocation mémoire a échoué. */
+# define WRSPACE 4 /* Pas assez d'espace pour stocker quelque chose */
# define WRNOHOST 10 /* Le serveur n'a pas pu être atteint. */
# define WRNOTFOUND 11 /* Un élément n'a pas été trouvé. */
@@ -232,6 +233,11 @@ typedef struct wes {
char *ftp_pass;
char *ftp_data;
+ /* Canaux (handles de la libcurl) pour le HTTP et FTP. */
+
+ CURL *http_handle;
+ CURL *ftp_handle;
+
/* Éléments pour la gestion de la configuration.
* Il s'agit d'une liste chaînée de sections. */
@@ -321,6 +327,11 @@ extern int set_ipv4(wes_t *wes, const unsigned char ip[4]);
extern int set_http_ids(wes_t *wes, const char *name, const char *pass);
extern int set_ftp_ids(wes_t *wes, const char *name, const char *pass);
+/* Ouvrir les canaux HTTP et FTP sur lesquels on fait les requêtes. */
+
+extern int open_http_handle(wes_t *wes, CURL **handlep, const char *path);
+extern int open_ftp_handle(wes_t *wes, CURL **handlep, const char *path);
+
/* Récupérer et définir la valeur d'une option de configuration sur le
* serveur WES. La « section » correspond au fichier dans le dossier `CFG/`
* accessible sur le serveur FTP du serveur WES. */
@@ -348,7 +359,7 @@ extern int clear_data(wes_t *wes);
extern int get_cgi(wes_t *wes, int num, wescgi_t *blocks);
extern int get_cgi_var(wes_t *wes, const char *var, const char *format,
- char *buffer, size_t len);
+ char *buffer, size_t *len);
/* ---
* Gestion de la liste.
diff --git a/daemon/main.c b/daemon/main.c
index 7023180..ced4f51 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -50,13 +50,13 @@ static int runtests(weslist_t *list)
printf("Nom du WES: %s\n", wes->name);
/* On récupète une variable via CGI. */
-
+#if 1
{
char value[200], value2[200], value3[3000];
wescgi_t blocks[] = {
WESCGI("v v", "[%s]", value, 11),
WESCGI("v K", "aa", value2, 200),
- WESCGI("r o", NULL, value3, 200)
+ WESCGI("r o", NULL, value3, 2500)
};
int i, count = sizeof(blocks) / sizeof(wescgi_t);
@@ -68,9 +68,10 @@ static int runtests(weslist_t *list)
i + 1, blocks[i].lines, blocks[i].full - 1, blocks[i].len - 1,
blocks[i].buffer);
}
+#endif
/* On récupère `RESEAU/ADIP` pour l'afficher. */
-#if 0
+#if 1
{
char value[21];
diff --git a/daemon/wes.c b/daemon/wes.c
index 0819804..4d59773 100644
--- a/daemon/wes.c
+++ b/daemon/wes.c
@@ -69,6 +69,8 @@ int init_wes(wes_t *wes)
wes->name = "";
wes->http_data = NULL;
wes->ftp_data = NULL;
+ wes->http_handle = NULL;
+ wes->ftp_handle = NULL;
err = set_http_ids(wes, DEFAULT_HTTP_NAME, DEFAULT_HTTP_PASS);
if (err)
@@ -91,6 +93,11 @@ int deinit_wes(wes_t *wes)
if (*wes->name)
free(wes->name);
+ if (wes->http_handle)
+ curl_easy_cleanup(wes->http_handle);
+ if (wes->ftp_handle)
+ curl_easy_cleanup(wes->ftp_handle);
+
clear_config(wes);
/* FIXME: clear_data(wes); */
free(wes->http_data);
@@ -190,3 +197,85 @@ int set_ftp_ids(wes_t *wes, const char *name, const char *pass)
return (0);
}
+
+/* `open_http_handle()`: Ouverture d'un canal HTTP pour un chemin HTTP.
+ * Ce canal n'a point besoin d'être fermé. */
+
+int open_http_handle(wes_t *wes, CURL **handlep, const char *path)
+{
+ CURL *handle;
+ const unsigned char *ip;
+ char url[50 + 200 + 1];
+
+ /* TODO: Faudrait gérer l'IPv6 aussi. */
+ ip = wes->addr.data.inet.ipv4;
+ sprintf(url, "http://%d.%d.%d.%d%.200s", ip[0], ip[1], ip[2], ip[3],
+ path);
+
+ if (wes->http_handle)
+ handle = wes->http_handle;
+ else {
+ handle = curl_easy_init();
+ if (!handle)
+ return (WRUNKNOWN);
+
+ wes->http_handle = handle;
+ }
+
+ /* TODO: put in the path and else as components? */
+ curl_easy_setopt(handle, CURLOPT_URL, url);
+
+ curl_easy_setopt(handle, CURLOPT_USERNAME, wes->http_name);
+ curl_easy_setopt(handle, CURLOPT_PASSWORD, wes->http_pass);
+ curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(handle, CURLOPT_VERBOSE, 0L);
+ curl_easy_setopt(handle, CURLOPT_QUOTE, NULL);
+ curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, NULL);
+ curl_easy_setopt(handle, CURLOPT_WRITEDATA, stdout);
+ curl_easy_setopt(handle, CURLOPT_READFUNCTION, NULL);
+ curl_easy_setopt(handle, CURLOPT_READDATA, stdin);
+
+ *handlep = handle;
+ return (WROK);
+}
+
+/* `open_ftp_handle()`: Ouverture d'un canal FTP pour un chemin FTP.
+ * Ce canal n'a point besoin d'être fermé. */
+
+int open_ftp_handle(wes_t *wes, CURL **handlep, const char *path)
+{
+ CURL *handle;
+ const unsigned char *ip;
+ char url[50 + 200 + 1];
+
+ /* TODO: Faudrait gérer l'IPv6 aussi. */
+ ip = wes->addr.data.inet.ipv4;
+ sprintf(url, "ftp://%d.%d.%d.%d%.200s", ip[0], ip[1], ip[2], ip[3],
+ path);
+
+ if (wes->ftp_handle)
+ handle = wes->ftp_handle;
+ else {
+ handle = curl_easy_init();
+ if (!handle)
+ return (WRUNKNOWN);
+
+ wes->ftp_handle = handle;
+ }
+
+ /* TODO: put in the path and else as components? */
+ curl_easy_setopt(handle, CURLOPT_URL, url);
+
+ curl_easy_setopt(handle, CURLOPT_USERNAME, wes->ftp_name);
+ curl_easy_setopt(handle, CURLOPT_PASSWORD, wes->ftp_pass);
+ curl_easy_setopt(handle, CURLOPT_UPLOAD, 0L);
+ curl_easy_setopt(handle, CURLOPT_VERBOSE, 0L);
+ curl_easy_setopt(handle, CURLOPT_QUOTE, NULL);
+ curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, stdout);
+ curl_easy_setopt(handle, CURLOPT_WRITEDATA, NULL);
+ curl_easy_setopt(handle, CURLOPT_READFUNCTION, stdin);
+ curl_easy_setopt(handle, CURLOPT_READDATA, NULL);
+
+ *handlep = handle;
+ return (WROK);
+}