int mpd_database_update_dir(MpdObj *mi, char *path)
{
	if(path == NULL || !strlen(path))
	{
		debug_printf(DEBUG_ERROR, "path != NULL  and strlen(path) > 0 failed");
		return MPD_ARGS_ERROR;
	}
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_WARNING,"not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_ERROR,"lock failed\n");
		return MPD_LOCK_FAILED;
	}

	mpd_sendUpdateCommand(mi->connection,path);
	mpd_finishCommand(mi->connection);
	/* I have no idea why do this ?? it even makes gmpc very very unhappy.
	 * Because it doesnt trigger an signal anymore when updating starts
	 * mi->CurrentState.updatingDb = mpd_getUpdateId(mi->connection);
	*/

	/* unlock */
	mpd_unlock_conn(mi);
	/* What I think you should do is to force a direct status updated
	 */
	mpd_status_update(mi);
	return MPD_OK;
}
void mpd_database_search_field_start(MpdObj *mi, mpd_TagItems field)
{
	/*
	 * Check argument
	 */
	if(mi == NULL || field >= MPD_TAG_NUM_OF_ITEM_TYPES || field < 0) 
	{
		debug_printf(DEBUG_ERROR, "Argument error");
		return ;
	}
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_ERROR, "Not Connected\n");
		return ;
	}
	if(!mpd_server_check_version(mi, 0,12,0))
	{
		debug_printf(DEBUG_ERROR, "Advanced field list requires mpd 0.12.0 or higher");
		return ;
	}
	/* lock, so we can work on mi->connection */
	if(mpd_lock_conn(mi) != MPD_OK)
	{
		debug_printf(DEBUG_ERROR, "Failed to lock connection");
		return ;
	}
	mpd_startFieldSearch(mi->connection, field);
	/* Set search type */
	mi->search_type = MPD_SEARCH_TYPE_LIST;
	mi->search_field = field;
	/* unlock, let the error handler handle any possible error.
	 */
	mpd_unlock_conn(mi);
	return;
}
int mpd_database_delete_playlist(MpdObj *mi,char *path)
{
	if(path == NULL)
	{
		debug_printf(DEBUG_WARNING, "path == NULL");
		return MPD_ARGS_ERROR;
	}
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_WARNING,"not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_ERROR,"lock failed\n");
		return MPD_LOCK_FAILED;
	}

	mpd_sendRmCommand(mi->connection,path);
	mpd_finishCommand(mi->connection);

	/* unlock */
	mpd_unlock_conn(mi);
	return MPD_OK;
}
Esempio n. 4
0
MpdData *mpd_database_get_playlist_content(MpdObj *mi,char *playlist)
{
	MpdData *data = NULL;
	mpd_InfoEntity *ent = NULL;
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_WARNING,"not connected\n");
		return NULL;
	}
	if(!mpd_server_check_version(mi, 0,12,0))
	{
		debug_printf(DEBUG_WARNING, "only works with mpd higher then 0.12.0");
		return NULL;
	}
	if(mpd_server_check_command_allowed(mi, "listplaylistinfo") != MPD_SERVER_COMMAND_ALLOWED)
	{
		debug_printf(DEBUG_WARNING, "Listing playlist content not supported or allowed");
		return NULL;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_WARNING,"lock failed\n");
		return NULL;
	}
	mpd_sendListPlaylistInfoCommand(mi->connection, playlist);
	while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
	{
		data = mpd_new_data_struct_append( data );
		if(ent->type == MPD_INFO_ENTITY_TYPE_DIRECTORY)
		{
			data->type = MPD_DATA_TYPE_DIRECTORY;
			data->directory = ent->info.directory->path;
			ent->info.directory->path = NULL;
		}
		else if (ent->type == MPD_INFO_ENTITY_TYPE_SONG)
		{
			data->type = MPD_DATA_TYPE_SONG;
			data->song = ent->info.song;
			ent->info.song = NULL;
		}
		else if (ent->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE)
		{
			data->type = MPD_DATA_TYPE_PLAYLIST;
			data->playlist = ent->info.playlistFile->path;
			ent->info.playlistFile->path = NULL;
		}

		mpd_freeInfoEntity(ent);
	}
	mpd_finishCommand(mi->connection);

	/* unlock */
	mpd_unlock_conn(mi);
	if(data == NULL)
	{
		return NULL;
	}
	return mpd_data_get_first(data);
}
Esempio n. 5
0
int mpd_playlist_queue_commit(MpdObj *mi)
{
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_WARNING,"not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if(mi->queue == NULL)
	{
		debug_printf(DEBUG_WARNING,"mi->queue is empty");
		return MPD_PLAYLIST_QUEUE_EMPTY;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_WARNING,"lock failed\n");
		return  MPD_LOCK_FAILED;
	}
	mpd_sendCommandListBegin(mi->connection);
	/* get first item */
	mi->queue = mi->queue->first;
	while(mi->queue != NULL)
	{
		if(mi->queue->type == MPD_QUEUE_ADD)
		{
			if(mi->queue->path != NULL)
			{
				mpd_sendAddCommand(mi->connection, mi->queue->path);
			}
		}
		else if(mi->queue->type == MPD_QUEUE_LOAD)
		{
			if(mi->queue->path != NULL)
			{
				mpd_sendLoadCommand(mi->connection, mi->queue->path);
			}
		}
		else if (mi->queue->type == MPD_QUEUE_DELETE_ID)
		{
			if(mi->queue->id >= 0)
			{
				mpd_sendDeleteIdCommand(mi->connection, mi->queue->id);
			}
		}
		else if (mi->queue->type == MPD_QUEUE_DELETE_POS)
		{                                                                      		
			if(mi->queue->id >= 0)
			{
				mpd_sendDeleteCommand(mi->connection, mi->queue->id);
			}
		}

		mpd_queue_get_next(mi);
	}
	mpd_sendCommandListEnd(mi->connection);
	mpd_finishCommand(mi->connection);
	mpd_unlock_conn(mi);
	mpd_status_update(mi);
	return MPD_OK;
}
Esempio n. 6
0
/**
 * @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.
 *
 * @returns a #mpd_Song
 */
