aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2014-09-09 05:38:22 +0200
committerMattias Andrée <maandree@operamail.com>2014-09-09 05:39:58 +0200
commitdf098f89ffe542a5725f7911fcd2f3e76d99a771 (patch)
tree1770dd20a512ac8b5b8f6e05b4396e3b6de93a79
parentwhoops, read wrong header (diff)
downloadmds-df098f89ffe542a5725f7911fcd2f3e76d99a771.tar.gz
mds-df098f89ffe542a5725f7911fcd2f3e76d99a771.tar.bz2
mds-df098f89ffe542a5725f7911fcd2f3e76d99a771.tar.xz
implement support for get-vt and configure-vt messages
Signed-off-by: Mattias Andrée <maandree@operamail.com>
-rw-r--r--src/mds-vt.c137
-rw-r--r--src/mds-vt.h28
2 files changed, 164 insertions, 1 deletions
diff --git a/src/mds-vt.c b/src/mds-vt.c
index aa82d34..8784058 100644
--- a/src/mds-vt.c
+++ b/src/mds-vt.c
@@ -375,7 +375,7 @@ int master_loop(void)
}
if (r = mds_message_read(&received, socket_fd), r == 0)
- if (r = 0, r == 0) /* FIXME */
+ if (r = handle_message(), r == 0)
continue;
if (r == -2)
@@ -414,6 +414,141 @@ int master_loop(void)
/**
+ * Handle the received message
+ *
+ * @return Zero on success, -1 on error
+ */
+int handle_message(void)
+{
+ /* Fetch message headers. */
+
+ const char* recv_client_id = "0:0";
+ const char* recv_message_id = NULL;
+ const char* recv_graphical = "neither";
+ const char* recv_exclusive = "neither";
+ const char* recv_command = NULL;
+ size_t i;
+
+#define __get_header(storage, header) \
+ (startswith(received.headers[i], header)) \
+ storage = received.headers[i] + strlen(header)
+
+ for (i = 0; i < received.header_count; i++)
+ {
+ if __get_header(recv_client_id, "Client ID: ");
+ else if __get_header(recv_message_id, "Message ID: ");
+ else if __get_header(recv_graphical, "Graphical: ");
+ else if __get_header(recv_exclusive, "Exclusive: ");
+ else if __get_header(recv_command, "Command: ");
+ }
+
+#undef __get_header
+
+
+ /* Validate headers. */
+
+ if (recv_message_id == NULL)
+ {
+ eprint("received message with ID, ignoring, master server is misbehaving.");
+ return 0;
+ }
+
+ if (strequals(recv_client_id, "0:0"))
+ {
+ eprint("received information request from an anonymous client, ignoring.");
+ return 0;
+ }
+
+ if (strlen(recv_client_id) > 21)
+ {
+ eprint("received invalid client ID, ignoring.");
+ return 0;
+ }
+ if (strlen(recv_message_id) > 10)
+ {
+ eprint("received invalid message ID, ignoring.");
+ return 0;
+ }
+
+
+ /* Take appropriate action. */
+
+ if (strequals(recv_command, "get-vt"))
+ return handle_get_vt(recv_client_id, recv_message_id);
+
+ if (strequals(recv_command, "configure-vt"))
+ return handle_configure_vt(recv_client_id, recv_message_id, recv_graphical, recv_exclusive);
+
+ return 0;
+}
+
+
+/**
+ * Handle a received `Command: get-vt` message
+ *
+ * @param client The value of the header `Client ID` in the received message
+ * @param message The value of the header `Message ID` in the received message
+ * @return Zero on success, -1 on error
+ */
+int handle_get_vt(const char* client, const char* message)
+{
+ char buf[57 + 44 + 3 * sizeof(int)];
+ int active = vt_get_active();
+ int r;
+
+ sprintf(buf,
+ "To: %s\n"
+ "In response to: %s\n"
+ "Message ID: %" PRIu32 "\n"
+ "VT index: %i\n"
+ "Active: %s\n"
+ "\n",
+ client, message, message_id, display_vt,
+ active == display_vt ? "yes" : "no");
+
+ message_id = message_id == UINT32_MAX ? 0 : (message_id + 1);
+
+ r = full_send(buf, strlen(buf));
+ return ((active < 0) || r) ? -1 : 0;
+}
+
+
+/**
+ * Handle a received `Command: configure-vt` message
+ *
+ * @param client The value of the header `Client ID` in the received message
+ * @param message The value of the header `Message ID` in the received message
+ * @param graphical The value of the header `Graphical` in the received message
+ * @param exclusive The value of the header `Exclusive` in the received message
+ * @return Zero on success, -1 on error
+ */
+int handle_configure_vt(const char* client, const char* message, const char* graphical, const char* exclusive)
+{
+ char buf[60 + 41 + 3 * sizeof(int)];
+ int r = 0;
+
+ if (strequals(exclusive, "yes") || strequals(exclusive, "no"))
+ r |= vt_set_graphical(display_tty_fd, strequals(exclusive, "yes"));
+
+ if (strequals(graphical, "yes") || strequals(graphical, "no"))
+ r |= vt_set_exclusive(display_tty_fd, strequals(graphical, "yes"));
+
+ sprintf(buf,
+ "Command: error\n"
+ "To: %s\n"
+ "In response to: %s\n"
+ "Message ID: %" PRIu32 "\n"
+ "Error: %i\n"
+ "\n",
+ client, message, message_id, r);
+
+ message_id = message_id == UINT32_MAX ? 0 : (message_id + 1);
+
+ return -!!full_send(buf, strlen(buf));
+}
+
+
+/**
* This function is called when the kernel wants
* to switch foreground virtual terminal
*
diff --git a/src/mds-vt.h b/src/mds-vt.h
index 55057c3..922e543 100644
--- a/src/mds-vt.h
+++ b/src/mds-vt.h
@@ -26,6 +26,34 @@
/**
+ * Handle the received message
+ *
+ * @return Zero on success, -1 on error
+ */
+int handle_message(void);
+
+/**
+ * Handle a received `Command: get-vt` message
+ *
+ * @param client The value of the header `Client ID` in the received message
+ * @param message The value of the header `Message ID` in the received message
+ * @return Zero on success, -1 on error
+ */
+int handle_get_vt(const char* client, const char* message);
+
+/**
+ * Handle a received `Command: configure-vt` message
+ *
+ * @param client The value of the header `Client ID` in the received message
+ * @param message The value of the header `Message ID` in the received message
+ * @param graphical The value of the header `Graphical` in the received message
+ * @param exclusive The value of the header `Exclusive` in the received message
+ * @return Zero on success, -1 on error
+ */
+int handle_configure_vt(const char* client, const char* message, const char* graphical, const char* exclusive);
+
+
+/**
* This function is called when the kernel wants
* to switch foreground virtual terminal
*