From 30009c26869094699c93ff5d922405e3a13fd26f Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 11 Apr 2018 02:36:41 +0200
Subject: Moved all the temporary creations in a temporary directory.

---
 src/analysis/db/client.c |  27 ++++-------
 src/analysis/db/server.c |  50 ++++++---------------
 src/common/io.c          | 114 ++++++++++++++++++++++++++++++++++++++++++++---
 src/common/io.h          |   7 +++
 src/core/params.c        |   3 ++
 src/core/params.h        |   1 +
 6 files changed, 141 insertions(+), 61 deletions(-)

diff --git a/src/analysis/db/client.c b/src/analysis/db/client.c
index 31fc062..26d71f3 100644
--- a/src/analysis/db/client.c
+++ b/src/analysis/db/client.c
@@ -29,8 +29,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
-#include <sys/socket.h>
-#include <sys/un.h>
 
 
 #include <i18n.h>
@@ -209,27 +207,15 @@ GDbClient *g_db_client_new(char *author, char *kfile, const char *name, const ch
 
 bool g_db_client_start_internal(GDbClient *client)
 {
-    char *suffix;                           /* Suffixe pour un fichier     */
-    char *sock_path;                        /* Chemin vers le canal UNIX   */
+    bool status;                            /* Bilan de la connexion       */
     struct sockaddr_un addr;                /* Adresse de transmission     */
     int ret;                                /* Bilan d'un appel            */
     char *desc;                             /* Description du serveur ciblé*/
-    bool status;                            /* Bilan de la connexion       */
 
     /* Identification du serveur à contacter */
 
-    asprintf(&suffix, "chrysalide" G_DIR_SEPARATOR_S ".internal_server.%d", getpid());
-    sock_path = get_xdg_config_dir(suffix);
-    free(suffix);
-
-    memset(&addr, 0, sizeof(struct sockaddr_un));
-
-#define UNIX_PATH_MAX 108
-
-    addr.sun_family = AF_UNIX;
-    strncpy(addr.sun_path, sock_path, UNIX_PATH_MAX - 1);
-
-    free(sock_path);
+    status = build_tmp_socket("internal-server", &addr);
+    if (!status) goto gdcni_error;
 
     /* Création d'un canal de communication */
 
@@ -237,7 +223,7 @@ bool g_db_client_start_internal(GDbClient *client)
     if (client->fd == -1)
     {
         perror("socket");
-        return false;
+        goto gdcni_error;
     }
 
     ret = connect(client->fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un));
@@ -247,7 +233,7 @@ bool g_db_client_start_internal(GDbClient *client)
         goto gdcsi_no_listening;
     }
 
-    asprintf(&desc, "unix://.internal_server.%d", getpid());
+    asprintf(&desc, "unix://%s", addr.sun_path);
 
     status = g_db_client_start_common(client, desc);
 
@@ -261,6 +247,9 @@ bool g_db_client_start_internal(GDbClient *client)
  gdcsi_no_listening:
 
     close(client->fd);
+
+ gdcni_error:
+
     client->fd = -1;
 
     return false;
diff --git a/src/analysis/db/server.c b/src/analysis/db/server.c
index 6455fda..1565501 100644
--- a/src/analysis/db/server.c
+++ b/src/analysis/db/server.c
@@ -31,8 +31,6 @@
 #include <string.h>
 #include <unistd.h>
 #include <arpa/inet.h>
-#include <sys/socket.h>
-#include <sys/un.h>
 
 
 #include <i18n.h>
@@ -65,10 +63,6 @@ typedef union _gen_sockaddr_t
 
 } gen_sockaddr_t;
 
-#ifndef UNIX_PATH_MAX
-#   define UNIX_PATH_MAX 108
-#endif
-
 
 /* Assure que le point de connexion est vierge. */
 typedef bool (* clean_server_socket_cb) (GDbServer *);
@@ -176,6 +170,8 @@ static void g_db_server_init(GDbServer *server)
 {
     server->fd = -1;
 
+    server->basedir = NULL;
+
     g_mutex_init(&server->mutex);
 
 }
@@ -199,6 +195,9 @@ static void g_db_server_finalize(GDbServer *server)
 
     free(server->desc);
 
