/** * Get the fallback connection path (if XMMS_PATH is not accessible) * * @param buf A char buffer * @param len The length of buf (XMMS_PATH_MAX is a good choice) * @return A pointer to buf, or NULL if an error occured. */ const char * xmms_fallback_ipcpath_get (char *buf, int len) { snprintf (buf, len, "tcp://127.0.0.1:" XMMS_STRINGIFY (XMMS_DEFAULT_TCP_PORT)); return buf; }
xmms_ipc_transport_t * xmms_ipc_tcp_client_init (const xmms_url_t *url, int ipv6) { xmms_socket_t fd = -1; xmms_ipc_transport_t *ipct; struct addrinfo hints; struct addrinfo *addrinfo; struct addrinfo *addrinfos; int gai_errno; if (!xmms_sockets_initialize ()) { return NULL; } memset (&hints, 0, sizeof (hints)); hints.ai_flags = 0; hints.ai_family = url->host[0] ? (ipv6 ? PF_INET6 : PF_INET) : PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = 0; if ((gai_errno = xmms_getaddrinfo (url->host[0] ? url->host : NULL, url->port[0] ? url->port : XMMS_STRINGIFY (XMMS_DEFAULT_TCP_PORT), &hints, &addrinfos))) { return NULL; } for (addrinfo = addrinfos; addrinfo; addrinfo = addrinfo->ai_next) { int _reuseaddr = 1; const char* reuseaddr = (const char*)&_reuseaddr; fd = socket (addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol); if (!xmms_socket_valid (fd)) { return NULL; } setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, reuseaddr, sizeof (_reuseaddr)); if (connect (fd, addrinfo->ai_addr, addrinfo->ai_addrlen) == 0) { break; } close (fd); } xmms_freeaddrinfo (addrinfos); if (!addrinfo) { return NULL; } assert (fd != -1); if (!xmms_socket_set_nonblock (fd)) { close (fd); return NULL; } ipct = x_new0 (xmms_ipc_transport_t, 1); ipct->fd = fd; ipct->path = strdup (url->host); ipct->read_func = xmms_ipc_tcp_read; ipct->write_func = xmms_ipc_tcp_write; ipct->destroy_func = xmms_ipc_tcp_destroy; return ipct; }