summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-01-31 21:03:27 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-01-31 21:06:33 (GMT)
commit7ba93e4d9e3e722d8771d665c5217510105375d2 (patch)
tree7730c8bfb9393e36e00d2bec660f162249055740 /src
parentbe1c4e8f3d8d223d11ff695785415413427f0405 (diff)
Avoided to pollute the configuration directory with old UNIX family sockets.
Diffstat (limited to 'src')
-rw-r--r--src/analysis/db/server.c95
-rw-r--r--src/main.c6
2 files changed, 97 insertions, 4 deletions
diff --git a/src/analysis/db/server.c b/src/analysis/db/server.c
index 219b8b6..bbc7415 100644
--- a/src/analysis/db/server.c
+++ b/src/analysis/db/server.c
@@ -35,6 +35,9 @@
#include <sys/un.h>
+#include <i18n.h>
+
+
#include "cdb.h"
#include "keymgn.h"
#include "protocol.h"
@@ -66,6 +69,11 @@ typedef union _gen_sockaddr_t
# define UNIX_PATH_MAX 108
#endif
+
+/* Assure que le point de connexion est vierge. */
+typedef bool (* clean_server_socket_cb) (GDbServer *);
+
+
/* Description de serveur à l'écoute (instance) */
struct _GDbServer
{
@@ -80,6 +88,8 @@ struct _GDbServer
socklen_t sock_len; /* Taille de cette adresse */
char *desc; /* Désignation du serveur */
+ clean_server_socket_cb clean_socket; /* Procédure de nettoyage ? */
+
char *basedir; /* Répertoire de stockage */
GThread *listener; /* Procédure de traitement */
@@ -106,6 +116,9 @@ static void g_db_server_init(GDbServer *);
/* Procède à la libération totale de la mémoire. */
static void g_db_server_finalize(GDbServer *);
+/* Assure que le point de connexion est vierge. */
+static bool g_db_server_clean_internal_socket(GDbServer *);
+
/* Supprime toute trace d'utilisateur inscrit. */
static void g_db_server_unregister_all_user(GDbServer *);
@@ -207,16 +220,17 @@ static void g_db_server_finalize(GDbServer *server)
GDbServer *g_db_server_new_internal(const char *author, char *kfile)
{
GDbServer *result; /* Adresse à retourner */
- bool ret; /* Bilan d'un appel */
+ bool status; /* Bilan d'un chargement */
char *suffix; /* Suffixe pour un fichier */
+ size_t sock_length; /* Taille du chemin complet */
char *sock_path; /* Chemin vers le canal UNIX */
result = g_object_new(G_TYPE_DB_SERVER, NULL);
/* Chargement du profil */
- ret = g_db_server_register_user(result, author, kfile);
- if (!ret) goto gdsni_error;
+ status = g_db_server_register_user(result, author, kfile);
+ if (!status) goto gdsni_error;
/* Détermination du point d'écoute */
@@ -226,6 +240,17 @@ GDbServer *g_db_server_new_internal(const char *author, char *kfile)
sock_path = get_xdg_config_dir(suffix);
free(suffix);
+ sock_length = strlen(sock_path) + 1;
+
+ if (sock_length > UNIX_PATH_MAX)
+ {
+ log_variadic_message(LMT_ERROR,
+ _("Impossible to use '%s' for the internal server: path is too long ! (%zu vs %u)\n"),
+ sock_path, sock_length, UNIX_PATH_MAX);
+
+ goto gdsni_too_long;
+ }
+
memset(&result->addr, 0, sizeof(struct sockaddr_un));
result->addr.unix_addr.sun_family = AF_UNIX;
@@ -239,12 +264,20 @@ GDbServer *g_db_server_new_internal(const char *author, char *kfile)
asprintf(&result->desc, "unix://.internal_server.%d", getpid());
+ /* Aide pour une sortie propre ? */
+
+ result->clean_socket = g_db_server_clean_internal_socket;
+
/* Répertoire de stockage */
result->basedir = get_xdg_config_dir("chrysalide" G_DIR_SEPARATOR_S "cdbs");
return result;
+ gdsni_too_long:
+
+ free(sock_path);
+
gdsni_error:
g_object_unref(G_OBJECT(result));
@@ -256,6 +289,47 @@ GDbServer *g_db_server_new_internal(const char *author, char *kfile)
/******************************************************************************
* *
+* Paramètres : server = instance à consulter et préparer. *
+* *
+* Description : Assure que le point de connexion est vierge. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_db_server_clean_internal_socket(GDbServer *server)
+{
+ bool result; /* Bilan à faire remonter */
+ char *sock_path; /* Chemin vers le canal UNIX */
+ int ret; /* Bilan d'un appel */
+
+ result = true;
+
+ sock_path = server->addr.unix_addr.sun_path;
+
+ ret = access(sock_path, F_OK);
+
+ if (ret == 0)
+ {
+ ret = unlink(sock_path);
+
+ if (ret != 0)
+ {
+ perror("unlink");
+ result = false;
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : conf = fichier de configuration à interpréter. *
* *
* Description : Prépare un serveur de BD pour les clients distants. *
@@ -324,6 +398,10 @@ GDbServer *g_db_server_new_remote(const char *conf)
snprintf(result->desc + strlen(ip), 1 + 5, ":%hu", port);
+ /* Aide pour une sortie propre ? */
+
+ result->clean_socket = NULL;
+
/* Répertoire de stockage */
@@ -738,6 +816,7 @@ static void *g_db_server_listener(GDbServer *server)
bool g_db_server_start(GDbServer *server)
{
int ret; /* Bilan d'un appel */
+ bool status; /* Bilan d'un nettoyage */
int backlog; /* Nombre de connexions maximal*/
server->fd = socket(server->domain, SOCK_STREAM, 0);
@@ -751,10 +830,15 @@ bool g_db_server_start(GDbServer *server)
if (ret == -1)
{
perror("setsockopt");
- exit(0);
goto gdss_error;
}
+ if (server->clean_socket != NULL)
+ {
+ status = server->clean_socket(server);
+ if (!status) goto gdss_error;
+ }
+
ret = bind(server->fd, (struct sockaddr *)&server->addr, server->sock_len);
if (ret == -1)
{
@@ -817,6 +901,9 @@ void g_db_server_stop(GDbServer *server)
server->fd = -1;
+ if (server->clean_socket != NULL)
+ server->clean_socket(server);
+
/* TODO : s'occuper des archives ouvertes */
}
diff --git a/src/main.c b/src/main.c
index 20a443d..f112842 100644
--- a/src/main.c
+++ b/src/main.c
@@ -279,6 +279,8 @@ int main(int argc, char **argv)
pub = get_xdg_config_dir("chrysalide" G_DIR_SEPARATOR_S "id_rsa.pub");
server = g_db_server_new_internal(author, pub);
+ if (server == NULL) goto no_internal_server;
+
g_db_server_start(server);
/* Charge le dernier projet ? */
@@ -306,6 +308,10 @@ int main(int argc, char **argv)
g_db_server_stop(server);
+ g_object_unref(G_OBJECT(server));
+
+ no_internal_server:
+
exit_complete_gui:
exit_all_plugins();