+    if (server->basedir != NULL)
+        free(server->basedir);
+
     G_OBJECT_CLASS(g_db_server_parent_class)->finalize(G_OBJECT(server));
 
 }
@@ -221,9 +220,6 @@ GDbServer *g_db_server_new_internal(const char *author, char *kfile)
 {
     GDbServer *result;                      /* Adresse à retourner         */
     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);
 
@@ -236,33 +232,14 @@ GDbServer *g_db_server_new_internal(const char *author, char *kfile)
 
     result->domain = AF_UNIX;
 
-    asprintf(&suffix, "chrysalide" G_DIR_SEPARATOR_S ".internal_server.%d", getpid());
-    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;
-    strncpy(result->addr.unix_addr.sun_path, sock_path, UNIX_PATH_MAX - 1);
-
-    free(sock_path);
+    status = build_tmp_socket("internal-server", &result->addr.unix_addr);
+    if (!status) goto gdsni_error;
 
     result->sock_len = sizeof(struct sockaddr_un);
 
     /* Désignation humaine */
 
-    asprintf(&result->desc, "unix://.internal_server.%d", getpid());
+    asprintf(&result->desc, "unix://%s", result->addr.unix_addr.sun_path);
 
     /* Aide pour une sortie propre ? */
 
@@ -274,10 +251,6 @@ GDbServer *g_db_server_new_internal(const char *author, char *kfile)
 
     return result;
 
- gdsni_too_long:
-
-    free(sock_path);
-
  gdsni_error:
 
     g_object_unref(G_OBJECT(result));
@@ -351,6 +324,8 @@ GDbServer *g_db_server_new_remote(const char *conf)
     struct hostent *hp;                     /* Informations sur l'hôte     */
     size_t desclen;                         /* Taille de désignation       */
     const char *ip;                         /* Adresse IPv4 ou IPv6        */
+    const char *tmpdir;                     /* Répertoire de travail       */
+    bool status;                            /* Bilan d'un consultation     */
 
     result = g_object_new(G_TYPE_DB_SERVER, NULL);
 
@@ -404,9 +379,10 @@ GDbServer *g_db_server_new_remote(const char *conf)
 
     /* Répertoire de stockage */
 
+    status = g_generic_config_get_value(get_main_configuration(), MPK_TMPDIR, &tmpdir);
+    if (!status) goto gdsn_error;
 
-    result->basedir = strdup("/tmp/"); /* TODO */
-
+    result->basedir = strdup(tmpdir);
 
     return result;
 
diff --git a/src/common/io.c b/src/common/io.c
index 8e56379..85be44c 100644
--- a/src/common/io.c
+++ b/src/common/io.c
@@ -28,10 +28,17 @@
 #include <libgen.h>
 #include <malloc.h>
 #include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
+#include <sys/un.h>
+
+
+#include "../core/logs.h"
+#include "../core/params.h"
 
 
 
@@ -284,11 +291,6 @@ bool safe_send(int sockfd, const void *buf, size_t len, int flags)
 }
 
 
-
-
-
-
-
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : path = chemin d'accès à valider.                             *
@@ -326,3 +328,105 @@ int ensure_path_exists(const char *path)
     return result;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : base     = préfixe du nom du fichier temporaire à créer.     *
