From 695a1d3c8c22b48fdf55b6d797d8b4b7e43abc27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Wennerstr=C3=B6m?= Date: Sun, 13 Dec 2020 17:19:40 +0100 Subject: [PATCH] Use popen for eval_password (reintroduce old behavior) Old commit that implemented the old behavior: bc9e6b79cdc246f7e97f6ddff7ea81474a698b05 --- src/config/account.c | 63 +++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/src/config/account.c b/src/config/account.c index 7e5297af..627c4a1c 100644 --- a/src/config/account.c +++ b/src/config/account.c @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -200,35 +201,49 @@ account_eval_password(ProfAccount* account) assert(account != NULL); assert(account->eval_password != NULL); - gchar* std_out = NULL; - gchar* std_err = NULL; + errno = 0; - gchar* argv[] = { "sh", "-c", account->eval_password, NULL }; - if (!call_external(argv, &std_out, &std_err)) { - log_error("Password command failed with: %s", std_err); - g_free(std_out); - g_free(std_err); + FILE* stream = popen(account->eval_password, "r"); + if (stream == NULL) { + const char* errmsg = strerror(errno); + if (errmsg) { + log_error("Could not execute `eval_password` command (%s).", + errmsg); + } else { + log_error("Failed to allocate memory for `eval_password` command."); + } return FALSE; } - if (!std_out || !std_out[0]) { - log_error("Password command returned empty output."); - g_free(std_out); - g_free(std_err); - return FALSE; - } - - // Remove leading and trailing whitespace from command output. - gchar* password = g_strdup(std_out); - g_strstrip(password); - - account->password = password; - g_free(std_out); - g_free(std_err); - + account->password = g_malloc(READ_BUF_SIZE); if (!account->password) { - log_error("Failed to allocate enough memory to read password command " - "output"); + log_error("Failed to allocate enough memory to read `eval_password` " + "output."); + return FALSE; + } + + account->password = fgets(account->password, READ_BUF_SIZE, stream); + if (!account->password) { + log_error("Failed to read password from stream."); + return FALSE; + } + + int exit_status = pclose(stream); + if (exit_status > 0) { + log_error("Command for `eval_password` returned error status (%s).", + exit_status); + return FALSE; + } else if (exit_status < 0) { + log_error("Failed to close stream for `eval_password` command output " + "(%s).", + strerror(errno)); + return FALSE; + }; + + // Remove leading and trailing whitespace from output. + g_strstrip(account->password); + if (!account->password) { + log_error("Empty password returned by `eval_password` command."); return FALSE; }