util: merge common code for xcb_connect
[free-sw/xcb/libxcb] / src / xcb_util.c
index 4ae9097..54361f4 100644 (file)
@@ -125,7 +125,7 @@ static int _xcb_open_unix(char *protocol, const char *file);
 static int _xcb_open_decnet(const char *host, char *protocol, const unsigned short port);
 #endif
 #ifdef HAVE_ABSTRACT_SOCKETS
-static int _xcb_open_abstract(char *protocol, const char *file);
+static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen);
 #endif
 
 static int _xcb_open(char *host, char *protocol, const int display)
@@ -135,6 +135,7 @@ static int _xcb_open(char *host, char *protocol, const int display)
 #endif
     static const char base[] = "/tmp/.X11-unix/X";
     char file[sizeof(base) + 20];
+    int filelen;
 
     if(*host)
     {
@@ -161,9 +162,13 @@ static int _xcb_open(char *host, char *protocol, const int display)
     }
 
     /* display specifies Unix socket */
-    snprintf(file, sizeof(file), "%s%d", base, display);
+    filelen = snprintf(file, sizeof(file), "%s%d", base, display);
+    if(filelen < 0)
+        return -1;
+    /* snprintf may truncate the file */
+    filelen = MIN(filelen, sizeof(file) - 1);
 #ifdef HAVE_ABSTRACT_SOCKETS
-    fd = _xcb_open_abstract(protocol, file);
+    fd = _xcb_open_abstract(protocol, file, filelen);
     if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED))
         return fd;
 
@@ -284,7 +289,7 @@ static int _xcb_open_unix(char *protocol, const char *file)
 }
 
 #ifdef HAVE_ABSTRACT_SOCKETS
-static int _xcb_open_abstract(char *protocol, const char *file)
+static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen)
 {
     int fd;
     struct sockaddr_un addr = {0};
@@ -295,9 +300,9 @@ static int _xcb_open_abstract(char *protocol, const char *file)
 
     strcpy(addr.sun_path + 1, file);
     addr.sun_family = AF_UNIX;
-    namelen = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(file);
+    namelen = offsetof(struct sockaddr_un, sun_path) + 1 + filelen;
 #ifdef HAVE_SOCKADDR_SUN_LEN
-    addr.sun_len = 1 + strlen(file);
+    addr.sun_len = 1 + filelen;
 #endif
     fd = socket(AF_UNIX, SOCK_STREAM, 0);
     if (fd == -1)
@@ -312,39 +317,7 @@ static int _xcb_open_abstract(char *protocol, const char *file)
 
 xcb_connection_t *xcb_connect(const char *displayname, int *screenp)
 {
-    int fd, display = 0;
-    char *host;
-    char *protocol;
-    xcb_connection_t *c;
-    xcb_auth_info_t auth;
-    
-    int parsed = _xcb_parse_display(displayname, &host, &protocol, &display, screenp);
-
-#ifdef HAVE_LAUNCHD
-    if(!displayname)
-        displayname = getenv("DISPLAY");
-    if(displayname && strlen(displayname)>11 && !strncmp(displayname, "/tmp/launch", 11))
-        fd = _xcb_open_unix(NULL, displayname);
-    else
-#endif
-    if(!parsed)
-        return (xcb_connection_t *) &error_connection;
-    else
-        fd = _xcb_open(host, protocol, display);
-    free(host);
-
-    if(fd == -1)
-        return (xcb_connection_t *) &error_connection;
-
-    if(_xcb_get_auth_info(fd, &auth, display))
-    {
-        c = xcb_connect_to_fd(fd, &auth);
-        free(auth.name);
-        free(auth.data);
-    }
-    else
-        c = xcb_connect_to_fd(fd, 0);
-    return c;
+    return xcb_connect_to_display_with_auth_info(displayname, NULL, screenp);
 }
 
 xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname, xcb_auth_info_t *auth, int *screenp)
@@ -352,6 +325,8 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname,
     int fd, display = 0;
     char *host;
     char *protocol;
+    xcb_auth_info_t ourauth;
+    xcb_connection_t *c;
 
     int parsed = _xcb_parse_display(displayname, &host, &protocol, &display, screenp);
     
@@ -371,5 +346,17 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname,
     if(fd == -1)
         return (xcb_connection_t *) &error_connection;
 
-    return xcb_connect_to_fd(fd, auth);
+    if(auth)
+        return xcb_connect_to_fd(fd, auth);
+
+    if(_xcb_get_auth_info(fd, &ourauth, display))
+    {
+        c = xcb_connect_to_fd(fd, &ourauth);
+        free(ourauth.name);
+        free(ourauth.data);
+    }
+    else
+        c = xcb_connect_to_fd(fd, 0);
+
+    return c;
 }