/** * This function should initialise the server, * and it not invoked after a re-exec. * * @return Non-zero on error */ int initialise_server(void) { int stage = 0; const char* const message = "Command: intercept\n" "Message ID: 0\n" "Length: 62\n" "\n" "Command: list-colours\n" "Command: get-colour\n" "Command: set-colour\n"; fail_if (full_send(message, strlen(message))); fail_if (server_initialised() < 0); stage++;; fail_if (colour_list_create(&colours, 64) < 0); stage++; fail_if (mds_message_initialise(&received)); return 0; fail: xperror(*argv); if (stage >= 2) colour_list_destroy(&colours); if (stage >= 1) mds_message_destroy(&received); return 1; }
/** * Wait for confirmation that we may switch virtual terminal * * @param data Thread input parameter, will always be `NULL` * @return Thread return value, will always be `NULL` */ void* secondary_loop(void* data) { mds_message_t secondary_received; int r; (void) data; secondary_thread_started = 1; fail_if (mds_message_initialise(&secondary_received) < 0); while (!reexecing && !terminating) { if (r = mds_message_read(&secondary_received, secondary_socket_fd), r == 0) r = vt_accept_switch(display_tty_fd); if (r == 0) continue; if (r == -2) { eprint("corrupt message received, aborting."); secondary_thread_failed = 1; goto done; } else if (errno == EINTR) continue; else fail_if (errno != ECONNRESET); eprint("lost secondary connection to server."); mds_message_destroy(&secondary_received); mds_message_initialise(&secondary_received); fail_if (reconnect_fd_to_display(&secondary_socket_fd) < 0); } goto done; fail: xperror(*argv); secondary_thread_failed = 1; done: secondary_thread_started = 0; mds_message_destroy(&secondary_received); if (!reexecing && !terminating) pthread_kill(master_thread, SIGTERM); return NULL; }
/** * Perform the server's mission * * @return Non-zero on error */ int master_loop(void) { int rc = 1, r; while (!reexecing && !terminating) { if (danger) { danger = 0; free(send_buffer); send_buffer = NULL; send_buffer_size = 0; colour_list_pack(&colours); free(colour_list_buffer_without_values); colour_list_buffer_without_values = NULL; free(colour_list_buffer_with_values); colour_list_buffer_with_values = NULL; } if (!(r = mds_message_read(&received, socket_fd))) if (!(r = handle_message())) continue; if (r == -2) { eprint("corrupt message received, aborting."); goto done; } else if (errno == EINTR) { continue; } else { fail_if (errno != ECONNRESET); } eprint("lost connection to server."); mds_message_destroy(&received); mds_message_initialise(&received); connected = 0; fail_if (reconnect_to_display()); connected = 1; } rc = 0; goto done; fail: xperror(*argv); done: if (rc || !reexecing) { mds_message_destroy(&received); colour_list_destroy(&colours); } free(send_buffer); free(colour_list_buffer_without_values); free(colour_list_buffer_with_values); return rc; }
/** * Perform the server's mission * * @return Non-zero on error */ int master_loop(void) { int rc = 1, r; while (!reexecing && !terminating) { if (switching_vt) { int leaving = switching_vt == 1; switching_vt = 0; r = switch_vt(leaving); } else if (r = mds_message_read(&received, socket_fd), r == 0) r = handle_message(); if (r == 0) continue; if (r == -2) { eprint("corrupt message received, aborting."); goto done; } else if (errno == EINTR) continue; else fail_if (errno != ECONNRESET); eprint("lost primary connection to server."); mds_message_destroy(&received); mds_message_initialise(&received); connected = 0; fail_if (reconnect_to_display()); connected = 1; } rc = 0; if (vt_set_exclusive(display_tty_fd, 0) < 0) xperror(*argv); if (vt_set_graphical(display_tty_fd, 0) < 0) xperror(*argv); if (unlink(vtfile_path) < 0) xperror(*argv); vt_close(display_tty_fd, &old_vt_stat); goto done; fail: xperror(*argv); done: rc |= secondary_thread_failed; if (rc || !reexecing) mds_message_destroy(&received); if ((errno = pthread_join(secondary_thread, NULL))) xperror(*argv); return rc; }
/** * This function should initialise the server, * and it not invoked after a re-exec. * * @return Non-zero on error */ int initialise_server(void) { int stage = 0; const char* const message = "Command: intercept\n" "Message ID: 0\n" "Length: 14\n" "\n" "Command: echo\n"; fail_if (full_send(message, strlen(message))); fail_if (server_initialised() < 0); stage++; fail_if (mds_message_initialise(&received)); return 0; fail: xperror(*argv); if (stage == 1) mds_message_destroy(&received); return 1; }
/** * Perform the server's mission * * @return Non-zero on error */ int master_loop(void) { int rc = 1, r; while (!reexecing && !terminating) { if (!(r = mds_message_read(&received, socket_fd))) if (!(r = echo_message())) continue; if (r == -2) { eprint("corrupt message received, aborting."); goto done; } else if (errno == EINTR) { continue; } else { fail_if (errno != ECONNRESET); } eprint("lost connection to server."); mds_message_destroy(&received); mds_message_initialise(&received); connected = 0; fail_if (reconnect_to_display()); connected = 1; } rc = 0; goto done; fail: xperror(*argv); done: if (rc || !reexecing) mds_message_destroy(&received); free(echo_buffer); return rc; }
/** * This function should initialise the server, * and it not invoked after a re-exec. * * @return Non-zero on error */ int initialise_server(void) { struct vt_mode mode; char* display_env; int primary_socket_fd; int stage = 0; const char* const message = "Command: intercept\n" "Message ID: 0\n" "Length: 38\n" "\n" "Command: get-vt\n" "Command: configure-vt\n"; const char* const secondary_message = "Command: intercept\n" "Message ID: 0\n" "Priority: -4611686018427387904\n" /* −2⁶² */ "Length: 22\n" "\n" "Command: switching-vt\n"; primary_socket_fd = socket_fd; fail_if (connect_to_display()); secondary_socket_fd = socket_fd; socket_fd = primary_socket_fd; display_env = getenv("MDS_DISPLAY"); display_env = display_env ? strchr(display_env, ':') : NULL; if ((display_env == NULL) || (strlen(display_env) < 2)) goto no_display; memset(vtfile_path, 0, sizeof(vtfile_path)); xsnprintf(vtfile_path, "%s/%s.vt", MDS_RUNTIME_ROOT_DIRECTORY, display_env + 1); stage = 1; if (is_respawn == 0) { display_vt = select_vt(); fail_if (display_vt < 0); display_tty_fd = vt_open(display_vt, &old_vt_stat); fail_if (write_vt_file() < 0); fail_if (vt_set_active(display_vt) < 0); } else { fail_if (read_vt_file() < 0); vt_is_active = (display_vt == vt_get_active()); fail_if (vt_is_active < 0); } fail_if (full_send(secondary_socket_fd, secondary_message, strlen(secondary_message))); fail_if (full_send(socket_fd, message, strlen(message))); fail_if (server_initialised() < 0); fail_if (mds_message_initialise(&received)); stage = 2; fail_if (xsigaction(SIGRTMIN + 2, received_switch_vt) < 0); fail_if (xsigaction(SIGRTMIN + 3, received_switch_vt) < 0); vt_construct_mode(1, SIGRTMIN + 2, SIGRTMIN + 3, &mode); fail_if (vt_get_set_mode(display_tty_fd, 1, &mode) < 0); if (vt_set_exclusive(display_tty_fd, 1) < 0) xperror(*argv); return 0; no_display: eprint("no display has been set, how did this happen."); return 1; fail: xperror(*argv); if (stage >= 1) unlink(vtfile_path); if (display_tty_fd >= 0) vt_close(display_tty_fd, &old_vt_stat); if (stage >= 2) mds_message_destroy(&received); return 1; }