fix typo
[monky] / src / libmpdclient.c
index 9eb0c05..e0dfe2c 100644 (file)
@@ -1,4 +1,7 @@
-/* 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
  *
@@ -29,9 +32,7 @@
  * 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>
 
@@ -54,6 +52,7 @@
 #  include <netinet/in.h>
 #  include <arpa/inet.h>
 #  include <sys/socket.h>
+#  include <sys/un.h>
 #  include <netdb.h>
 #endif
 
@@ -121,6 +120,38 @@ static int do_connect_fail(mpd_Connection *connection,
 }
 #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)
@@ -131,9 +162,12 @@ static int mpd_connect(mpd_Connection *connection, const char *host, int port,
        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;
@@ -195,27 +229,41 @@ static int mpd_connect(mpd_Connection *connection, const char *host, int port,
 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;
@@ -293,8 +341,8 @@ static mpd_ReturnElement *mpd_newReturnElement(const char *name,
 {
        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;
 }
@@ -415,7 +463,7 @@ mpd_Connection *mpd_newConnection(const char *host, int port, float timeout)
        }
 
        *rt = '\0';
-       output = strdup(connection->buffer);
+       output = strndup(connection->buffer, text_buffer_size);
        strcpy(connection->buffer, rt + 1);
        connection->buflen = strlen(connection->buffer);
 
@@ -768,7 +816,7 @@ mpd_Status *mpd_getStatus(mpd_Connection *connection)
                                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) {
@@ -1018,37 +1066,37 @@ mpd_Song *mpd_songDup(mpd_Song *song)
        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;
@@ -1090,7 +1138,7 @@ mpd_Directory *mpd_directoryDup(mpd_Directory *directory)
        mpd_Directory *ret = mpd_newDirectory();
 
        if (directory->path) {
-               ret->path = strdup(directory->path);
+               ret->path = strndup(directory->path, text_buffer_size);
        }
 
        return ret;
@@ -1128,7 +1176,7 @@ mpd_PlaylistFile *mpd_playlistFileDup(mpd_PlaylistFile *playlist)
        mpd_PlaylistFile *ret = mpd_newPlaylistFile();
 
        if (playlist->path) {
-               ret->path = strdup(playlist->path);
+               ret->path = strndup(playlist->path, text_buffer_size);
        }
 
        return ret;
@@ -1190,19 +1238,19 @@ mpd_InfoEntity *mpd_getNextInfoEntity(mpd_Connection *connection)
                        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;
@@ -1234,19 +1282,19 @@ mpd_InfoEntity *mpd_getNextInfoEntity(mpd_Connection *connection)
                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);
@@ -1258,22 +1306,22 @@ mpd_InfoEntity *mpd_getNextInfoEntity(mpd_Connection *connection)
                                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) {
@@ -1298,7 +1346,7 @@ static char *mpd_getNextReturnElementNamed(mpd_Connection *connection,
                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);
        }
@@ -1652,22 +1700,22 @@ void mpd_sendSwapIdCommand(mpd_Connection *connection, int id1, int id2)
        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);
 }
@@ -1835,7 +1883,7 @@ mpd_OutputEntity *mpd_getNextOutput(mpd_Connection *connection)
                        }
                        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);
                }
@@ -1923,9 +1971,9 @@ void mpd_startSearch(mpd_Connection *connection, int exact)
        }
 
        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);
        }
 }
 
@@ -1937,7 +1985,7 @@ void mpd_startStatsSearch(mpd_Connection *connection)
                return;
        }
 
-       connection->request = strdup("count");
+       connection->request = strndup("count", text_buffer_size);
 }
 
 void mpd_startPlaylistSearch(mpd_Connection *connection, int exact)
@@ -1949,9 +1997,9 @@ 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);
        }
 }
 
@@ -2007,7 +2055,7 @@ void mpd_addConstraintSearch(mpd_Connection *connection, int type,
                return;
        }
 
-       string = strdup(connection->request);
+       string = strndup(connection->request, text_buffer_size);
        strtype = mpdTagItemKeys[type];
        arg = mpd_sanitizeArg(name);