Esempio n. 1
0
File: mpd.c Progetto: cmende/mpd2irc
gboolean mpd_connect(void)
{
	mpd.conn = mpd_connection_new(prefs.mpd_server, prefs.mpd_port, 10000);
	mpd.idle_source = 0;

	if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS) {
		g_warning("Failed to connect to MPD: %s",
				mpd_connection_get_error_message(mpd.conn));
		return FALSE;
	} else if (mpd_connection_cmp_server_version(mpd.conn, 0, 14, 0) < 0) {
		g_critical("MPD too old, please upgrade to 0.14 or newer");
		return FALSE;
	} else {
		GIOChannel *channel;

		mpd_command_list_begin(mpd.conn, TRUE);
		if (prefs.mpd_password)
			mpd_send_password(mpd.conn, prefs.mpd_password);
		mpd_send_status(mpd.conn);
		mpd_send_current_song(mpd.conn);
		mpd_command_list_end(mpd.conn);

		mpd.status = mpd_recv_status(mpd.conn);
		if (!mpd_response_next(mpd.conn)) {
			mpd_report_error();
			return FALSE;
		}
		mpd.song = mpd_recv_song(mpd.conn);
		if (!mpd_response_finish(mpd.conn)) {
			mpd_report_error();
			return FALSE;
		}

		g_message("Connected to MPD");
		irc_say("Connected to MPD");

		mpd_send_idle_mask(mpd.conn, MPD_IDLE_PLAYER);

		channel = g_io_channel_unix_new(
				mpd_connection_get_fd(mpd.conn));
		mpd.idle_source = g_io_add_watch(channel, G_IO_IN,
				(GIOFunc) mpd_parse, NULL);
		g_io_channel_unref(channel);

		return TRUE;
	}
}
Esempio n. 2
0
void mpd_poll()
{
//    printf("%d\n", mpd.conn_state);
    switch (mpd.conn_state) {
        case MPD_DISCONNECTED:
            syslog(LOG_INFO, "%s - MPD Connecting...\n", __func__);
            mpd.conn = mpd_connection_new(NULL, NULL, 3000);
            if (mpd.conn == NULL) {
                syslog(LOG_ERR, "%s - Out of memory.", __func__);
                mpd.conn_state = MPD_FAILURE;
                return;
            }
            if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS) {
                syslog(LOG_ERR, "%s - MPD connection: %s\n", __func__,
                        mpd_connection_get_error_message(mpd.conn));
                mpd.conn_state = MPD_FAILURE;
                return;
            }
            syslog(LOG_INFO, "%s - MPD connected.\n", __func__);
            mpd_connection_set_timeout(mpd.conn, 10000);
            mpd.conn_state = MPD_CONNECTED;
            break;
        case MPD_FAILURE:
        case MPD_DISCONNECT:
        case MPD_RECONNECT:
            syslog(LOG_ERR, "%s - MPD (dis)reconnect or failure\n", __func__);
            if(mpd.conn != NULL)
                mpd_connection_free(mpd.conn);
            mpd.conn = NULL;
            mpd.conn_state = MPD_DISCONNECTED;
            break;
        case MPD_CONNECTED:
            mpd_put_state();
            //TODO: display status
/*            if (queue_is_empty) {
                queue_is_empty = 0;
                get_random_song(mpd.conn, str, rcm.file_path);
                if (strcmp(str, "") != 0) {
                    syslog(LOG_DEBUG, "%s: add random song %s\n", __func__, str);
                    mpd_run_add(mpd.conn, str);
                }
            }*/
            break;
        default:
            syslog(LOG_INFO, "%s - mpd.conn_state %i\n", __func__, mpd.conn_state);
    }
}
int
main(int argc, char **argv)
{
    int t;
    bool firsttime = true;
    pid=getpid();
    _debug = (bool) getenv("MADAUDIO_DEBUG");
    if(!_debug)
        daemon(0, 0);
    int flags = LOG_NDELAY | LOG_PID;
    if(_debug)
        flags |= LOG_PERROR;
    openlog("madaudio-unsuspend", flags, LOG_DAEMON);

    struct mpd_connection *conn;
    for(t=1000; t > 0; t++) {
        conn = mpd_connection_new(MADAUDIO_SOCKET, 0, 0);
        if(conn && mpd_connection_get_error(conn)==MPD_ERROR_SUCCESS)
            break;
        debug("can't connect to mpd, retry", pid);
        usleep(1000);
    };
    debug("connected...");
    while(true)
    {
        struct mpd_status * status = mpd_run_status(conn);
        check(conn);
        if(!status)
            err(1, "madaudio-unsuspend[%d]: Can't get status\n");
        enum mpd_state state = mpd_status_get_state(status);
        if(state != oldstate)
        {
            if(state == MPD_STATE_PLAY)
                lock_autosuspend();
            else
            {
                if(!firsttime)
                    unlock_autosuspend();
            }
        };
        oldstate = state;
        firsttime = false;
        mpd_status_free(status);
        mpd_run_idle_mask(conn, MPD_IDLE_PLAYER);
        check(conn);
    }
}
Esempio n. 4
0
static void mpd_printerror(const char *cmd)
{
    const char *s;
    if (conn) {
	//assert(mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS);

	s = mpd_connection_get_error_message(conn);
	if (mpd_connection_get_error(conn) == MPD_ERROR_SERVER)
	    /* messages received from the server are UTF-8; the
	       rest is either US-ASCII or locale */
	    s = charset_from_utf8(s);

	error("[MPD] %s to [%s]:[%i] failed : [%s]", cmd, host, iport, s);
	mpd_connection_free(conn);
	conn = NULL;
    }
}
Esempio n. 5
0
/*
 * pgmpc_init
 *
 * Initialize connection to mpd server.
 */
static void
pgmpc_init(void)
{
	Assert(mpd_conn == NULL);

	/* Establish connection to mpd server */
	mpd_conn = mpd_connection_new(mpd_host, mpd_port, mpd_timeout * 1000);
	if (mpd_connection_get_error(mpd_conn) != MPD_ERROR_SUCCESS)
		pgmpc_print_error();

	/* Send password if any */
	if (mpd_password[0])
	{
		if (!mpd_run_password(mpd_conn, mpd_password))
			pgmpc_print_error();
	}
}
/*new_connection*/
int new_connection(struct mpd_connection **conn)
{
	*conn = mpd_connection_new(NULL, 0, 30000);
	if (*conn == NULL)
	{
		printf("nd new_connection %s\n", "Out of memory");
		return -1;
	}

	if (mpd_connection_get_error(*conn) != MPD_ERROR_SUCCESS)
	{
		printf("nd new_connection %s\n", mpd_connection_get_error_message(*conn));
		mpd_connection_free(*conn);
		*conn = NULL;
		return -1;
	}
	return 0;
}
Esempio n. 7
0
bool
CMPD::Connect()
{
    if(_conn)
        mpd_connection_free(_conn);

	_conn = mpd_connection_new(Config->getMHost().c_str(), Config->getMPort(), 0);
    _connected = _conn && mpd_connection_get_error(_conn) == MPD_ERROR_SUCCESS;

    if(_connected && Config->getMPassword().size() > 0) {
        _connected &= mpd_run_password(_conn, Config->getMPassword().c_str());
    }

    if(_connected)
        mpd_run_subscribe(_conn, "mpdas");

	return _connected;
}
Esempio n. 8
0
void Connection::checkErrors() const
{
	mpd_error code = mpd_connection_get_error(m_connection.get());
	if (code != MPD_ERROR_SUCCESS)
	{
		std::string msg = mpd_connection_get_error_message(m_connection.get());
		if (code == MPD_ERROR_SERVER)
		{
			mpd_server_error server_code = mpd_connection_get_server_error(m_connection.get());
			bool clearable = mpd_connection_clear_error(m_connection.get());
			throw ServerError(server_code, msg, clearable);
		}
		else
		{
			bool clearable = mpd_connection_clear_error(m_connection.get());
			throw ClientError(code, msg, clearable);
		}
	}
}
Esempio n. 9
0
/*
 * pgmpc_print_error
 *
 * Relay an error from mpd to Postgres.
 */
static void
pgmpc_print_error(void)
{
	const char *message;

	Assert(mpd_connection_get_error(mpd_conn) != MPD_ERROR_SUCCESS);

	/* Obtain error message */
	message = mpd_connection_get_error_message(mpd_conn);

	/* Cleanup */
	pgmpc_reset();

	/* Report error */
	ereport(ERROR,
			(errcode(ERRCODE_SYSTEM_ERROR),
			 errmsg("mpd command failed: %s",
					message)));
}
static int
connect(struct mpd_connection **conn)
{
	*conn = mpd_connection_new(NULL, 0, 30000);
	if (*conn == NULL)
	{
		LOG_ERROR("%s", "Out of memory");
		return -1;
	}

	if (mpd_connection_get_error(*conn) != MPD_ERROR_SUCCESS)
	{
		LOG_ERROR("%s", mpd_connection_get_error_message(*conn));
		mpd_connection_free(*conn);
		*conn = NULL;
		return -1;
	}
	return 1;
}
Esempio n. 11
0
File: mpd.cpp Progetto: hrkfdn/mpdas
bool CMPD::Connect()
{
    if(_conn)
        mpd_connection_free(_conn);

    _conn = mpd_connection_new(_cfg->Get("host").c_str(), _cfg->GetInt("port"), 0);
    _connected = _conn && mpd_connection_get_error(_conn) == MPD_ERROR_SUCCESS;

    if(_connected && _cfg->Get("mpdpassword").size() > 0) {
        _connected &= mpd_run_password(_conn, _cfg->Get("mpdpassword").c_str());
    }
    else if(!_connected) {
        eprintf("MPD connection error: %s", mpd_connection_get_error_message(_conn));
    }

    if(_connected)
        mpd_run_subscribe(_conn, "mpdas");

    return _connected;
}
Esempio n. 12
0
/*
 * returns: 0 - error; 1 - ok 
 */
