Ejemplo n.º 1
0
/**
 * 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;
}
Ejemplo n.º 2
0
/**
 * 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;
}
Ejemplo n.º 3
0
/**
 * 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;
}
Ejemplo n.º 4
0
/**
 * 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;
}
Ejemplo n.º 5
0
/**
 * 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;
}
Ejemplo n.º 6
0
/**
 * 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;
}
Ejemplo n.º 7
0
/**
 * 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;
}