diff options
author | Kalle Wallin <kaw@linux.se> | 2004-06-14 18:32:31 +0000 |
---|---|---|
committer | Kalle Wallin <kaw@linux.se> | 2004-06-14 18:32:31 +0000 |
commit | 39758c8503fb5390afaceeff3dd5b0bca75feb97 (patch) | |
tree | 94f42a18c5cb0da8778e8525ded49fb98012bbfc /src/libmpdclient.c | |
parent | 7844008980d4d1b9cb7cbd4dda4ae912e12dd7a9 (diff) | |
download | mpd-39758c8503fb5390afaceeff3dd5b0bca75feb97.tar.gz mpd-39758c8503fb5390afaceeff3dd5b0bca75feb97.tar.xz mpd-39758c8503fb5390afaceeff3dd5b0bca75feb97.zip |
Major cleanup of the mpd client code (mpc->mpdclient)
git-svn-id: https://svn.musicpd.org/ncmpc/trunk@1481 09075e82-0dd4-0310-85a5-a0d7c8717e4f
Diffstat (limited to 'src/libmpdclient.c')
-rw-r--r-- | src/libmpdclient.c | 270 |
1 files changed, 194 insertions, 76 deletions
diff --git a/src/libmpdclient.c b/src/libmpdclient.c index b61e2d1e9..089e7201f 100644 --- a/src/libmpdclient.c +++ b/src/libmpdclient.c @@ -30,13 +30,7 @@ #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> - -#ifdef HAVE_CONFIG_H -#include "config.h" -#ifndef HAVE_SOCKLEN_T -typedef SOCKLEN_T socklen_t; -#endif -#endif +#include <fcntl.h> #ifndef MPD_NO_IPV6 #ifdef AF_INET6 @@ -44,6 +38,9 @@ typedef SOCKLEN_T socklen_t; #endif #endif +#define COMMAND_LIST 1 +#define COMMAND_LIST_OK 2 + #ifdef MPD_HAVE_IPV6 int mpd_ipv6Supported() { int s; @@ -104,7 +101,11 @@ mpd_Connection * mpd_newConnection(const char * host, int port, float timeout) { int err; struct hostent * he; struct sockaddr * dest; +#ifdef MPD_HAVE_SOCKLEN_T socklen_t destlen; +#else + int destlen; +#endif struct sockaddr_in sin; char * rt; char * output; @@ -121,6 +122,8 @@ mpd_Connection * mpd_newConnection(const char * host, int port, float timeout) { connection->error = 0; connection->doneProcessing = 0; connection->commandList = 0; + connection->listOks = 0; + connection->doneListOk = 0; connection->returnElement = NULL; if(!(he=gethostbyname(host))) { @@ -174,60 +177,22 @@ mpd_Connection * mpd_newConnection(const char * host, int port, float timeout) { return connection; } + mpd_setConnectionTimeout(connection,timeout); + /* connect stuff */ { -#ifdef SO_RCVTIMEO - struct timeval rcvoldto; - struct timeval sndoldto; - socklen_t oldlen = sizeof(struct timeval); + int flags = fcntl(connection->sock, F_GETFL, 0); + fcntl(connection->sock, F_SETFL, flags | O_NONBLOCK); - mpd_setConnectionTimeout(connection,timeout); - - tv.tv_sec = connection->timeout.tv_sec; - tv.tv_usec = connection->timeout.tv_usec; - - if(getsockopt(connection->sock,SOL_SOCKET,SO_RCVTIMEO,&rcvoldto, - &oldlen)<0 || - getsockopt(connection->sock,SOL_SOCKET, - SO_SNDTIMEO,&sndoldto,&oldlen)<0) + if(connect(connection->sock,dest,destlen)<0 && + errno!=EINPROGRESS) { - strcpy(connection->errorStr,"problems getting socket " - "timeout\n"); - connection->error = MPD_ERROR_SYSTEM; - return connection; - } - if(setsockopt(connection->sock,SOL_SOCKET,SO_RCVTIMEO,&tv, - sizeof(struct timeval))<0 || - setsockopt(connection->sock,SOL_SOCKET, - SO_SNDTIMEO,&tv, - sizeof(struct timeval))<0) - { - strcpy(connection->errorStr,"problems setting socket " - "timeout\n"); - connection->error = MPD_ERROR_SYSTEM; - return connection; - } -#endif - if(connect(connection->sock,dest,destlen)<0) { snprintf(connection->errorStr,MPD_BUFFER_MAX_LENGTH, "problems connecting to \"%s\" on port" " %i",host,port); connection->error = MPD_ERROR_CONNPORT; return connection; } -#ifdef SO_RCVTIMEO - if(setsockopt(connection->sock,SOL_SOCKET,SO_SNDTIMEO,&rcvoldto, - sizeof(struct timeval))<0 || - setsockopt(connection->sock,SOL_SOCKET, - SO_SNDTIMEO,&sndoldto, - sizeof(struct timeval))<0) - { - strcpy(connection->errorStr,"problems setting socket " - "timeout\n"); - connection->error = MPD_ERROR_SYSTEM; - return connection; - } -#endif } while(!(rt = strstr(connection->buffer,"\n"))) { @@ -253,7 +218,19 @@ mpd_Connection * mpd_newConnection(const char * host, int port, float timeout) { tv.tv_sec = connection->timeout.tv_sec; tv.tv_usec = connection->timeout.tv_usec; } - else if(err<0 && errno==EINTR) continue; + else if(err<0) { + switch(errno) { + case EINTR: + continue; + default: + snprintf(connection->errorStr, + MPD_BUFFER_MAX_LENGTH, + "problems connecting to \"%s\" on port" + " %i",host,port); + connection->error = MPD_ERROR_CONNPORT; + return connection; + } + } else { snprintf(connection->errorStr,MPD_BUFFER_MAX_LENGTH, "timeout in attempting to get a response from" @@ -380,6 +357,9 @@ void mpd_executeCommand(mpd_Connection * connection, char * command) { } if(!connection->commandList) connection->doneProcessing = 0; + else if(connection->commandList == COMMAND_LIST_OK) { + connection->listOks++; + } } void mpd_getNextReturnElement(mpd_Connection * connection) { @@ -397,7 +377,9 @@ void mpd_getNextReturnElement(mpd_Connection * connection) { if(connection->returnElement) mpd_freeReturnElement(connection->returnElement); connection->returnElement = NULL; - if(connection->doneProcessing) { + if(connection->doneProcessing || (connection->listOks && + connection->doneListOk)) + { strcpy(connection->errorStr,"already done processing current command"); connection->error = 1; return; @@ -459,9 +441,28 @@ void mpd_getNextReturnElement(mpd_Connection * connection) { connection->bufstart = rt - connection->buffer + 1; if(strcmp(output,"OK")==0) { + if(connection->listOks > 0) { + strcpy(connection->errorStr, "expected more list_OK's"); + connection->error = 1; + } + connection->listOks = 0; connection->doneProcessing = 1; return; } + + if(strcmp(output, "list_OK") == 0) { + if(!connection->listOks) { + strcpy(connection->errorStr, + "got an unexpected list_OK"); + connection->error = 1; + } + else { + connection->doneListOk = 1; + connection->listOks--; + } + return; + } + if(strncmp(output,"ACK",strlen("ACK"))==0) { char * test; char * needle; @@ -503,15 +504,45 @@ void mpd_getNextReturnElement(mpd_Connection * connection) { } void mpd_finishCommand(mpd_Connection * connection) { - while(!connection->doneProcessing) mpd_getNextReturnElement(connection); + while(!connection->doneProcessing) { + if(connection->doneListOk) connection->doneListOk = 0; + mpd_getNextReturnElement(connection); + } +} + +void mpd_finishListOkCommand(mpd_Connection * connection) { + while(!connection->doneProcessing && connection->listOks && + !connection->doneListOk ) + { + mpd_getNextReturnElement(connection); + } +} + +int mpd_nextListOkCommand(mpd_Connection * connection) { + mpd_finishListOkCommand(connection); + if(!connection->doneProcessing) connection->doneListOk = 0; + if(connection->listOks == 0 || connection->doneProcessing) return -1; + return 0; +} + +void mpd_sendStatusCommand(mpd_Connection * connection) { + mpd_executeCommand(connection,"status\n"); } mpd_Status * mpd_getStatus(mpd_Connection * connection) { mpd_Status * status; - mpd_executeCommand(connection,"status\n"); + /*mpd_executeCommand(connection,"status\n"); - if(connection->error) return NULL; + if(connection->error) return NULL;*/ + + if(connection->doneProcessing || (connection->listOks && + connection->doneListOk)) + { + return NULL; + } + + if(!connection->returnElement) mpd_getNextReturnElement(connection); status = malloc(sizeof(mpd_Status)); status->volume = -1; @@ -531,7 +562,6 @@ mpd_Status * mpd_getStatus(mpd_Connection * connection) { status->error = NULL; status->updatingDb = 0; - mpd_getNextReturnElement(connection); if(connection->error) { free(status); return NULL; @@ -573,6 +603,9 @@ mpd_Status * mpd_getStatus(mpd_Connection * connection) { else if(strcmp(re->name,"song")==0) { status->song = atoi(re->value); } + else if(strcmp(re->name,"songid")==0) { + status->songid = atoi(re->value); + } else if(strcmp(re->name,"time")==0) { char * tok; char * copy; @@ -639,12 +672,24 @@ void mpd_freeStatus(mpd_Status * status) { free(status); } +void mpd_sendStatsCommand(mpd_Connection * connection) { + mpd_executeCommand(connection,"stats\n"); +} + mpd_Stats * mpd_getStats(mpd_Connection * connection) { mpd_Stats * stats; - mpd_executeCommand(connection,"stats\n"); + /*mpd_executeCommand(connection,"stats\n"); - if(connection->error) return NULL; + if(connection->error) return NULL;*/ + + if(connection->doneProcessing || (connection->listOks && + connection->doneListOk)) + { + return NULL; + } + + if(!connection->returnElement) mpd_getNextReturnElement(connection); stats = malloc(sizeof(mpd_Stats)); stats->numberOfArtists = 0; @@ -655,7 +700,6 @@ mpd_Stats * mpd_getStats(mpd_Connection * connection) { stats->playTime = 0; stats->dbPlayTime = 0; - mpd_getNextReturnElement(connection); if(connection->error) { free(stats); return NULL; @@ -711,7 +755,8 @@ void mpd_initSong(mpd_Song * song) { song->title = NULL; song->name = NULL; song->time = MPD_SONG_NO_TIME; - song->num = MPD_SONG_NO_NUM; + song->pos = MPD_SONG_NO_NUM; + song->id = MPD_SONG_NO_ID; } void mpd_finishSong(mpd_Song * song) { @@ -746,7 +791,8 @@ mpd_Song * mpd_songDup(mpd_Song * song) { if(song->track) ret->track = strdup(song->track); if(song->name) ret->name = strdup(song->name); ret->time = song->time; - ret->num = song->num; + ret->pos = song->pos; + ret->id = song->id; return ret; } @@ -848,7 +894,11 @@ void mpd_sendInfoCommand(mpd_Connection * connection, char * command) { mpd_InfoEntity * mpd_getNextInfoEntity(mpd_Connection * connection) { mpd_InfoEntity * entity = NULL; - if(connection->doneProcessing) return NULL; + if(connection->doneProcessing || (connection->listOks && + connection->doneListOk)) + { + return NULL; + } if(!connection->returnElement) mpd_getNextReturnElement(connection); @@ -917,9 +967,13 @@ mpd_InfoEntity * mpd_getNextInfoEntity(mpd_Connection * connection) { strcmp(re->name,"Time")==0) { entity->info.song->time = atoi(re->value); } - else if(entity->info.song->num==MPD_SONG_NO_NUM && - strcmp(re->name,"Num")==0) { - entity->info.song->num = atoi(re->value); + else if(entity->info.song->pos==MPD_SONG_NO_NUM && + strcmp(re->name,"Pos")==0) { + entity->info.song->pos = atoi(re->value); + } + else if(entity->info.song->id==MPD_SONG_NO_ID && + strcmp(re->name,"Id")==0) { + entity->info.song->id = atoi(re->value); } } else if(entity->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) { @@ -936,7 +990,11 @@ mpd_InfoEntity * mpd_getNextInfoEntity(mpd_Connection * connection) { char * mpd_getNextReturnElementNamed(mpd_Connection * connection, const char * name) { - if(connection->doneProcessing) return NULL; + if(connection->doneProcessing || (connection->listOks && + connection->doneListOk)) + { + return NULL; + } mpd_getNextReturnElement(connection); while(connection->returnElement) { @@ -957,13 +1015,20 @@ char * mpd_getNextAlbum(mpd_Connection * connection) { return mpd_getNextReturnElementNamed(connection,"Album"); } -void mpd_sendPlaylistInfoCommand(mpd_Connection * connection, int songNum) { +void mpd_sendPlaylistInfoCommand(mpd_Connection * connection, int songPos) { char * string = malloc(strlen("playlistinfo")+25); - sprintf(string,"playlistinfo \"%i\"\n",songNum); + sprintf(string,"playlistinfo \"%i\"\n",songPos); mpd_sendInfoCommand(connection,string); free(string); } +void mpd_sendPlaylistIdCommand(mpd_Connection * connection, int id) { + char * string = malloc(strlen("playlistid")+25); + sprintf(string, "playlistid \"%i\"\n", id); + mpd_sendInfoCommand(connection, string); + free(string); +} + void mpd_sendPlChangesCommand(mpd_Connection * connection, long long playlist) { char * string = malloc(strlen("plchanges")+25); sprintf(string,"plchanges \"%lld\"\n",playlist); @@ -998,6 +1063,10 @@ void mpd_sendLsInfoCommand(mpd_Connection * connection, const char * dir) { free(sDir); } +void mpd_sendCurrentSongCommand(mpd_Connection * connection) { + mpd_executeCommand(connection,"currentsong\n"); +} + void mpd_sendSearchCommand(mpd_Connection * connection, int table, const char * str) { @@ -1076,9 +1145,16 @@ void mpd_sendAddCommand(mpd_Connection * connection, const char * file) { free(sFile); } -void mpd_sendDeleteCommand(mpd_Connection * connection, int songNum) { +void mpd_sendDeleteCommand(mpd_Connection * connection, int songPos) { char * string = malloc(strlen("delete")+25); - sprintf(string,"delete \"%i\"\n",songNum); + sprintf(string,"delete \"%i\"\n",songPos); + mpd_sendInfoCommand(connection,string); + free(string); +} + +void mpd_sendDeleteIdCommand(mpd_Connection * connection, int id) { + char * string = malloc(strlen("deleteid")+25); + sprintf(string, "deleteid \"%i\"\n", id); mpd_sendInfoCommand(connection,string); free(string); } @@ -1118,9 +1194,16 @@ void mpd_sendClearCommand(mpd_Connection * connection) { mpd_executeCommand(connection,"clear\n"); } -void mpd_sendPlayCommand(mpd_Connection * connection, int songNum) { +void mpd_sendPlayCommand(mpd_Connection * connection, int songPos) { char * string = malloc(strlen("play")+25); - sprintf(string,"play \"%i\"\n",songNum); + sprintf(string,"play \"%i\"\n",songPos); + mpd_sendInfoCommand(connection,string); + free(string); +} + +void mpd_sendPlayIdCommand(mpd_Connection * connection, int id) { + char * string = malloc(strlen("playid")+25); + sprintf(string,"playid \"%i\"\n",id); mpd_sendInfoCommand(connection,string); free(string); } @@ -1129,8 +1212,11 @@ void mpd_sendStopCommand(mpd_Connection * connection) { mpd_executeCommand(connection,"stop\n"); } -void mpd_sendPauseCommand(mpd_Connection * connection) { - mpd_executeCommand(connection,"pause\n"); +void mpd_sendPauseCommand(mpd_Connection * connection, int pauseMode) { + char * string = malloc(strlen("pause")+25); + sprintf(string,"pause \"%i\"\n",pauseMode); + mpd_executeCommand(connection,string); + free(string); } void mpd_sendNextCommand(mpd_Connection * connection) { @@ -1144,6 +1230,13 @@ void mpd_sendMoveCommand(mpd_Connection * connection, int from, int to) { free(string); } +void mpd_sendMoveIdCommand(mpd_Connection * connection, int id, int to) { + char * string = malloc(strlen("moveid")+25); + sprintf(string, "moveid \"%i\" \"%i\"\n", id, to); + mpd_sendInfoCommand(connection,string); + free(string); +} + void mpd_sendSwapCommand(mpd_Connection * connection, int song1, int song2) { char * string = malloc(strlen("swap")+25); sprintf(string,"swap \"%i\" \"%i\"\n",song1,song2); @@ -1151,6 +1244,13 @@ void mpd_sendSwapCommand(mpd_Connection * connection, int song1, int song2) { free(string); } +void mpd_sendSwapIdCommand(mpd_Connection * connection, int id1, int id2) { + char * string = malloc(strlen("swapid")+25); + sprintf(string, "swapid \"%i\" \"%i\"\n", id1, id2); + mpd_sendInfoCommand(connection,string); + free(string); +} + void mpd_sendSeekCommand(mpd_Connection * connection, int song, int time) { char * string = malloc(strlen("seek")+25); sprintf(string,"seek \"%i\" \"%i\"\n",song,time); @@ -1158,6 +1258,13 @@ void mpd_sendSeekCommand(mpd_Connection * connection, int song, int time) { free(string); } +void mpd_sendSeekIdCommand(mpd_Connection * connection, int id, int time) { + char * string = malloc(strlen("seekid")+25); + sprintf(string,"seekid \"%i\" \"%i\"\n",id,time); + mpd_sendInfoCommand(connection,string); + free(string); +} + void mpd_sendUpdateCommand(mpd_Connection * connection) { mpd_executeCommand(connection,"update\n"); } @@ -1229,10 +1336,21 @@ void mpd_sendCommandListBegin(mpd_Connection * connection) { connection->error = 1; return; } - connection->commandList = 1; + connection->commandList = COMMAND_LIST; mpd_executeCommand(connection,"command_list_begin\n"); } +void mpd_sendCommandListOkBegin(mpd_Connection * connection) { + if(connection->commandList) { + strcpy(connection->errorStr,"already in command list mode"); + connection->error = 1; + return; + } + connection->commandList = COMMAND_LIST_OK; + mpd_executeCommand(connection,"command_list_ok_begin\n"); + connection->listOks = 0; +} + void mpd_sendCommandListEnd(mpd_Connection * connection) { if(!connection->commandList) { strcpy(connection->errorStr,"not in command list mode"); |