int mgr_mpd_connect( void ) {
	if (conn != NULL) {
		if (DEBUG)
			fprintf(stderr, "DEBUG: [mgr-thread] mpd: close open connection\n");

        	mpd_connection_free(conn);
		conn = NULL;
	}

	conn = mpd_connection_new(NULL, 0, 30000);

	if (conn == NULL || mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) {
                fprintf(stderr, "ERROR: MPD: Unable to connect to MPD\n");

		return 0;
	}

	// SETUP mode: repeat:yes, random:yes
	if (!mpd_run_repeat(conn, true) || !mpd_run_random(conn, true)) {
                fprintf(stderr, "ERROR: MPD: Unable to change mode for the created MPD connection\n");
		mgr_handle_mpd_error();

		return 0;
	}

	if (DEBUG)
		fprintf(stderr, "DEBUG: [mgr-thread] mpd: new MPD connection was created\n");

	if (DEBUG)
		fprintf(stderr, "DEBUG: [mgr-thread] mpd: database update started\n");

	// Send update command
	if (!mpd_run_update(conn, NULL)) { // ALL MUSIC in the folder
		fprintf(stderr, "ERROR: MPD: Unable to update MPD database\n");
		mgr_handle_mpd_error();
		return 0;
	}

	return 1;
}
Esempio n. 13
0
int
main(int argc, char *argv[])
{
  char *password = NULL;
  struct mpd_connection *conn = mpd_connection_new(mpd_check_host(NULL, &password), 0, 0);

  if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
  {
    fprintf(stderr,"%s: %s\n", argv[0], mpd_connection_get_error_message(conn));
    return 1;
  }

  if (password != NULL)
  {
    if (mpd_run_password(conn, password) == false)
    {
      fprintf(stderr, "%s: mpd_run_password %s\n", argv[0],
	  mpd_connection_get_error_message(conn));
      free(password);
      return 2;
    }
  }

  if (notify_init("MPD_Notification") == 0)
  {
    fprintf(stderr, "%s: Cannot initialize libnotify.\n", argv[0]);
    return 3;
  }

  infinite_loop(conn);

  mpd_connection_free(conn);
  free(password);
  notify_uninit();

  return 0;
}
Esempio n. 14
0
bool mpd_is_in_queue(const char *uri)
{
    bool res = false;
    struct mpd_entity *entity;
    struct mpd_connection *conn = mpd_connection_new(NULL, NULL, 3000);

    if (conn == NULL) {
        syslog(LOG_ERR, "%s - Out of memory.", __func__);
        goto DONE;
    }
    if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) {
        syslog(LOG_ERR, "%s - MPD connection: %s\n", __func__,
                mpd_connection_get_error_message(conn));
        goto DONE;
    }
    if (!mpd_send_list_queue_meta(conn)) {
        syslog(LOG_ERR, "%s: %s", __func__, mpd_connection_get_error_message(conn));
        mpd_connection_clear_error(conn);
        goto DONE;
    }
    while((entity = mpd_recv_entity(conn)) != NULL) {
        const struct mpd_song *song;
        if(mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG && !res) {
            song = mpd_entity_get_song(entity);
            if (strcmp(mpd_song_get_uri(song), uri) == 0) {
                syslog(LOG_INFO, "%s: %s is already in the queue", __func__, uri);
                res = true;
            }
        }
        mpd_entity_free(entity);
    }

DONE:
    if(conn != NULL)
        mpd_connection_free(conn);
    return res;
}
Esempio n. 15
0
void print_mpd(yajl_gen json_gen, char *buffer, const char *host, int port, const char *password, const char *format) {
        const char *walk;
        char *outwalk = buffer;
        static char titlebuf[40];
        static char artistbuf[40];
        static char albumbuf[40];
        static char trackbuf[10];
        static char datebuf[10];

        static struct mpd_connection *conn;
        struct mpd_status *status = NULL;
        enum mpd_state state;
        struct mpd_song *song;

        /* First run */
        if (conn == NULL) {
                conn = mpd_connection_new(host, port, 1500);
                if (conn == NULL) {
                        START_COLOR("color_bad");
                        outwalk += sprintf(outwalk, "%s", "ERROR");
                        goto print_end;
                }

                if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) {
                        START_COLOR("color_bad");
                        outwalk += sprintf(outwalk, "%s", "CONNECT ERROR");
                        mpd_connection_free(conn);
                        conn = NULL;
                        goto print_end;
                }

                if (password != NULL && strcmp(password, "") != 0 &&
                                !mpd_run_password(conn, password)) {
                        START_COLOR("color_bad");
                        outwalk += sprintf(outwalk, "%s", "PASS ERROR");
                        mpd_connection_free(conn);
                        conn = NULL;
                        goto print_end;
                }
        }

        if ((status = mpd_run_status(conn))) {
                state = mpd_status_get_state(status);
        }

        if (!status || (state != MPD_STATE_PLAY && state != MPD_STATE_PAUSE)) {
                START_COLOR("color_bad");
                outwalk += sprintf(outwalk, "%s", "Stopped");
                mpd_connection_free(conn);
                conn = NULL;
                goto print_end;
        }

        mpd_status_free(status);

        if (state == MPD_STATE_PLAY)
                START_COLOR("color_good");
        else if (state == MPD_STATE_PAUSE)
                START_COLOR("color_degraded");

        song = mpd_run_current_song(conn);

        COPY_CROP(titlebuf, mpd_song_get_tag(song, MPD_TAG_TITLE, 0));
        COPY_CROP(artistbuf, mpd_song_get_tag(song, MPD_TAG_ARTIST, 0));
        COPY_CROP(albumbuf, mpd_song_get_tag(song, MPD_TAG_ALBUM, 0));
        COPY_CROP(trackbuf, mpd_song_get_tag(song, MPD_TAG_TRACK, 0));
        COPY_CROP(datebuf, mpd_song_get_tag(song, MPD_TAG_DATE, 0));

        mpd_song_free(song);

        for (walk = format; *walk != '\0'; walk++) {
                if (*walk != '%') {
                        *(outwalk++) = *walk;
                        continue;
                }

                if (BEGINS_WITH(walk+1, "title")) {
                        if (*titlebuf)
                                outwalk += sprintf(outwalk, "%s", titlebuf);
                        walk += strlen("title");
                }
                else if (BEGINS_WITH(walk+1, "artist")) {
                        if (*artistbuf)
                                outwalk += sprintf(outwalk, "%s", artistbuf);
                        walk += strlen("artist");
                }
                else if (BEGINS_WITH(walk+1, "album")) {
                        if (*albumbuf)
                                outwalk += sprintf(outwalk, "%s", albumbuf);
                        walk += strlen("album");
                }
                else if (BEGINS_WITH(walk+1, "track")) {
                        if (*trackbuf)
                                outwalk += sprintf(outwalk, "%s", trackbuf);
                        walk += strlen("track");
                }
                else if (BEGINS_WITH(walk+1, "date")) {
                        if (*datebuf)
                                outwalk += sprintf(outwalk, "%s", datebuf);
                        walk += strlen("date");
                }
        }

