[misc] Consolidate control file reader (e.g. for pairing credentials) into misc.c
- also remove requirement to enter device name in .remote file
This commit is contained in:
parent
2676b9bbab
commit
283df8aa72
140
src/lastfm.c
140
src/lastfm.c
|
@ -63,108 +63,6 @@ static char *lastfm_session_key = NULL;
|
|||
|
||||
/* --------------------------------- HELPERS ------------------------------- */
|
||||
|
||||
/* Reads a LastFM credentials file (1st line username, 2nd line password) */
|
||||
static int
|
||||
credentials_read(char *path, char **username, char **password)
|
||||
{
|
||||
FILE *fp;
|
||||
char *u;
|
||||
char *p;
|
||||
char buf[256];
|
||||
int len;
|
||||
|
||||
fp = fopen(path, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
DPRINTF(E_LOG, L_LASTFM, "Could not open lastfm credentials file %s: %s\n", path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
u = fgets(buf, sizeof(buf), fp);
|
||||
if (!u)
|
||||
{
|
||||
DPRINTF(E_LOG, L_LASTFM, "Empty lastfm credentials file %s\n", path);
|
||||
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = strlen(u);
|
||||
if (buf[len - 1] != '\n')
|
||||
{
|
||||
DPRINTF(E_LOG, L_LASTFM, "Invalid lastfm credentials file %s: username name too long or missing password\n", path);
|
||||
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (len)
|
||||
{
|
||||
if ((buf[len - 1] == '\r') || (buf[len - 1] == '\n'))
|
||||
{
|
||||
buf[len - 1] = '\0';
|
||||
len--;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (!len)
|
||||
{
|
||||
DPRINTF(E_LOG, L_LASTFM, "Invalid lastfm credentials file %s: empty line where username expected\n", path);
|
||||
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
u = strdup(buf);
|
||||
if (!u)
|
||||
{
|
||||
DPRINTF(E_LOG, L_LASTFM, "Out of memory for username while reading %s\n", path);
|
||||
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = fgets(buf, sizeof(buf), fp);
|
||||
fclose(fp);
|
||||
if (!p)
|
||||
{
|
||||
DPRINTF(E_LOG, L_LASTFM, "Invalid lastfm credentials file %s: no password\n", path);
|
||||
|
||||
free(u);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = strlen(p);
|
||||
|
||||
while (len)
|
||||
{
|
||||
if ((buf[len - 1] == '\r') || (buf[len - 1] == '\n'))
|
||||
{
|
||||
buf[len - 1] = '\0';
|
||||
len--;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
p = strdup(buf);
|
||||
if (!p)
|
||||
{
|
||||
DPRINTF(E_LOG, L_LASTFM, "Out of memory for password while reading %s\n", path);
|
||||
|
||||
free(u);
|
||||
return -1;
|
||||
}
|
||||
|
||||
DPRINTF(E_LOG, L_LASTFM, "lastfm credentials file OK, logging in with username %s\n", u);
|
||||
|
||||
*username = u;
|
||||
*password = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Creates an md5 signature of the concatenated parameters and adds it to keyval */
|
||||
static int
|
||||
|
@ -417,59 +315,39 @@ scrobble(int id)
|
|||
/* ---------------------------- Our lastfm API --------------------------- */
|
||||
|
||||
/* Thread: filescanner */
|
||||
int
|
||||
lastfm_login(char *path)
|
||||
void
|
||||
lastfm_login(char **arglist)
|
||||
{
|
||||
struct keyval *kv;
|
||||
char *username;
|
||||
char *password;
|
||||
int ret;
|
||||
|
||||
DPRINTF(E_DBG, L_LASTFM, "Got LastFM login request\n");
|
||||
DPRINTF(E_LOG, L_LASTFM, "LastFM credentials file OK, logging in with username %s\n", arglist[0]);
|
||||
|
||||
// Delete any existing session key
|
||||
if (lastfm_session_key)
|
||||
free(lastfm_session_key);
|
||||
|
||||
free(lastfm_session_key);
|
||||
lastfm_session_key = NULL;
|
||||
|
||||
db_admin_delete("lastfm_sk");
|
||||
|
||||
// Read the credentials file
|
||||
ret = credentials_read(path, &username, &password);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
// Enable LastFM now that we got a login attempt
|
||||
lastfm_disabled = 0;
|
||||
|
||||
kv = keyval_alloc();
|
||||
if (!kv)
|
||||
{
|
||||
ret = -1;
|
||||
goto out_free_credentials;
|
||||
}
|
||||
return;
|
||||
|
||||
ret = ( (keyval_add(kv, "api_key", lastfm_api_key) == 0) &&
|
||||
(keyval_add(kv, "username", username) == 0) &&
|
||||
(keyval_add(kv, "password", password) == 0) );
|
||||
(keyval_add(kv, "username", arglist[0]) == 0) &&
|
||||
(keyval_add(kv, "password", arglist[1]) == 0) );
|
||||
if (!ret)
|
||||
{
|
||||
ret = -1;
|
||||
goto out_free_kv;
|
||||
}
|
||||
goto out_free_kv;
|
||||
|
||||
// Send the login request
|
||||
ret = request_post("auth.getMobileSession", kv, 1);
|
||||
request_post("auth.getMobileSession", kv, 1);
|
||||
|
||||
out_free_kv:
|
||||
keyval_clear(kv);
|
||||
free(kv);
|
||||
out_free_credentials:
|
||||
free(username);
|
||||
free(password);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Thread: worker */
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
#ifndef __LASTFM_H__
|
||||
#define __LASTFM_H__
|
||||
|
||||
int
|
||||
lastfm_login(char *path);
|
||||
void
|
||||
lastfm_login(char **arglist);
|
||||
|
||||
int
|
||||
lastfm_scrobble(int id);
|
||||
|
|
|
@ -92,6 +92,7 @@ enum file_type {
|
|||
FILE_ITUNES,
|
||||
FILE_ARTWORK,
|
||||
FILE_CTRL_REMOTE,
|
||||
FILE_CTRL_RAOP_VERIFICATION,
|
||||
FILE_CTRL_LASTFM,
|
||||
FILE_CTRL_SPOTIFY,
|
||||
FILE_CTRL_INITSCAN,
|
||||
|
@ -318,6 +319,9 @@ file_type_get(const char *path) {
|
|||
if (strcasecmp(ext, ".remote") == 0)
|
||||
return FILE_CTRL_REMOTE;
|
||||
|
||||
if (strcasecmp(ext, ".verification") == 0)
|
||||
return FILE_CTRL_RAOP_VERIFICATION;
|
||||
|
||||
if (strcasecmp(ext, ".lastfm") == 0)
|
||||
return FILE_CTRL_LASTFM;
|
||||
|
||||
|
@ -356,6 +360,25 @@ process_playlist(char *file, time_t mtime, int dir_id)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* If we found a control file we want to kickoff some action */
|
||||
static void
|
||||
kickoff(void (*kickoff_func)(char **arg), const char *file, int lines)
|
||||
{
|
||||
char **file_content;
|
||||
int i;
|
||||
|
||||
file_content = m_readfile(file, lines);
|
||||
if (!file_content)
|
||||
return;
|
||||
|
||||
kickoff_func(file_content);
|
||||
|
||||
for (i = 0; i < lines; i++)
|
||||
free(file_content[i]);
|
||||
|
||||
free(file_content);
|
||||
}
|
||||
|
||||
/* Thread: scan */
|
||||
static void
|
||||
defer_playlist(char *path, time_t mtime, int dir_id)
|
||||
|
@ -523,7 +546,13 @@ process_file(char *file, struct stat *sb, int type, int flags, int dir_id)
|
|||
if (flags & F_SCAN_BULK)
|
||||
DPRINTF(E_LOG, L_SCAN, "Bulk scan will ignore '%s' (to process, add it after startup)\n", file);
|
||||
else
|
||||
remote_pairing_kickoff_byfile(file);
|
||||
kickoff(remote_pairing_kickoff, file, 1);
|
||||
|
||||
case FILE_CTRL_RAOP_VERIFICATION:
|
||||
if (flags & F_SCAN_BULK)
|
||||
DPRINTF(E_LOG, L_SCAN, "Bulk scan will ignore '%s' (to process, add it after startup)\n", file);
|
||||
// else
|
||||
// kickoff(player_raop_verification_kickoff, file, 1);
|
||||
break;
|
||||
|
||||
case FILE_CTRL_LASTFM:
|
||||
|
@ -531,7 +560,7 @@ process_file(char *file, struct stat *sb, int type, int flags, int dir_id)
|
|||
if (flags & F_SCAN_BULK)
|
||||
DPRINTF(E_LOG, L_SCAN, "Bulk scan will ignore '%s' (to process, add it after startup)\n", file);
|
||||
else
|
||||
lastfm_login(file);
|
||||
kickoff(lastfm_login, file, 2);
|
||||
#else
|
||||
DPRINTF(E_LOG, L_SCAN, "Found '%s', but this version was built without LastFM support\n", file);
|
||||
#endif
|
||||
|
@ -542,7 +571,7 @@ process_file(char *file, struct stat *sb, int type, int flags, int dir_id)
|
|||
if (flags & F_SCAN_BULK)
|
||||
DPRINTF(E_LOG, L_SCAN, "Bulk scan will ignore '%s' (to process, add it after startup)\n", file);
|
||||
else
|
||||
spotify_login(file);
|
||||
kickoff(spotify_login, file, 2);
|
||||
#else
|
||||
DPRINTF(E_LOG, L_SCAN, "Found '%s', but this version was built without Spotify support\n", file);
|
||||
#endif
|
||||
|
|
51
src/misc.c
51
src/misc.c
|
@ -533,6 +533,57 @@ m_realpath(const char *pathname)
|
|||
return ret;
|
||||
}
|
||||
|
||||
char **
|
||||
m_readfile(const char *path, int num_lines)
|
||||
{
|
||||
char buf[256];
|
||||
FILE *fp;
|
||||
char **lines;
|
||||
char *line;
|
||||
int i;
|
||||
|
||||
// Alloc array of char pointers
|
||||
lines = calloc(num_lines, sizeof(char *));
|
||||
if (!lines)
|
||||
return NULL;
|
||||
|
||||
fp = fopen(path, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MISC, "Could not open file '%s' for reading: %s\n", path, strerror(errno));
|
||||
free(lines);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_lines; i++)
|
||||
{
|
||||
line = fgets(buf, sizeof(buf), fp);
|
||||
if (!line)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MISC, "File '%s' has fewer lines than expected (found %d, expected %d)\n", path, i, num_lines);
|
||||
goto error;
|
||||
}
|
||||
|
||||
lines[i] = trimwhitespace(line);
|
||||
if (strlen(lines[i]) == 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_MISC, "Line %d in '%s' is invalid\n", i+1, path);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return lines;
|
||||
|
||||
error:
|
||||
for (i = 0; i < num_lines; i++)
|
||||
free(lines[i]);
|
||||
|
||||
free(lines);
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
unicode_fixup_string(char *str, const char *fromcode)
|
||||
|
|
|
@ -80,6 +80,9 @@ keyval_sort(struct keyval *kv);
|
|||
char *
|
||||
m_realpath(const char *pathname);
|
||||
|
||||
char **
|
||||
m_readfile(const char *path, int num_lines);
|
||||
|
||||
char *
|
||||
unicode_fixup_string(char *str, const char *fromcode);
|
||||
|
||||
|
|
|
@ -714,131 +714,28 @@ touch_remote_cb(const char *name, const char *type, const char *domain, const ch
|
|||
|
||||
/* Thread: filescanner, mpd */
|
||||
void
|
||||
remote_pairing_kickoff_bypin(const char *pin)
|
||||
remote_pairing_kickoff(char **arglist)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DPRINTF(E_INFO, L_REMOTE, "Kickoff pairing with pin '%s'\n", pin);
|
||||
ret = strlen(arglist[0]);
|
||||
if (ret != 4)
|
||||
{
|
||||
DPRINTF(E_LOG, L_REMOTE, "Kickoff pairing failed, unexpected pin length (got %d, expected 4)\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
DPRINTF(E_LOG, L_REMOTE, "Kickoff pairing with pin '%s'\n", arglist[0]);
|
||||
|
||||
CHECK_ERR(L_REMOTE, pthread_mutex_lock(&remote_lck));
|
||||
|
||||
ret = add_remote_pin_data(pin);
|
||||
ret = add_remote_pin_data(arglist[0]);
|
||||
if (ret == 0)
|
||||
kickoff_pairing();
|
||||
|
||||
CHECK_ERR(L_REMOTE, pthread_mutex_unlock(&remote_lck));
|
||||
}
|
||||
|
||||
/* Thread: filescanner */
|
||||
void
|
||||
remote_pairing_kickoff_byfile(char *path)
|
||||
{
|
||||
char buf[256];
|
||||
FILE *fp;
|
||||
char *devname;
|
||||
char *pin;
|
||||
int len;
|
||||
|
||||
fp = fopen(path, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
DPRINTF(E_LOG, L_REMOTE, "Could not open Remote pairing file %s: %s\n", path, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
devname = fgets(buf, sizeof(buf), fp);
|
||||
if (!devname)
|
||||
{
|
||||
DPRINTF(E_LOG, L_REMOTE, "Empty Remote pairing file %s\n", path);
|
||||
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
len = strlen(devname);
|
||||
if (buf[len - 1] != '\n')
|
||||
{
|
||||
DPRINTF(E_LOG, L_REMOTE, "Invalid Remote pairing file %s: device name too long or missing pin\n", path);
|
||||
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
while (len)
|
||||
{
|
||||
if ((buf[len - 1] == '\r') || (buf[len - 1] == '\n'))
|
||||
{
|
||||
buf[len - 1] = '\0';
|
||||
len--;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (!len)
|
||||
{
|
||||
DPRINTF(E_LOG, L_REMOTE, "Invalid Remote pairing file %s: empty line where device name expected\n", path);
|
||||
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
devname = strdup(buf);
|
||||
if (!devname)
|
||||
{
|
||||
DPRINTF(E_LOG, L_REMOTE, "Out of memory for device name while reading %s\n", path);
|
||||
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
pin = fgets(buf, sizeof(buf), fp);
|
||||
fclose(fp);
|
||||
if (!pin)
|
||||
{
|
||||
DPRINTF(E_LOG, L_REMOTE, "Invalid Remote pairing file %s: no pin\n", path);
|
||||
|
||||
free(devname);
|
||||
return;
|
||||
}
|
||||
|
||||
len = strlen(pin);
|
||||
|
||||
while (len)
|
||||
{
|
||||
if ((buf[len - 1] == '\r') || (buf[len - 1] == '\n'))
|
||||
{
|
||||
buf[len - 1] = '\0';
|
||||
len--;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (len != 4)
|
||||
{
|
||||
DPRINTF(E_LOG, L_REMOTE, "Invalid pin in Remote pairing file %s: pin length should be 4, got %d\n", path, len);
|
||||
|
||||
free(devname);
|
||||
return;
|
||||
}
|
||||
|
||||
pin = strdup(buf);
|
||||
if (!pin)
|
||||
{
|
||||
DPRINTF(E_LOG, L_REMOTE, "Out of memory for device pin while reading %s\n", path);
|
||||
|
||||
free(devname);
|
||||
return;
|
||||
}
|
||||
|
||||
DPRINTF(E_LOG, L_REMOTE, "Read Remote pairing data (name '%s', pin '%s') from %s\n", devname, pin, path);
|
||||
|
||||
remote_pairing_kickoff_bypin(pin);
|
||||
free(devname);
|
||||
free(pin);
|
||||
}
|
||||
|
||||
|
||||
/* Thread: main */
|
||||
int
|
||||
|
|
|
@ -3,10 +3,7 @@
|
|||
#define __REMOTE_PAIRING_H__
|
||||
|
||||
void
|
||||
remote_pairing_kickoff_bypin(const char *pin);
|
||||
|
||||
void
|
||||
remote_pairing_kickoff_byfile(char *path);
|
||||
remote_pairing_kickoff(char **arglist);
|
||||
|
||||
int
|
||||
remote_pairing_init(void);
|
||||
|
|
123
src/spotify.c
123
src/spotify.c
|
@ -406,110 +406,6 @@ webapi_pl_remove(void *arg, int *ret);
|
|||
static void
|
||||
create_base_playlist();
|
||||
|
||||
/* ------------------------------- MISC HELPERS ---------------------------- */
|
||||
|
||||
static int
|
||||
spotify_file_read(char *path, char **username, char **password)
|
||||
{
|
||||
FILE *fp;
|
||||
char *u;
|
||||
char *p;
|
||||
char buf[256];
|
||||
int len;
|
||||
|
||||
fp = fopen(path, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SPOTIFY, "Could not open Spotify credentials file %s: %s\n", path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
u = fgets(buf, sizeof(buf), fp);
|
||||
if (!u)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SPOTIFY, "Empty Spotify credentials file %s\n", path);
|
||||
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = strlen(u);
|
||||
if (buf[len - 1] != '\n')
|
||||
{
|
||||
DPRINTF(E_LOG, L_SPOTIFY, "Invalid Spotify credentials file %s: username name too long or missing password\n", path);
|
||||
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (len)
|
||||
{
|
||||
if ((buf[len - 1] == '\r') || (buf[len - 1] == '\n'))
|
||||
{
|
||||
buf[len - 1] = '\0';
|
||||
len--;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (!len)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SPOTIFY, "Invalid Spotify credentials file %s: empty line where username expected\n", path);
|
||||
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
u = strdup(buf);
|
||||
if (!u)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SPOTIFY, "Out of memory for username while reading %s\n", path);
|
||||
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = fgets(buf, sizeof(buf), fp);
|
||||
fclose(fp);
|
||||
if (!p)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SPOTIFY, "Invalid Spotify credentials file %s: no password\n", path);
|
||||
|
||||
free(u);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = strlen(p);
|
||||
|
||||
while (len)
|
||||
{
|
||||
if ((buf[len - 1] == '\r') || (buf[len - 1] == '\n'))
|
||||
{
|
||||
buf[len - 1] = '\0';
|
||||
len--;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
p = strdup(buf);
|
||||
if (!p)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SPOTIFY, "Out of memory for password while reading %s\n", path);
|
||||
|
||||
free(u);
|
||||
return -1;
|
||||
}
|
||||
|
||||
DPRINTF(E_LOG, L_SPOTIFY, "Spotify credentials file OK, logging in with username %s\n", u);
|
||||
|
||||
*username = u;
|
||||
*password = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------- PLAYLIST HELPERS ------------------------- */
|
||||
/* Should only be called from within the spotify thread */
|
||||
|
@ -1945,12 +1841,9 @@ spotify_uri_register(const char *uri)
|
|||
|
||||
/* Thread: library */
|
||||
void
|
||||
spotify_login(char *path)
|
||||
spotify_login(char **arglist)
|
||||
{
|
||||
sp_error err;
|
||||
char *username;
|
||||
char *password;
|
||||
int ret;
|
||||
|
||||
if (!g_sess)
|
||||
{
|
||||
|
@ -1982,20 +1875,14 @@ spotify_login(char *path)
|
|||
CHECK_ERR(L_SPOTIFY, pthread_mutex_unlock(&login_lck));
|
||||
}
|
||||
|
||||
DPRINTF(E_INFO, L_SPOTIFY, "Logging into Spotify\n");
|
||||
|
||||
if (path)
|
||||
if (arglist)
|
||||
{
|
||||
ret = spotify_file_read(path, &username, &password);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
err = fptr_sp_session_login(g_sess, username, password, 1, NULL);
|
||||
free(username);
|
||||
free(password);
|
||||
DPRINTF(E_LOG, L_SPOTIFY, "Spotify credentials file OK, logging in with username %s\n", arglist[0]);
|
||||
err = fptr_sp_session_login(g_sess, arglist[0], arglist[1], 1, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF(E_INFO, L_SPOTIFY, "Relogin to Spotify\n");
|
||||
err = fptr_sp_session_relogin(g_sess);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ void
|
|||
spotify_oauth_callback(struct evbuffer *evbuf, struct evkeyvalq *param, const char *redirect_uri);
|
||||
|
||||
void
|
||||
spotify_login(char *path);
|
||||
spotify_login(char **arglist);
|
||||
|
||||
int
|
||||
spotify_init(void);
|
||||
|
|
Loading…
Reference in New Issue