diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 77 | ||||
-rw-r--r-- | src/settings.c | 3 | ||||
-rw-r--r-- | src/settings.h | 2 |
3 files changed, 74 insertions, 8 deletions
@@ -31,6 +31,7 @@ THE SOFTWARE. #include <stdlib.h> #include <string.h> #include <stdio.h> +/* fork () */ #include <unistd.h> #include <sys/select.h> #include <time.h> @@ -46,6 +47,10 @@ THE SOFTWARE. #include <stdbool.h> #include <limits.h> #include <signal.h> +/* waitpid () */ +#include <sys/types.h> +#include <sys/wait.h> + /* pandora.com library */ #include <piano.h> @@ -92,22 +97,78 @@ static bool BarMainLoginUser (BarApp_t *app) { /* ask for username/password if none were provided in settings */ -static void BarMainGetLoginCredentials (BarSettings_t *settings, +static bool BarMainGetLoginCredentials (BarSettings_t *settings, BarReadlineFds_t *input) { if (settings->username == NULL) { char nameBuf[100]; + BarUiMsg (settings, MSG_QUESTION, "Email: "); BarReadlineStr (nameBuf, sizeof (nameBuf), input, BAR_RL_DEFAULT); settings->username = strdup (nameBuf); } + if (settings->password == NULL) { char passBuf[100]; - BarUiMsg (settings, MSG_QUESTION, "Password: "); - BarReadlineStr (passBuf, sizeof (passBuf), input, BAR_RL_NOECHO); - /* write missing newline */ - puts (""); - settings->password = strdup (passBuf); + + if (settings->passwordCmd == NULL) { + BarUiMsg (settings, MSG_QUESTION, "Password: "); + BarReadlineStr (passBuf, sizeof (passBuf), input, BAR_RL_NOECHO); + /* write missing newline */ + puts (""); + settings->password = strdup (passBuf); + } else { + pid_t chld; + int pipeFd[2]; + + BarUiMsg (settings, MSG_INFO, "Requesting password from external helper... "); + + if (pipe (pipeFd) == -1) { + BarUiMsg (settings, MSG_NONE, "Error: %s\n", strerror (errno)); + return false; + } + + chld = fork (); + if (chld == 0) { + /* child */ + close (pipeFd[0]); + dup2 (pipeFd[1], fileno (stdout)); + execl ("/bin/sh", "/bin/sh", "-c", settings->passwordCmd, (char *) NULL); + BarUiMsg (settings, MSG_NONE, "Error: %s\n", strerror (errno)); + close (pipeFd[1]); + exit (1); + } else if (chld == -1) { + BarUiMsg (settings, MSG_NONE, "Error: %s\n", strerror (errno)); + return false; + } else { + /* parent */ + int status; + + close (pipeFd[1]); + memset (passBuf, 0, sizeof (passBuf)); + read (pipeFd[0], passBuf, sizeof (passBuf)-1); + close (pipeFd[0]); + + /* drop trailing newlines */ + ssize_t len = strlen (passBuf)-1; + while (len >= 0 && passBuf[len] == '\n') { + passBuf[len] = '\0'; + --len; + } + + waitpid (chld, &status, 0); + if (WEXITSTATUS (status) == 0) { + settings->password = strdup (passBuf); + BarUiMsg (settings, MSG_NONE, "Ok.\n"); + } else { + BarUiMsg (settings, MSG_NONE, "Error: Exit status %i.\n", WEXITSTATUS (status)); + return false; + } + } + + } } + + return true; } /* get station list @@ -270,7 +331,9 @@ static void BarMainPrintTime (BarApp_t *app) { static void BarMainLoop (BarApp_t *app) { pthread_t playerThread; - BarMainGetLoginCredentials (&app->settings, &app->input); + if (!BarMainGetLoginCredentials (&app->settings, &app->input)) { + return; + } BarMainLoadProxy (&app->settings, &app->waith); diff --git a/src/settings.c b/src/settings.c index c8bcbfe..014c561 100644 --- a/src/settings.c +++ b/src/settings.c @@ -86,6 +86,7 @@ void BarSettingsDestroy (BarSettings_t *settings) { free (settings->proxy); free (settings->username); free (settings->password); + free (settings->passwordCmd); free (settings->autostartStation); free (settings->eventCmd); free (settings->loveIcon); @@ -189,6 +190,8 @@ void BarSettingsRead (BarSettings_t *settings) { settings->username = strdup (val); } else if (streq ("password", key)) { settings->password = strdup (val); + } else if (streq ("password_command", key)) { + settings->passwordCmd = strdup (val); } else if (streq ("rpc_host", key)) { free (settings->rpcHost); settings->rpcHost = strdup (val); diff --git a/src/settings.h b/src/settings.h index 0f4c6de..30915c2 100644 --- a/src/settings.h +++ b/src/settings.h @@ -87,7 +87,7 @@ typedef struct { BarStationSorting_t sortOrder; PianoAudioQuality_t audioQuality; char *username; - char *password; + char *password, *passwordCmd; char *controlProxy; /* non-american listeners need this */ char *proxy; char *autostartStation; |