-/* 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 connecting 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;
break;
}
+ if (connection->sock > -1) {
+ closesocket(connection->sock);
+ }
if ((connection->sock = socket(dest->sa_family, SOCK_STREAM, 0)) < 0) {
strcpy(connection->errorStr, "problems creating socket");
connection->error = MPD_ERROR_SYSTEM;
{
mpd_ReturnElement *ret = malloc(sizeof(mpd_ReturnElement));
- ret->name = strdup(name);
- ret->value = strdup(value);
+ ret->name = strndup(name, text_buffer_size);
+ ret->value = strndup(value, text_buffer_size);
return ret;
}
connection->commandList = 0;
connection->listOks = 0;
connection->doneListOk = 0;
+ connection->sock = -1;
connection->returnElement = NULL;
connection->request = NULL;
}
*rt = '\0';
- output = strdup(connection->buffer);
+ output = strndup(connection->buffer, text_buffer_size);
strcpy(connection->buffer, rt + 1);
connection->buflen = strlen(connection->buffer);
status->totalTime = atoi(tok + 1);
}
} else if (strcmp(re->name, "error") == 0) {
- status->error = strdup(re->value);
+ status->error = strndup(re->value, text_buffer_size);
} else if (strcmp(re->name, "xfade") == 0) {
status->crossfade = atoi(re->value);
} else if (strcmp(re->name, "updating_db") == 0) {
mpd_Song *ret = mpd_newSong();
if (song->file) {
- ret->file = strdup(song->file);
+ ret->file = strndup(song->file, text_buffer_size);
}
if (song->artist) {
- ret->artist = strdup(song->artist);
+ ret->artist = strndup(song->artist, text_buffer_size);
}
if (song->album) {
- ret->album = strdup(song->album);
+ ret->album = strndup(song->album, text_buffer_size);
}
if (song->title) {
- ret->title = strdup(song->title);
+ ret->title = strndup(song->title, text_buffer_size);
}
if (song->track) {
- ret->track = strdup(song->track);
+ ret->track = strndup(song->track, text_buffer_size);
}
if (song->name) {
- ret->name = strdup(song->name);
+ ret->name = strndup(song->name, text_buffer_size);
}
if (song->date) {
- ret->date = strdup(song->date);
+ ret->date = strndup(song->date, text_buffer_size);
}
if (song->genre) {
- ret->genre = strdup(song->genre);
+ ret->genre = strndup(song->genre, text_buffer_size);
}
if (song->composer) {
- ret->composer = strdup(song->composer);
+ ret->composer = strndup(song->composer, text_buffer_size);
}
if (song->disc) {
- ret->disc = strdup(song->disc);
+ ret->disc = strndup(song->disc, text_buffer_size);
}
if (song->comment) {
- ret->comment = strdup(song->comment);
+ ret->comment = strndup(song->comment, text_buffer_size);
}
ret->time = song->time;
ret->pos = song->pos;
mpd_Directory *ret = mpd_newDirectory();
if (directory->path) {
- ret->path = strdup(directory->path);
+ ret->path = strndup(directory->path, text_buffer_size);
}
return ret;
mpd_PlaylistFile *ret = mpd_newPlaylistFile();
if (playlist->path) {
- ret->path = strdup(playlist->path);
+ ret->path = strndup(playlist->path, text_buffer_size);
}
return ret;
entity = mpd_newInfoEntity();
entity->type = MPD_INFO_ENTITY_TYPE_SONG;
entity->info.song = mpd_newSong();
- entity->info.song->file = strdup(connection->returnElement->value);
+ entity->info.song->file = strndup(connection->returnElement->value, text_buffer_size);
} else if (strcmp(connection->returnElement->name, "directory") == 0) {
entity = mpd_newInfoEntity();
entity->type = MPD_INFO_ENTITY_TYPE_DIRECTORY;
entity->info.directory = mpd_newDirectory();
entity->info.directory->path =
- strdup(connection->returnElement->value);
+ strndup(connection->returnElement->value, text_buffer_size);
} else if (strcmp(connection->returnElement->name, "playlist") == 0) {
entity = mpd_newInfoEntity();
entity->type = MPD_INFO_ENTITY_TYPE_PLAYLISTFILE;
entity->info.playlistFile = mpd_newPlaylistFile();
entity->info.playlistFile->path =
- strdup(connection->returnElement->value);
+ strndup(connection->returnElement->value, text_buffer_size);
} else if (strcmp(connection->returnElement->name, "cpos") == 0) {
entity = mpd_newInfoEntity();
entity->type = MPD_INFO_ENTITY_TYPE_SONG;
if (entity->type == MPD_INFO_ENTITY_TYPE_SONG && strlen(re->value)) {
if (!entity->info.song->artist
&& strcmp(re->name, "Artist") == 0) {
- entity->info.song->artist = strdup(re->value);
+ entity->info.song->artist = strndup(re->value, text_buffer_size);
} else if (!entity->info.song->album
&& strcmp(re->name, "Album") == 0) {
- entity->info.song->album = strdup(re->value);
+ entity->info.song->album = strndup(re->value, text_buffer_size);
} else if (!entity->info.song->title
&& strcmp(re->name, "Title") == 0) {
- entity->info.song->title = strdup(re->value);
+ entity->info.song->title = strndup(re->value, text_buffer_size);
} else if (!entity->info.song->track
&& strcmp(re->name, "Track") == 0) {
- entity->info.song->track = strdup(re->value);
+ entity->info.song->track = strndup(re->value, text_buffer_size);
} else if (!entity->info.song->name
&& strcmp(re->name, "Name") == 0) {
- entity->info.song->name = strdup(re->value);
+ entity->info.song->name = strndup(re->value, text_buffer_size);
} else if (entity->info.song->time == MPD_SONG_NO_TIME
&& strcmp(re->name, "Time") == 0) {
entity->info.song->time = atoi(re->value);
entity->info.song->id = atoi(re->value);
} else if (!entity->info.song->date
&& strcmp(re->name, "Date") == 0) {
- entity->info.song->date = strdup(re->value);
+ entity->info.song->date = strndup(re->value, text_buffer_size);
} else if (!entity->info.song->genre
&& strcmp(re->name, "Genre") == 0) {
- entity->info.song->genre = strdup(re->value);
+ entity->info.song->genre = strndup(re->value, text_buffer_size);
} else if (!entity->info.song->composer
&& strcmp(re->name, "Composer") == 0) {
- entity->info.song->composer = strdup(re->value);
+ entity->info.song->composer = strndup(re->value, text_buffer_size);
} else if (!entity->info.song->performer
&& strcmp(re->name, "Performer") == 0) {
- entity->info.song->performer = strdup(re->value);
+ entity->info.song->performer = strndup(re->value, text_buffer_size);
} else if (!entity->info.song->disc
&& strcmp(re->name, "Disc") == 0) {
- entity->info.song->disc = strdup(re->value);
+ entity->info.song->disc = strndup(re->value, text_buffer_size);
} else if (!entity->info.song->comment
&& strcmp(re->name, "Comment") == 0) {
- entity->info.song->comment = strdup(re->value);
+ entity->info.song->comment = strndup(re->value, text_buffer_size);
}
} else if (entity->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) {
} else if (entity->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE) {
mpd_ReturnElement *re = connection->returnElement;
if (strcmp(re->name, name) == 0) {
- return strdup(re->value);
+ return strndup(re->value, text_buffer_size);
}
mpd_getNextReturnElement(connection);
}
free(string);
}
-void mpd_sendSeekCommand(mpd_Connection *connection, int song, int time)
+void mpd_sendSeekCommand(mpd_Connection *connection, int song, int seek_time)
{
int len = strlen("seek") + 2 + INTLEN + 3 + INTLEN + 3;
char *string = malloc(len);
- snprintf(string, len, "seek \"%i\" \"%i\"\n", song, time);
+ snprintf(string, len, "seek \"%i\" \"%i\"\n", song, seek_time);
mpd_sendInfoCommand(connection, string);
free(string);
}
-void mpd_sendSeekIdCommand(mpd_Connection *connection, int id, int time)
+void mpd_sendSeekIdCommand(mpd_Connection *connection, int id, int seek_time)
{
int len = strlen("seekid") + 2 + INTLEN + 3 + INTLEN + 3;
char *string = malloc(len);
- snprintf(string, len, "seekid \"%i\" \"%i\"\n", id, time);
+ snprintf(string, len, "seekid \"%i\" \"%i\"\n", id, seek_time);
mpd_sendInfoCommand(connection, string);
free(string);
}
}
output->id = atoi(re->value);
} else if (strcmp(re->name, "outputname") == 0) {
- output->name = strdup(re->value);
+ output->name = strndup(re->value, text_buffer_size);
} else if (strcmp(re->name, "outputenabled") == 0) {
output->enabled = atoi(re->value);
}
}
if (exact) {
- connection->request = strdup("find");
+ connection->request = strndup("find", text_buffer_size);
} else {
- connection->request = strdup("search");
+ connection->request = strndup("search", text_buffer_size);
}
}
return;
}
- connection->request = strdup("count");
+ connection->request = strndup("count", text_buffer_size);
}
void mpd_startPlaylistSearch(mpd_Connection *connection, int exact)
}
if (exact) {
- connection->request = strdup("playlistfind");
+ connection->request = strndup("playlistfind", text_buffer_size);
} else {
- connection->request = strdup("playlistsearch");
+ connection->request = strndup("playlistsearch", text_buffer_size);
}
}
return;
}
- string = strdup(connection->request);
+ string = strndup(connection->request, text_buffer_size);
strtype = mpdTagItemKeys[type];
arg = mpd_sanitizeArg(name);