diff --git a/src/common.c b/src/common.c index fc1f60ab..3d3b00dd 100644 --- a/src/common.c +++ b/src/common.c @@ -471,92 +471,35 @@ get_mentions(gboolean whole_word, gboolean case_sensitive, const char* const mes return mentions; } -/* - * Take an NULL-terminated array used as the tokens of a command, and optionally - * pointers to the string arrays that will store each lines of the call standard - * output and standard error. - * - * argv - NULL-terminated string array containing the tokens of the command - * line to spawn - * output_ptr - a pointer to the string array where to store spawned command - * standard output - * set to NULL to ignore the command standard output - * error_ptr - a pointer to the string array where to store spawned command - * standard error - * set to NULL to ignore the command standard error - * - * Returns: - * - TRUE if the command has been successfully spawned and exited normally - * - FALSE otherwise - */ gboolean -call_external(gchar** argv, gchar*** const output_ptr, gchar*** const error_ptr) +call_external(gchar** argv, gchar** std_out, gchar** std_err) { - gchar* stdout_str = NULL; - gchar** stdout_str_ptr = &stdout_str; - gchar* stderr_str = NULL; - gchar** stderr_str_ptr = &stderr_str; - GSpawnFlags flags = G_SPAWN_SEARCH_PATH; - gint status; - GError* error = NULL; - gchar* cmd = NULL; - - cmd = g_strjoinv(" ", argv); - log_debug("Calling external: %s", cmd); - - if (!output_ptr) { - stdout_str_ptr = NULL; + GSpawnFlags flags = G_SPAWN_SEARCH_PATH | G_SPAWN_CHILD_INHERITS_STDIN; + if (std_out == NULL) flags |= G_SPAWN_STDOUT_TO_DEV_NULL; - } - - if (!error_ptr) { - stderr_str_ptr = NULL; + if (std_err == NULL) flags |= G_SPAWN_STDERR_TO_DEV_NULL; - } - if (!g_spawn_sync(NULL, argv, NULL, flags, NULL, NULL, stdout_str_ptr, stderr_str_ptr, &status, &error)) { - log_error("Spawning '%s' failed: %s.", cmd, error->message); - g_error_free(error); - error = NULL; - return FALSE; - } + gint exit_status; + gboolean spawn_result; + GError* spawn_error; + spawn_result = g_spawn_sync(NULL, // Inherit the parent PWD. + argv, + NULL, // Inherit the parent environment. + flags, + NULL, NULL, // No func. before exec() in child. + std_out, std_err, + &exit_status, &spawn_error); - if (!g_spawn_check_exit_status(status, &error)) { - log_error("Calling '%s' failed: %s.", cmd, error->message); - g_error_free(error); - error = NULL; + if (!spawn_result + || !g_spawn_check_exit_status(exit_status, &spawn_error)) { + gchar* cmd = g_strjoinv(" ", argv); + log_error("Spawning '%s' failed with '%s'.", cmd, spawn_error->message); g_free(cmd); - cmd = NULL; - g_free(stdout_str); - stdout_str = NULL; - stdout_str_ptr = NULL; - if (stderr_str && strlen(stderr_str)) { - log_error("Called command returned the following on stderr: %s.", stderr_str); - } - g_free(stderr_str); - stderr_str = NULL; - stderr_str_ptr = NULL; - return FALSE; + g_error_free(spawn_error); } - g_free(cmd); - cmd = NULL; - - if (output_ptr) { - *output_ptr = g_strsplit(stdout_str, "\n", 0); - g_free(stdout_str); - stdout_str = NULL; - stdout_str_ptr = NULL; - } - - if (error_ptr) { - *error_ptr = g_strsplit(stderr_str, "\n", 0); - g_free(stderr_str); - stderr_str = NULL; - stderr_str_ptr = NULL; - } - - return TRUE; + return spawn_result; } gchar** diff --git a/src/common.h b/src/common.h index 44a61a79..bd33bf90 100644 --- a/src/common.h +++ b/src/common.h @@ -104,10 +104,10 @@ void get_file_paths_recursive(const char* directory, GSList** contents); char* get_random_string(int length); -gboolean call_external(gchar** argv, gchar*** const output_ptr, gchar*** const error_ptr); +gboolean call_external(gchar** argv, gchar** std_out, gchar** std_err); gchar** format_call_external_argv(const char* template, const char* url, const char* filename); gchar* unique_filename_from_url(const char* url, const char* path); -gchar* get_expanded_path(const char *path); +gchar* get_expanded_path(const char* path); #endif diff --git a/src/config/account.c b/src/config/account.c index c0f508b4..7e5297af 100644 --- a/src/config/account.c +++ b/src/config/account.c @@ -200,27 +200,35 @@ account_eval_password(ProfAccount* account) assert(account != NULL); assert(account->eval_password != NULL); - gchar** output = NULL; - gchar** error = NULL; + gchar* std_out = NULL; + gchar* std_err = NULL; gchar* argv[] = { "sh", "-c", account->eval_password, NULL }; - if (!call_external(argv, &output, &error)) { + 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); return FALSE; } - if (!output || !output[0]) { - log_error("Failed to read eval_password output"); - g_strfreev(output); - output = NULL; + if (!std_out || !std_out[0]) { + log_error("Password command returned empty output."); + g_free(std_out); + g_free(std_err); return FALSE; } - account->password = strdup(output[0]); - g_strfreev(output); - output = NULL; + // 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); if (!account->password) { - log_error("Failed to allocate enough memory to read eval_password output"); + log_error("Failed to allocate enough memory to read password command " + "output"); return FALSE; }