Changeset: 410970e38bc3 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/410970e38bc3
Modified Files:
        clients/mapilib/connect.c
        clients/mapilib/mapi.c
        clients/mapilib/msettings.c
        clients/mapilib/msettings.h
        clients/mapilib/parseurl.c
Branch: monetdburl
Log Message:

Make sockdir configurable

using MP_SOCKDIR and also using mapi_mapi's host parameter (!)


diffs (truncated from 309 to 300 lines):

diff --git a/clients/mapilib/connect.c b/clients/mapilib/connect.c
--- a/clients/mapilib/connect.c
+++ b/clients/mapilib/connect.c
@@ -65,12 +65,21 @@ scan_unix_sockets(Mapi mid)
        DIR *dir = NULL;
        struct dirent *entry;
 
+       const char *sockdir = msettings_connect_sockdir(mid->settings);
+       size_t len = strlen(sockdir);
+       char *namebuf = malloc(len + 50);
+       if (namebuf == NULL)
+               return mapi_setError(mid, "malloc failed", __func__, MERROR);
+       strcpy(namebuf, sockdir);
+       strcpy(namebuf + len, "/.s.monetdb.PORTXXXXX");
+       char *put_port_here = strrchr(namebuf, 'P');
+
        msettings *original = mid->settings;
        mid->settings = NULL;  // invalid state, will fix it before use and on 
return
 
        // Make a list of Unix domain sockets in /tmp
        uid_t me = getuid();