mpd_Song * mpd_database_get_fileinfo(MpdObj *mi,const char *path)
{
	mpd_Song *song = NULL;
	mpd_InfoEntity *ent = NULL;
	/*
	 * Check path for availibility and length
	 */
	if(path == NULL || path[0] == '\0')
	{
		debug_printf(DEBUG_ERROR, "path == NULL || strlen(path) == 0");
		return NULL;
	}
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_ERROR, "Not Connected\n");
		return NULL;
	}
	/* lock, so we can work on mi->connection */
	if(mpd_lock_conn(mi) != MPD_OK)
	{
		debug_printf(DEBUG_ERROR, "Failed to lock connection");
		return NULL;
	}
	/* send the request */
	mpd_sendListallInfoCommand(mi->connection, path);
	/* get the first (and only) result */
	ent = mpd_getNextInfoEntity(mi->connection);
	/* finish and clean up libmpdclient */
	mpd_finishCommand(mi->connection);
	/* unlock again */
	if(mpd_unlock_conn(mi))
	{
		if(ent) mpd_freeInfoEntity(ent);
		debug_printf(DEBUG_ERROR, "Failed to unlock");
		return NULL;
	}

	if(ent == NULL)
	{
		debug_printf(DEBUG_ERROR, "Failed to grab song from mpd\n");
		return NULL;
	}

	if(ent->type != MPD_INFO_ENTITY_TYPE_SONG)
	{
		mpd_freeInfoEntity(ent);
		debug_printf(DEBUG_ERROR, "Failed to grab correct song type from mpd, path might not be a file\n");
		return NULL;
	}
	/* get the song */
	song = ent->info.song;
	/* remove reference to song from the entity */
	ent->info.song = NULL;
	/* free the entity */
	mpd_freeInfoEntity(ent);

	return song;
}
Esempio n. 7
0
MpdData * mpd_database_get_directory(MpdObj *mi,char *path)
{
	MpdData *data = NULL;
	mpd_InfoEntity *ent = NULL;
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_WARNING,"not connected\n");
		return NULL;
	}
	if(path == NULL)
	{
		path = "/";
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_WARNING,"lock failed\n");
		return NULL;
	}

	mpd_sendLsInfoCommand(mi->connection,path);
	while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
	{
		data = mpd_new_data_struct_append(data);
		if(ent->type == MPD_INFO_ENTITY_TYPE_DIRECTORY)
		{
			data->type = MPD_DATA_TYPE_DIRECTORY;
			data->directory = ent->info.directory->path;
			ent->info.directory->path = NULL;
		}
		else if (ent->type == MPD_INFO_ENTITY_TYPE_SONG)
		{
			data->type = MPD_DATA_TYPE_SONG;
			data->song = ent->info.song;
			ent->info.song = NULL;
		}
		else if (ent->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE)
		{
			data->type = MPD_DATA_TYPE_PLAYLIST;
			data->playlist = ent->info.playlistFile->path;
			ent->info.playlistFile->path = NULL;
		}

		mpd_freeInfoEntity(ent);
	}
	mpd_finishCommand(mi->connection);

	/* unlock */
	mpd_unlock_conn(mi);
	if(data == NULL)
	{
		return NULL;
	}
	return mpd_data_get_first(data);
}
Esempio n. 8
0
int mpd_server_get_allowed_commands(MpdObj *mi)
{
	char *temp = NULL;
	int num_commands = 0;
	if(!mi){
		debug_printf(DEBUG_ERROR, "mi != NULL failed\n");
	       	return MPD_ARGS_ERROR;
	}
	if(!mpd_check_connected(mi)) {
		debug_printf(DEBUG_WARNING, "Not Connected");
		return MPD_NOT_CONNECTED;
	}
	if(!mpd_server_check_version(mi,0,12,0)){
		debug_printf(DEBUG_INFO, "Not supported by mpd");
	       	return MPD_SERVER_NOT_SUPPORTED;
	}

	mpd_server_free_commands(mi);

	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_ERROR, "lock failed");
		return MPD_LOCK_FAILED;
	}
	mpd_sendCommandsCommand(mi->connection);
	while((temp = mpd_getNextCommand(mi->connection)))
	{
		num_commands++;
		mi->commands = realloc(mi->commands, (num_commands+1)*sizeof(MpdCommand));
		mi->commands[num_commands-1].command_name = temp;
		mi->commands[num_commands-1].enabled = TRUE;
		mi->commands[num_commands].command_name = NULL;
		mi->commands[num_commands].enabled = FALSE;
	}
	mpd_finishCommand(mi->connection);
	mpd_sendNotCommandsCommand(mi->connection);
	while((temp = mpd_getNextCommand(mi->connection)))
	{
		num_commands++;
		mi->commands = realloc(mi->commands, (num_commands+1)*sizeof(MpdCommand));
		mi->commands[num_commands-1].command_name = temp;
		mi->commands[num_commands-1].enabled = FALSE;
		mi->commands[num_commands].command_name = NULL;
		mi->commands[num_commands].enabled = FALSE;
	}
	mpd_finishCommand(mi->connection);

	if(mpd_unlock_conn(mi))
    {
        return MPD_LOCK_FAILED;
    }
	return MPD_OK;
}
Esempio n. 9
0
MpdData * mpd_playlist_get_changes_posid(MpdObj *mi,int old_playlist_id)
{
	MpdData *data = NULL;
	mpd_InfoEntity *ent = NULL;
	debug_printf(DEBUG_INFO, "Fetching using new plchangesposid command");
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_WARNING,"not connected\n");
		return NULL;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_WARNING,"lock failed\n");
		return NULL;
	}

	if(old_playlist_id == -1)
	{
		debug_printf(DEBUG_INFO,"get fresh playlist\n");
		mpd_sendPlChangesPosIdCommand (mi->connection, 0);
/*		mpd_sendPlaylistIdCommand(mi->connection, -1); */
	}
	else
	{
		mpd_sendPlChangesPosIdCommand (mi->connection, old_playlist_id);
	}

	while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
	{
		if(ent->type == MPD_INFO_ENTITY_TYPE_SONG)
		{
			data = mpd_new_data_struct_append(data);
			data->type = MPD_DATA_TYPE_SONG;
			data->song = ent->info.song;
			ent->info.song = NULL;
		}
		mpd_freeInfoEntity(ent);
	}
	mpd_finishCommand(mi->connection);

	/* unlock */
	if(mpd_unlock_conn(mi))
	{
		debug_printf(DEBUG_WARNING,"mpd_playlist_get_changes: unlock failed.\n");
		mpd_data_free(data);
		return NULL;
	}
	if(data == NULL)
	{
		return NULL;
	}
	return mpd_data_get_first(data);
}
Esempio n. 10
0
int mpd_stats_update_real(MpdObj *mi, ChangedStatusType* what_changed)
{
	ChangedStatusType what_changed_here = 0;
	if ( what_changed == NULL ) {
		/* we need to save the current state, because we're called standalone */
		memcpy(&(mi->OldState), &(mi->CurrentState), sizeof(MpdServerState));
	}

	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_INFO,"not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_ERROR,"lock failed\n");
		return MPD_LOCK_FAILED;
	}

	if(mi->stats != NULL)
	{
		mpd_freeStats(mi->stats);
	}
	mpd_sendStatsCommand(mi->connection);
	mi->stats = mpd_getStats(mi->connection);
	if(mi->stats == NULL)
	{
		debug_printf(DEBUG_ERROR,"Failed to grab stats from mpd\n");
	}
	else if(mi->stats->dbUpdateTime != mi->OldState.dbUpdateTime)  
	{
		debug_printf(DEBUG_INFO, "database updated\n");
		what_changed_here |= MPD_CST_DATABASE;

		mi->CurrentState.dbUpdateTime = mi->stats->dbUpdateTime;
	}

	if (what_changed) {
		(*what_changed) |= what_changed_here;
	} else {
		if((mi->the_status_changed_callback != NULL) & what_changed_here)
		{
			mi->the_status_changed_callback(mi, what_changed_here, mi->the_status_changed_signal_userdata);
		}
	}

	if(mpd_unlock_conn(mi))
	{
		debug_printf(DEBUG_ERROR, "unlock failed");
		return MPD_LOCK_FAILED;
	}
	return MPD_OK;
}
Esempio n. 11
0
MpdData * mpd_playlist_search_commit(MpdObj *mi)
{
	mpd_InfoEntity *ent = NULL;
	MpdData *data = NULL;
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_WARNING,"not connected\n");
		return NULL;
	}
	if(mi->search_type < MPD_SEARCH_TYPE_PLAYLIST_FIND )
	{
		debug_printf(DEBUG_ERROR, "no or wrong search in progress to commit");
		return NULL;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_ERROR,"lock failed\n");
		return NULL;
	}
	mpd_commitSearch(mi->connection);
	while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
	{
		if(ent->type == MPD_INFO_ENTITY_TYPE_SONG)
		{
			data = mpd_new_data_struct_append(data);
			data->type = MPD_DATA_TYPE_SONG;
			data->song = ent->info.song;
			ent->info.song = NULL;
		}
		mpd_freeInfoEntity(ent);
	}
	mpd_finishCommand(mi->connection);
	/*
	 * reset search type
	 */
	mi->search_type = MPD_SEARCH_TYPE_NONE;
	mi->search_field = MPD_TAG_ITEM_ARTIST;
	/* unlock */
	if(mpd_unlock_conn(mi))
	{
		debug_printf(DEBUG_ERROR, "Failed to unlock connection");
		if(data)mpd_data_free(data);
		return NULL;
	}
	if(data == NULL)
	{
		return NULL;
	}
	return mpd_data_get_first(data);
}
Esempio n. 12
0
MpdData * mpd_playlist_get_song_from_pos_range(MpdObj *mi, int start, int stop)
{
    MpdData *data = NULL;
    int i;
	mpd_InfoEntity *ent = NULL;
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_ERROR, "Not Connected\n");
		return NULL;
	}
	if(mpd_status_check(mi) != MPD_OK)
	{
		debug_printf(DEBUG_ERROR,"Failed grabbing status\n");
		return NULL;
	}

	if(mpd_lock_conn(mi))
	{
		return NULL;
	}
    /* Don't check outside playlist length */
    if(!(stop < mi->status->playlistLength)) {
        stop = mi->status->playlistLength -1;
    }
    mpd_sendCommandListBegin(mi->connection);
    for(i=start; i <= stop; i++){
        mpd_sendPlaylistInfoCommand(mi->connection, i);
    }
	mpd_sendCommandListEnd(mi->connection);
	while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
	{
		if(ent->type == MPD_INFO_ENTITY_TYPE_SONG)
		{
			data = mpd_new_data_struct_append(data);
			data->type = MPD_DATA_TYPE_SONG;
			data->song = ent->info.song;
			ent->info.song = NULL;
		}
		mpd_freeInfoEntity(ent);
	}
	mpd_finishCommand(mi->connection);

	if(mpd_unlock_conn(mi))
	{
		/*TODO free entity. for now this can never happen */
		return NULL;
	}
    return data;
}
Esempio n. 13
0
/*******************************************************************************
 * PLAYLIST
 */
