diff options
| author | Lars-Dominik Braun <PromyLOPh@lavabit.com> | 2010-08-09 11:22:10 +0200 | 
|---|---|---|
| committer | Lars-Dominik Braun <PromyLOPh@lavabit.com> | 2010-08-09 12:01:58 +0200 | 
| commit | bc3c92cb0e5a219d8f94a8bee6765885dbfc4333 (patch) | |
| tree | 98208c5f72e06bd45956247bc69328f9e9a89f30 /libpiano/src | |
| parent | 2269c74007cbae25875f76195fdc8d548da8f0ce (diff) | |
| download | pianobar-bc3c92cb0e5a219d8f94a8bee6765885dbfc4333.tar.gz pianobar-bc3c92cb0e5a219d8f94a8bee6765885dbfc4333.tar.bz2 pianobar-bc3c92cb0e5a219d8f94a8bee6765885dbfc4333.zip | |
Make something useful with misc.sync response
Calculcate offset to time() and use that offset to avoid out of sync
errors.
Diffstat (limited to 'libpiano/src')
| -rw-r--r-- | libpiano/src/piano.c | 114 | ||||
| -rw-r--r-- | libpiano/src/piano.h | 2 | 
2 files changed, 88 insertions, 28 deletions
| diff --git a/libpiano/src/piano.c b/libpiano/src/piano.c index ebaf860..bb3cf23 100644 --- a/libpiano/src/piano.c +++ b/libpiano/src/piano.c @@ -28,6 +28,7 @@ THE SOFTWARE.  #include <stdlib.h>  #include <time.h>  #include <assert.h> +#include <stdint.h>  /* needed for urlencode */  #include <waitress.h> @@ -225,6 +226,8 @@ static const char *PianoAudioFormatToString (PianoAudioFormat_t format) {  PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  		PianoRequestType_t type) {  	char xmlSendBuf[PIANO_SEND_BUFFER_SIZE]; +	/* corrected timestamp */ +	time_t timestamp = time (NULL) - ph->timeOffset;  	assert (ph != NULL);  	assert (req != NULL); @@ -238,16 +241,29 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  			assert (logindata != NULL); -			snprintf (xmlSendBuf, sizeof (xmlSendBuf),  -					"<?xml version=\"1.0\"?><methodCall>" -					"<methodName>listener.authenticateListener</methodName>" -					"<params><param><value><int>%lu</int></value></param>" -					"<param><value><string>%s</string></value></param>" -					"<param><value><string>%s</string></value></param>" -					"</params></methodCall>", (unsigned long) time (NULL), -					logindata->user, logindata->password); -			snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH -					"rid=%s&method=authenticateListener", ph->routeId); +			switch (logindata->step) { +				case 0: +					snprintf (xmlSendBuf, sizeof (xmlSendBuf),  +							"<?xml version=\"1.0\"?><methodCall>" +							"<methodName>misc.sync</methodName>" +							"<params></params></methodCall>"); +					snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH +							"rid=%s&method=sync", ph->routeId); +					break; + +				case 1: +					snprintf (xmlSendBuf, sizeof (xmlSendBuf),  +							"<?xml version=\"1.0\"?><methodCall>" +							"<methodName>listener.authenticateListener</methodName>" +							"<params><param><value><int>%lu</int></value></param>" +							"<param><value><string>%s</string></value></param>" +							"<param><value><string>%s</string></value></param>" +							"</params></methodCall>", (unsigned long) timestamp, +							logindata->user, logindata->password); +					snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH +							"rid=%s&method=authenticateListener", ph->routeId); +					break; +			}  			break;  		} @@ -259,7 +275,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  					"<methodCall><methodName>station.getStations</methodName>"  					"<params><param><value><int>%lu</int></value></param>"  					"<param><value><string>%s</string></value></param>" -					"</params></methodCall>", (unsigned long) time (NULL), +					"</params></methodCall>", (unsigned long) timestamp,  					ph->user.authToken);  			snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH  					"rid=%s&lid=%s&method=getStations", ph->routeId, @@ -287,7 +303,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>0</string></value></param>"  					"<param><value><string>0</string></value></param>" -					"</params></methodCall>", (unsigned long) time (NULL), +					"</params></methodCall>", (unsigned long) timestamp,  					ph->user.authToken, reqData->station->id,  					PianoAudioFormatToString (reqData->format));  			snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH @@ -326,7 +342,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  					"<param><value><boolean>0</boolean></value></param>"  					/* song type */  					"<param><value><int>%u</int></value></param>" -					"</params></methodCall>", (unsigned long) time (NULL), +					"</params></methodCall>", (unsigned long) timestamp,  					ph->user.authToken, reqData->stationId, reqData->musicId,  					(reqData->userSeed == NULL) ? "" : reqData->userSeed,  					reqData->testStrategy, @@ -364,7 +380,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>%s</string></value></param>" -					"</params></methodCall>", (unsigned long) time (NULL), +					"</params></methodCall>", (unsigned long) timestamp,  					ph->user.authToken, reqData->station->id,  					xmlencodedNewName);  			snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH @@ -388,7 +404,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  					"<params><param><value><int>%lu</int></value></param>"  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>%s</string></value></param>" -					"</params></methodCall>", (unsigned long) time (NULL), +					"</params></methodCall>", (unsigned long) timestamp,  					ph->user.authToken, station->id);  			snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH  					"rid=%s&lid=%s&method=removeStation&arg1=%s", ph->routeId, @@ -414,7 +430,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  					"<params><param><value><int>%lu</int></value></param>"  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>%s</string></value></param>" -					"</params></methodCall>", (unsigned long) time (NULL), +					"</params></methodCall>", (unsigned long) timestamp,  					ph->user.authToken, xmlencodedSearchStr);  			snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH  					"rid=%s&lid=%s&method=search&arg1=%s", ph->routeId, @@ -439,7 +455,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  					"<params><param><value><int>%lu</int></value></param>"  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>%s%s</string></value></param>" -					"</params></methodCall>", (unsigned long) time (NULL), +					"</params></methodCall>", (unsigned long) timestamp,  					ph->user.authToken, reqData->type, reqData->id);  			snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH @@ -462,7 +478,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>%s</string></value></param>" -					"</params></methodCall>", (unsigned long) time (NULL), +					"</params></methodCall>", (unsigned long) timestamp,  					ph->user.authToken, reqData->station->id, reqData->musicId);  			snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH  					"rid=%s&lid=%s&method=addSeed&arg1=%s&arg2=%s", ph->routeId, @@ -481,7 +497,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  					"<param><value><int>%lu</int></value></param>"  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>%s</string></value></param>" -					"</params></methodCall>", (unsigned long) time (NULL), +					"</params></methodCall>", (unsigned long) timestamp,  					ph->user.authToken, song->identity);  			snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH  					"rid=%s&lid=%s&method=addTiredSong&arg1=%s", ph->routeId, @@ -501,7 +517,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  					"<param><value><int>%lu</int></value></param>"  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>RANDOM</string></value></param>" -					"<param><value><array><data>", (unsigned long) time (NULL), +					"<param><value><array><data>", (unsigned long) timestamp,  					ph->user.authToken);  			while (curStation != NULL) {  				/* quick mix can't contain itself */ @@ -538,7 +554,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  			/* receive list of pandora's genre stations */  			xmlSendBuf[0] = '\0';  			snprintf (req->urlPath, sizeof (req->urlPath), "/xml/genre?r=%lu", -					(unsigned long) time (NULL)); +					(unsigned long) timestamp);  			break;  		case PIANO_REQUEST_TRANSFORM_STATION: { @@ -552,7 +568,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  					"<params><param><value><int>%lu</int></value></param>"  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>%s</string></value></param>" -					"</params></methodCall>", (unsigned long) time (NULL), +					"</params></methodCall>", (unsigned long) timestamp,  					ph->user.authToken, station->id);  			snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH  					"rid=%s&lid=%s&method=transformShared&arg1=%s", ph->routeId, @@ -573,7 +589,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>%s</string></value></param>" -					"</params></methodCall>", (unsigned long) time (NULL), +					"</params></methodCall>", (unsigned long) timestamp,  					ph->user.authToken, reqData->song->stationId,  					reqData->song->musicId);  			snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH @@ -597,7 +613,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>%s</string></value></param>"  					"<param><value><int>%u</int></value></param>" -					"</params></methodCall>", (unsigned long) time (NULL), +					"</params></methodCall>", (unsigned long) timestamp,  					ph->user.authToken, reqData->musicId, reqData->max);  			snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH  					"rid=%s&lid=%s&method=getSeedSuggestions&arg1=%s&arg2=%u", @@ -617,7 +633,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>%s</string></value></param>" -					"</params></methodCall>", (unsigned long) time (NULL), +					"</params></methodCall>", (unsigned long) timestamp,  					ph->user.authToken, song->stationId, song->musicId);  			snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH  					"rid=%s&lid=%s&method=createBookmark&arg1=%s&arg2=%s", @@ -637,7 +653,7 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  					"<params><param><value><int>%lu</int></value></param>"  					"<param><value><string>%s</string></value></param>"  					"<param><value><string>%s</string></value></param>" -					"</params></methodCall>", (unsigned long) time (NULL), +					"</params></methodCall>", (unsigned long) timestamp,  					ph->user.authToken, song->artistMusicId);  			snprintf (req->urlPath, sizeof (req->urlPath), PIANO_RPC_PATH  					"rid=%s&lid=%s&method=createArtistBookmark&arg1=%s", @@ -722,6 +738,11 @@ PianoReturn_t PianoRequest (PianoHandle_t *ph, PianoRequest_t *req,  	return PIANO_RET_OK;  } +#define byteswap32(x) ((((x) >> 24) & 0x000000ff) | \ +		(((x) >> 8) & 0x0000ff00) | \ +		(((x) << 8) & 0x00ff0000) | \ +		(((x) << 24) & 0xff000000)) +  /*	parse xml response and update data structures/return new data structure   *	@param piano handle   *	@param initialized request (expects responseData to be a NUL-terminated @@ -734,12 +755,49 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) {  	assert (req != NULL);  	switch (req->type) { -		case PIANO_REQUEST_LOGIN: +		case PIANO_REQUEST_LOGIN: {  			/* authenticate user */ +			PianoRequestDataLogin_t *reqData = req->data; +  			assert (req->responseData != NULL); +			assert (reqData != NULL); + +			switch (reqData->step) { +				case 0: { +					char *cryptedTimestamp = NULL; + +					assert (req->responseData != NULL); + +					/* abusing parseNarrative; has same xml structure */ +					ret = PianoXmlParseNarrative (req->responseData, &cryptedTimestamp); +					if (cryptedTimestamp != NULL) { +						unsigned long timestamp = 0; +						time_t realTimestamp = time (NULL); +						char *decryptedTimestamp = NULL, *decryptedPos = NULL; +						unsigned char i = 4; + +						if ((decryptedTimestamp = PianoDecryptString (cryptedTimestamp)) != NULL) { +							decryptedPos = decryptedTimestamp; +							/* skip four bytes garbage? at beginning */ +							while (i-- > 0 && *decryptedPos++ != '\0'); +							timestamp = strtoul (decryptedPos, NULL, 0); +							ph->timeOffset = realTimestamp - timestamp; + +							PianoFree (decryptedTimestamp, 0); +						} +						PianoFree (cryptedTimestamp, 0); +					} +					ret = PIANO_RET_CONTINUE_REQUEST; +					++reqData->step; +					break; +				} -			ret = PianoXmlParseUserinfo (ph, req->responseData); +				case 1: +					ret = PianoXmlParseUserinfo (ph, req->responseData); +					break; +			}  			break; +		}  		case PIANO_REQUEST_GET_STATIONS:  			/* get stations */ diff --git a/libpiano/src/piano.h b/libpiano/src/piano.h index aba4ebd..6dac931 100644 --- a/libpiano/src/piano.h +++ b/libpiano/src/piano.h @@ -105,6 +105,7 @@ typedef struct PianoHandle {  	/* linked lists */  	PianoStation_t *stations;  	PianoGenreCategory_t *genreStations; +	int timeOffset;  } PianoHandle_t;  typedef struct PianoSearchResult { @@ -147,6 +148,7 @@ typedef struct PianoRequest {  typedef struct {  	char *user;  	char *password; +	unsigned char step;  } PianoRequestDataLogin_t;  typedef struct { | 
