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