GUACAMOLE-934: Merge support for the Play Sound PDU.
diff --git a/src/protocols/rdp/client.c b/src/protocols/rdp/client.c
index db98d9b..415f226 100644
--- a/src/protocols/rdp/client.c
+++ b/src/protocols/rdp/client.c
@@ -38,12 +38,45 @@
#include <guacamole/audio.h>
#include <guacamole/client.h>
+#include <dirent.h>
#include <errno.h>
+#include <fcntl.h>
#include <pthread.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
+#include <unistd.h>
+
+/**
+ * Tests whether the given path refers to a directory which the current user
+ * can write to. If the given path is not a directory, is not writable, or is
+ * not a link pointing to a writable directory, this test will fail, and
+ * errno will be set appropriately.
+ *
+ * @param path
+ * The path to test.
+ *
+ * @return
+ * Non-zero if the given path is (or points to) a writable directory, zero
+ * otherwise.
+ */
+static int is_writable_directory(const char* path) {
+
+ /* Verify path is writable */
+ if (faccessat(AT_FDCWD, path, W_OK, 0))
+ return 0;
+
+ /* If writable, verify path is actually a directory */
+ DIR* dir = opendir(path);
+ if (!dir)
+ return 0;
+
+ /* Path is both writable and a directory */
+ closedir(dir);
+ return 1;
+
+}
int guac_client_init(guac_client* client, int argc, char** argv) {
@@ -70,13 +103,37 @@
"assigned: %s", passwd->pw_dir, strerror(errno));
/* HOME has been successfully set */
- else
+ else {
guac_client_log(client, GUAC_LOG_DEBUG, "\"HOME\" "
"environment variable was unset and has been "
"automatically set to \"%s\"", passwd->pw_dir);
+ current_home = passwd->pw_dir;
+ }
}
+ /* Verify that detected home directory is actually writable and actually a
+ * directory, as FreeRDP initialization will mysteriously fail otherwise */
+ if (current_home != NULL && !is_writable_directory(current_home)) {
+ if (errno == EACCES)
+ guac_client_log(client, GUAC_LOG_WARNING, "FreeRDP initialization "
+ "may fail: The current user's home directory (\"%s\") is "
+ "not writable, but FreeRDP generally requires a writable "
+ "home directory for storage of configuration files and "
+ "certificates.", current_home);
+ else if (errno == ENOTDIR)
+ guac_client_log(client, GUAC_LOG_WARNING, "FreeRDP initialization "
+ "may fail: The current user's home directory (\"%s\") is "
+ "not actually a directory, but FreeRDP generally requires "
+ "a writable home directory for storage of configuration "
+ "files and certificates.", current_home);
+ else
+ guac_client_log(client, GUAC_LOG_WARNING, "FreeRDP initialization "
+ "may fail: Writability of the current user's home "
+ "directory (\"%s\") could not be determined: %s",
+ current_home, strerror(errno));
+ }
+
/* Set client args */
client->args = GUAC_RDP_CLIENT_ARGS;