+*                filename = chemin d'accès complet au nouveau fichier. [OUT]  *
+*                                                                             *
+*  Description : Met en place un fichier temporaire.                          *
+*                                                                             *
+*  Retour      : Flux ouvert en lecture et écriture, ou -1 en cas d'erreur.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int make_tmp_file(const char *base, char **filename)
+{
+    int result;                             /* Flux ou code à retourner    */
+    const char *tmpdir;                     /* Répertoire d'accueil        */
+    bool status;                            /* Bilan d'un consultation     */
+
+    status = g_generic_config_get_value(get_main_configuration(), MPK_TMPDIR, &tmpdir);
+    if (!status) return -1;
+
+    asprintf(filename, "%s" G_DIR_SEPARATOR_S "%s-%d.XXXXXX", tmpdir, base, getpid());
+
+    result = ensure_path_exists(*filename);
+
+    if (result == 0)
+    {
+        result = mkstemp(*filename);
+        if (result == -1) perror("mkstemp");
+    }
+
+    if (result == -1)
+        free(*filename);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : base = préfixe du nom du fichier temporaire à créer.         *
+*                addr = adresse UNIX constituée. [OUT]                        *
+*                                                                             *
+*  Description : Met en place un canal UNIX temporaire.                       *
+*                                                                             *
+*  Retour      : Bilan de la définition.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool build_tmp_socket(const char *base, struct sockaddr_un *addr)
+{
+    bool result;                            /* Bilan à retourner           */
+    const char *tmpdir;                     /* Répertoire d'accueil        */
+    bool status;                            /* Bilan d'un consultation     */
+    char *path;                             /* Chemin d'accès au canal     */
+    int ret;                                /* Bilan intermédiaire         */
+    size_t length;                          /* Taille du chemin complet    */
+
+    status = g_generic_config_get_value(get_main_configuration(), MPK_TMPDIR, &tmpdir);
+    if (!status) return false;
+
+    result = false;
+
+    asprintf(&path, "%s" G_DIR_SEPARATOR_S "%s-%d", tmpdir, base, getpid());
+
+    ret = ensure_path_exists(path);
+    if (ret != 0) goto mts_exit;
+
+    length = strlen(path) + 1;
+
+#ifndef UNIX_PATH_MAX
+#   define UNIX_PATH_MAX 108
+#endif
+
+    if (length > UNIX_PATH_MAX)
+    {
+        log_variadic_message(LMT_ERROR,
+                             _("Impossible to use '%s' as UNIX socket path: string is too long ! (%zu vs %u)\n"),
+                             path, length, UNIX_PATH_MAX);
+        goto mts_exit;
+    }
+
+    memset(addr, 0, sizeof(struct sockaddr_un));
+
+    addr->sun_family = AF_UNIX;
+    strncpy(addr->sun_path, path, UNIX_PATH_MAX - 1);
+
+    result = true;
+
+ mts_exit:
+
+    free(path);
+
+    return result;
+
+}
diff --git a/src/common/io.h b/src/common/io.h
index 0ada366..d70c64a 100644
--- a/src/common/io.h
+++ b/src/common/io.h
@@ -28,6 +28,7 @@
 #include <stdbool.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 
 
 
@@ -49,6 +50,12 @@ bool safe_send(int, const void *, size_t, int);
 /* S'assure qu'un chemin donné existe dans le système. */
 int ensure_path_exists(const char *);
 
+/* Met en place un fichier temporaire. */
+int make_tmp_file(const char *, char **);
+
+/* Met en place un canal UNIX temporaire. */
+bool build_tmp_socket(const char *, struct sockaddr_un *);
+
 
 
 #endif  /* _COMMON_IO_H */
diff --git a/src/core/params.c b/src/core/params.c
index a3783d7..ce8b9ce 100644
--- a/src/core/params.c
+++ b/src/core/params.c
@@ -216,6 +216,9 @@ bool load_main_config_parameters(void)
     param = g_generic_config_create_param(config, MPK_KEYBINDINGS_EDIT, CPT_STRING, "<Shift>F2");
     if (param == NULL) return false;
 
+    param = g_generic_config_create_param(config, MPK_TMPDIR, CPT_STRING, "/tmp/chrysalide");
+    if (param == NULL) return false;
+
     param = g_generic_config_create_param(config, MPK_AUTO_SAVE, CPT_BOOLEAN, true);
     if (param == NULL) return false;
 
diff --git a/src/core/params.h b/src/core/params.h
index 60c57d4..4535b04 100644
--- a/src/core/params.h
+++ b/src/core/params.h
@@ -66,6 +66,7 @@
 #define MPK_TOOLTIP_MAX_CALLS   "gui.editor.views.tooltip_max_calls"
 #define MPK_TOOLTIP_MAX_STRINGS "gui.editor.views.tooltip_max_strings"
 #define MPK_KEYBINDINGS_EDIT    "gui.key_bindings.global.edit"
+#define MPK_TMPDIR              "misc.tmpdir"
 #define MPK_AUTO_SAVE           "project.autosave"
 
 
-- 
cgit v0.11.2-87-g4458