-/* libmpdclient
+/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
+ * vim: ts=4 sw=4 noet ai cindent syntax=c
+ *
+ * libmpdclient
* (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
*
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id$
- *
- * */
+ */
#include "conky.h"
#include "libmpdclient.h"
#include <errno.h>
#include <ctype.h>
#include <sys/types.h>
-#include <stdio.h>
#include <sys/param.h>
-#include <string.h>
#include <unistd.h>
-#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <sys/socket.h>
+# include <sys/un.h>
# include <netdb.h>
#endif
}
#endif /* !WIN32 */
+static int uds_connect(mpd_Connection *connection, const char *host,
+ float timeout)
+{
+ struct sockaddr_un addr;
+
+ strncpy(addr.sun_path, host, sizeof(addr.sun_path)-1);
+ addr.sun_family = AF_UNIX;
+ addr.sun_path[sizeof(addr.sun_path)-1] = 0;
+ connection->sock = socket(AF_UNIX, SOCK_STREAM, 0);
+
+ if (connection->sock < 0) {
+ snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH,
+ "problems creating socket: %s", strerror(errno));
+ connection->error = MPD_ERROR_SYSTEM;
+ return -1;
+ }
+
+ mpd_setConnectionTimeout(connection, timeout);
+
+ /* connect stuff */
+ if (do_connect_fail(connection, (struct sockaddr *)&addr, SUN_LEN(&addr))) {
+ snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH,
+ "problems cconnecting socket: %s", strerror(errno));
+ closesocket(connection->sock);
+ connection->sock = -1;
+ connection->error = MPD_ERROR_SYSTEM;
+ return -1;
+ }
+
+ return 0;
+}
+
#ifdef MPD_HAVE_GAI
static int mpd_connect(mpd_Connection *connection, const char *host, int port,
float timeout)
struct addrinfo *res = NULL;
struct addrinfo *addrinfo = NULL;
+ if (*host == '/')
+ return uds_connect(connection, host, timeout);
+
/* Setup hints */
hints.ai_flags = AI_ADDRCONFIG;
- hints.ai_family = PF_UNSPEC;
+ hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_addrlen = 0;
static int mpd_connect(mpd_Connection *connection, const char *host, int port,
float timeout)
{
- struct hostent *he;
+ struct hostent he, *he_res = 0;
+ int he_errno;
+ char hostbuff[2048];
struct sockaddr *dest;
int destlen;
struct sockaddr_in sin;
- if (!(he = gethostbyname(host))) {
+ if (*host == '/')
+ return uds_connect(connection, host, timeout);
+
+#ifdef HAVE_GETHOSTBYNAME_R
+ if (gethostbyname_r(rhost, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info
+ snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH,
+ "%s ('%s')", hstrerror(h_errno), host);
+ connection->error = MPD_ERROR_UNKHOST;
+ return -1;
+ }
+#else /* HAVE_GETHOSTBYNAME_R */
+ if (!(he_res = gethostbyname(host))) {
snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH,
"host \"%s\" not found", host);
connection->error = MPD_ERROR_UNKHOST;
return -1;
}
+#endif /* HAVE_GETHOSTBYNAME_R */
memset(&sin, 0, sizeof(struct sockaddr_in));
- /* dest.sin_family = he->h_addrtype; */
+ /* dest.sin_family = he_res->h_addrtype; */
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
- switch (he->h_addrtype) {
+ switch (he_res->h_addrtype) {
case AF_INET:
- memcpy((char *) &sin.sin_addr.s_addr, (char *) he->h_addr,
- he->h_length);
+ memcpy((char *) &sin.sin_addr.s_addr, (char *) he_res->h_addr,
+ he_res->h_length);
dest = (struct sockaddr *) &sin;
destlen = sizeof(struct sockaddr_in);
break;