Changeset: 166d521e5469 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/166d521e5469
Added Files:
        clients/mapilib/connect_unix.c
Modified Files:
        clients/mapilib/CMakeLists.txt
        clients/mapilib/connect.c
        clients/mapilib/mapi_intern.h
Branch: monetdburl
Log Message:

Split off Unix domain functionality to separate file


diffs (truncated from 476 to 300 lines):

diff --git a/clients/mapilib/CMakeLists.txt b/clients/mapilib/CMakeLists.txt
--- a/clients/mapilib/CMakeLists.txt
+++ b/clients/mapilib/CMakeLists.txt
@@ -23,6 +23,7 @@ target_sources(mapi
   connect.c
   msettings.c
   parseurl.c
+  $<$<BOOL:${HAVE_SYS_UN_H}>:connect_unix.c>
   $<$<BOOL:${OPENSSL_FOUND}>:connect_openssl.c>
   mapi_intern.h
   PUBLIC
diff --git a/clients/mapilib/connect.c b/clients/mapilib/connect.c
--- a/clients/mapilib/connect.c
+++ b/clients/mapilib/connect.c
@@ -34,14 +34,41 @@
 #endif
 
 
-static MapiMsg establish_connection(Mapi mid);
-static MapiMsg scan_unix_sockets(Mapi mid);
+static MapiMsg scan_sockets(Mapi mid);
 static MapiMsg connect_socket(Mapi mid);
-static MapiMsg connect_socket_unix(Mapi mid);
 static MapiMsg connect_socket_tcp(Mapi mid);
 static SOCKET connect_socket_tcp_addr(Mapi mid, struct addrinfo *addr);
 static MapiMsg mapi_handshake(Mapi mid);
 
+#ifndef HAVE_OPENSSL
+// The real implementation is in connect_openssl.c.
+MapiMsg
+wrap_tls(Mapi mid, SOCKET sock)
+{
+       closesocket(sock);
+       return mapi_setError(mid, "Cannot connect to monetdbs://, not built 
with OpenSSL support", __func__, MERROR);
+}
+#endif // HAVE_OPENSSL
+
+#ifndef HAVE_SYS_UN_H
+
+MapiMsg
+connect_socket_unix(Mapi mid)
+{
+       return mapi_setError(mid, "Unix domain sockets not supported", 
__func__, MERROR);
+}
+
+static MapiMsg
+scan_unix_sockets(Mapi mid)
+{
+       return mapi_setError(mid, "Unix domain sockets not supported", 
__func__, MERROR);
+}
+
+#endif
+
+
+
+
 /* (Re-)establish a connection with the server. */
 MapiMsg
 mapi_reconnect(Mapi mid)
@@ -57,112 +84,18 @@ mapi_reconnect(Mapi mid)
        // /tmp and see if any of them serve this database.
        // Otherwise, just try to connect to what was given.
        if (msettings_connect_scan(mid->settings))
-               return scan_unix_sockets(mid);
+               return scan_sockets(mid);
        else
                return establish_connection(mid);
 }
 
-#define MAX_SCAN (24)
-
 static MapiMsg
-scan_unix_sockets(Mapi mid)
+scan_sockets(Mapi mid)
 {
-       struct {
-               int port;
-               int priority;
-       } candidates[MAX_SCAN];
-       int ncandidates = 0;
-       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
-
-       mapi_log_record(mid, "CONN", "Scanning %s for Unix domain sockets", 
sockdir);
-
-       // Make a list of Unix domain sockets in /tmp
-       uid_t me = getuid();
-       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)
-                               continue;
-
-                       char *end;
-                       long port = strtol(basename + 11, &end, 10);
-                       if (port < 1 || port > 65535 || *end)
-                               continue;
-
-                       sprintf(put_port_here, "%ld", port);
-                       struct stat st;
-                       if (stat(namebuf, &st) < 0 || !S_ISSOCK(st.st_mode))
-                               continue;
-
-                       candidates[ncandidates].port = port;
-                       candidates[ncandidates++].priority = st.st_uid == me ? 
0 : 1;
-               }
-       }
+       if (scan_unix_sockets(mid) == MOK)
+               return MOK;
 