mpd_Song * mpd_playlist_get_song(MpdObj *mi, int songid)
{
	mpd_Song *song = NULL;
	mpd_InfoEntity *ent = NULL;
	if(songid < 0){
		debug_printf(DEBUG_ERROR, "songid < 0 Failed");
		return NULL;
	}
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_ERROR, "Not Connected\n");
		return NULL;
	}

	if(mpd_lock_conn(mi))
	{
		return NULL;
	}
	debug_printf(DEBUG_INFO, "Trying to grab song with id: %i\n", songid);
	mpd_sendPlaylistIdCommand(mi->connection, songid);
	ent = mpd_getNextInfoEntity(mi->connection);
	mpd_finishCommand(mi->connection);

	if(mpd_unlock_conn(mi))
	{
		if(ent) mpd_freeInfoEntity(ent);
		return NULL;
	}

	if(ent == NULL)
	{
		debug_printf(DEBUG_ERROR, "Failed to grab song from mpd\n");
		return NULL;
	}

	if(ent->type != MPD_INFO_ENTITY_TYPE_SONG)
	{
		mpd_freeInfoEntity(ent);
		debug_printf(DEBUG_ERROR, "Failed to grab correct song type from mpd\n");
		return NULL;
	}
	song = ent->info.song;
	ent->info.song = NULL;

	mpd_freeInfoEntity(ent);

	return song;
}
Esempio n. 14
0
int mpd_player_set_random(MpdObj * mi, int random)
{
	if (!mpd_check_connected(mi)) {
		debug_printf(DEBUG_WARNING, "not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if (mpd_lock_conn(mi)) {
		debug_printf(DEBUG_WARNING, "lock failed\n");
		return MPD_LOCK_FAILED;
	}
	mpd_sendRandomCommand(mi->connection, random);
	mpd_finishCommand(mi->connection);

	mpd_unlock_conn(mi);
	mpd_status_queue_update(mi);
	return MPD_OK;
}
Esempio n. 15
0
int mpd_status_set_crossfade(MpdObj *mi,int crossfade_time)
{
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_WARNING,"not connected\n");	
		return MPD_NOT_CONNECTED;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_ERROR,"lock failed\n");
		return MPD_LOCK_FAILED;
	}
	mpd_sendCrossfadeCommand(mi->connection, crossfade_time);
	mpd_finishCommand(mi->connection);

	mpd_unlock_conn(mi);
	mpd_status_queue_update(mi);
	return MPD_OK;
}
Esempio n. 16
0
int	mpd_playlist_swap_id (MpdObj *mi, int old_id, int new_id) {
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_WARNING,"not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_ERROR,"lock failed\n");
		return MPD_LOCK_FAILED;
	}
	
	mpd_sendSwapIdCommand(mi->connection,old_id, new_id);
	mpd_finishCommand(mi->connection);
	
	/* unlock */
	mpd_unlock_conn(mi);
	return MPD_OK;
}
Esempio n. 17
0
MpdData * mpd_database_get_directory_recursive(MpdObj *mi, const char *path)
{
	MpdData *data = NULL;
	mpd_InfoEntity *ent = NULL;
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_WARNING,"not connected\n");
		return NULL;
	}
	if(path == '\0' || path[0] == '\0')
	{
		debug_printf(DEBUG_ERROR, "argumant invalid\n");
		return NULL;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_ERROR,"lock failed\n");
		return NULL;
	}
	mpd_sendListallInfoCommand(mi->connection,path); 
	while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
	{

		if (ent->type == MPD_INFO_ENTITY_TYPE_SONG)
		{
			data = mpd_new_data_struct_append(data);
			data->type = MPD_DATA_TYPE_SONG;
			data->song = ent->info.song;
			ent->info.song = NULL;
		}
		mpd_freeInfoEntity(ent);
	}
	mpd_finishCommand(mi->connection);

	/* unlock */
	mpd_unlock_conn(mi);
	if(data == NULL)
	{
		return NULL;
	}
	return mpd_data_get_first(data);
}
Esempio n. 18
0
int mpd_playlist_shuffle(MpdObj *mi)
{
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_WARNING,"not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_ERROR,"lock failed\n");
		return MPD_LOCK_FAILED;
	}

	mpd_sendShuffleCommand(mi->connection);
	mpd_finishCommand(mi->connection);

	/* unlock */
	mpd_unlock_conn(mi);
	return FALSE;

}
Esempio n. 19
0
int mpd_player_prev(MpdObj * mi)
{
	if (!mpd_check_connected(mi)) {
		debug_printf(DEBUG_WARNING, "not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if (mpd_lock_conn(mi)) {
		debug_printf(DEBUG_WARNING, "lock failed\n");
		return MPD_LOCK_FAILED;
	}

	mpd_sendPrevCommand(mi->connection);
	mpd_finishCommand(mi->connection);


	mpd_unlock_conn(mi);
	if (mpd_status_update(mi)) {
		return MPD_STATUS_FAILED;
	}
	return MPD_OK;
}
Esempio n. 20
0
char * mpd_sticker_song_get(MpdObj *mi, const char *path, const char *tag)
{
    char *retv_value = NULL;
    char *retv = NULL;
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_INFO,"not connected\n");
		return NULL;
	}
    if(mpd_server_check_command_allowed(mi, "sticker") != MPD_SERVER_COMMAND_ALLOWED) {
        debug_printf(DEBUG_WARNING, "Command not allowed\n");
        return NULL;
    }
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_ERROR,"lock failed\n");
		return NULL;
	}

    mpd_sendGetSongSticker(mi->connection,path, tag); 
    retv_value = mpd_getNextSticker(mi->connection);
    mpd_finishCommand(mi->connection);
    if(retv_value && strlen(retv_value) > strlen(tag)){
            retv = g_strdup(&retv_value[strlen(tag)]+1);
    }
    free(retv_value);
    if(mi->connection->error == MPD_ERROR_ACK && mi->connection->errorCode == MPD_ACK_ERROR_NO_EXIST)
    {
		mpd_clearError(mi->connection);
		g_free(retv);
        retv = NULL;
    }
    if(mpd_unlock_conn(mi))
    {
		debug_printf(DEBUG_ERROR, "Failed to unlock");
        g_free(retv);
		return NULL;
	}
    return retv;
}
Esempio n. 21
0
void mpd_database_playlist_clear(MpdObj *mi, const char *path)
{
	if(!path )
		return;
	if (!mpd_check_connected(mi)) {
		debug_printf(DEBUG_WARNING, "not connected\n");
		return;
	}
	if (mpd_status_check(mi) != MPD_OK) {
		debug_printf(DEBUG_WARNING, "Failed to get status\n");
		return;
	}
	if(mpd_lock_conn(mi))
	{
		return ;
	}

	mpd_sendPlaylistClearCommand(mi->connection, (char *)path);
	mpd_finishCommand(mi->connection);

	mpd_unlock_conn(mi);
}
Esempio n. 22
0
int mpd_player_play_id(MpdObj * mi, int id)
{
	debug_printf(DEBUG_INFO, "trying to play id: %i\n", id);
	if (!mpd_check_connected(mi)) {
		debug_printf(DEBUG_WARNING, "not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if (mpd_lock_conn(mi)) {
		debug_printf(DEBUG_WARNING, "lock failed\n");
		return MPD_LOCK_FAILED;
	}

	mpd_sendPlayIdCommand(mi->connection, id);
	mpd_finishCommand(mi->connection);


	mpd_unlock_conn(mi);
	if (mpd_status_update(mi)) {
		return MPD_STATUS_FAILED;
	}
	return MPD_OK;
}
Esempio n. 23
0
int mpd_playlist_clear(MpdObj *mi)
{
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_WARNING,"not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_WARNING,"lock failed\n");
		return MPD_LOCK_FAILED;
	}

	mpd_sendClearCommand(mi->connection);
	mpd_finishCommand(mi->connection);
	/* hack to make it update correctly when replacing 1 song */
	mi->CurrentState.songid = -1;
	/* unlock */
	mpd_unlock_conn(mi);
	mpd_status_update(mi);
	return FALSE;
}
Esempio n. 24
0
int mpd_playlist_set_priority(MpdObj *mi, int song_id, int priority)
{
    if(!mpd_check_connected(mi))
    {
        debug_printf(DEBUG_WARNING,"not connected\n");
        return MPD_NOT_CONNECTED;
    }
    if(mpd_server_check_command_allowed(mi, "prioid") != MPD_SERVER_COMMAND_ALLOWED) 
    {
        return MPD_SERVER_NOT_SUPPORTED;
    }
    if(mpd_lock_conn(mi))
    {
        debug_printf(DEBUG_ERROR,"lock failed\n");
        return MPD_LOCK_FAILED;
    }

    mpd_sendSetPrioId(mi->connection,priority, song_id);
    mpd_finishCommand(mi->connection);

    /* unlock */
    mpd_unlock_conn(mi);
    return MPD_OK;
}
Esempio n. 25
0
int mpd_playlist_add_get_id(MpdObj *mi,const char *path)
{
	int songid = -1;
	if(mi == NULL || path == NULL)
	{
		debug_printf(DEBUG_ERROR, "mi == NULL || path == NULL failed");
		return MPD_ARGS_ERROR;
	}
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_WARNING,"mpd_playlist_add: not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_WARNING,"lock failed\n");
		return MPD_LOCK_FAILED;
	}
	songid = mpd_sendAddIdCommand(mi->connection, path);
	mpd_finishCommand(mi->connection);

	mpd_unlock_conn(mi);
	return songid; 
}
Esempio n. 26
0
int mpd_set_connection_timeout(MpdObj *mi, float timeout)
{
	if(mi == NULL)
	{
		debug_printf(DEBUG_ERROR, "mi == NULL\n");
		return MPD_ARGS_ERROR;
	}
	mi->connection_timeout = timeout;
	if(mpd_check_connected(mi))
	{
		/*TODO: set timeout */	
		if(mpd_lock_conn(mi))
		{
			debug_printf(DEBUG_ERROR,"lock failed\n");
			return MPD_LOCK_FAILED;
		}
		mpd_setConnectionTimeout(mi->connection, timeout);
		mpd_finishCommand(mi->connection);

		mpd_unlock_conn(mi);

	}
	return MPD_OK;
}
Esempio n. 27
0
int mpd_connect_real(MpdObj *mi,mpd_Connection *connection)
{
    int retv;
    if(mi == NULL)
	{
		/* should return some spiffy error here */
		debug_printf(DEBUG_ERROR, "mi != NULL failed");
		return MPD_ARGS_ERROR;
	}
	/* reset errors */
	mi->error = 0;
	mi->error_mpd_code = 0;
	if(mi->error_msg != NULL)
	{
		free(mi->error_msg);
	}
	mi->error_msg = NULL;

	debug_printf(DEBUG_INFO, "connecting\n");
	mpd_init_MpdServerState(&(mi->CurrentState));

	memcpy(&(mi->OldState), &(mi->CurrentState), sizeof(MpdServerState));

	if(mi->connected)
	{
		/* disconnect */
		mpd_disconnect(mi);
	}

	if(mi->hostname == NULL)
	{
		mpd_set_hostname(mi, "localhost");
	}
	/* make sure this is locked */
	if(!mi->connection_lock)
	{
		mpd_lock_conn(mi);
	}
	if(connection) {
		mi->connection = connection;
	} else {
		/* make timeout configurable */
		mi->connection = mpd_newConnection(mi->hostname,mi->port,mi->connection_timeout);
	}
	if(mi->connection == NULL)
	{
		/* TODO: make seperate error message? */
		return MPD_NOT_CONNECTED;
	}
	if(mpd_check_error(mi) != MPD_OK)
	{
		/* TODO: make seperate error message? */
		return MPD_NOT_CONNECTED;
	}

	/* set connected state */
	mi->connected = TRUE;
	if(mpd_unlock_conn(mi))
	{
		return MPD_LOCK_FAILED;
	}

	/* get the commands we are allowed to use */
	retv = mpd_server_get_allowed_commands(mi);
    if(retv!= MPD_OK)
    {
        return retv;
    }
    if(mi->the_connection_changed_callback != NULL)
	{
		mi->the_connection_changed_callback( mi, TRUE, mi->the_connection_changed_signal_userdata );
	}

	debug_printf(DEBUG_INFO, "Connected to mpd");
	return MPD_OK;
}
Esempio n. 28
0
/* should be called mpd_database_find */
MpdData * mpd_database_find(MpdObj *mi, int table, char *string, int exact)
{
	MpdData *data = NULL;
/*	MpdData *artist = NULL;
	MpdData *album = NULL;
*/	mpd_InfoEntity *ent = NULL;
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_WARNING,"not connected\n");
		return NULL;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_WARNING,"lock failed\n");
		return NULL;
	}
	if(exact)
	{
		mpd_sendFindCommand(mi->connection,table,string);
	}
	else
	{
		mpd_sendSearchCommand(mi->connection, table,string);
	}
	while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL)
	{
		data = mpd_new_data_struct_append(data);
		/* mpd_sendSearch|Find only returns songs */
		/*
		if(ent->type == MPD_INFO_ENTITY_TYPE_DIRECTORY)
		{
			data->type = MPD_DATA_TYPE_DIRECTORY;
			data->directory = ent->info.directory->path;
			ent->info.directory->path = NULL;
		}
		else*/ if (ent->type == MPD_INFO_ENTITY_TYPE_SONG)
		{
			data->type = MPD_DATA_TYPE_SONG;
			data->song = ent->info.song;
			ent->info.song = NULL;
			/* This is something the client can and should do */
/*			if(data->song->artist != NULL)
			{
				int found = FALSE;
				if(artist != NULL)
				{
					MpdData *fartist = mpd_data_get_first(artist);
					do{
						if( (fartist->type == MPD_DATA_TYPE_TAG) && (fartist->tag_type == MPD_TAG_ITEM_ARTIST))
						{
							if(fartist->tag == NULL)
							{
								printf("crap this should'nt be \n");
							}
							if(!strcmp(fartist->tag, data->song->artist))
							{
								found = TRUE;
							}
						}
						fartist = mpd_data_get_next_real(fartist, FALSE);
					}while(fartist && !found);
				}
				if(!found)
				{
					artist= mpd_new_data_struct_append(artist);
					artist->type = MPD_DATA_TYPE_TAG;
					artist->tag_type = MPD_TAG_ITEM_ARTIST;
					artist->tag = strdup(data->song->artist);
				}
			}
			if(data->song->album != NULL)
			{
				int found = FALSE;
				if(album != NULL)
				{
					MpdData *falbum = mpd_data_get_first(album);
					do{
						if( (falbum->type == MPD_DATA_TYPE_TAG) && (falbum->tag_type == MPD_TAG_ITEM_ALBUM))
						{
							if(falbum->tag == NULL)
							{
								printf("crap this should'nt be \n");
							}
							if(!strcmp(falbum->tag, data->song->album))
							{
								found = TRUE;
							}
						}
						falbum = mpd_data_get_next_real(falbum, FALSE);
					}while(falbum && !found);
				}
				if(!found)
				{
					album = mpd_new_data_struct_append(album);
					album->type = MPD_DATA_TYPE_TAG;
					album->tag_type = MPD_TAG_ITEM_ALBUM;
					album->tag = strdup(data->song->album);
				}
			}
*/
		}
		/*
		else if (ent->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE)
		{
			data->type = MPD_DATA_TYPE_PLAYLIST;
			data->playlist = ent->info.playlistFile->path;
			ent->info.playlistFile->path = NULL;
		}
		*/

		mpd_freeInfoEntity(ent);
	}
	mpd_finishCommand(mi->connection);

	/* unlock */
	mpd_unlock_conn(mi);
	if(data == NULL)
	{
		return NULL;
	}
	data = mpd_data_get_first(data);
	/* prepend the album then artists*/