print_end:

        END_COLOR;
        OUTPUT_FULL_TEXT(buffer);

        return;
}
Esempio n. 16
0
void cmd_np(irc_session_t* session, const char* cmd, const char* origin, char* args) {
    struct mpd_connection* conn;
    struct mpd_song* song;
    char master_nick[20];
    const char* title;
    const char* album;
    const char* artist;

    int out_len = 20 + 18 /* master_nick + " is now playing: "*/;
    char* out_str;

    irc_target_get_nick(master_origin, master_nick, 20);

    conn = mpd_connection_new(NULL, 0, 30000);

    if(mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) {
        log_and_print("Impossible de se connecter à MPD");
        mpd_connection_free(conn);

        return;
    }

    mpd_send_current_song(conn);
    song = mpd_recv_song(conn);
    if(song == NULL) {
        out_len += strlen("THE GAME");
        out_str = malloc(out_len * sizeof(char));
        strcpy(out_str, master_nick);
        strcat(out_str, " is now playing: THE GAME");
        irc_cmd_msg(session, channel, out_str);
        free(out_str);
        return;
    }

    title = mpd_song_get_tag(song, MPD_TAG_TITLE, 0);
    album = mpd_song_get_tag(song, MPD_TAG_ALBUM, 0);
    artist = mpd_song_get_tag(song, MPD_TAG_ARTIST, 0);
    if(title)
        out_len += strlen(title) + 2;
    if(album)
        out_len += strlen(album) + 2;
    if(artist)
        out_len += strlen(artist) + 2;

    out_str = malloc(out_len * sizeof(char));
    strcpy(out_str, master_nick);
    strcat(out_str, " is now playing: ");
    if(title)
        strcat(out_str, title);
    if(artist) {
        strcat(out_str, " - ");
        strcat(out_str, artist);
    }
    if(album) {
        strcat(out_str, " - ");
        strcat(out_str, album);
    }
    irc_cmd_msg(session, channel, out_str);
    free(out_str);
    mpd_song_free(song);
    mpd_connection_free(conn);
}
Esempio n. 17
0
int mpd_put_browse(char *buffer, char *path, unsigned int offset)
{
    char *cur = buffer;
    const char *end = buffer + MAX_SIZE;
    struct mpd_entity *entity;
    unsigned int entity_count = 0;

    if (!mpd_send_list_meta(mpd.conn, path))
        RETURN_ERROR_AND_RECOVER("mpd_send_list_meta");

    cur += json_emit_raw_str(cur, end  - cur, "{\"type\":\"browse\",\"data\":[ ");

    while((entity = mpd_recv_entity(mpd.conn)) != NULL) {
        const struct mpd_song *song;
        const struct mpd_directory *dir;
        const struct mpd_playlist *pl;

        if(offset > entity_count)
        {
            mpd_entity_free(entity);
            entity_count++;
            continue;
        }
        else if(offset + MAX_ELEMENTS_PER_PAGE - 1 < entity_count)
        {
            mpd_entity_free(entity);
            cur += json_emit_raw_str(cur, end  - cur, "{\"type\":\"wrap\",\"count\":");
            cur += json_emit_int(cur, end - cur, entity_count);
            cur += json_emit_raw_str(cur, end  - cur, "} ");
            break;
        }

        switch (mpd_entity_get_type(entity)) {
            case MPD_ENTITY_TYPE_UNKNOWN:
                break;

            case MPD_ENTITY_TYPE_SONG:
                song = mpd_entity_get_song(entity);
                cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"song\",\"uri\":");
                cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_uri(song));
                cur += json_emit_raw_str(cur, end - cur, ",\"duration\":");
                cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song));
                cur += json_emit_raw_str(cur, end - cur, ",\"title\":");
                cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song));
                cur += json_emit_raw_str(cur, end - cur, "},");
                break;

            case MPD_ENTITY_TYPE_DIRECTORY:
                dir = mpd_entity_get_directory(entity);

                cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"directory\",\"dir\":");
                cur += json_emit_quoted_str(cur, end - cur, mpd_directory_get_path(dir));
                cur += json_emit_raw_str(cur, end - cur, "},");
                break;

            case MPD_ENTITY_TYPE_PLAYLIST:
                pl = mpd_entity_get_playlist(entity);
                cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"playlist\",\"plist\":");
                cur += json_emit_quoted_str(cur, end - cur, mpd_playlist_get_path(pl));
                cur += json_emit_raw_str(cur, end - cur, "},");
                break;
        }
        mpd_entity_free(entity);
        entity_count++;
    }

    if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(mpd.conn)) {
        fprintf(stderr, "MPD mpd_send_list_meta: %s\n", mpd_connection_get_error_message(mpd.conn));
        mpd.conn_state = MPD_FAILURE;
        return 0;
    }

    /* remove last ',' */
    cur--;

    cur += json_emit_raw_str(cur, end - cur, "]}");
    return cur - buffer;
}
Esempio n. 18
0
int callback_mpd(struct mg_connection *c)
{
    enum mpd_cmd_ids cmd_id = get_cmd_id(c->content);
    size_t n = 0;
    unsigned int uint_buf, uint_buf_2;
    int int_buf;
    char *p_charbuf = NULL, *token;

    if(cmd_id == -1)
        return MG_TRUE;

    if(mpd.conn_state != MPD_CONNECTED && cmd_id != MPD_API_SET_MPDHOST &&
        cmd_id != MPD_API_GET_MPDHOST && cmd_id != MPD_API_SET_MPDPASS &&
        cmd_id != MPD_API_GET_DIRBLEAPITOKEN)
        return MG_TRUE;

    switch(cmd_id)
    {
        case MPD_API_UPDATE_DB:
            mpd_run_update(mpd.conn, NULL);
            break;
        case MPD_API_SET_PAUSE:
            mpd_run_toggle_pause(mpd.conn);
            break;
        case MPD_API_SET_PREV:
            mpd_run_previous(mpd.conn);
            break;
        case MPD_API_SET_NEXT:
            mpd_run_next(mpd.conn);
            break;
        case MPD_API_SET_PLAY:
            mpd_run_play(mpd.conn);
            break;
        case MPD_API_SET_STOP:
            mpd_run_stop(mpd.conn);
            break;
        case MPD_API_RM_ALL:
            mpd_run_clear(mpd.conn);
            break;
        case MPD_API_RM_TRACK:
            if(sscanf(c->content, "MPD_API_RM_TRACK,%u", &uint_buf))
                mpd_run_delete_id(mpd.conn, uint_buf);
            break;
        case MPD_API_PLAY_TRACK:
            if(sscanf(c->content, "MPD_API_PLAY_TRACK,%u", &uint_buf))
                mpd_run_play_id(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_RANDOM:
            if(sscanf(c->content, "MPD_API_TOGGLE_RANDOM,%u", &uint_buf))
                mpd_run_random(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_REPEAT:
            if(sscanf(c->content, "MPD_API_TOGGLE_REPEAT,%u", &uint_buf))
                mpd_run_repeat(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_CONSUME:
            if(sscanf(c->content, "MPD_API_TOGGLE_CONSUME,%u", &uint_buf))
                mpd_run_consume(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_SINGLE:
            if(sscanf(c->content, "MPD_API_TOGGLE_SINGLE,%u", &uint_buf))
                mpd_run_single(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_CROSSFADE:
            if(sscanf(c->content, "MPD_API_TOGGLE_CROSSFADE,%u", &uint_buf))
                mpd_run_crossfade(mpd.conn, uint_buf);
            break;
        case MPD_API_GET_OUTPUTS:
            mpd.buf_size = mpd_put_outputs(mpd.buf, 1);
            c->callback_param = NULL;
            mpd_notify_callback(c, MG_POLL);
            break;
        case MPD_API_TOGGLE_OUTPUT:
            if (sscanf(c->content, "MPD_API_TOGGLE_OUTPUT,%u,%u", &uint_buf, &uint_buf_2)) {
                if (uint_buf_2)
                    mpd_run_enable_output(mpd.conn, uint_buf);
                else
                    mpd_run_disable_output(mpd.conn, uint_buf);
            }
            break;
        case MPD_API_SET_VOLUME:
            if(sscanf(c->content, "MPD_API_SET_VOLUME,%ud", &uint_buf) && uint_buf <= 100)
                mpd_run_set_volume(mpd.conn, uint_buf);
            break;
        case MPD_API_SET_SEEK:
            if(sscanf(c->content, "MPD_API_SET_SEEK,%u,%u", &uint_buf, &uint_buf_2))
                mpd_run_seek_id(mpd.conn, uint_buf, uint_buf_2);
            break;
        case MPD_API_GET_QUEUE:
            if(sscanf(c->content, "MPD_API_GET_QUEUE,%u", &uint_buf))
                n = mpd_put_queue(mpd.buf, uint_buf);
            break;
        case MPD_API_GET_BROWSE:
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_GET_BROWSE"))
                goto out_browse;

            uint_buf = strtoul(strtok(NULL, ","), NULL, 10);
            if((token = strtok(NULL, ",")) == NULL)
                goto out_browse;

			free(p_charbuf);
            p_charbuf = strdup(c->content);
            n = mpd_put_browse(mpd.buf, get_arg2(p_charbuf), uint_buf);
out_browse:
			free(p_charbuf);
            break;
        case MPD_API_ADD_TRACK:
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_ADD_TRACK"))
                goto out_add_track;

            if((token = strtok(NULL, ",")) == NULL)
                goto out_add_track;

			free(p_charbuf);
            p_charbuf = strdup(c->content);
            mpd_run_add(mpd.conn, get_arg1(p_charbuf));
out_add_track:
            free(p_charbuf);
            break;
        case MPD_API_ADD_PLAY_TRACK:
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_ADD_PLAY_TRACK"))
                goto out_play_track;

            if((token = strtok(NULL, ",")) == NULL)
                goto out_play_track;

			free(p_charbuf);
            p_charbuf = strdup(c->content);
            int_buf = mpd_run_add_id(mpd.conn, get_arg1(p_charbuf));
            if(int_buf != -1)
                mpd_run_play_id(mpd.conn, int_buf);
out_play_track:
            free(p_charbuf);
            break;
        case MPD_API_ADD_PLAYLIST:
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_ADD_PLAYLIST"))
                goto out_playlist;

            if((token = strtok(NULL, ",")) == NULL)
                goto out_playlist;

			free(p_charbuf);
            p_charbuf = strdup(c->content);
            mpd_run_load(mpd.conn, get_arg1(p_charbuf));
out_playlist:
            free(p_charbuf);
            break;
        case MPD_API_SAVE_QUEUE:
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_SAVE_QUEUE"))
                goto out_save_queue;

            if((token = strtok(NULL, ",")) == NULL)
                goto out_save_queue;

			free(p_charbuf);
            p_charbuf = strdup(c->content);
            mpd_run_save(mpd.conn, get_arg1(p_charbuf));
out_save_queue:
            free(p_charbuf);
            break;
        case MPD_API_SEARCH:
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_SEARCH"))
				goto out_search;

            if((token = strtok(NULL, ",")) == NULL)
                goto out_search;

			free(p_charbuf);
            p_charbuf = strdup(c->content);
            n = mpd_search(mpd.buf, get_arg1(p_charbuf));
out_search:
            free(p_charbuf);
            break;
#ifdef WITH_MPD_HOST_CHANGE
        /* Commands allowed when disconnected from MPD server */
        case MPD_API_SET_MPDHOST:
            int_buf = 0;
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_SET_MPDHOST"))
                goto out_host_change;

            if((int_buf = strtol(strtok(NULL, ","), NULL, 10)) <= 0)
                goto out_host_change;

            if((token = strtok(NULL, ",")) == NULL)
                goto out_host_change;

            strncpy(mpd.host, token, sizeof(mpd.host));
            mpd.port = int_buf;
            mpd.conn_state = MPD_RECONNECT;
            free(p_charbuf);
            return MG_TRUE;
out_host_change:
            free(p_charbuf);
            break;
        case MPD_API_GET_MPDHOST:
            n = snprintf(mpd.buf, MAX_SIZE, "{\"type\":\"mpdhost\", \"data\": "
                "{\"host\" : \"%s\", \"port\": \"%d\", \"passwort_set\": %s}"
                "}", mpd.host, mpd.port, mpd.password ? "true" : "false");
            break;
        case MPD_API_GET_DIRBLEAPITOKEN:
            n = snprintf(mpd.buf, MAX_SIZE, "{\"type\":\"dirbleapitoken\", \""
                "data\": \"%s\"}", dirble_api_token);
            break;
        case MPD_API_SET_MPDPASS:
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_SET_MPDPASS"))
                goto out_set_pass;

            if((token = strtok(NULL, ",")) == NULL)
                goto out_set_pass;

            if(mpd.password)
                free(mpd.password);

            mpd.password = strdup(token);
            mpd.conn_state = MPD_RECONNECT;
            free(p_charbuf);
            return MG_TRUE;
out_set_pass:
            free(p_charbuf);
            break;
#endif
    }

    if(mpd.conn_state == MPD_CONNECTED && mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS)
    {
        n = snprintf(mpd.buf, MAX_SIZE, "{\"type\":\"error\", \"data\": \"%s\"}", 
            mpd_connection_get_error_message(mpd.conn));

        /* Try to recover error */
        if (!mpd_connection_clear_error(mpd.conn))
            mpd.conn_state = MPD_FAILURE;
    }

    if(n > 0)
        mg_websocket_write(c, 1, mpd.buf, n);

    return MG_TRUE;
}
Esempio n. 19
0
void mpd_poll(struct mg_server *s)
{
    switch (mpd.conn_state) {
        case MPD_DISCONNECTED:
            /* Try to connect */
            fprintf(stdout, "MPD Connecting to %s:%d\n", mpd.host, mpd.port);
            mpd.conn = mpd_connection_new(mpd.host, mpd.port, 3000);
            if (mpd.conn == NULL) {
                fprintf(stderr, "Out of memory.");
                mpd.conn_state = MPD_FAILURE;
                return;
            }

            if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS) {
                fprintf(stderr, "MPD connection: %s\n", mpd_connection_get_error_message(mpd.conn));
                for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c))
                {
                    c->callback_param = (void *)mpd_connection_get_error_message(mpd.conn);
                    mpd_notify_callback(c, MG_POLL);
                }
                mpd.conn_state = MPD_FAILURE;
                return;
            }

            if(mpd.password && !mpd_run_password(mpd.conn, mpd.password))
            {
                fprintf(stderr, "MPD connection: %s\n", mpd_connection_get_error_message(mpd.conn));
                for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c))
                {
                    c->callback_param = (void *)mpd_connection_get_error_message(mpd.conn);
                    mpd_notify_callback(c, MG_POLL);
                }
                mpd.conn_state = MPD_FAILURE;
                return;
            }

            fprintf(stderr, "MPD connected.\n");
            mpd_connection_set_timeout(mpd.conn, 10000);
            mpd.conn_state = MPD_CONNECTED;
            /* write outputs */
            mpd.buf_size = mpd_put_outputs(mpd.buf, 1);
            for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c))
            {
                c->callback_param = NULL;
                mpd_notify_callback(c, MG_POLL);
            }
            break;

        case MPD_FAILURE:
            fprintf(stderr, "MPD connection failed.\n");

        case MPD_DISCONNECT:
        case MPD_RECONNECT:
            if(mpd.conn != NULL)
                mpd_connection_free(mpd.conn);
            mpd.conn = NULL;
            mpd.conn_state = MPD_DISCONNECTED;
            break;

        case MPD_CONNECTED:
            mpd.buf_size = mpd_put_state(mpd.buf, &mpd.song_id, &mpd.queue_version);
            for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c))
            {
                c->callback_param = NULL;
                mpd_notify_callback(c, MG_POLL);
            }
            mpd.buf_size = mpd_put_outputs(mpd.buf, 0);
            for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c))
            {
                c->callback_param = NULL;
                mpd_notify_callback(c, MG_POLL);
            }
            break;
    }
}
Esempio n. 20
0
int callback_mpd(struct mg_connection *c)
{
    enum mpd_cmd_ids cmd_id = get_cmd_id(c->content);
    size_t n = 0;
    unsigned int uint_buf, uint_buf_2;
    int int_buf;
    char *p_charbuf = NULL;

    if(cmd_id == -1)
        return MG_CLIENT_CONTINUE;

    if(mpd.conn_state != MPD_CONNECTED && cmd_id != MPD_API_SET_MPDHOST &&
        cmd_id != MPD_API_GET_MPDHOST && cmd_id != MPD_API_SET_MPDPASS)
        return MG_CLIENT_CONTINUE;

    mpd_connection_set_timeout(mpd.conn, 10000);
    switch(cmd_id)
    {
        case MPD_API_UPDATE_DB:
            mpd_run_update(mpd.conn, NULL);
            break;
        case MPD_API_SET_PAUSE:
            mpd_run_toggle_pause(mpd.conn);
            break;
        case MPD_API_SET_PREV:
            mpd_run_previous(mpd.conn);
            break;
        case MPD_API_SET_NEXT:
            mpd_run_next(mpd.conn);
            break;
        case MPD_API_SET_PLAY:
            mpd_run_play(mpd.conn);
            break;
        case MPD_API_SET_STOP:
            mpd_run_stop(mpd.conn);
            break;
        case MPD_API_RM_ALL:
            mpd_run_clear(mpd.conn);
            break;
        case MPD_API_RM_TRACK:
            if(sscanf(c->content, "MPD_API_RM_TRACK,%u", &uint_buf))
                mpd_run_delete_id(mpd.conn, uint_buf);
            break;
        case MPD_API_PLAY_TRACK:
            if(sscanf(c->content, "MPD_API_PLAY_TRACK,%u", &uint_buf))
                mpd_run_play_id(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_RANDOM:
            if(sscanf(c->content, "MPD_API_TOGGLE_RANDOM,%u", &uint_buf))
                mpd_run_random(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_REPEAT:
            if(sscanf(c->content, "MPD_API_TOGGLE_REPEAT,%u", &uint_buf))
                mpd_run_repeat(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_CONSUME:
            if(sscanf(c->content, "MPD_API_TOGGLE_CONSUME,%u", &uint_buf))
                mpd_run_consume(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_SINGLE:
            if(sscanf(c->content, "MPD_API_TOGGLE_SINGLE,%u", &uint_buf))
                mpd_run_single(mpd.conn, uint_buf);
            break;
        case MPD_API_SET_VOLUME:
            if(sscanf(c->content, "MPD_API_SET_VOLUME,%ud", &uint_buf) && uint_buf <= 100)
                mpd_run_set_volume(mpd.conn, uint_buf);
            break;
        case MPD_API_SET_SEEK:
            if(sscanf(c->content, "MPD_API_SET_SEEK,%u,%u", &uint_buf, &uint_buf_2))
                mpd_run_seek_id(mpd.conn, uint_buf, uint_buf_2);
            break;
        case MPD_API_GET_QUEUE:
            if(sscanf(c->content, "MPD_API_GET_QUEUE,%u", &uint_buf))
                n = mpd_put_queue(mpd.buf, uint_buf);
            break;
        case MPD_API_GET_BROWSE:
            if(sscanf(c->content, "MPD_API_GET_BROWSE,%u,%m[^\t\n]", &uint_buf, &p_charbuf) && p_charbuf != NULL)
            {
                n = mpd_put_browse(mpd.buf, p_charbuf, uint_buf);
                free(p_charbuf);
            }
            break;
        case MPD_API_ADD_TRACK:
            if(sscanf(c->content, "MPD_API_ADD_TRACK,%m[^\t\n]", &p_charbuf) && p_charbuf != NULL)
            {
                mpd_run_add(mpd.conn, p_charbuf);
                free(p_charbuf);
            }
            break;
        case MPD_API_ADD_PLAY_TRACK:
            if(sscanf(c->content, "MPD_API_ADD_PLAY_TRACK,%m[^\t\n]", &p_charbuf) && p_charbuf != NULL)
            {
                int_buf = mpd_run_add_id(mpd.conn, p_charbuf);
                if(int_buf != -1)
                    mpd_run_play_id(mpd.conn, int_buf);
                free(p_charbuf);
            }
            break;
        case MPD_API_ADD_PLAYLIST:
            if(sscanf(c->content, "MPD_API_ADD_PLAYLIST,%m[^\t\n]", &p_charbuf) && p_charbuf != NULL)
            {
                mpd_run_load(mpd.conn, p_charbuf);
                free(p_charbuf);
            }
            break;
        case MPD_API_SEARCH:
            if(sscanf(c->content, "MPD_API_SEARCH,%m[^\t\n]", &p_charbuf) && p_charbuf != NULL)
            {
                n = mpd_search(mpd.buf, p_charbuf);
                free(p_charbuf);
            }
            break;
#ifdef WITH_MPD_HOST_CHANGE
        /* Commands allowed when disconnected from MPD server */
        case MPD_API_SET_MPDHOST:
            int_buf = 0;
            if(sscanf(c->content, "MPD_API_SET_MPDHOST,%d,%m[^\t\n ]", &int_buf, &p_charbuf) && 
                p_charbuf != NULL && int_buf > 0)
            {
                strncpy(mpd.host, p_charbuf, sizeof(mpd.host));
                free(p_charbuf);
                mpd.port = int_buf;
                mpd.conn_state = MPD_RECONNECT;
                return MG_CLIENT_CONTINUE;
            }
            break;
        case MPD_API_GET_MPDHOST:
            n = snprintf(mpd.buf, MAX_SIZE, "{\"type\":\"mpdhost\", \"data\": "
                "{\"host\" : \"%s\", \"port\": \"%d\", \"passwort_set\": %s}"
                "}", mpd.host, mpd.port, mpd.password ? "true" : "false");
            break;
        case MPD_API_SET_MPDPASS:
            if(sscanf(c->content, "MPD_API_SET_MPDPASS,%m[^\t\n ]", &p_charbuf))
            {
                if(mpd.password)
                    free(mpd.password);

                mpd.password = p_charbuf;
                mpd.conn_state = MPD_RECONNECT;
                return MG_CLIENT_CONTINUE;
            }
            break;
#endif
    }

    if(mpd.conn_state == MPD_CONNECTED && mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS)
    {
        n = snprintf(mpd.buf, MAX_SIZE, "{\"type\":\"error\", \"data\": \"%s\"}", 
            mpd_connection_get_error_message(mpd.conn));

        /* Try to recover error */
        if (!mpd_connection_clear_error(mpd.conn))
            mpd.conn_state = MPD_FAILURE;
    }

    if(n > 0)
        mg_websocket_write(c, 1, mpd.buf, n);

    return MG_CLIENT_CONTINUE;
}
Esempio n. 21
0
void MpdWidget::psMpdHB()
{

	timerMpd->stop();


	QString dataSender, dataVol, dataTitle;

	struct mpd_connection *conn;
	struct mpd_status * status;
	struct mpd_song *song;
//	const struct mpd_audio_format *audio_format;

	conn = mpd_connection_new(NULL, 0, 30000);


	if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
	{
		timerMpd->start();
		return;
	}

	if (aktPlay)
	{
		aktPlay = false;
		mpd_send_command(conn, "play", NULL);
		timerMpd->start();
		return;
	}

	if (aktStop)
	{
		aktStop = false;
		mpd_send_command(conn, "stop", NULL);
		timerMpd->start();
		return;
	}


	mpd_command_list_begin(conn, true);
	mpd_send_status(conn);
	mpd_send_current_song(conn);
	mpd_command_list_end(conn);


// Status
	status = mpd_recv_status(conn);
	if (status == NULL)
	{
		timerMpd->start();
		return ;
	}



// Volume
	dataVol.number(mpd_status_get_volume(status));
	if (labelVol->text().compare(dataVol) != 0)
		labelVol->setText(dataVol);

	if (mpd_status_get_error(status) != NULL)
		new QListWidgetItem(QString("status error: %1").
				arg(mpd_status_get_error(status)));



	mpd_status_free(status);
// Status

	mpd_response_next(conn);

// Song
	song = mpd_recv_song(conn);
	if (song == NULL)
	{
		handle_error(conn);
		timerMpd->start();
		return ;
	}


// Title
	dataTitle = mpd_song_get_uri(song);
	if (labelTitle->text().compare(dataTitle) != 0)
		labelTitle->setText(dataTitle);




	unsigned int i = 0;
	QString value;

	while ((value = mpd_song_get_tag(song, MPD_TAG_TITLE, i++)) != NULL)
	{
		if (i > 0)
			dataSender.append("  ");
		dataSender.append(value);
	}

	if (labelSender->text().compare(dataSender) != 0)
	{
		labelSender->setText(dataSender);
		qDebug() << "refresh";
	}

	mpd_song_free(song);
// Song

	mpd_connection_free(conn);

	timerMpd->start();
}
Esempio n. 22
0
/* Execute the given command. In fact, it just will ask MPD to do it.
 * You will have to check the next "status" or "playlist" update (using the corresponding slot)
 * to know if the command has really been executed.
 */
void Player::executeCmd(EMSPlayerCmd cmd)
{
    bool waitResponse = true; /* Wait the responase by default */
    bool error = false;

    if (conn == NULL)
    {
        return;
    }

    /* Dispatch execution depending on the action */
    switch (cmd.action)
    {
        case ACTION_ADD:
        {
            if(searchTrackInPlaylist(cmd.track) >= 0)
            {
                qDebug() << "Do not add track in the playlist as it already exist";
                return;
            }
            QString filename = getMPDFilename(cmd.track);
            mpd_send_add(conn, filename.toStdString().c_str());
            break;
        }
        case ACTION_DEL:
        {
            int pos = searchTrackInPlaylist(cmd.track);
            if (pos >= 0)
            {
                mpd_send_delete(conn, pos);
            }
            break;
        }
        case ACTION_DEL_ALL:
        {
            mpd_send_clear(conn);
            break;
        }
        case ACTION_PLAY_POS:
        {
            mutex.lock();
            int size = playlist.tracks.size();
            mutex.unlock();
            if (size <= 0 || cmd.uintValue >= (unsigned int)size)
            {
                qDebug() << "Asked to play a track after the end of the current playlist";
                error = true;
                break;
            }
            mpd_send_play_pos(conn, cmd.uintValue);
            break;
        }
        case ACTION_PLAY_TRACK:
        {
            int position = searchTrackInPlaylist(cmd.track);
            if (position < 0)
            {
                qDebug() << "Asked to play a track which is not in the current playlist";
                error = true;
                break;
            }
            mpd_send_play_pos(conn, position);
            break;
        }
        case ACTION_PLAY:
        {
            mpd_send_play(conn);
            break;
        }
        case ACTION_SEEK:
        {
            /* Get current position */
            int songId = getCurrentPos();
            if (songId >= 0)
            {
                mpd_send_seek_pos(conn, songId, cmd.uintValue);
            }
            break;
        }
        case ACTION_PAUSE:
        {
            mpd_send_pause(conn, true);
            break;
        }
        case ACTION_TOGGLE:
        {
            mpd_send_toggle_pause(conn);
            break;
        }
        case ACTION_STOP:
        {
            mpd_send_stop(conn);
            break;
        }
        case ACTION_NEXT:
        {
            mpd_send_next(conn);
            break;
        }
        case ACTION_PREV:
        {
            mpd_send_previous(conn);
            break;
        }
        case ACTION_REPEAT:
        {
            mutex.lock();
            bool repeatTmp = status.repeat;
            mutex.unlock();
            if (cmd.boolValue != repeatTmp)
            {
                mpd_send_repeat(conn, cmd.boolValue);
            }
            break;
        }
        case ACTION_RANDOM:
        {
            mutex.lock();
            bool randomTmp = status.random;
            mutex.unlock();
            if (cmd.boolValue != randomTmp)
            {
                mpd_send_random(conn, cmd.boolValue);
            }
            break;
        }
        case ACTION_ENABLE_OUTPUT:
        {
            if (cmd.uintValue >= 1)
            {
                mpd_send_enable_output(conn, cmd.uintValue-1);
            }
            break;
        }
        case ACTION_DISABLE_OUTPUT:
        {
            if (cmd.uintValue >= 1)
            {
                mpd_send_disable_output(conn, cmd.uintValue-1);
            }
            break;
        }
        default:
        {
            qCritical() << "Unhandled action in the current command.";
            waitResponse = false;
            break;
        }
    }

    if (waitResponse && !mpd_response_finish(conn))
    {
        error = true;
        qCritical() << "MPD could not execute the current command.";
        enum mpd_error errorMpd = mpd_connection_get_error(conn);
        if (errorMpd == MPD_ERROR_SERVER ||
            errorMpd == MPD_ERROR_ARGUMENT) /* Problem with the command */
        {
            QString errorMessage = QString::fromUtf8(mpd_connection_get_error_message(conn));
            qCritical() << "Command error : " << errorMessage;
            if (!mpd_connection_clear_error(conn))
            {
                qCritical() << "This error cannot be cleared, reconnecting...";
                connectToMpd();
            }

        }
        else if (errorMpd == MPD_ERROR_TIMEOUT ||
                 errorMpd == MPD_ERROR_RESOLVER ||
                 errorMpd == MPD_ERROR_MALFORMED ||
                 errorMpd == MPD_ERROR_CLOSED ) /* Assume there is a connection problem, try to reconnect... */
        {
            QString errorMessage = QString::fromUtf8(mpd_connection_get_error_message(conn));
            qCritical() << "Connexion error : " << errorMessage;
            qCritical() << "Reconnecting...";
            connectToMpd();
            mutex.lock();
            queue.push_front(cmd);
            mutex.unlock();
            cmdAvailable.release(1);
        }
    }

    /* Post-action depending on the command
     * Do the minimum here as the whole status will be
     * retrieve here. But for playlist ADD/DEL, we need to
     * store the EMSTrack structure.
     */
    if(!error)
    {
        switch (cmd.action)
        {
            case ACTION_ADD:
            {
                EMSPlaylist newPlaylist;
                mutex.lock();
                playlist.tracks.append(cmd.track);
                newPlaylist = playlist;
                mutex.unlock();
                emit playlistChanged(newPlaylist);
                break;
            }
            case ACTION_DEL:
            {
                int pos = searchTrackInPlaylist(cmd.track);
                if (pos >= 0)
                {
                    EMSPlaylist newPlaylist;
                    mutex.lock();
                    playlist.tracks.removeAt(pos);
                    newPlaylist = playlist;
                    mutex.unlock();
                    emit playlistChanged(newPlaylist);
                }
                break;
            }
            case ACTION_DEL_ALL:
            {
                EMSPlaylist newPlaylist;
                mutex.lock();
                playlist.tracks.clear();
                newPlaylist = playlist;
                mutex.unlock();
                emit playlistChanged(newPlaylist);
                break;
            }
            case ACTION_ENABLE_OUTPUT:
            {
                mutex.lock();
                for(int i=0; i<outputs.size(); i++)
                {
                    if (outputs.at(i).id_mpd == cmd.uintValue)
                    {
                        EMSSndCard card = outputs.at(i);
                        card.enabled = true;
                        outputs.replace(i, card);
                    }
                }
                emit outputsChanged(outputs);
                mutex.unlock();
                break;
            }
            case ACTION_DISABLE_OUTPUT:
            {
                mutex.lock();
                for(int i=0; i<outputs.size(); i++)
                {
                    if (outputs.at(i).id_mpd == cmd.uintValue)
                    {
                        EMSSndCard card = outputs.at(i);
                        card.enabled = false;
                        outputs.replace(i, card);
                    }
                }
                emit outputsChanged(outputs);
                mutex.unlock();
                break;
            }
            default:
                break;
        }
    }
}
Esempio n. 23
0
/* Establish a connection with the MPD server
 * If the connection failed, the "conn" is set to NULL
 */
void Player::connectToMpd()
{
    QSettings settings;
    unsigned int retryPeriod;
    QString host;
    unsigned int port;
    unsigned int timeout;
    QString password;

    EMS_LOAD_SETTINGS(retryPeriod, "player/retry_period", EMS_MPD_CONNECTION_RETRY_PERIOD, UInt);
    EMS_LOAD_SETTINGS(host, "player/host", EMS_MPD_IP, String);
    EMS_LOAD_SETTINGS(timeout, "player/timeout", EMS_MPD_TIMEOUT, UInt);
    EMS_LOAD_SETTINGS(port, "player/port", EMS_MPD_PORT, UInt);
    EMS_LOAD_SETTINGS(password, "player/password", EMS_MPD_PASSWORD, String);

    if (conn != NULL)
    {
        disconnectToMpd();
    }

    /* Try to connect until it success */
    while (!conn && !isInterruptionRequested())
    {
        qDebug() << "Connecting to " << QString("%1:%2... (timeout %3ms)").arg(host).arg(port).arg(timeout);
        conn = mpd_connection_new(host.toStdString().c_str(), port, timeout);

        if (conn == NULL)
        {
            qCritical() << "MPD Connection failed.";
        }
        else if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
        {
            QString errorMessage = QString::fromUtf8(mpd_connection_get_error_message(conn));
            qCritical() << "MPD Connection failed : " << errorMessage;
            mpd_connection_free(conn);
            conn = NULL;
        }
        else if (!password.isEmpty())
        {
            qDebug() << "Setting password...";
            if (!mpd_run_password(conn, password.toStdString().c_str()))
            {
                qCritical() << "Setting MPD password failed.";
                mpd_connection_free(conn);
                conn = NULL;
            }
        }

        if (!conn)
        {
            qCritical() << "Retrying within " << QString("%1 ms").arg(retryPeriod);
            for (unsigned int i=0; i<retryPeriod; i++)
            {
                if (!isInterruptionRequested())
                    usleep(1000);
                else
                    break;
            }
        }
    }

    qDebug() << "Connected to " << host;
}
Esempio n. 24
0
/*
 * Returns: 0 - error; 1 - ok 
 */
int mgr_mpd_fetch_status( struct mpd_connection *conn, int dump_status ) {
	struct mpd_status *status;
	struct mpd_stats *stats;

        if (DEBUG > 1)
                fprintf(stderr, "DEBUG: [mgr-thread] mpd: -status fetching...\n");

	if (conn == NULL) {
                fprintf(stderr, "ERROR: MPD: Unable to retrieve the MPD status: not connected\n");
		return 0;
	}

	if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) {
                fprintf(stderr, "ERROR: MPD: Unable to retrieve MPD status: connection error\n");
		return 0;
	}

	if (DEBUG > 1)
		fprintf(stderr, "DEBUG: [mgr-thread] mpd: run status\n");

	status = mpd_run_status(conn);
	if (!status) {
                fprintf(stderr, "ERROR: MPD: Unable to retrieve MPD status\n");
		return 0;
	}

	cur_mpd_player_status = mpd_status_get_state(status);

	if (DEBUG > 1) {
		fprintf(stderr, "DEBUG: [mgr-thread] mpd: +status received:\n");
	}


	if (DEBUG && dump_status) {
		fprintf(stderr, "DEBUG: [mgr-thread] mpd status: => mode      : %s\n", (cur_mpd_player_status == MPD_STATE_PLAY ? "Play" : "Other"));
		fprintf(stderr, "DEBUG: [mgr-thread] mpd status: => random    : %d\n", mpd_status_get_random(status));
		fprintf(stderr, "DEBUG: [mgr-thread] mpd status: => repeat    : %d\n", mpd_status_get_random(status));
		fprintf(stderr, "DEBUG: [mgr-thread] mpd status: => volume    : %d\n", mpd_status_get_volume(status));
		fprintf(stderr, "DEBUG: [mgr-thread] mpd status: => queue ver : %d\n", mpd_status_get_queue_version(status));
		fprintf(stderr, "DEBUG: [mgr-thread] mpd status: => queue len : %d\n", mpd_status_get_queue_length(status));
	}

	cur_mpd_random = mpd_status_get_random(status) ? 1 : 0;
	cur_mpd_volume = mpd_status_get_volume(status);
	cur_mpd_status_queue_len = mpd_status_get_queue_length(status);

	if (DEBUG > 1)
		fprintf(stderr, "DEBUG: [mgr-thread] mpd: release status\n");

	if (mpd_status_get_error(status) != NULL) {
		fprintf(stderr, "WARNING: MPD: Error Received from MPD: %s\n", mpd_status_get_error(status));
		// TODO - clear error
	}

	mpd_status_free(status);
	mpd_response_finish(conn);

	stats = mpd_run_stats(conn);
	if (stats == NULL) {
                fprintf(stderr, "ERROR: MPD: Unable to retrieve MPD statistics\n");
		return 0;
	}

	cur_mpd_stats_number_of_songs = mpd_stats_get_number_of_songs( stats );
	if (DEBUG && dump_status) {
		fprintf(stderr, "DEBUG: [mgr-thread] mpd stats : => # of songs: %d\n", cur_mpd_stats_number_of_songs);
	}

	mpd_stats_free( stats );

	return 1;
}
Esempio n. 25
0
/**
 * Return the success or error status of the last MPD command sent.
 */
bool
Control::get_error_bool()
{
	return (mpd_connection_get_error(conn->h()) == MPD_ERROR_SUCCESS);
}
Esempio n. 26
0
File: db.c Progetto: cykerway/ncmpcr
/* fetch a new db tree on root */
static int fetch_db_tree(DB_NODE **p_root,struct mpd_connection *conn)
{
    if (*p_root)
        return 1;

    /* create root */
    DB_NODE *root = (DB_NODE*)malloc(sizeof(DB_NODE));
    root->type = DB_DIRECTORY;
    /* use calloc for root->uri to ease free_db_tree() */
    root->uri = (char *)calloc(2,sizeof(char));
    strncpy(root->uri,"/",1);
    root->rating = 0;
    root->duration = 0;
    root->p = NULL;
    root->s = NULL;
    root->c = NULL;
    root->num_c = 0;

    /* set top node */
    DB_NODE *top = root;

	if (!mpd_send_list_all_meta(conn,"/")) {
        clear_or_exit_on_error(conn);
        return 1;
    }

    /* add nodes recursively */
    struct mpd_entity *entity;
	while ((entity = mpd_recv_entity(conn))) {

        DB_NODE *node = (DB_NODE*)malloc(sizeof(DB_NODE));

        const char *name = NULL;
        switch (mpd_entity_get_type(entity)) {
            case MPD_ENTITY_TYPE_DIRECTORY:
                node->type = DB_DIRECTORY;

                name = mpd_directory_get_path(mpd_entity_get_directory(entity));
                assert (name && strlen(name));
                node->uri = (char *)calloc(strlen(name)+1,sizeof(char));
                strncpy(node->uri,name,strlen(name));

                node->rating = 0;
                node->duration = 0;
                break;
            case MPD_ENTITY_TYPE_SONG:
                node->type = DB_SONG;

                name = mpd_song_get_uri(mpd_entity_get_song(entity));
                assert (name && strlen(name));
                node->uri = (char *)calloc(strlen(name)+1,sizeof(char));
                strncpy(node->uri,name,strlen(name));

                node->rating = 0;
                node->duration = mpd_song_get_duration(mpd_entity_get_song(entity));
                break;
            case MPD_ENTITY_TYPE_PLAYLIST:
                node->type = DB_PLAYLIST;

                name = mpd_playlist_get_path(mpd_entity_get_playlist(entity));
                assert (name && strlen(name));
                node->uri = (char *)calloc(strlen(name)+1,sizeof(char));
                strncpy(node->uri,name,strlen(name));

                node->rating = 0;
                node->duration = 0;
                break;
            case MPD_ENTITY_TYPE_UNKNOWN:
                break;
        }

        /* backtrace top until it's parent of node */
        while (top != root && !(strstr(node->uri,top->uri) && node->uri[strlen(top->uri)] == '/'))
            top = top->p;

        /* if current top already has chlidren */
        if (top->c) {
            DB_NODE *node2 = top->c;
            /* find the last child */
            while (node2->s)
                node2 = node2->s;
            node2->s = node;
            node->p = node2->p;
            node->p->num_c++;
        } else {
            top->c = node;
            node->p = top;
            node->p->num_c++;
        }
        /* no child, no next sibling */
        node->c = NULL;
        node->s = NULL;
        node->num_c = 0;

        /* update top node */
        if (node->type == DB_DIRECTORY)
            top = node;

		mpd_entity_free(entity);
	}
    if (mpd_connection_get_error(conn) == MPD_ERROR_SUCCESS)
        mpd_response_finish(conn);
    else if (!mpd_connection_clear_error(conn))
        exit_on_error(conn);

    *p_root = root;
    return 0;
}
Esempio n. 27
0
/*
 * pgmpc_playlist
 * List all songs in given playlist. If not playlist is specified list
 * songs of current playlist.
 */
Datum
pgmpc_playlist(PG_FUNCTION_ARGS)
{
	TupleDesc   tupdesc;
	Tuplestorestate *tupstore;
	char *playlist = NULL;
	bool ret;

	if (PG_NARGS() == 1 && !PG_ARGISNULL(0))
		playlist = text_to_cstring(PG_GETARG_TEXT_PP(0));

	/* Initialize function context */
	pgmpc_init_setof_single(fcinfo, TEXTOID, "playlist", &tupdesc, &tupstore);

	/*
	 * Run the command to get all the songs.
	 */
	pgmpc_init();
	ret = playlist ?
		mpd_send_list_playlist_meta(mpd_conn, playlist) :
		mpd_send_list_queue_meta(mpd_conn);
	if (!ret)
		pgmpc_print_error();

	/* Now get all the songs and send them back to caller */
	while (true)
	{
		Datum       values[1];
		bool		nulls[1];
		struct mpd_song *song = mpd_recv_song(mpd_conn);

		/* Leave if done */
		if (song == NULL)
			break;

		/* Assign song name */
		nulls[0] = false;
		values[0] = CStringGetTextDatum(mpd_song_get_uri(song));

		/* Save values */
		tuplestore_putvalues(tupstore, tupdesc, values, nulls);

		/* Clean up for the next one */
		mpd_song_free(song);
	}

	/* We may be in error state, so check for it */
	if (mpd_connection_get_error(mpd_conn) != MPD_ERROR_SUCCESS)
	{
		const char *message = mpd_connection_get_error_message(mpd_conn);
		pgmpc_reset();
		ereport(ERROR,
				(errcode(ERRCODE_SYSTEM_ERROR),
				 errmsg("mpd command failed: %s",
						message)));
	}

	/* Clean up */
	pgmpc_reset();

	/* clean up and return the tuplestore */
	tuplestore_donestoring(tupstore);

	return (Datum) 0;
}
Esempio n. 28
0
int main(int argc, char ** argv) {
	struct mpd_connection *conn;

	conn = mpd_connection_new(NULL, 0, 30000);

	if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
		return handle_error(conn);

	{
		int i;
		for(i=0;i<3;i++) {
			printf("version[%i]: %i\n",i,
			       mpd_connection_get_server_version(conn)[i]);
		}
	}

	if(argc==1) {
		struct mpd_status * status;
		struct mpd_song *song;
		const struct mpd_audio_format *audio_format;

		mpd_command_list_begin(conn, true);
		mpd_send_status(conn);
		mpd_send_current_song(conn);
		mpd_command_list_end(conn);

		status = mpd_recv_status(conn);
		if (status == NULL)
			return handle_error(conn);

		printf("volume: %i\n", mpd_status_get_volume(status));
		printf("repeat: %i\n", mpd_status_get_repeat(status));
		printf("queue version: %u\n", mpd_status_get_queue_version(status));
		printf("queue length: %i\n", mpd_status_get_queue_length(status));
		if (mpd_status_get_error(status) != NULL)
			printf("error: %s\n", mpd_status_get_error(status));

		if (mpd_status_get_state(status) == MPD_STATE_PLAY ||
		    mpd_status_get_state(status) == MPD_STATE_PAUSE) {
			printf("song: %i\n", mpd_status_get_song_pos(status));
			printf("elaspedTime: %i\n",mpd_status_get_elapsed_time(status));
			printf("elasped_ms: %u\n", mpd_status_get_elapsed_ms(status));
			printf("totalTime: %i\n", mpd_status_get_total_time(status));
			printf("bitRate: %i\n", mpd_status_get_kbit_rate(status));
		}

		audio_format = mpd_status_get_audio_format(status);
		if (audio_format != NULL) {
			printf("sampleRate: %i\n", audio_format->sample_rate);
			printf("bits: %i\n", audio_format->bits);
			printf("channels: %i\n", audio_format->channels);
		}

		mpd_status_free(status);

		if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
			return handle_error(conn);

		mpd_response_next(conn);

		while ((song = mpd_recv_song(conn)) != NULL) {
			printf("uri: %s\n", mpd_song_get_uri(song));
			print_tag(song, MPD_TAG_ARTIST, "artist");
			print_tag(song, MPD_TAG_ALBUM, "album");
			print_tag(song, MPD_TAG_TITLE, "title");
			print_tag(song, MPD_TAG_TRACK, "track");
			print_tag(song, MPD_TAG_NAME, "name");
			print_tag(song, MPD_TAG_DATE, "date");

			if (mpd_song_get_duration(song) > 0) {
				printf("time: %u\n", mpd_song_get_duration(song));
			}

			printf("pos: %u\n", mpd_song_get_pos(song));

			mpd_song_free(song);
		}

		if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS ||
		    !mpd_response_finish(conn))
			return handle_error(conn);
	}
	else if(argc==3 && strcmp(argv[1],"lsinfo")==0) {
		struct mpd_entity * entity;

		if (!mpd_send_list_meta(conn, argv[2]))
			return handle_error(conn);

		while ((entity = mpd_recv_entity(conn)) != NULL) {
			const struct mpd_song *song;
			const struct mpd_directory *dir;
			const struct mpd_playlist *pl;

			switch (mpd_entity_get_type(entity)) {
			case MPD_ENTITY_TYPE_UNKNOWN:
				break;

			case MPD_ENTITY_TYPE_SONG:
				song = mpd_entity_get_song(entity);
				printf("uri: %s\n", mpd_song_get_uri(song));
				print_tag(song, MPD_TAG_ARTIST, "artist");
				print_tag(song, MPD_TAG_ALBUM, "album");
				print_tag(song, MPD_TAG_TITLE, "title");
				print_tag(song, MPD_TAG_TRACK, "track");
				break;

			case MPD_ENTITY_TYPE_DIRECTORY:
				dir = mpd_entity_get_directory(entity);
				printf("directory: %s\n", mpd_directory_get_path(dir));
				break;

			case MPD_ENTITY_TYPE_PLAYLIST:
				pl = mpd_entity_get_playlist(entity);
				printf("playlist: %s\n",
				       mpd_playlist_get_path(pl));
				break;
			}

			mpd_entity_free(entity);
		}

		if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS ||
		    !mpd_response_finish(conn))
			return handle_error(conn);
	}
	else if(argc==2 && strcmp(argv[1],"artists")==0) {
		struct mpd_pair *pair;

		if (!mpd_search_db_tags(conn, MPD_TAG_ARTIST) ||
		    !mpd_search_commit(conn))
			return handle_error(conn);

		while ((pair = mpd_recv_pair_tag(conn,
						 MPD_TAG_ARTIST)) != NULL) {
			printf("%s\n", pair->value);
			mpd_return_pair(conn, pair);
		}

		if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS ||
		    !mpd_response_finish(conn))
			return handle_error(conn);
	} else if (argc == 2 && strcmp(argv[1], "playlists") == 0) {
		if (!mpd_send_list_playlists(conn))
			return handle_error(conn);

		struct mpd_playlist *playlist;
		while ((playlist = mpd_recv_playlist(conn)) != NULL) {
			printf("%s\n",
			       mpd_playlist_get_path(playlist));
			mpd_playlist_free(playlist);
		}

		if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS ||
		    !mpd_response_finish(conn))
			return handle_error(conn);
	} else if (argc == 2 && strcmp(argv[1], "idle") == 0) {
		enum mpd_idle idle = mpd_run_idle(conn);
		if (idle == 0 &&
		    mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
			return handle_error(conn);

		for (unsigned j = 0;; ++j) {
			enum mpd_idle i = 1 << j;
			const char *name = mpd_idle_name(i);

			if (name == NULL)
				break;

			if (idle & i)
				printf("%s\n", name);
		}
	} else if (argc == 3 && strcmp(argv[1], "subscribe") == 0) {
		/* subscribe to a channel and print all messages */

		if (!mpd_run_subscribe(conn, argv[2]))
			return handle_error(conn);

		while (mpd_run_idle_mask(conn, MPD_IDLE_MESSAGE) != 0) {
			if (!mpd_send_read_messages(conn))
				return handle_error(conn);

			struct mpd_message *msg;
			while ((msg = mpd_recv_message(conn)) != NULL) {
				printf("%s\n", mpd_message_get_text(msg));
				mpd_message_free(msg);
			}

			if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS ||
			    !mpd_response_finish(conn))
				return handle_error(conn);
		}

		return handle_error(conn);
	} else if (argc == 2 && strcmp(argv[1], "channels") == 0) {
		/* print a list of channels */

		if (!mpd_send_channels(conn))
			return handle_error(conn);

		struct mpd_pair *pair;
		while ((pair = mpd_recv_channel_pair(conn)) != NULL) {
			printf("%s\n", pair->value);
			mpd_return_pair(conn, pair);
		}

		if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS ||
		    !mpd_response_finish(conn))
			return handle_error(conn);
	} else if (argc == 4 && strcmp(argv[1], "message") == 0) {
		/* send a message to a channel */

		if (!mpd_run_send_message(conn, argv[2], argv[3]))
			return handle_error(conn);
	}

	mpd_connection_free(conn);

	return 0;
}
/*** main ***/
int main(int argc, char ** argv) {
	char * album = NULL, * artist = NULL, * icon = NULL, * notifystr = NULL, * title = NULL;
	GError * error = NULL;
	unsigned short int errcount = 0, state = MPD_STATE_UNKNOWN;
	const char * mpd_host = MPD_HOST, * music_dir = NULL, * uri = NULL;;
	unsigned mpd_port = MPD_PORT, mpd_timeout = MPD_TIMEOUT;
	struct mpd_song * song = NULL;
	unsigned int i;

	program = argv[0];

	music_dir = getenv("XDG_MUSIC_DIR");

	/* get the verbose status */
	while ((i = getopt_long(argc, argv, optstring, options_long, NULL)) != -1) {
		switch (i) {
			case 'v':
				verbose++;
				break;
		}
	}

	/* reinitialize getopt() by resetting optind to 0 */
	optind = 0;

	/* say hello */
	if (verbose > 0)
		printf("%s: %s v%s (compiled: " __DATE__ ", " __TIME__ ")\n", program, PROGNAME, VERSION);

	/* get command line options */
	while ((i = getopt_long(argc, argv, optstring, options_long, NULL)) != -1) {
		switch (i) {
			case 'h':
				fprintf(stderr, "usage: %s [-h] [-H HOST] [-p PORT] [-m MUSIC-DIR] [-v]\n", program);
				return EXIT_SUCCESS;
			case 'p':
				mpd_port = atoi(optarg);
				if (verbose > 0)
					printf("%s: using port %d\n", program, mpd_port);
				break;
			case 'm':
				music_dir = optarg;
				if (verbose > 0)
					printf("%s: using music-dir %s\n", program, music_dir);
				break;
			case 'H':
				mpd_host = optarg;
				if (verbose > 0)
					printf("%s: using host %s\n", program, mpd_host);
				break;
		}
	}

	/* disable artwork stuff if we are connected to a foreign host */
	if (mpd_host != NULL)
		music_dir = NULL;

	/* change directory to music base directory */
	if (music_dir != NULL) {
		if (chdir(music_dir) == -1) {
			fprintf(stderr, "%s: Can not change directory to '%s'.\n", program, music_dir);
			music_dir = NULL;
		}
	}

	/* libav */
	av_register_all();

	conn = mpd_connection_new(mpd_host, mpd_port, mpd_timeout);

	if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) {
		fprintf(stderr,"%s: %s\n", program, mpd_connection_get_error_message(conn));
		mpd_connection_free(conn);
		exit(EXIT_FAILURE);
	}

	if(notify_init(PROGNAME) == FALSE) {
		fprintf(stderr, "%s: Can't create notify.\n", program);
		exit(EXIT_FAILURE);
	}

	notification =