-       if (DO_UNIX_DOMAIN && (dir = opendir("/tmp"))) {
+       if (DO_UNIX_DOMAIN && (dir = opendir(sockdir))) {
                while (ncandidates < MAX_SCAN && (entry = readdir(dir)) != 
NULL) {
                        const char *basename = entry->d_name;
                        if (strncmp(basename, ".s.monetdb.", 11) != 0 || 
basename[11] == '\0' || strlen(basename) > 20)
@@ -80,11 +89,10 @@ scan_unix_sockets(Mapi mid)
                        long port = strtol(basename + 11, &end, 10);
                        if (port < 1 || port > 65535 || *end)
                                continue;
-                       char name[80]; // enough, see checks above
-                       sprintf(name, "/tmp/.s.monetdb.%ld", port);
 
+                       sprintf(put_port_here, "%ld", port);
                        struct stat st;
-                       if (stat(name, &st) < 0 || !S_ISSOCK(st.st_mode))
+                       if (stat(namebuf, &st) < 0 || !S_ISSOCK(st.st_mode))
                                continue;
 
                        candidates[ncandidates].port = port;
@@ -103,6 +111,7 @@ scan_unix_sockets(Mapi mid)
                        mid->settings = msettings_clone(original);
                        if (!mid->settings) {
                                mid->settings = original;
+                               free(namebuf);
                                return mapi_setError(mid, "malloc failed", 
__func__, MERROR);
                        }
                        msettings_error errmsg = 
msetting_set_long(mid->settings, MP_PORT, candidates[i].port);
@@ -113,6 +122,7 @@ scan_unix_sockets(Mapi mid)
                        if (errmsg) {
                                mapi_setError(mid, errmsg, __func__, MERROR);
                                free(allocated_errmsg);
+                               free(namebuf);
                                msettings_destroy(mid->settings);
                                mid->settings = original;
                                return MERROR;
@@ -121,6 +131,7 @@ scan_unix_sockets(Mapi mid)
                        if (msg == MOK) {
                                // do not restore original
                                msettings_destroy(original);
+                               free(namebuf);
                                return MOK;
                        } else {
                                msettings_destroy(mid->settings);
@@ -130,11 +141,17 @@ scan_unix_sockets(Mapi mid)
                }
        }
 
+       free(namebuf);
+
        // Last-ditch attempt.
        // We can now freely modify original
        assert(mid->settings == NULL);
        mid->settings = original;
        msettings_error errmsg = msetting_set_string(mid->settings, MP_HOST, 
"localhost");
+       char *allocated_errmsg = NULL;
+       if (!errmsg && !msettings_validate(mid->settings, &allocated_errmsg)) {
+               errmsg = allocated_errmsg;
+       }
        if (errmsg) {
                return mapi_setError(mid, errmsg, __func__, MERROR);
        }
@@ -300,9 +317,6 @@ connect_socket_tcp(Mapi mid, const char 
        char portbuf[10];
        snprintf(portbuf, sizeof(portbuf), "%d", port);
 
-       if (host[0] == '/')
-               return mapi_setError(mid, "Setting the socket dir is not 
supported yet", __func__, MERROR);
-
        struct addrinfo hints = (struct addrinfo) {
                .ai_family = AF_UNSPEC,
                .ai_socktype = SOCK_STREAM,
diff --git a/clients/mapilib/mapi.c b/clients/mapilib/mapi.c
--- a/clients/mapilib/mapi.c
+++ b/clients/mapilib/mapi.c
@@ -1855,10 +1855,18 @@ mapi_mapi(const char *host, int port, co
        if (lang == NULL)
                lang = "sql";
 
+       const char *sockdir = NULL;
+       if (host && host[0] == '/') {
+               sockdir = host;
+               host = NULL;
+       }
+
        msettings_error err = NULL;
        do {
                if (host && (err = msetting_set_string(settings, MP_HOST, 
host)))
                        break;
+               if (sockdir && (err = msetting_set_string(settings, MP_SOCKDIR, 
sockdir)))
+                       break;
                if (username && (err = msetting_set_string(settings, MP_USER, 
username)))
                        break;
                if (password && (err = msetting_set_string(settings, 
MP_PASSWORD, password)))
diff --git a/clients/mapilib/msettings.c b/clients/mapilib/msettings.c
--- a/clients/mapilib/msettings.c
+++ b/clients/mapilib/msettings.c
@@ -1,4 +1,5 @@
-#define _POSIX_C_SOURCE 200809L
+
+
 
 #include "msettings.h"
 
@@ -73,6 +74,7 @@ by_name[] = {
        { .name="fetchsize", .parm=MP_REPLYSIZE },
        { .name="schema", .parm=MP_SCHEMA },
        { .name="sock", .parm=MP_SOCK },
+       { .name="sockdir", .parm=MP_SOCKDIR},
        { .name="table", .parm=MP_TABLE },
        { .name="tableschema", .parm=MP_TABLESCHEMA },
        { .name="timezone", .parm=MP_TIMEZONE },
@@ -114,6 +116,7 @@ mparm_name(mparm parm)
                case MP_REPLYSIZE: return "replysize";
                case MP_SCHEMA: return "schema";
                case MP_SOCK: return "sock";
+               case MP_SOCKDIR: return "sockdir";
                case MP_TABLE: return "table";
                case MP_TABLESCHEMA: return "tableschema";
                case MP_TIMEZONE: return "timezone";
@@ -146,14 +149,17 @@ struct msettings {
        bool autocommit;
        bool dummy_end_bool;
 
+       // Must match EXACTLY the order of enum mparm
        long dummy_start_long;
        long port;
        long timezone;
        long replysize;
        long dummy_end_long;
 
+       // Must match EXACTLY the order of enum mparm
        char *dummy_start_string;
        char *sock;
+       char *sockdir;
        char *cert;
        char *clientkey;
        char *clientcert;
@@ -176,7 +182,7 @@ struct msettings {
        bool lang_is_sql;
        long user_generation;
        long password_generation;
-       char unix_sock_name_buffer[50];
+       char *unix_sock_name_buffer;
        char certhash_digits_buffer[64 + 2 + 1]; // fit more than required plus 
trailing '\0'
        bool validated;
 };
@@ -207,9 +213,10 @@ const msettings msettings_default_values
 
        .unknown_parameters = NULL,
        .nr_unknown = 0,
+
        .lang_is_mal = false,
        .lang_is_sql = true,
-
+       .unix_sock_name_buffer = NULL,
        .validated = false,
 };
 
@@ -229,14 +236,17 @@ msettings *msettings_create(void)
 msettings *msettings_clone(const msettings *orig)
 {
        msettings *mp = malloc(sizeof(*mp));
-       char **unknowns = calloc(2 * mp->nr_unknown, sizeof(char*));
-       if (!mp || !unknowns) {
+       char **unknowns = calloc(2 * orig->nr_unknown, sizeof(char*));
+       char *cloned_name_buffer = strdup(orig->unix_sock_name_buffer);
+       if (!mp || !unknowns || !cloned_name_buffer) {
                free(mp);
                free(unknowns);
+               free(cloned_name_buffer);
                return NULL;
        }
        *mp = *orig;
        mp->unknown_parameters = unknowns;
+       mp->unix_sock_name_buffer = cloned_name_buffer;
 
        // now we have to very carefully duplicate the strings.
        // taking care to only free our own ones if that fails
@@ -253,7 +263,7 @@ msettings *msettings_clone(const msettin
                p++;
        }
 
-       for (int i = 0; i < 2 * mp->nr_unknown; i++) {
+       for (size_t i = 0; i < 2 * mp->nr_unknown; i++) {
                assert(orig->unknown_parameters[i]);
                char *u = strdup(orig->unknown_parameters[i]);
                if (u == NULL)
@@ -266,8 +276,9 @@ msettings *msettings_clone(const msettin
 bailout:
        for (char **q = start; q < p; q++)
                free(*q);
-       for (int i = 0; i < 2 * mp->nr_unknown; i++)
+       for (size_t i = 0; i < 2 * mp->nr_unknown; i++)
                free(mp->unknown_parameters[i]);
+       free(mp->unix_sock_name_buffer);
        free(mp);
        return NULL;
 }
@@ -286,6 +297,7 @@ msettings_destroy(msettings *mp)
                free(mp->unknown_parameters[2 * i + 1]);
        }
        free(mp->unknown_parameters);
+       free(mp->unix_sock_name_buffer);
        free(mp);
 
        return NULL;
@@ -649,8 +661,11 @@ msettings_validate(msettings *mp, char *
        }
 
        // compute this here so the getter function can take const msettings*
+       const char *sockdir = msettings_connect_sockdir(mp);
        long effective_port = msettings_connect_port(mp);
-       snprintf(mp->unix_sock_name_buffer, sizeof(mp->unix_sock_name_buffer), 
"/tmp/.s.monetdb.%ld", effective_port);
+       mp->unix_sock_name_buffer = allocprintf("%s/.s.monetdb.%ld", sockdir, 
effective_port);
+       if (mp->unix_sock_name_buffer == NULL)
+               return false;
 
        mp->validated = true;
        return true;
@@ -676,6 +691,16 @@ msettings_connect_scan(const msettings *
 }
 
 const char *
+msettings_connect_sockdir(const msettings *mp)
+{
+       const char *dir = msetting_string(mp, MP_SOCKDIR);
+       if (dir[0] != '\0')
+               return dir;
+       else
+               return "/tmp";
+}
+
+const char *
 msettings_connect_unix(const msettings *mp)
 {
        assert(mp->validated);
@@ -687,8 +712,11 @@ msettings_connect_unix(const msettings *
                return sock;
        if (tls)
                return "";
-       if (*host == '\0')
+       if (*host == '\0') {
+               // This was precomputed in msettings_validate(),
+               // {sockdir}/.s.monetdb.{port}
                return mp->unix_sock_name_buffer;
+       }
        return "";
 }
 
diff --git a/clients/mapilib/msettings.h b/clients/mapilib/msettings.h
--- a/clients/mapilib/msettings.h
+++ b/clients/mapilib/msettings.h
@@ -5,8 +5,8 @@
 #define MP__STRING_START (300)
 
 typedef enum mparm {
-               MP_UNKNOWN,
-               MP_IGNORE,
+       MP_UNKNOWN,
+       MP_IGNORE,
 
         // bool
         MP_TLS = MP__BOOL_START,
@@ -19,6 +19,7 @@ typedef enum mparm {
 
         // string
         MP_SOCK = MP__STRING_START,
+       MP_SOCKDIR,
         MP_CERT,
         MP_CLIENTKEY,
         MP_CLIENTCERT,
@@ -106,6 +107,7 @@ bool msettings_validate(msettings *mp, c
 
 /* virtual parameters */
 bool msettings_connect_scan(const msettings *mp);
+const char *msettings_connect_sockdir(const msettings *mp);
 const char *msettings_connect_unix(const msettings *mp);
 const char *msettings_connect_tcp(const msettings *mp);
 long msettings_connect_port(const msettings *mp);
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to