/*	if(album != NULL)
	{
		if(data){
			data  = mpd_data_concatenate( album, data);
		}else{
			data = album;
		}
	}
	if(artist != NULL)
	{
		if(data) {
			album = mpd_data_concatenate( artist, data );
		}else{
			data = artist;
		}
	}                                                     	
*/
	return mpd_data_get_first(data);
}
Esempio n. 29
0
int mpd_status_update(MpdObj *mi)
{
	ChangedStatusType what_changed=0;
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_INFO,"Where not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_ERROR,"lock failed\n");
		return MPD_LOCK_FAILED;
	}


	if(mi->status != NULL)
	{
		mpd_freeStatus(mi->status);
		mi->status = NULL;
	}
	mpd_sendStatusCommand(mi->connection);
	mi->status = mpd_getStatus(mi->connection);
	if(mi->status == NULL)
	{
		debug_printf(DEBUG_ERROR,"Failed to grab status from mpd\n");
		mpd_unlock_conn(mi);
		return MPD_STATUS_FAILED;
	}
	if(mpd_unlock_conn(mi))
	{
		debug_printf(DEBUG_ERROR, "Failed to unlock");
		return MPD_LOCK_FAILED;
	}
	/*
	 * check for changes 
	 */
	/* first save the old status */
	memcpy(&(mi->OldState), &(mi->CurrentState), sizeof(MpdServerState));

	/* playlist change */
	if(mi->CurrentState.playlistid != mi->status->playlist)
	{
		/* print debug message */
		debug_printf(DEBUG_INFO, "Playlist has changed!");

		/* We can't trust the current song anymore. so we remove it */
		/* tags might have been updated */
		if(mi->CurrentSong != NULL)
		{
			mpd_freeSong(mi->CurrentSong);
			mi->CurrentSong = NULL;
		}

		/* set MPD_CST_PLAYLIST to be changed */
		what_changed |= MPD_CST_PLAYLIST;

		/* save new id */
		mi->CurrentState.playlistid = mi->status->playlist;
	}


	/* state change */
	if(mi->CurrentState.state != mi->status->state)
	{
		what_changed |= MPD_CST_STATE;
		mi->CurrentState.state = mi->status->state;
	}

	if(mi->CurrentState.songid != mi->status->songid)
	{
		/* print debug message */
		debug_printf(DEBUG_INFO, "Song has changed %i %i!", mi->OldState.songid, mi->status->songid);

		what_changed |= MPD_CST_SONGID;
		/* save new songid */
		mi->CurrentState.songid = mi->status->songid;

	}
	if(mi->CurrentState.songpos != mi->status->song)
	{
		/* print debug message */
		debug_printf(DEBUG_INFO, "Song has changed %i %i!", mi->OldState.songpos, mi->status->song);

		what_changed |= MPD_CST_SONGPOS;
		/* save new songid */
		mi->CurrentState.songpos = mi->status->song;

	}
	
	if(mi->CurrentState.repeat != mi->status->repeat)
	{
		what_changed |= MPD_CST_REPEAT;
		mi->CurrentState.repeat = mi->status->repeat;
	}
	if(mi->CurrentState.random != mi->status->random)
	{
		what_changed |= MPD_CST_RANDOM;
		mi->CurrentState.random = mi->status->random;
	}
	if(mi->CurrentState.volume != mi->status->volume)
	{
		what_changed |= MPD_CST_VOLUME;
		mi->CurrentState.volume = mi->status->volume;
	}
	if(mi->CurrentState.xfade != mi->status->crossfade)
	{
		what_changed |= MPD_CST_CROSSFADE;
		mi->CurrentState.xfade = mi->status->crossfade;
	}
	if(mi->CurrentState.totaltime != mi->status->totalTime)
	{
		what_changed |= MPD_CST_TOTAL_TIME;
		mi->CurrentState.totaltime = mi->status->totalTime;
	}
	if(mi->CurrentState.elapsedtime != mi->status->elapsedTime)
	{
		what_changed |= MPD_CST_ELAPSED_TIME;
		mi->CurrentState.elapsedtime = mi->status->elapsedTime;
	}

	/* Check if bitrate changed, happens with vbr encodings. */
	if(mi->CurrentState.bitrate != mi->status->bitRate)
	{
		what_changed |= MPD_CST_BITRATE;
		mi->CurrentState.bitrate = mi->status->bitRate;
	}

	/* The following 3 probly only happen on a song change, or is it possible in one song/stream? */
	/* Check if the sample rate changed */
	if(mi->CurrentState.samplerate != mi->status->sampleRate)
	{
		what_changed |= MPD_CST_AUDIOFORMAT;
		mi->CurrentState.samplerate = mi->status->sampleRate;
	}
	
	/* check if the sampling depth changed */
	if(mi->CurrentState.bits != mi->status->bits)
	{
		what_changed |= MPD_CST_AUDIOFORMAT;
		mi->CurrentState.bits = mi->status->bits;
	}
	
	/* Check if the amount of audio channels changed */
	if(mi->CurrentState.channels != mi->status->channels)
	{
		what_changed |= MPD_CST_AUDIOFORMAT;
		mi->CurrentState.channels = mi->status->channels;
	}

	/* Check if the updating changed,
	 * If it stopped, also update the stats for the new db-time.
	 */
	if(mi->CurrentState.updatingDb != mi->status->updatingDb )
	{
		what_changed |= MPD_CST_UPDATING;
		if(!mi->status->updatingDb)
		{
			mpd_stats_update_real(mi, &what_changed);
		}
		mi->CurrentState.updatingDb = mi->status->updatingDb;
	}

	/* Run the callback */
	if((mi->the_status_changed_callback != NULL) && what_changed)
	{
		mi->the_status_changed_callback( mi, what_changed, mi->the_status_changed_signal_userdata );
	}

	/* We could have lost connection again during signal handling... so before we return check again if we are connected */
	if(!mpd_check_connected(mi))
	{
		return MPD_NOT_CONNECTED;
	}
	return MPD_OK;
}
Esempio n. 30
0
int mpd_status_update(MpdObj *mi)
{
	ChangedStatusType what_changed=0;
	if(!mpd_check_connected(mi))
	{
		debug_printf(DEBUG_INFO,"not connected\n");
		return MPD_NOT_CONNECTED;
	}
	if(mpd_lock_conn(mi))
	{
		debug_printf(DEBUG_ERROR,"lock failed\n");
		return MPD_LOCK_FAILED;
	}



	if(mi->status != NULL)
	{
		mpd_freeStatus(mi->status);
		mi->status = NULL;
	}
	mpd_sendStatusCommand(mi->connection);
	mi->status = mpd_getStatus(mi->connection);
	if(mi->status == NULL)
	{
		debug_printf(DEBUG_ERROR,"Failed to grab status from mpd\n");
		mpd_unlock_conn(mi);
		return MPD_STATUS_FAILED;
	}
	if(mpd_unlock_conn(mi))
	{
		debug_printf(DEBUG_ERROR, "Failed to unlock");
		return MPD_LOCK_FAILED;
	}
	/*
	 * check for changes 
	 */
	/* first save the old status */
	memcpy(&(mi->OldState), &(mi->CurrentState), sizeof(MpdServerState));

	/* playlist change */
	if(mi->CurrentState.playlistid != mi->status->playlist)
	{
		/* print debug message */
		debug_printf(DEBUG_INFO, "Playlist has changed!");

		/* We can't trust the current song anymore. so we remove it */
		/* tags might have been updated */
		if(mi->CurrentSong != NULL)
		{
			mpd_freeSong(mi->CurrentSong);
			mi->CurrentSong = NULL;
		}

		/* set MPD_CST_PLAYLIST to be changed */
		what_changed |= MPD_CST_PLAYLIST;

        if(mi->CurrentState.playlistLength == mi->status->playlistLength)
        {
//            what_changed |= MPD_CST_SONGID; 
        }
		/* save new id */
		mi->CurrentState.playlistid = mi->status->playlist;
	}
	
	if(mi->CurrentState.storedplaylistid != mi->status->storedplaylist)
	{
		/* set MPD_CST_QUEUE to be changed */
		what_changed |= MPD_CST_STORED_PLAYLIST;


		/* save new id */
		mi->CurrentState.storedplaylistid = mi->status->storedplaylist;
	}


	/* state change */
	if(mi->CurrentState.state != mi->status->state)
	{
		what_changed |= MPD_CST_STATE;
		mi->CurrentState.state = mi->status->state;
	}

	if(mi->CurrentState.songid != mi->status->songid)
	{
		/* print debug message */
		debug_printf(DEBUG_INFO, "Songid has changed %i %i!", mi->OldState.songid, mi->status->songid);

		what_changed |= MPD_CST_SONGID;
		/* save new songid */
		mi->CurrentState.songid = mi->status->songid;

	}
	if(mi->CurrentState.songpos != mi->status->song)
	{
		/* print debug message */
		debug_printf(DEBUG_INFO, "Songpos has changed %i %i!", mi->OldState.songpos, mi->status->song);

		what_changed |= MPD_CST_SONGPOS;
		/* save new songid */
		mi->CurrentState.songpos = mi->status->song;

	}
    if(mi->CurrentState.nextsongid != mi->status->nextsongid || mi->CurrentState.nextsongpos != mi->status->nextsong)
    {
		what_changed |= MPD_CST_NEXTSONG;
		/* save new songid */
		mi->CurrentState.nextsongpos = mi->status->nextsong;
        mi->CurrentState.nextsongid = mi->status->nextsongid;
    }
	
	if(mi->CurrentState.single != mi->status->single)
	{
		what_changed |= MPD_CST_SINGLE_MODE;
		mi->CurrentState.single = mi->status->single;
	}
	if(mi->CurrentState.consume != mi->status->consume)
	{
		what_changed |= MPD_CST_CONSUME_MODE;
		mi->CurrentState.consume = mi->status->consume;
	}
	if(mi->CurrentState.repeat != mi->status->repeat)
	{
		what_changed |= MPD_CST_REPEAT;
		mi->CurrentState.repeat = mi->status->repeat;
	}
	if(mi->CurrentState.random != mi->status->random)
	{
		what_changed |= MPD_CST_RANDOM;
		mi->CurrentState.random = mi->status->random;
	}
	if(mi->CurrentState.volume != mi->status->volume)
	{
		what_changed |= MPD_CST_VOLUME;
		mi->CurrentState.volume = mi->status->volume;
	}
	if(mi->CurrentState.xfade != mi->status->crossfade)
	{
		what_changed |= MPD_CST_CROSSFADE;
		mi->CurrentState.xfade = mi->status->crossfade;
	}
	if(mi->CurrentState.totaltime != mi->status->totalTime)
	{
		what_changed |= MPD_CST_TOTAL_TIME;
		mi->CurrentState.totaltime = mi->status->totalTime;
	}
	if(mi->CurrentState.elapsedtime != mi->status->elapsedTime)
	{
		what_changed |= MPD_CST_ELAPSED_TIME;
		mi->CurrentState.elapsedtime = mi->status->elapsedTime;
	}

	/* Check if bitrate changed, happens with vbr encodings. */
	if(mi->CurrentState.bitrate != mi->status->bitRate)
	{
		what_changed |= MPD_CST_BITRATE;
		mi->CurrentState.bitrate = mi->status->bitRate;
	}

	/* The following 3 probly only happen on a song change, or is it possible in one song/stream? */
	/* Check if the sample rate changed */
	if(mi->CurrentState.samplerate != mi->status->sampleRate)
	{
		what_changed |= MPD_CST_AUDIOFORMAT;
		mi->CurrentState.samplerate = mi->status->sampleRate;
	}
	
	/* check if the sampling depth changed */
	if(mi->CurrentState.bits != mi->status->bits)
	{
		what_changed |= MPD_CST_AUDIOFORMAT;
		mi->CurrentState.bits = mi->status->bits;
	}
	
	/* Check if the amount of audio channels changed */
	if(mi->CurrentState.channels != mi->status->channels)
	{
		what_changed |= MPD_CST_AUDIOFORMAT;
		mi->CurrentState.channels = mi->status->channels;
	}

    if(mi->status->error)
    {
        what_changed |= MPD_CST_SERVER_ERROR;
        strcpy(mi->CurrentState.error,mi->status->error);
        mpd_sendClearErrorCommand(mi->connection);
        mpd_finishCommand(mi->connection);
    }
    else
    {
        mi->CurrentState.error[0] ='\0';
    }

	/* Check if the updating changed,
	 * If it stopped, also update the stats for the new db-time.
	 */
	if(mi->CurrentState.updatingDb != mi->status->updatingDb )
	{
		what_changed |= MPD_CST_UPDATING;
		if(!mi->status->updatingDb)
		{
			mpd_stats_update_real(mi, &what_changed);
		}
		mi->CurrentState.updatingDb = mi->status->updatingDb;
	}


    mi->CurrentState.playlistLength = mi->status->playlistLength;


    /* Detect changed outputs */
    if(!mi->has_idle)
    {
        if(mi->num_outputs >0 )
        {
            mpd_OutputEntity *output = NULL;
            mpd_sendOutputsCommand(mi->connection);
            while (( output = mpd_getNextOutput(mi->connection)) != NULL)
            {   
                if(mi->num_outputs < output->id)
                {
                    mi->num_outputs++;
                    mi->output_states = realloc(mi->output_states,mi->num_outputs*sizeof(int));
                    mi->output_states[mi->num_outputs] = output->enabled;
                    what_changed |= MPD_CST_OUTPUT;
                }
                if(mi->output_states[output->id] != output->enabled)
                {
                    mi->output_states[output->id] = output->enabled;
                    what_changed |= MPD_CST_OUTPUT;
                }
                mpd_freeOutputElement(output);
            }
            mpd_finishCommand(mi->connection);
        }
        else
        {
            /* 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;
        }
    }else {
        char *name;
        int update_stats = 0;
        mpd_sendGetEventsCommand(mi->connection);    
        while((name = mpd_getNextEvent(mi->connection))){
            if(strcmp(name, "output") == 0){
                what_changed |= MPD_CST_OUTPUT;
            }else if (strcmp(name, "database") == 0) {
                if((what_changed&MPD_CST_DATABASE) == 0)
                {
                    update_stats = 1;
                }
                what_changed |= MPD_CST_DATABASE;
            }else if (strcmp(name, "stored_playlist")==0) {
                what_changed |= MPD_CST_STORED_PLAYLIST;
            }else if (strcmp(name, "tag") == 0) {
                what_changed |= MPD_CST_PLAYLIST;
            }else if (strcmp (name, "sticker") == 0) {
                what_changed |= MPD_CST_STICKER;
            }
            free(name);
       }
       mpd_finishCommand(mi->connection);
       if(update_stats) {
           mpd_stats_update_real(mi, &what_changed);
       }
    }

  
	/* Run the callback */
	if((mi->the_status_changed_callback != NULL) && what_changed)
	{
		mi->the_status_changed_callback( mi, what_changed, mi->the_status_changed_signal_userdata );
	}

        /* We could have lost connection again during signal handling... so before we return check again if we are connected */
	if(!mpd_check_connected(mi))
	{
		return MPD_NOT_CONNECTED;
	}
	return MPD_OK;
}