#		if NOTIFY_CHECK_VERSION(0, 7, 0)
		notify_notification_new(TEXT_TOPIC, TEXT_NONE, ICON_SOUND);
#		else
		notify_notification_new(TEXT_TOPIC, TEXT_NONE, ICON_SOUND, NULL);
#		endif
	notify_notification_set_category(notification, PROGNAME);
	notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL);

	signal(SIGHUP, received_signal);
	signal(SIGINT, received_signal);
	signal(SIGTERM, received_signal);
	signal(SIGUSR1, received_signal);

	while(doexit == 0 && mpd_run_idle_mask(conn, MPD_IDLE_PLAYER)) {
		mpd_command_list_begin(conn, true);
		mpd_send_status(conn);
		mpd_send_current_song(conn);
		mpd_command_list_end(conn);

		state = mpd_status_get_state(mpd_recv_status(conn));
		if (state == MPD_STATE_PLAY) {
			mpd_response_next(conn);

			song = mpd_recv_song(conn);

			uri = mpd_song_get_uri(song);

			if (music_dir != NULL && uri != NULL)
				icon = get_icon(music_dir, uri);

			if (verbose > 0 && icon != NULL)
				printf("%s: found icon: %s\n", program, icon);

			if ((title = g_markup_escape_text(mpd_song_get_tag(song, MPD_TAG_TITLE, 0), -1)) == NULL)
				title = strdup(TEXT_UNKNOWN);
			if ((artist = g_markup_escape_text(mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), -1)) == NULL)
				artist = strdup(TEXT_UNKNOWN);
			if ((album = g_markup_escape_text(mpd_song_get_tag(song, MPD_TAG_ALBUM, 0), -1)) == NULL)
				album = strdup(TEXT_UNKNOWN);

			notifystr = malloc(sizeof(TEXT_PLAY) + strlen(title) + strlen(artist) + strlen(album));
			sprintf(notifystr, TEXT_PLAY, title, artist, album);

			free(title);
			free(artist);
			free(album);

			mpd_song_free(song);
		} else if (state == MPD_STATE_PAUSE)
			notifystr = TEXT_PAUSE;
		else if (state == MPD_STATE_STOP)
			notifystr = TEXT_STOP;
		else
			notifystr = TEXT_UNKNOWN;

		if (verbose > 0)
			printf("%s: %s\n", program, notifystr);

		notify_notification_update(notification, TEXT_TOPIC, notifystr, icon ? icon : ICON_SOUND);

		notify_notification_set_timeout(notification, NOTIFICATION_TIMEOUT);

		while(notify_notification_show(notification, &error) == FALSE) {
			if (errcount > 1) {
				fprintf(stderr, "%s: Looks like we can not reconnect to notification daemon... Exiting.\n", program);
				exit(EXIT_FAILURE);
			} else {
				g_printerr("%s: Error \"%s\" while trying to show notification. Trying to reconnect.\n", program, error->message);
				errcount++;

				g_error_free(error);
				error = NULL;

				notify_uninit();

				usleep(500 * 1000);

				if(notify_init(PROGNAME) == FALSE) {
					fprintf(stderr, "%s: Can't create notify.\n", program);
					exit(EXIT_FAILURE);
				}
			}
		}
		errcount = 0;

		if (state == MPD_STATE_PLAY)
			free(notifystr);
		if (icon != NULL) {
			free(icon);
			icon = NULL;
		}
		mpd_response_finish(conn);
	}

	if (verbose > 0)
		printf("Exiting...\n");

	mpd_connection_free(conn);

	g_object_unref(G_OBJECT(notification));
	notify_uninit();

	return EXIT_SUCCESS;
}