config.h.in | 4 ++ src/libmpd-database.c | 2 +- src/libmpd-database.h | 32 ++++++++++---------- src/libmpd-internal.h | 1 + src/libmpd-playlist.h | 36 ++++++++++++------------ src/libmpd-status.c | 61 +++++++++++++++++++++++++++------------ src/libmpd-status.h | 20 ++++++------ src/libmpd.c | 10 ++++++ src/libmpd.h | 33 ++++++++++++++------- src/libmpdclient.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++-- src/libmpdclient.h | 3 ++ 11 files changed, 198 insertions(+), 79 deletions(-) diff --git a/config.h.in b/config.h.in index 2483fa9..6c54f2a 100644 --- a/config.h.in +++ b/config.h.in @@ -33,6 +33,10 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT diff --git a/src/libmpd-database.c b/src/libmpd-database.c index c9eb824..3738b21 100644 --- a/src/libmpd-database.c +++ b/src/libmpd-database.c @@ -703,7 +703,7 @@ void mpd_database_search_start(MpdObj *mi, int exact) */ void mpd_database_search_add_constraint(MpdObj *mi, mpd_TagItems field, const char *value) { - if(mi == NULL || value == NULL || value[0] == '\0') + if(mi == NULL || value == NULL ) { debug_printf(DEBUG_ERROR,"Failed to parse arguments"); return; diff --git a/src/libmpd-database.h b/src/libmpd-database.h index 66f2e71..bc31907 100644 --- a/src/libmpd-database.h +++ b/src/libmpd-database.h @@ -30,7 +30,7 @@ * @param mi A #MpdObj * @param artist an artist name * - * Grab's a list of albums of a certain artist from mpd. + * Grabs a list of albums of a certain artist from mpd. * if artist is %NULL it grabs all albums * * @returns A #MpdData list. @@ -41,7 +41,7 @@ MpdData * mpd_database_get_albums (MpdObj *mi, char *artist); /** * @param mi a #MpdObj * - * returns a list of all availible artists. + * returns a list of all available artists. * * @returns a #MpdData list */ @@ -51,7 +51,7 @@ MpdData * mpd_database_get_artists (MpdObj *mi); /** * @param mi a #MpdObj * - * Get's the complete datababse, only returns songs + * Gets the complete datababse, only returns songs * * @returns a #MpdData list with songs */ @@ -63,7 +63,7 @@ MpdData * mpd_database_get_complete(MpdObj *mi); *@param mi A #MpdObj *@param path The path mpd should update. * - * Force mpd to update (parts of )the database. + * Force mpd to update (parts of) the database. * * @returns a #MpdError */ @@ -104,8 +104,8 @@ MpdData * mpd_database_get_directory_recursive(MpdObj *mi, const char *path); * @param mi A #MpdObj * @param path an Path to a file * - * Grabs the song info for a single file. Make sure you pass an url to a song - * and not a directory, that might result in strange behauviour. + * Grabs the song info for a single file. Make sure you pass a url to a song + * and not a directory, that might result in strange behaviour. * * @returns a #mpd_Song */ @@ -160,7 +160,7 @@ void mpd_database_search_start(MpdObj *mi, int exact); * @param mi a #MpdObj * @param field a #mpd_TagItems * - * Starts a field search, f.e. if you want a list of all albums, you do; + * Starts a field search, eg. if you want a list of all albums, you do; * * @code * mpd_database_search_field_start(mi, MPD_TAG_ITEM_ALBUM); @@ -183,7 +183,7 @@ void mpd_database_search_field_start(MpdObj *mi, mpd_TagItems field); * * Commits the search and gathers the result in a #MpdData list. * - * @returns a #MpdData list with the search result,or NULL when nothing is found + * @returns a #MpdData list with the search result, or NULL when nothing is found */ MpdData * mpd_database_search_commit(MpdObj *mi); @@ -230,7 +230,7 @@ MpdDBStats * mpd_database_search_stats_commit(MpdObj *mi); /** * @param data a #MpdDBStats * - * free's the #MpdDBStats structure. + * frees the #MpdDBStats structure. */ void mpd_database_search_free_stats(MpdDBStats *data); @@ -285,8 +285,8 @@ void mpd_database_playlist_list_add(MpdObj *mi, const char *path, const char *fi /** * @param mi a #MpdObj - * @param path a string contains the path of the playlist - * @param pos a int representing the position of a song + * @param path a string containing the path of the playlist + * @param pos an int representing the position of a song * * Deletes the song at position pos from a playlist. * Needs mpd 0.13.0 @@ -296,7 +296,7 @@ void mpd_database_playlist_list_delete(MpdObj *mi, const char *path, int pos); /** * @param mi a #MpdObj - * @param path a string contains the path of the playlist + * @param path a string containing the path of the playlist * * Clears the content of a stored playlist, also used to create an empty playlist * Needs mpd 0.13.0 @@ -315,11 +315,11 @@ void mpd_database_playlist_rename(MpdObj *mi, const char *old_name, const char * /** * @param mi a #MpdObj - * @param playlist a string contains the path of the playlist - * @param old_pos integer representing old position - * @param new_pos integer representing the position to move old_pos to. + * @param playlist a string containing the path of the playlist + * @param old_pos an integer representing old position + * @param new_pos an integer representing the position to move old_pos to. * - * Moves songs in a stored playlists + * Moves songs in a stored playlist * Needs mpd 0.13.0 */ int mpd_database_playlist_move(MpdObj *mi, const char *playlist, int old_pos, int new_pos); diff --git a/src/libmpd-internal.h b/src/libmpd-internal.h index 86849ab..8962011 100644 --- a/src/libmpd-internal.h +++ b/src/libmpd-internal.h @@ -124,6 +124,7 @@ typedef struct _MpdObj { int num_outputs; int *output_states; + int has_idle; }_MpdObj; diff --git a/src/libmpd-playlist.h b/src/libmpd-playlist.h index cfd5805..adb5629 100644 --- a/src/libmpd-playlist.h +++ b/src/libmpd-playlist.h @@ -75,7 +75,7 @@ mpd_Song * mpd_playlist_get_song_from_pos(MpdObj *mi, int songpos); * * returns the mpd_Song for the currently playing song * - * @returns a mpd_Song, this is an internally cached version, and should not be free'ed. It's also not guaranteed to stay valid (it will be inside the same function if no other mpd_* function gets called.) + * @returns a mpd_Song, this is an internally cached version, and should not be freed. It's also not guaranteed to stay valid (it will be inside the same function if no other mpd_* function gets called.) * if you need to keep it around, make a copy. */ mpd_Song * mpd_playlist_get_current_song (MpdObj *mi); @@ -95,7 +95,7 @@ int mpd_playlist_clear (MpdObj *mi); /** * @param mi a #MpdObj * - * Shuffle's the order of the playlist, this is different then playing random + * Shuffles the order of the playlist, this is different than playing random * * @returns */ @@ -128,7 +128,7 @@ int mpd_playlist_move_id (MpdObj *mi, int old_id, int new_id); * @param mi a #MpdObj * @param old_playlist_id The id of the old playlist you want to get the changes with. * - * Get's a list of the song that changed between the current and the old playlist + * Gets a list of songs that changed between the current and the old playlist * * @returns a #MpdData list */ @@ -138,8 +138,8 @@ MpdData * mpd_playlist_get_changes (MpdObj *mi,int old_playlist_id); * @param mi a #MpdObj * @param old_playlist_id The id of the old playlist you want to get the changes with. * - * Get's a list of the song id/pos that changed between the current and the old playlist - * Check if this command is availible. + * Gets a list of the song id/pos that changed between the current and the old playlist + * Check if this command is available. * * @returns a #MpdData list */ @@ -157,7 +157,7 @@ int mpd_playlist_get_playlist_length (MpdObj *mi); * @param mi a #MpdObj * @param path the path of the song to be added. * - * Add's a song to the playlist, use #mpd_playlist_queue_add to add multiple songs. + * Adds a song to the playlist, use #mpd_playlist_queue_add to add multiple songs. * * @returns a #MpdError */ @@ -167,7 +167,7 @@ int mpd_playlist_add (MpdObj *mi, char *path); * @param mi a #MpdObj * @param songid a song id. * - * Delete's a single song by it's id. + * Deletes a single song by it's id. * * @returns a #MpdError */ @@ -177,7 +177,7 @@ int mpd_playlist_delete_id(MpdObj *mi, int songid); * @param mi a #MpdObj * @param songpos a song pos. * - * Delete's a single song by it's position. + * Deletes a single song by it's position. * * @returns a #MpdError */ @@ -188,7 +188,7 @@ int mpd_playlist_delete_pos(MpdObj *mi, int songpos); * @param path a path to a song * * Add a single path and return the id - * Only use this to add a single list, if you need to add multiple songs, + * Only use this to add a single song, if you need to add multiple songs, * use the #mpd_playlist_queue_add for improved performance * * @returns a #MpdError or the songid of the added song @@ -203,8 +203,8 @@ int mpd_playlist_add_get_id(MpdObj *mi, char *path); * \ingroup Playlist * These functions allow you to queue commands, and send them * in one command list to mpd. This is very efficient. - * It's adviced to use these for large deletes and add's. - * These functions doesn't cause an extra overhead compared to the non_queue functions. + * It's advised to use these for large deletions and additions. + * These functions don't cause an extra overhead compared to the non_queue functions. * Because the non_queue functions just wrap the following. */ /*@{*/ @@ -213,7 +213,7 @@ int mpd_playlist_add_get_id(MpdObj *mi, char *path); * @param mi a #MpdObj * @param path The path to a song to add * - * This queue's an add command. The actuall add isn't done until #mpd_playlist_queue_commit is called + * This queues an add command. The actual add isn't done until #mpd_playlist_queue_commit is called * * @returns a #MpdError */ @@ -225,7 +225,7 @@ int mpd_playlist_queue_add (MpdObj *mi,char *path); * @param mi a #MpdObj * @param path The path to a playlist to load * - * This queue's an load command. The actuall load isn't done until #mpd_playlist_queue_commit is called + * This queues a load command. The actual load isn't done until #mpd_playlist_queue_commit is called * * @returns a #MpdError */ @@ -236,7 +236,7 @@ int mpd_playlist_queue_load (MpdObj *mi,char *path); * @param mi a #MpdObj * @param id The songid of the song you want to delete * - * This queue's an delete song from playlist command. The actually delete isn't done until #mpd_playlist_queue_commit is called + * This queues a delete song from playlist command. The actually delete isn't done until #mpd_playlist_queue_commit is called * @returns a #MpdError */ int mpd_playlist_queue_delete_id (MpdObj *mi,int id); @@ -246,7 +246,7 @@ int mpd_playlist_queue_delete_id (MpdObj *mi,int id); * @param mi a #MpdObj * @param songpos a song pos. * - * Queue's the deletion of a single song by it's position. + * Queues the deletion of a single song by it's position. * * @returns a #MpdError */ @@ -256,7 +256,7 @@ int mpd_playlist_queue_delete_pos (MpdObj *mi,int songpos); /** * @param mi a #MpdObj * - * Commits the queue'd commands in a command list. This is an efficient way of doing alot of add's/removes. + * Commits the queue'd commands in a command list. This is an efficient way of doing a lot of adds/removes. * * @returns a #MpdError */ @@ -311,7 +311,7 @@ void mpd_playlist_search_add_constraint(MpdObj *mi, mpd_TagItems field, const ch * @param mi a #MpdObj * @param songid the id of the song to add * - * Add the song from the playlist with id id. + * Add the song from the playlist with id songid. * * @returns a #MpdError */ @@ -322,7 +322,7 @@ int mpd_playlist_mpd_queue_add(MpdObj *mi, int songid); * @param mi a #MpdObj * @param songpos the pos of the song to remove * - * Removes the song from the queue at position pos + * Removes the song from the queue at position songpos * * @returns a #MpdError */ diff --git a/src/libmpd-status.c b/src/libmpd-status.c index abc3d33..2a2db26 100644 --- a/src/libmpd-status.c +++ b/src/libmpd-status.c @@ -63,6 +63,7 @@ int mpd_status_update(MpdObj *mi) } + if(mi->status != NULL) { mpd_freeStatus(mi->status); @@ -117,6 +118,7 @@ int mpd_status_update(MpdObj *mi) /* set MPD_CST_QUEUE to be changed */ what_changed |= MPD_CST_STORED_PLAYLIST; + /* save new id */ mi->CurrentState.storedplaylistid = mi->status->storedplaylist; } @@ -240,32 +242,53 @@ int mpd_status_update(MpdObj *mi) /* Detect changed outputs */ - if(mi->num_outputs >0 ) + if(!mi->has_idle) { - mpd_OutputEntity *output = NULL; - mpd_sendOutputsCommand(mi->connection); - while (( output = mpd_getNextOutput(mi->connection)) != NULL) - { - if(mi->output_states[output->id] != output->enabled) - { - mi->output_states[output->id] = output->enabled; - what_changed |= MPD_CST_OUTPUT; + if(mi->num_outputs >0 ) + { + mpd_OutputEntity *output = NULL; + mpd_sendOutputsCommand(mi->connection); + while (( output = mpd_getNextOutput(mi->connection)) != NULL) + { + if(mi->output_states[output->id] != output->enabled) + { + mi->output_states[output->id] = output->enabled; + what_changed |= MPD_CST_OUTPUT; + } + mpd_freeOutputElement(output); } - mpd_freeOutputElement(output); + mpd_finishCommand(mi->connection); } - mpd_finishCommand(mi->connection); - } - else - { - /* if no outputs, lets fetch them */ - mpd_server_update_outputs(mi); - if(mi->num_outputs == 0) + else { - assert("No outputs defined? that cannot be\n"); + /* if no outputs, lets fetch them */ + mpd_server_update_outputs(mi); + if(mi->num_outputs == 0) + { + assert("No outputs defined? that cannot be\n"); + } + what_changed |= MPD_CST_OUTPUT; } - what_changed |= MPD_CST_OUTPUT; + }else { + char *name; + mpd_sendGetEventsCommand(mi->connection); + while((name = mpd_getNextEvent(mi->connection))){ + printf("Event: %s\n", name); + if(strcmp(name, "output") == 0){ + what_changed |= MPD_CST_OUTPUT; + printf("playlist changed\n"); + }else if (strcmp(name, "stored_playlist")==0) { + what_changed |= MPD_CST_STORED_PLAYLIST; + printf("stored playlist changed\n"); + } + + } +// mpd_executeCommand(mi->connection, "noidle\n"); + mpd_finishCommand(mi->connection); + } + /* Run the callback */ if((mi->the_status_changed_callback != NULL) && what_changed) { diff --git a/src/libmpd-status.h b/src/libmpd-status.h index f8958f4..3784545 100644 --- a/src/libmpd-status.h +++ b/src/libmpd-status.h @@ -28,7 +28,7 @@ /** * @param mi a #MpdObj * - * Checks if there is status information is availibe, if not availible it tries to fetch it. + * Checks if there is status information availibe. if not availible, it tries to fetch it. * This function is called from within libmpd, and shouldn't be called from the program. * * @returns 0 when successful @@ -52,7 +52,7 @@ int mpd_status_queue_update (MpdObj *mi); * @param mi a #MpdObj * * Updates the status field from mpd. - * Call this function ever 0.x seconds from the program's main-loop to recieve signals when mpd's status has changed. + * Call this function every 0.x seconds from the program's main-loop to recieve signals when mpd's status has changed. * * @returns 0 when succesfull */ @@ -85,9 +85,9 @@ int mpd_status_set_volume (MpdObj *mi,int volume); /** * @param mi a #MpdObj * - * Set the audio output volume. + * Get the audio output volume. * - * @returns the volume between 0 and 100 or < 0 when failed + * @returns the audio output volume between 0 and 100 or < 0 when failed */ int mpd_status_get_volume (MpdObj *mi); @@ -96,7 +96,7 @@ int mpd_status_get_volume (MpdObj *mi); /** * @param mi a #MpdObj * - * get the bitrate of the current playing song in kbs. This is a constantly updating value. (for vbr songs) + * get the bitrate of the currently playing song in kbs. This is a constantly updating value. (for vbr songs) * * @returns bitrate in kbs */ @@ -107,7 +107,7 @@ int mpd_status_get_bitrate (MpdObj *mi); /** * @param mi a #MpdObj * - * get the samplerate of the current playing song in bps. + * get the samplerate of the currently playing song in bps. * * @returns samplerate in bps */ @@ -118,7 +118,7 @@ unsigned int mpd_status_get_samplerate (MpdObj *mi); /** * @param mi a #MpdObj * - * get the number of channels in the current playing song. This is usually only 1(mono) or 2(stereo), but this might change in the future. + * get the number of channels in the currently playing song. This is usually only 1(mono) or 2(stereo), but this might change in the future. * * @returns number of channels */ @@ -129,7 +129,7 @@ int mpd_status_get_channels (MpdObj *mi); /** * @param mi a #MpdObj * - * get the number of bits per sample of the current playing song. + * get the number of bits per sample of the currently playing song. * * @returns bits per sample */ @@ -172,7 +172,7 @@ int mpd_status_get_crossfade (MpdObj *mi); * @param mi a #MpdObj * @param crossfade_time the time to crossfade in seconds * - * Sets the crossfade time. 0 is disabled + * Sets the crossfade time. 0 to disable crossfade. * * @returns */ @@ -192,7 +192,7 @@ int mpd_status_db_is_updating (MpdObj *mi); /** * @param mi a #MpdObj * - * @returns the error message that mpd last reported, on NULL. Needs to be free'ed. + * @returns the error message that mpd last reported, on NULL. Needs to be freed. */ char * mpd_status_get_mpd_error(MpdObj *mi); diff --git a/src/libmpd.c b/src/libmpd.c index 9dd3204..2316f2b 100644 --- a/src/libmpd.c +++ b/src/libmpd.c @@ -150,6 +150,7 @@ static MpdObj * mpd_create() /* outputs */ mi->num_outputs = 0; mi->output_states = NULL; + mi->has_idle = 0; /* commands */ mi->commands = NULL; return mi; @@ -493,6 +494,9 @@ int mpd_server_get_allowed_commands(MpdObj *mi) mi->commands[num_commands-1].enabled = TRUE; mi->commands[num_commands].command_name = NULL; mi->commands[num_commands].enabled = FALSE; + if(strcmp(mi->commands[num_commands-1].command_name, "idle") == 0) { + mi->has_idle = TRUE; + } } mpd_finishCommand(mi->connection); mpd_sendNotCommandsCommand(mi->connection); @@ -571,6 +575,7 @@ int mpd_disconnect(MpdObj *mi) if(mi->output_states) g_free(mi->output_states); mi->output_states = NULL; + mi->has_idle = 0; memcpy(&(mi->OldState), &(mi->CurrentState) , sizeof(MpdServerState)); @@ -1206,3 +1211,8 @@ int mpd_server_update_outputs(MpdObj *mi) mpd_finishCommand(mi->connection); return mpd_unlock_conn(mi); } + +int mpd_server_has_idle(MpdObj *mi) +{ + return mi->has_idle; +} diff --git a/src/libmpd.h b/src/libmpd.h index 27ab2c0..e29e7b8 100644 --- a/src/libmpd.h +++ b/src/libmpd.h @@ -73,7 +73,7 @@ typedef enum { /** Mpd doesn't support this feature */ MPD_SERVER_NOT_SUPPORTED = -51, - /** The playlist allready extists */ + /** The playlist already exists */ MPD_DATABASE_PLAYLIST_EXIST = -60, /** Playlist is empty */ MPD_PLAYLIST_EMPTY = -70, @@ -82,7 +82,7 @@ typedef enum { /** Player isn't Playing */ MPD_PLAYER_NOT_PLAYING = -80, - /** Tag ITem not found */ + /** Tag Item not found */ MPD_TAG_NOT_FOUND = -90, /** Fatal error, something I am not sure what todo with */ @@ -170,7 +170,7 @@ typedef struct _MpdData { /** * mpd_new_default * - * Create an new #MpdObj with default settings. + * Create a new #MpdObj with default settings. * Hostname will be set to "localhost". * Port will be 6600. * @@ -259,7 +259,7 @@ int mpd_connect_real(MpdObj *mi,mpd_Connection *connection); * @param mi a #MpdObj * * Connect to the mpd daemon. - * Warning: mpd_connect connects anonymous, to authentificate use #mpd_send_password + * Warning: mpd_connect connects anonymous, to authenticate use #mpd_send_password * * @returns returns a #MpdError, MPD_OK when successful */ @@ -389,7 +389,7 @@ typedef enum { * @param what a #ChangedStatusType that determines what changed triggered the signal. This is a bitmask. * @param userdata user data set when the signal handler was connected. * - * Signal that get's called when the state of mpd changed. Look #ChangedStatusType to see the possible events. + * Signal that get's called when the state of mpd has changed. Look #ChangedStatusType to see the possible events. */ typedef void (*StatusChangedCallback) (MpdObj * mi, ChangedStatusType what, void *userdata); @@ -411,7 +411,7 @@ typedef int (*ErrorCallback) (MpdObj * mi, int id, char *msg, void *userdata); /** * @param mi a #MpdObj - * @param connect 1 if you are now connect, 0 if you are disconnect. + * @param connect 1 if you are now connected, 0 if you are disconnected. * @param userdata user data set when the signal handler was connected. * Signal is triggered when the connection state changes. */ @@ -462,7 +462,7 @@ void mpd_signal_connect_connection_changed(MpdObj * mi, /** * @param data a #MpdData * - * Check's if the passed #MpdData is the last in a list + * Checks if the passed #MpdData is the last in a list * @returns TRUE when data is the last in the list. */ int mpd_data_is_last(MpdData const *data); @@ -483,7 +483,7 @@ void mpd_data_free(MpdData * data); * Returns the next #MpdData in the list. * If it's the last item in the list, it will free the list. * - * You can itterate through a list like this and have it free'ed afterwards. + * You can iterate through a list like this and have it freed afterwards. * @code * for(data = mpd_database_get_albums(mi);data != NULL; data = mpd_data_get_next(data)) * { @@ -555,7 +555,7 @@ int mpd_server_set_output_device(MpdObj * mi, int device_id, int state); /** * @param mi a #MpdObj * - * Get's a unix timestamp of the last time the database was updated. + * Gets a unix timestamp of the last time the database was updated. * * @returns unix Timestamp */ @@ -597,14 +597,14 @@ int mpd_server_check_command_allowed(MpdObj * mi, const char *command); /** * @param mi a #MpdObj * - * @returns an array with urlhandlers (NULL terminated). Result must be free-ed. + * @returns an array with urlhandlers (NULL terminated). Result must be freed. */ char ** mpd_server_get_url_handlers(MpdObj *mi); /** * @param mi a #MpdObj * - * @returns an array with supported tag types. (NULL Terminated). Result must be free-ed. + * @returns an array with supported tag types. (NULL Terminated). Result must be freed. */ char ** mpd_server_get_tag_types(MpdObj *mi); @@ -625,6 +625,17 @@ char ** mpd_server_get_tag_types(MpdObj *mi); int mpd_misc_get_tag_by_name(char *name); /*@}*/ + +/** + * @param mi a #MpdObj + * + * Reports if the connected mpd supports the idle command. + * + * @returns a boolean, TRUE if it has idle support + */ +int mpd_server_has_idle(MpdObj *mi); + + #endif #ifdef __cplusplus diff --git a/src/libmpdclient.c b/src/libmpdclient.c index c7b1d15..5db2851 100644 --- a/src/libmpdclient.c +++ b/src/libmpdclient.c @@ -66,6 +66,10 @@ # endif #endif +#ifndef WIN32 +#include +#endif + #ifndef MSG_DONTWAIT # define MSG_DONTWAIT 0 #endif @@ -348,6 +352,53 @@ static int mpd_parseWelcome(mpd_Connection * connection, const char * host, int return 0; } +#ifndef WIN32 +static int mpd_connect_un(mpd_Connection * connection, + const char * host, float timeout) +{ + int error, flags; + size_t path_length; + struct sockaddr_un sun; + + path_length = strlen(host); + if (path_length >= sizeof(sun.sun_path)) { + strcpy(connection->errorStr, "unix socket path is too long"); + connection->error = MPD_ERROR_UNKHOST; + return -1; + } + + sun.sun_family = AF_UNIX; + memcpy(sun.sun_path, host, path_length + 1); + + connection->sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (connection->sock < 0) { + strcpy(connection->errorStr, "problems creating socket"); + connection->error = MPD_ERROR_SYSTEM; + return -1; + } + + mpd_setConnectionTimeout(connection, timeout); + + flags = fcntl(connection->sock, F_GETFL, 0); + fcntl(connection->sock, F_SETFL, flags | O_NONBLOCK); + + error = connect(connection->sock, (struct sockaddr*)&sun, sizeof(sun)); + if (error < 0) { + /* try the next address family */ + close(connection->sock); + connection->sock = 0; + + snprintf(connection->errorStr,MPD_BUFFER_MAX_LENGTH, + "problems connecting to \"%s\": %s", + host, strerror(errno)); + connection->error = MPD_ERROR_CONNPORT; + return -1; + } + + return 0; +} +#endif /* WIN32 */ + mpd_Connection * mpd_newConnection(const char * host, int port, float timeout) { int err; char * rt; @@ -371,7 +422,13 @@ mpd_Connection * mpd_newConnection(const char * host, int port, float timeout) { if (winsock_dll_error(connection)) return connection; - if (mpd_connect(connection, host, port, timeout) < 0) +#ifndef WIN32 + if (host[0] == '/') + err = mpd_connect_un(connection, host, timeout); + else +#endif + err = mpd_connect(connection, host, port, timeout); + if (err < 0) return connection; while(!(rt = strstr(connection->buffer,"\n"))) { @@ -458,9 +515,9 @@ static void mpd_executeCommand(mpd_Connection * connection, char * command) { FD_SET(connection->sock,&fds); tv.tv_sec = connection->timeout.tv_sec; tv.tv_usec = connection->timeout.tv_usec; - - while((ret = select(connection->sock+1,NULL,&fds,NULL,&tv)==1) || + while((ret = select(connection->sock+1,NULL,&fds,NULL,&tv)==1) || (ret==-1 && SELECT_ERRNO_IGNORE)) { + fflush(NULL); ret = send(connection->sock,commandPtr,commandLen,MSG_DONTWAIT); if(ret<=0) { @@ -477,7 +534,6 @@ static void mpd_executeCommand(mpd_Connection * connection, char * command) { if(commandLen<=0) break; } - if(commandLen>0) { perror(""); snprintf(connection->errorStr,MPD_ERRORSTR_MAX_LENGTH, @@ -683,6 +739,7 @@ mpd_Status * mpd_getStatus(mpd_Connection * connection) { status->repeat = 0; status->random = 0; status->playlist = -1; + status->storedplaylist = -1; status->playlistLength = -1; status->state = -1; status->song = 0; @@ -1969,3 +2026,13 @@ void mpd_sendClearErrorCommand(mpd_Connection * connection) { mpd_executeCommand(connection,"clearerror\n"); } + +void mpd_sendGetEventsCommand(mpd_Connection *connection) { + mpd_executeCommand(connection, "idle\nnoidle\n"); +// mpd_executeCommand(connection, "noidle\n"); +} + +char * mpd_getNextEvent(mpd_Connection *connection) +{ + return mpd_getNextReturnElementNamed(connection, "changed"); +} diff --git a/src/libmpdclient.h b/src/libmpdclient.h index 9ba1dc5..8b1452b 100644 --- a/src/libmpdclient.h +++ b/src/libmpdclient.h @@ -667,6 +667,9 @@ void mpd_sendPlaylistDeleteCommand(mpd_Connection *connection, char *playlist, int pos); void mpd_sendClearErrorCommand(mpd_Connection * connection); + +void mpd_sendGetEventsCommand(mpd_Connection *connection); +char * mpd_getNextEvent(mpd_Connection *connection); #ifdef __cplusplus } #endif