-       mapi_log_record(mid, "CONN", "Found %d Unix domain sockets", 
ncandidates);
-
-       // Try those owned by us first, then all others
-       for (int round = 0; round < 2; round++) {
-               for (int i = 0; i < ncandidates; i++) {
-                       if (candidates[i].priority != round)
-                               continue;
-
-                       assert(!mid->connected);
-                       assert(mid->settings == NULL);
-                       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);
-                       char *allocated_errmsg = NULL;
-                       if (!errmsg && !msettings_validate(mid->settings, 
&allocated_errmsg)) {
-                               errmsg = allocated_errmsg;
-                       }
-                       if (errmsg) {
-                               mapi_setError(mid, errmsg, __func__, MERROR);
-                               free(allocated_errmsg);
-                               free(namebuf);
-                               msettings_destroy(mid->settings);
-                               mid->settings = original;
-                               return MERROR;
-                       }
-                       MapiMsg msg = establish_connection(mid);
-                       if (msg == MOK) {
-                               // do not restore original
-                               msettings_destroy(original);
-                               free(namebuf);
-                               return MOK;
-                       } else {
-                               msettings_destroy(mid->settings);
-                               mid->settings = NULL;
-                               // now we're ready to try another one
-                       }
-               }
-       }
-
-       free(namebuf);
-
-       // Last-ditch attempt.
-       mapi_log_record(mid, "CONN", "All %d Unix domain sockets failed. 
Falling back to TCP", ncandidates);
-
-       // We can now freely modify original
-       assert(mid->settings == NULL);
-       mid->settings = original;
+       // When the Unix sockets have been scanned we can freely modify 
'original'.
        msettings_error errmsg = msetting_set_string(mid->settings, MP_HOST, 
"localhost");
        char *allocated_errmsg = NULL;
        if (!errmsg && !msettings_validate(mid->settings, &allocated_errmsg)) {
@@ -175,7 +108,7 @@ scan_unix_sockets(Mapi mid)
 }
 
 /* (Re-)establish a connection with the server. */
-static MapiMsg
+MapiMsg
 establish_connection(Mapi mid)
 {
        if (mid->connected) {
@@ -224,7 +157,7 @@ connect_socket(Mapi mid)
        return MOK;
 }
 
-static MapiMsg
+MapiMsg
 wrap_socket(Mapi mid, SOCKET sock)
 {
        // do not use check_stream here yet because the socket is not yet in 
'mid'
@@ -266,86 +199,6 @@ bailout:
        }
 }
 
-#ifndef HAVE_OPENSSL
-// The real implementation is in connect_openssl.c.
-MapiMsg
-wrap_tls(Mapi mid, SOCKET sock)
-{
-       closesocket(sock);
-       return mapi_setError(mid, "Cannot connect to monetdbs://, not built 
with OpenSSL support", __func__, MERROR);
-}
-#endif // HAVE_OPENSSL
-
-#ifndef HAVE_SYS_UN_H
-static MapiMsg
-connect_socket_unix(Mapi mid)
-{
-       return mapi_setError(mid, "Unix domain sockets not supported", 
__func__, MERROR);
-}
-#endif
-
-#ifdef HAVE_SYS_UN_H
-
-static MapiMsg
-connect_socket_unix(Mapi mid)
-{
-       const char *sockname = msettings_connect_unix(mid->settings);
-       assert (*sockname != '\0');
-
-       mapi_log_record(mid, "CONN", "Connecting to Unix domain socket %s", 
sockname);
-
-       struct sockaddr_un userver;
-       if (strlen(sockname) >= sizeof(userver.sun_path)) {
-               return mapi_printError(mid, __func__, MERROR, "path name '%s' 
too long", sockname);
-       }
-
-       // Create the socket, taking care of CLOEXEC
-
-#ifdef SOCK_CLOEXEC
-       int s = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
-#else
-       int s = socket(PF_UNIX, SOCK_STREAM, 0);
-#endif
-       if (s == INVALID_SOCKET) {
-               return mapi_printError(
-                       mid, __func__, MERROR,
-                       "could not create Unix domain socket '%s': %s", 
sockname, SOCKET_STRERROR());
-       }
-#if !defined(SOCK_CLOEXEC) && defined(HAVE_FCNTL)
-       (void) fcntl(s, F_SETFD, FD_CLOEXEC);
-#endif
-
-       // Attempt to connect
-
-       userver = (struct sockaddr_un) {
-               .sun_family = AF_UNIX,
-       };
-       strcpy_len(userver.sun_path, sockname, sizeof(userver.sun_path));
-
-       if (connect(s, (struct sockaddr *) &userver, sizeof(struct 
sockaddr_un)) == SOCKET_ERROR) {
-               closesocket(s);
-               return mapi_printError(
-                       mid, __func__, MERROR,
-                       "connect to Unix domain socket '%s' failed: %s", 
sockname, SOCKET_STRERROR());
-       }
-
-       // Send an initial zero (not NUL) to let the server know we're not 
passing a file
-       // descriptor.
-
-       ssize_t n = send(s, "0", 1, 0);
-       if (n < 1) {
-               // used to be if n < 0 but this makes more sense
-               closesocket(s);
-               return mapi_printError(
-                       mid, __func__, MERROR,
-                       "could not send initial '0' on Unix domain socket: %s", 
SOCKET_STRERROR());
-       }
-
-       return wrap_socket(mid, s);
-}
-
-#endif  // end of ifdef HAVE_SYS_UN_H
-
 static MapiMsg
 connect_socket_tcp(Mapi mid)
 {
diff --git a/clients/mapilib/connect_unix.c b/clients/mapilib/connect_unix.c
new file mode 100644
--- /dev/null
+++ b/clients/mapilib/connect_unix.c
@@ -0,0 +1,175 @@
+
+
+#include "monetdb_config.h"
+#include "stream.h"            /* include before mapi.h */
+#include "stream_socket.h"
+#include "mapi.h"
+#include "mapi_prompt.h"
+#include "mcrypt.h"
+#include "matomic.h"
+#include "mstring.h"
+#include "mutils.h"
+
+#include "mapi_intern.h"
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to