X-Git-Url: http://git.demorecorder.com/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fxcb_util.c;h=5a82ac129c6b2434306e6e0b790d5dcab50339e8;hb=de3cdad87a341c238c544425f4dd574b19c58ae3;hp=3516186fa35b842f1ca18c2fe38736e86482ab00;hpb=5e86cb05666c448de2f61c23ae94e94ef4b38d64;p=free-sw%2Fxcb%2Flibxcb diff --git a/src/xcb_util.c b/src/xcb_util.c index 3516186..5a82ac1 100644 --- a/src/xcb_util.c +++ b/src/xcb_util.c @@ -64,6 +64,7 @@ static int _xcb_parse_display(const char *name, char **host, char **protocol, { int len, display, screen; char *slash, *colon, *dot, *end; + if(!name || !*name) name = getenv("DISPLAY"); if(!name) @@ -92,35 +93,43 @@ static int _xcb_parse_display(const char *name, char **host, char **protocol, colon = strrchr(name, ':'); if(!colon) - return 0; + goto error_out; len = colon - name; ++colon; display = strtoul(colon, &dot, 10); if(dot == colon) - return 0; + goto error_out; if(*dot == '\0') screen = 0; else { if(*dot != '.') - return 0; + goto error_out; ++dot; screen = strtoul(dot, &end, 10); if(end == dot || *end != '\0') - return 0; + goto error_out; } /* At this point, the display string is fully parsed and valid, but * the caller's memory is untouched. */ *host = malloc(len + 1); if(!*host) - return 0; + goto error_out; memcpy(*host, name, len); (*host)[len] = '\0'; *displayp = display; if(screenp) *screenp = screen; return 1; + +error_out: + if (protocol) { + free(*protocol); + *protocol = NULL; + } + + return 0; } int xcb_parse_display(const char *name, char **host, int *displayp, @@ -129,7 +138,7 @@ int xcb_parse_display(const char *name, char **host, int *displayp, return _xcb_parse_display(name, host, NULL, displayp, screenp); } -static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port); +static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short port); static int _xcb_open_unix(char *protocol, const char *file); #ifdef DNETCONN static int _xcb_open_decnet(const char *host, char *protocol, const unsigned short port); @@ -138,7 +147,7 @@ static int _xcb_open_decnet(const char *host, char *protocol, const unsigned sho 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) +static int _xcb_open(const char *host, char *protocol, const int display) { int fd; static const char unix_base[] = "/tmp/.X11-unix/X"; @@ -147,14 +156,16 @@ static int _xcb_open(char *host, char *protocol, const int display) char *file = NULL; int actual_filelen; - if(*host) - { #ifdef HAVE_LAUNCHD if(strncmp(host, "/tmp/launch", 11) == 0) { - base = host; - } else { + base = host; + host = ""; + protocol = NULL; + } #endif + if(*host || protocol) + { #ifdef DNETCONN /* DECnet displays have two colons, so _xcb_parse_display will have left one at the end. However, an IPv6 address can end with *two* @@ -175,9 +186,6 @@ static int _xcb_open(char *host, char *protocol, const int display) unsigned short port = X_TCP_PORT + display; return _xcb_open_tcp(host, protocol, port); } -#ifdef HAVE_LAUNCHD - } -#endif } filelen = strlen(base) + 1 + sizeof(display) * 3 + 1; @@ -187,7 +195,7 @@ static int _xcb_open(char *host, char *protocol, const int display) /* display specifies Unix socket */ #ifdef HAVE_LAUNCHD - if(base == host) + if(strncmp(base, "/tmp/launch", 11) == 0) actual_filelen = snprintf(file, filelen, "%s:%d", base, display); else #endif @@ -270,7 +278,7 @@ static int _xcb_open_decnet(const char *host, const char *protocol, const unsign } #endif -static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port) +static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short port) { int fd = -1; struct addrinfo hints; @@ -278,8 +286,15 @@ static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port) struct addrinfo *results, *addr; char *bracket; - if (protocol && strcmp("tcp",protocol)) + if (protocol && strcmp("tcp",protocol) && strcmp("inet",protocol) +#ifdef AF_INET6 + && strcmp("inet6",protocol) +#endif + ) return -1; + + if (*host == '\0') + host = "localhost"; memset(&hints, 0, sizeof(hints)); #ifdef AI_ADDRCONFIG @@ -383,24 +398,28 @@ xcb_connection_t *xcb_connect(const char *displayname, int *screenp) xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname, xcb_auth_info_t *auth, int *screenp) { int fd, display = 0; - char *host; - char *protocol; + char *host = NULL; + char *protocol = NULL; xcb_auth_info_t ourauth; xcb_connection_t *c; int parsed = _xcb_parse_display(displayname, &host, &protocol, &display, screenp); - if(!parsed) - return (xcb_connection_t *) &error_connection; - else + if(!parsed) { + c = (xcb_connection_t *) &error_connection; + goto out; + } else fd = _xcb_open(host, protocol, display); - free(host); - if(fd == -1) - return (xcb_connection_t *) &error_connection; + if(fd == -1) { + c = (xcb_connection_t *) &error_connection; + goto out; + } - if(auth) - return xcb_connect_to_fd(fd, auth); + if(auth) { + c = xcb_connect_to_fd(fd, auth); + goto out; + } if(_xcb_get_auth_info(fd, &ourauth, display)) { @@ -411,5 +430,8 @@ xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname, else c = xcb_connect_to_fd(fd, 0); +out: + free(host); + free(protocol); return c; }