diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analysis/db/server.c | 95 | ||||
-rw-r--r-- | src/main.c | 6 |
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 */ } @@ -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(); |