Exemplo n.º 1
0
static int APP_CC
xrdp_listen_fork(struct xrdp_listen *self, struct trans *server_trans)
{
    int pid;
    struct xrdp_process *process;

    pid = g_fork();

    if (pid == 0)
    {
        /* child */
        /* recreate some main globals */
        xrdp_child_fork();
        /* recreate the process done wait object, not used in fork mode */
        /* close, don't delete this */
        g_close_wait_obj(self->pro_done_event);
        xrdp_listen_create_pro_done(self);
        /* delete listener, child need not listen */
        trans_delete(self->listen_trans);
        self->listen_trans = 0;
        /* new connect instance */
        process = xrdp_process_create(self, 0);
        process->server_trans = server_trans;
        g_process = process;
        xrdp_process_run(0);
        xrdp_process_delete(process);
        /* mark this process to exit */
        g_set_term(1);
        return 0;
    }

    /* parent */
    trans_delete(server_trans);
    return 0;
}
Exemplo n.º 2
0
int APP_CC
xrdp_mm_check_wait_objs(struct xrdp_mm* self)
{
  int rv = 0;

  if (self == 0)
  {
    return 0;
  }
  rv = 0;
  if ((self->sesman_trans != 0) && self->sesman_trans_up)
  {
    if (trans_check_wait_objs(self->sesman_trans) != 0)
    {
      self->delete_sesman_trans = 1;
    }
  }
  if ((self->chan_trans != 0) && self->chan_trans_up)
  {
    if (trans_check_wait_objs(self->chan_trans) != 0)
    {
      self->delete_chan_trans = 1;
    }
  }
  if (self->mod != 0)
  {
    if (self->mod->mod_check_wait_objs != 0)
    {
      rv = self->mod->mod_check_wait_objs(self->mod);
    }
  }
  if (self->delete_sesman_trans)
  {
    trans_delete(self->sesman_trans);
    self->sesman_trans = 0;
    self->sesman_trans_up = 0;
    self->delete_sesman_trans = 0;
  }
  if (self->delete_chan_trans)
  {
    trans_delete(self->chan_trans);
    self->chan_trans = 0;
    self->chan_trans_up = 0;
    self->delete_chan_trans = 0;
  }

  return rv;
}
Exemplo n.º 3
0
	int DEFAULT_CC
my_trans_conn_in(struct trans* trans, struct trans* new_trans)
{
	if (trans == 0)
	{
		return 1;
	}
	if (trans != g_lis_trans)
	{
		return 1;
	}
	if (g_con_trans != 0) /* if already set, error */
	{
		return 1;
	}
	if (new_trans == 0)
	{
		return 1;
	}
	LOG(10, ("my_trans_conn_in:"));
	g_con_trans = new_trans;
	g_con_trans->trans_data_in = my_trans_data_in;
	g_con_trans->header_size = 8;
	/* stop listening */
	trans_delete(g_lis_trans);
	g_lis_trans = 0;
	return 0;
}
Exemplo n.º 4
0
	static int APP_CC
setup_listen(void)
{
	char port[256];
	int error;

	if (g_lis_trans != 0)
	{
		trans_delete(g_lis_trans);
	}
	if (g_use_unix_socket)
	{
		g_lis_trans = trans_create(2, 8192, 8192);
		g_snprintf(port, 255, "/var/spool/xrdp/xrdp_chansrv_socket_%d", 7200 + g_display_num);
	}
	else
	{
		g_lis_trans = trans_create(1, 8192, 8192);
		g_snprintf(port, 255, "%d", 7200 + g_display_num);
	}
	g_lis_trans->trans_conn_in = my_trans_conn_in;
	error = trans_listen(g_lis_trans, port);
	if (error != 0)
	{
		log_message(&log_conf, LOG_LEVEL_DEBUG, "chansrv[setup_listen]: "
				"setup_listen: trans_listen failed for port %s", port);
		return 1;
	}
	return 0;
}
Exemplo n.º 5
0
static int APP_CC
setup_listen(void)
{
    char port[256];
    int error = 0;

    if (g_lis_trans != 0)
    {
        trans_delete(g_lis_trans);
    }

    if (g_use_unix_socket)
    {
        g_lis_trans = trans_create(2, 8192, 8192);
        g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d",
                   7200 + g_display_num);
    }
    else
    {
        g_lis_trans = trans_create(1, 8192, 8192);
        g_snprintf(port, 255, "%d", 7200 + g_display_num);
    }

    g_lis_trans->trans_conn_in = my_trans_conn_in;
    error = trans_listen(g_lis_trans, port);

    if (error != 0)
    {
        LOGM((LOG_LEVEL_ERROR, "setup_listen: trans_listen failed for port %s",
              port));
        return 1;
    }

    return 0;
}
Exemplo n.º 6
0
Arquivo: sound.c Projeto: OSgenie/xrdp
static int DEFAULT_CC
sound_trans_audio_conn_in(struct trans *trans, struct trans *new_trans)
{
    LOG(0, ("sound_trans_audio_conn_in:"));
    print_got_here();

    if (trans == 0)
    {
        return 1;
    }

    if (trans != g_audio_l_trans)
    {
        return 1;
    }

    if (g_audio_c_trans != 0) /* if already set, error */
    {
        return 1;
    }

    if (new_trans == 0)
    {
        return 1;
    }

    g_audio_c_trans = new_trans;
    g_audio_c_trans->trans_data_in = sound_trans_audio_data_in;
    g_audio_c_trans->header_size = 8;
    trans_delete(g_audio_l_trans);
    g_audio_l_trans = 0;
    return 0;
}
Exemplo n.º 7
0
static int APP_CC
run_exec(void)
{
    int pid;

    LOG(10, ("run_exec:"));
    pid = g_fork();

    if (pid == 0)
    {
        trans_delete(g_con_trans);
        g_close_wait_obj(g_term_event);
        g_close_wait_obj(g_thread_done_event);
        g_close_wait_obj(g_exec_event);
        tc_mutex_delete(g_exec_mutex);
        tc_sem_delete(g_exec_sem);
        g_execlp3(g_exec_name, g_exec_name, 0);
        g_exit(0);
    }

    g_exec_pid = pid;
    tc_sem_inc(g_exec_sem);

    return 0;
}
Exemplo n.º 8
0
Arquivo: sound.c Projeto: OSgenie/xrdp
int APP_CC
sound_deinit(void)
{
    print_got_here();

    if (g_audio_l_trans != 0)
    {
        trans_delete(g_audio_l_trans);
        g_audio_l_trans = 0;
    }

    if (g_audio_c_trans != 0)
    {
        trans_delete(g_audio_c_trans);
        g_audio_c_trans = 0;
    }

    return 0;
}
Exemplo n.º 9
0
void APP_CC
xrdp_process_delete(struct xrdp_process* self)
{
  if (self == 0)
  {
    return;
  }
  g_delete_wait_obj(self->self_term_event);
  libxrdp_exit(self->session);
  xrdp_wm_delete(self->wm);
  trans_delete(self->server_trans);
  g_free(self);
}
Exemplo n.º 10
0
void APP_CC
xrdp_mm_delete(struct xrdp_mm* self)
{
  if (self == 0)
  {
    return;
  }
  /* free any module stuff */
  xrdp_mm_module_cleanup(self);
  trans_delete(self->sesman_trans);
  self->sesman_trans = 0;
  self->sesman_trans_up = 0;
  list_delete(self->login_names);
  list_delete(self->login_values);
  g_free(self);
}
Exemplo n.º 11
0
void APP_CC
xrdp_listen_delete(struct xrdp_listen* self)
{
  if (self->listen_trans != 0)
  {
    trans_delete(self->listen_trans);
  }
  if (g_process_sem != 0)
  {
    tc_sem_delete(g_process_sem);
    g_process_sem = 0;
  }
  g_delete_wait_obj(self->pro_done_event);
  list_delete(self->process_list);
  g_free(self);
}
Exemplo n.º 12
0
static void APP_CC
xrdp_mm_module_cleanup(struct xrdp_mm* self)
{
  if (self->mod != 0)
  {
    if (self->mod_exit != 0)
    {
      /* let the module cleanup */
      self->mod_exit(self->mod);
    }
  }
  if (self->mod_handle != 0)
  {
    /* main thread unload */
    g_xrdp_sync(xrdp_mm_sync_unload, self->mod_handle, 0);
  }
  trans_delete(self->chan_trans);
  self->chan_trans = 0;
  self->chan_trans_up = 0;
  self->mod_init = 0;
  self->mod_exit = 0;
  self->mod = 0;
  self->mod_handle = 0;
}
Exemplo n.º 13
0
int APP_CC
xrdp_mm_connect(struct xrdp_mm* self)
{
  struct list* names = (struct list *)NULL;
  struct list* values = (struct list *)NULL;
  int index = 0;
  int count = 0;
  int use_sesman = 0;
  int error = 0;
  int ok = 0;
  int rv = 0;
  char* name = (char *)NULL;
  char* value = (char *)NULL;
  char ip[256];
  char errstr[256];
  char text[256];
  char port[8];

  g_memset(ip,0,sizeof(char) * 256);
  g_memset(errstr,0,sizeof(char) * 256);
  g_memset(text,0,sizeof(char) * 256);
  g_memset(port,0,sizeof(char) * 8);
  rv = 0;
  use_sesman = 0;
  names = self->login_names;
  values = self->login_values;
  count = names->count;
  for (index = 0; index < count; index++)
  {
    name = (char*)list_get_item(names, index);
    value = (char*)list_get_item(values, index);
    if (g_strcasecmp(name, "ip") == 0)
    {
      g_strncpy(ip, value, 255);
    }
    else if (g_strcasecmp(name, "port") == 0)
    {
      if (g_strcasecmp(value, "-1") == 0)
      {
        use_sesman = 1;
      }
    }
  }
  if (use_sesman)
  {
    ok = 0;
    errstr[0] = 0;
    trans_delete(self->sesman_trans);
    self->sesman_trans = trans_create(TRANS_MODE_TCP, 8192, 8192);
    xrdp_mm_get_sesman_port(port, sizeof(port));
    g_snprintf(text, 255, "connecting to sesman ip %s port %s", ip, port);
    xrdp_wm_log_msg(self->wm, text);

    self->sesman_trans->trans_data_in = xrdp_mm_sesman_data_in;
    self->sesman_trans->header_size = 8;
    self->sesman_trans->callback_data = self;
    /* try to connect up to 4 times */
    for (index = 0; index < 4; index++)
    {
      if (trans_connect(self->sesman_trans, ip, port, 3000) == 0)
      {
        self->sesman_trans_up = 1;
        ok = 1;
        break;
      }
      g_sleep(1000);
      g_writeln("xrdp_mm_connect: connect failed "
                "trying again...");
    }
    if (ok)
    {
      /* fully connect */
      xrdp_wm_log_msg(self->wm, "sesman connect ok");
      self->connected_state = 1;
      rv = xrdp_mm_send_login(self);
    }
    else
    {
      xrdp_wm_log_msg(self->wm, errstr);
      trans_delete(self->sesman_trans);
      self->sesman_trans = 0;
      self->sesman_trans_up = 0;
      rv = 1;
    }
  }
  else /* no sesman */
  {
    if (xrdp_mm_setup_mod1(self) == 0)
    {
      if (xrdp_mm_setup_mod2(self) == 0)
      {
        xrdp_wm_set_login_mode(self->wm, 10);
      }
    }
    if (self->wm->login_mode != 10)
    {
      xrdp_wm_set_login_mode(self->wm, 11);
      xrdp_mm_module_cleanup(self);
    }
  }
  self->sesman_controlled = use_sesman;

  return rv;
}
Exemplo n.º 14
0
THREAD_RV THREAD_CC
channel_thread_loop(void *in_val)
{
    tbus objs[32];
    int num_objs;
    int timeout;
    int error;
    THREAD_RV rv;

    LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start"));
    rv = 0;
    setup_api_listen();
    error = setup_listen();

    if (error == 0)
    {
        timeout = -1;
        num_objs = 0;
        objs[num_objs] = g_term_event;
        num_objs++;
        trans_get_wait_objs(g_lis_trans, objs, &num_objs);
        trans_get_wait_objs(g_api_lis_trans, objs, &num_objs);

        while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0)
        {
            if (g_is_wait_obj_set(g_term_event))
            {
                LOGM((LOG_LEVEL_INFO, "channel_thread_loop: g_term_event set"));
                clipboard_deinit();
                sound_deinit();
                dev_redir_deinit();
                rail_deinit();
                break;
            }

            if (g_lis_trans != 0)
            {
                if (trans_check_wait_objs(g_lis_trans) != 0)
                {
                    LOGM((LOG_LEVEL_INFO, "channel_thread_loop: "
                          "trans_check_wait_objs error"));
                }
            }

            if (g_con_trans != 0)
            {
                if (trans_check_wait_objs(g_con_trans) != 0)
                {
                    LOGM((LOG_LEVEL_INFO, "channel_thread_loop: "
                          "trans_check_wait_objs error resetting"));
                    clipboard_deinit();
                    sound_deinit();
                    dev_redir_deinit();
                    rail_deinit();
                    /* delete g_con_trans */
                    trans_delete(g_con_trans);
                    g_con_trans = 0;
                    /* create new listener */
                    error = setup_listen();

                    if (error != 0)
                    {
                        break;
                    }
                }
            }

            if (g_api_lis_trans != 0)
            {
                if (trans_check_wait_objs(g_api_lis_trans) != 0)
                {
                    LOG(0, ("channel_thread_loop: trans_check_wait_objs failed"));
                }
            }

            LOG(10, ("0 %p", g_api_con_trans));

            if (g_api_con_trans != 0)
            {
                LOG(10, ("1 %p %d", g_api_con_trans, g_tcp_can_recv(g_api_con_trans->sck, 0)));

                if (trans_check_wait_objs(g_api_con_trans) != 0)
                {
                    LOG(10, ("channel_thread_loop: trans_check_wait_objs failed, "
                             "or disconnected"));
                    g_free(g_api_con_trans->callback_data);
                    trans_delete(g_api_con_trans);
                    g_api_con_trans = 0;
                }
            }

            xcommon_check_wait_objs();
            sound_check_wait_objs();
            dev_redir_check_wait_objs();
            fuse_check_wait_objs();
            timeout = -1;
            num_objs = 0;
            objs[num_objs] = g_term_event;
            num_objs++;
            trans_get_wait_objs(g_lis_trans, objs, &num_objs);
            trans_get_wait_objs(g_con_trans, objs, &num_objs);
            trans_get_wait_objs(g_api_lis_trans, objs, &num_objs);
            trans_get_wait_objs(g_api_con_trans, objs, &num_objs);
            xcommon_get_wait_objs(objs, &num_objs, &timeout);
            sound_get_wait_objs(objs, &num_objs, &timeout);
            dev_redir_get_wait_objs(objs, &num_objs, &timeout);
            fuse_get_wait_objs(objs, &num_objs, &timeout);
        }
    }

    trans_delete(g_lis_trans);
    g_lis_trans = 0;
    trans_delete(g_con_trans);
    g_con_trans = 0;
    trans_delete(g_api_lis_trans);
    g_api_lis_trans = 0;
    trans_delete(g_api_con_trans);
    g_api_con_trans = 0;
    LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop"));
    g_set_wait_obj(g_thread_done_event);
    return rv;
}
Exemplo n.º 15
0
	THREAD_RV THREAD_CC
channel_thread_loop(void* in_val)
{
	tbus objs[32];
	int num_objs;
	int timeout;
	int error;
	THREAD_RV rv;
	log_message(&log_conf, LOG_LEVEL_DEBUG, "chansrv[channel_thread_loop]: "
			"channel_thread_loop: thread start");
	rv = 0;
	error = setup_listen();
	if (error == 0)
	{
		timeout = 0;
		num_objs = 0;
		objs[num_objs] = g_term_event;
		num_objs++;
		trans_get_wait_objs(g_lis_trans, objs, &num_objs, &timeout);
		while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0)
		{
			if (g_is_wait_obj_set(g_term_event))
			{
				log_message(&log_conf, LOG_LEVEL_DEBUG, "chansrv[channel_thread_loop]: "
						"channel_thread_loop: g_term_event set");
				//clipboard_deinit();
				//sound_deinit();
				//dev_redir_deinit();
				//seamrdp_deinit();
				user_channel_deinit();
				break;
			}
			if (g_lis_trans != 0)
			{
				if (trans_check_wait_objs(g_lis_trans) != 0)
				{
					log_message(&log_conf, LOG_LEVEL_WARNING, "chansrv[channel_thread_loop]: "
							"trans_check_wait_objs error");
				}
			}
			if (g_con_trans != 0)
			{
				if (trans_check_wait_objs(g_con_trans) != 0)
				{
					log_message(&log_conf, LOG_LEVEL_WARNING, "chansrv[channel_thread_loop]: "
							"trans_check_wait_objs error resetting");
					//clipboard_deinit();
					//sound_deinit();
					//dev_redir_deinit();
					//seamrdp_deinit();
					user_channel_deinit();

					trans_delete(g_con_trans);
					g_con_trans = 0;
					error = setup_listen();
					if (error != 0)
					{
						break;
					}
				}
			}
			//clipboard_check_wait_objs();
			//sound_check_wait_objs();
			//dev_redir_check_wait_objs();
			//seamrdp_check_wait_objs();
			user_channel_check_wait_objs();
			timeout = 0;
			num_objs = 0;
			objs[num_objs] = g_term_event;
			num_objs++;
			trans_get_wait_objs(g_lis_trans, objs, &num_objs, &timeout);
			trans_get_wait_objs(g_con_trans, objs, &num_objs, &timeout);
			//clipboard_get_wait_objs(objs, &num_objs, &timeout);
			//sound_get_wait_objs(objs, &num_objs, &timeout);
			//dev_redir_get_wait_objs(objs, &num_objs, &timeout);
			//seamrdp_get_wait_objs(objs, &num_objs, &timeout);
			user_channel_get_wait_objs(objs, &num_objs, &timeout);

		}
	}
	trans_delete(g_lis_trans);
	g_lis_trans = 0;
	trans_delete(g_con_trans);
	g_con_trans = 0;
	log_message(&log_conf, LOG_LEVEL_DEBUG, "chansrv[channel_thread_loop]: "
			"channel_thread_loop: thread stop");
	g_set_wait_obj(g_thread_done_event);
	return rv;
}
Exemplo n.º 16
0
/* wait for incoming connections */
int APP_CC
xrdp_listen_main_loop(struct xrdp_listen* self)
{
  int error;
  int robjs_count;
  int cont;
  int timeout = 0;
  char port[8];
  char address[256];
  tbus robjs[8];
  tbus term_obj;
  tbus sync_obj;
  tbus sck_obj;
  tbus done_obj;

  self->status = 1;
  if (xrdp_listen_get_port_address(port, sizeof(port),
                                   address, sizeof(address)) != 0)
  {
    g_writeln("xrdp_listen_main_loop: xrdp_listen_get_port failed");
    self->status = -1;
    return 1;
  }
  error = trans_listen_address(self->listen_trans, port, address);
  if (error == 0)
  {
    self->listen_trans->trans_conn_in = xrdp_listen_conn_in;
    self->listen_trans->callback_data = self;
    term_obj = g_get_term_event();
    sync_obj = g_get_sync_event();
    done_obj = self->pro_done_event;
    cont = 1;
    while (cont)
    {
      /* build the wait obj list */
      robjs_count = 0;
      robjs[robjs_count++] = term_obj;
      robjs[robjs_count++] = sync_obj;
      robjs[robjs_count++] = done_obj;
      timeout = -1;
      if (trans_get_wait_objs(self->listen_trans, robjs, &robjs_count,
                              &timeout) != 0)
      {
        break;
      }
      /* wait */
      if (g_obj_wait(robjs, robjs_count, 0, 0, timeout) != 0)
      {
        /* error, should not get here */
        g_sleep(100);
      }
      if (g_is_wait_obj_set(term_obj)) /* term */
      {
        break;
      }
      if (g_is_wait_obj_set(sync_obj)) /* sync */
      {
        g_reset_wait_obj(sync_obj);
        g_loop();
      }
      if (g_is_wait_obj_set(done_obj)) /* pro_done_event */
      {
        g_reset_wait_obj(done_obj);
        xrdp_listen_delete_done_pro(self);
      }
      if (trans_check_wait_objs(self->listen_trans) != 0)
      {
        break;  
      }
    }
    /* stop listening */
    trans_delete(self->listen_trans);
    self->listen_trans = 0;
    /* second loop to wait for all process threads to close */
    cont = 1;
    while (cont)
    {
      if (self->process_list->count == 0)
      {
        break;
      }
      /* build the wait obj list */
      robjs_count = 0;
      robjs[robjs_count++] = sync_obj;
      robjs[robjs_count++] = done_obj;
      /* wait */
      if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0)
      {
        /* error, should not get here */
        g_sleep(100);
      }
      if (g_is_wait_obj_set(sync_obj)) /* sync */
      {
        g_reset_wait_obj(sync_obj);
        g_loop();
      }
      if (g_is_wait_obj_set(done_obj)) /* pro_done_event */
      {
        g_reset_wait_obj(done_obj);
        xrdp_listen_delete_done_pro(self);
      }
    }
  }
  else
  {
    DEBUG(("listen error in xrdp_listen_main_loop"));
  }
  self->status = -1;
  return 0;
}
Exemplo n.º 17
0
/* wait for incoming connections */
int APP_CC
xrdp_listen_main_loop(struct xrdp_listen *self)
{
    int error;
    int robjs_count;
    int cont;
    int timeout = 0;
    char port[128];
    char address[256];
    tbus robjs[8];
    tbus term_obj;
    tbus sync_obj;
    tbus done_obj;
    int tcp_nodelay;
    int tcp_keepalive;
    int bytes;

    self->status = 1;

    if (xrdp_listen_get_port_address(port, sizeof(port),
                                     address, sizeof(address),
                                     &tcp_nodelay, &tcp_keepalive,
                                     self->startup_params) != 0)
    {
        log_message(LOG_LEVEL_ERROR,"xrdp_listen_main_loop: xrdp_listen_get_port failed");
        self->status = -1;
        return 1;
    }

    if (port[0] == '/')
    {
        /* set UDS mode */
        self->listen_trans->mode = TRANS_MODE_UNIX;
        /* not valid with UDS */
        tcp_nodelay = 0;
    }

    /* Create socket */
    error = trans_listen_address(self->listen_trans, port, address);

    if (error == 0)
    {
        if (tcp_nodelay)
        {
            if (g_tcp_set_no_delay(self->listen_trans->sck))
            {
                log_message(LOG_LEVEL_ERROR,"Error setting tcp_nodelay");
            }
        }

        if (tcp_keepalive)
        {
            if (g_tcp_set_keepalive(self->listen_trans->sck))
            {
                log_message(LOG_LEVEL_ERROR,"Error setting tcp_keepalive");
            }
        }

        if (self->startup_params->send_buffer_bytes > 0)
        {
            bytes = self->startup_params->send_buffer_bytes;
            log_message(LOG_LEVEL_INFO, "setting send buffer to %d bytes",
                        bytes);
            if (g_sck_set_send_buffer_bytes(self->listen_trans->sck,
                                            bytes) != 0)
            {
                log_message(LOG_LEVEL_ERROR, "error setting send buffer");
            }
            else
            {
                if (g_sck_get_send_buffer_bytes(self->listen_trans->sck,
                                                &bytes) != 0)
                {
                    log_message(LOG_LEVEL_ERROR, "error getting send buffer");
                }
                else
                {
                    log_message(LOG_LEVEL_INFO, "send buffer set to %d bytes", bytes);
                }
            }
        }

        if (self->startup_params->recv_buffer_bytes > 0)
        {
            bytes = self->startup_params->recv_buffer_bytes;
            log_message(LOG_LEVEL_INFO, "setting recv buffer to %d bytes",
                        bytes);
            if (g_sck_set_recv_buffer_bytes(self->listen_trans->sck,
                                            bytes) != 0)
            {
                log_message(LOG_LEVEL_ERROR, "error setting recv buffer");
            }
            else
            {
                if (g_sck_get_recv_buffer_bytes(self->listen_trans->sck,
                                                &bytes) != 0)
                {
                    log_message(LOG_LEVEL_ERROR, "error getting recv buffer");
                }
                else
                {
                    log_message(LOG_LEVEL_INFO, "recv buffer set to %d bytes", bytes);
                }
            }
        }

        self->listen_trans->trans_conn_in = xrdp_listen_conn_in;
        self->listen_trans->callback_data = self;
        term_obj = g_get_term_event(); /*Global termination event */
        sync_obj = g_get_sync_event();
        done_obj = self->pro_done_event;
        cont = 1;

        while (cont)
        {
            /* build the wait obj list */
            robjs_count = 0;
            robjs[robjs_count++] = term_obj;
            robjs[robjs_count++] = sync_obj;
            robjs[robjs_count++] = done_obj;
            timeout = -1;

            /* if (self->listen_trans != 0) */
            {
                if (trans_get_wait_objs(self->listen_trans, robjs,
                                        &robjs_count) != 0)
                {
                    log_message(LOG_LEVEL_ERROR,"Listening socket is in wrong state we "
                              "terminate listener");
                    break;
                }
            }

            /* wait - timeout -1 means wait indefinitely*/
            if (g_obj_wait(robjs, robjs_count, 0, 0, timeout) != 0)
            {
                /* error, should not get here */
                g_sleep(100);
            }

            if (g_is_wait_obj_set(term_obj)) /* termination called */
            {
                break;
            }

            /* some function must be processed by this thread */
            if (g_is_wait_obj_set(sync_obj))
            {
                g_reset_wait_obj(sync_obj);
                g_process_waiting_function(); /* run the function */
            }

            if (g_is_wait_obj_set(done_obj)) /* pro_done_event */
            {
                g_reset_wait_obj(done_obj);
                /* a process has died remove it from lists*/
                xrdp_listen_delete_done_pro(self);
            }

            /* Run the callback when accept() returns a new socket*/
            if (trans_check_wait_objs(self->listen_trans) != 0)
            {
                break;
            }
        }

        /* stop listening */
        trans_delete(self->listen_trans);
        self->listen_trans = 0;
        /* second loop to wait for all process threads to close */
        cont = 1;

        while (cont)
        {
            if (self->process_list->count == 0)
            {
                break;
            }

            timeout = -1;
            /* build the wait obj list */
            robjs_count = 0;
            robjs[robjs_count++] = sync_obj;
            robjs[robjs_count++] = done_obj;

            /* wait - timeout -1 means wait indefinitely*/
            if (g_obj_wait(robjs, robjs_count, 0, 0, timeout) != 0)
            {
                /* error, should not get here */
                g_sleep(100);
            }

            /* some function must be processed by this thread */
            if (g_is_wait_obj_set(sync_obj))
            {
                g_reset_wait_obj(sync_obj);
                g_process_waiting_function(); /* run the function that is waiting*/
            }

            if (g_is_wait_obj_set(done_obj)) /* pro_done_event */
            {
                g_reset_wait_obj(done_obj);
                xrdp_listen_delete_done_pro(self);
            }
        }
    }
    else
    {
        log_message(LOG_LEVEL_ERROR,"xrdp_listen_main_loop: listen error, possible port "
                  "already in use");
    }

    self->status = -1;
    return 0;
}
Exemplo n.º 18
0
int APP_CC
trans_check_wait_objs(struct trans* self)
{
  tbus in_sck;
  struct trans* in_trans;
  int read_bytes;
  int to_read;
  int read_so_far;
  int rv;

  if (self == 0)
  {
    return 1;
  }
  if (self->status != 1)
  {
    return 1;
  }
  rv = 0;
  if (self->type1 == 1) /* listening */
  {
    if (g_tcp_can_recv(self->sck, 0))
    {
      in_sck = g_tcp_accept(self->sck);
      if (in_sck == -1)
      {
        if (g_tcp_last_error_would_block(self->sck))
        {
          /* ok, but shouldn't happen */
        }
        else
        {
          /* error */
          self->status = 0;
          rv = 1;
        }
      }
      if (in_sck != -1)
      {
        if (self->trans_conn_in != 0) /* is function assigned */
        {
          in_trans = trans_create(self->mode, self->in_s->size,
                                  self->out_s->size);
          in_trans->sck = in_sck;
          in_trans->type1 = 2;
          in_trans->status = 1;
          if (self->trans_conn_in(self, in_trans) != 0)
          {
            trans_delete(in_trans);
          }
        }
        else
        {
          g_tcp_close(in_sck);
        }
      }
    }
  }
  else /* connected server or client (2 or 3) */
  {
    if (g_tcp_can_recv(self->sck, 0))
    {
      read_so_far = (int)(self->in_s->end - self->in_s->data);
      to_read = self->header_size - read_so_far;
      read_bytes = g_tcp_recv(self->sck, self->in_s->end, to_read, 0);
      if (read_bytes == -1)
      {
        if (g_tcp_last_error_would_block(self->sck))
        {
          /* ok, but shouldn't happen */
        }
        else
        {
          /* error */
          self->status = 0;
          rv = 1;
        }
      }
      else if (read_bytes == 0)
      {
        /* error */
        self->status = 0;
        rv = 1;
      }
      else
      {
        self->in_s->end += read_bytes;
      }
      read_so_far = (int)(self->in_s->end - self->in_s->data);
      if (read_so_far == self->header_size)
      {
        if (self->trans_data_in != 0)
        {
          rv = self->trans_data_in(self);
          init_stream(self->in_s, 0);
        }
      }
    }
  }
  return rv;
}
Exemplo n.º 19
0
Arquivo: sound.c Projeto: OSgenie/xrdp
static void *DEFAULT_CC
read_raw_audio_data(void *arg)
{
    pa_sample_spec samp_spec;
    pa_simple *simple = NULL;
    uint32_t bytes_read;
    char *cptr;
    int i;
    int error;
    struct trans *strans;
    char path[256];
    struct stream *outs;

    strans = trans_create(TRANS_MODE_UNIX, 8192, 8192);

    if (strans == 0)
    {
        LOG(0, ("read_raw_audio_data: trans_create failed\n"));
        return 0;
    }

    strans->trans_data_in = sttrans_data_in;
    g_snprintf(path, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num);

    if (trans_connect(strans, "", path, 100) != 0)
    {
        LOG(0, ("read_raw_audio_data: trans_connect failed\n"));
        trans_delete(strans);
        return 0;
    }

    /* setup audio format */
    samp_spec.format = PA_SAMPLE_S16LE;
    samp_spec.rate = 44100;
    samp_spec.channels = 2;

    /* if we are root, then for first 8 seconds connection to pulseaudo server
       fails; if we are non-root, then connection succeeds on first attempt;
       for now we have changed code to be non-root, but this may change in the
       future - so pretend we are root and try connecting to pulseaudio server
       for upto one minute */
    for (i = 0; i < 60; i++)
    {
        simple = pa_simple_new(NULL, "xrdp", PA_STREAM_RECORD, NULL,
                               "record", &samp_spec, NULL, NULL, &error);

        if (simple)
        {
            /* connected to pulseaudio server */
            LOG(0, ("read_raw_audio_data: connected to pulseaudio server\n"));
            break;
        }

        LOG(0, ("read_raw_audio_data: ERROR creating PulseAudio async interface\n"));
        LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error)));
        g_sleep(1000);
    }

    if (i == 60)
    {
        /* failed to connect to audio server */
        trans_delete(strans);
        return NULL;
    }

    /* insert header just once */
    outs = trans_get_out_s(strans, 8192);
    out_uint32_le(outs, 0);
    out_uint32_le(outs, AUDIO_BUF_SIZE + 8);
    cptr = outs->p;
    out_uint8s(outs, AUDIO_BUF_SIZE);
    s_mark_end(outs);

    while (1)
    {
        /* read a block of raw audio data... */
        g_memset(cptr, 0, 4);
        bytes_read = pa_simple_read(simple, cptr, AUDIO_BUF_SIZE, &error);

        if (bytes_read < 0)
        {
            LOG(0, ("read_raw_audio_data: ERROR reading from pulseaudio stream\n"));
            LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error)));
            break;
        }

        /* bug workaround:
           even when there is no audio data, pulseaudio is returning without
           errors but the data itself is zero; we use this zero data to
           determine that there is no audio data present */
        if (*cptr == 0 && *(cptr + 1) == 0 && *(cptr + 2) == 0 && *(cptr + 3) == 0)
        {
            g_sleep(10);
            continue;
        }

        if (trans_force_write_s(strans, outs) != 0)
        {
            LOG(0, ("read_raw_audio_data: ERROR writing audio data to server\n"));
            break;
        }
    }

    pa_simple_free(simple);
    trans_delete(strans);
    return NULL;
}
Exemplo n.º 20
0
/*
 * called when WTSVirtualChannelOpenEx is invoked in xrdpapi.c
 *
 ******************************************************************************/
int DEFAULT_CC
my_api_trans_conn_in(struct trans *trans, struct trans *new_trans)
{
    struct xrdp_api_data *ad;
    struct stream        *s;
    int                   error;
    int                   index;
    char                  chan_pri;

    if ((trans == 0) || (trans != g_api_lis_trans) || (new_trans == 0))
    {
        return 1;
    }

    LOGM((LOG_LEVEL_DEBUG, "my_api_trans_conn_in:"));
    LOG(10, ("my_api_trans_conn_in: got incoming"));

    s = trans_get_in_s(new_trans);
    s->end = s->data;

    error = trans_force_read(new_trans, 64);

    if (error != 0)
    {
        LOG(0, ("my_api_trans_conn_in: trans_force_read failed"));
        trans_delete(new_trans);
    }

    s->end = s->data;

    ad = (struct xrdp_api_data *) g_malloc(sizeof(struct xrdp_api_data), 1);
    g_memcpy(ad->header, s->data, 64);

    ad->flags = GGET_UINT32(ad->header, 16);
    ad->chan_id = -1;
    ad->dvc_chan_id = -1;

    if (ad->flags > 0)
    {
        /* opening a dynamic virtual channel */

        if ((index = find_empty_slot_in_dvc_channels()) < 0)
        {
            /* exceeded MAX_DVC_CHANNELS */
            LOG(0, ("my_api_trans_conn_in: MAX_DVC_CHANNELS reached; giving up!"))
            g_free(ad);
            trans_delete(new_trans);
            return 1;
        }

        g_dvc_channels[index] = ad;
        chan_pri = 4 - ad->flags;
        ad->dvc_chan_id = g_dvc_chan_id++;
        ad->is_connected = 0;
        ad->transp = new_trans;
        drdynvc_send_open_channel_request(chan_pri, ad->dvc_chan_id, ad->header);
    }
    else
    {
        /* opening a static virtual channel */

        for (index = 0; index < g_num_chan_items; index++)
        {
            LOG(10, ("my_api_trans_conn_in:  %s %s", ad->header,
                    g_chan_items[index].name));

            if (g_strcasecmp(ad->header, g_chan_items[index].name) == 0)
            {
                LOG(10, ("my_api_trans_conn_in: found it at %d", index));
                ad->chan_id = g_chan_items[index].id;
                break;
            }
        }
        if (index == g_num_chan_items)
        {
            g_writeln("did not find SVC named %s", ad->header);
        }
    }

    new_trans->callback_data = ad;

    trans_delete(g_api_con_trans);
    g_api_con_trans = new_trans;
    g_api_con_trans->trans_data_in = my_api_trans_data_in;
    g_api_con_trans->header_size = 0;

    return 0;
}
Exemplo n.º 21
0
Arquivo: trans.c Projeto: speidy/xrdp
int APP_CC
trans_check_wait_objs(struct trans *self)
{
    tbus in_sck = (tbus) 0;
    struct trans *in_trans = (struct trans *) NULL;
    int read_bytes = 0;
    int to_read = 0;
    int read_so_far = 0;
    int rv = 0;
    int cur_source;

    if (self == 0)
    {
        return 1;
    }

    if (self->status != TRANS_STATUS_UP)
    {
        return 1;
    }

    rv = 0;

    if (self->type1 == TRANS_TYPE_LISTENER) /* listening */
    {
        if (g_sck_can_recv(self->sck, 0))
        {
            in_sck = g_sck_accept(self->sck, self->addr, sizeof(self->addr),
                                  self->port, sizeof(self->port));

            if (in_sck == -1)
            {
                if (g_tcp_last_error_would_block(self->sck))
                {
                    /* ok, but shouldn't happen */
                }
                else
                {
                    /* error */
                    self->status = TRANS_STATUS_DOWN;
                    return 1;
                }
            }

            if (in_sck != -1)
            {
                if (self->trans_conn_in != 0) /* is function assigned */
                {
                    in_trans = trans_create(self->mode, self->in_s->size,
                                            self->out_s->size);
                    in_trans->sck = in_sck;
                    in_trans->type1 = TRANS_TYPE_SERVER;
                    in_trans->status = TRANS_STATUS_UP;
                    in_trans->is_term = self->is_term;
                    g_strncpy(in_trans->addr, self->addr,
                              sizeof(self->addr) - 1);
                    g_strncpy(in_trans->port, self->port,
                              sizeof(self->port) - 1);
                    g_sck_set_non_blocking(in_sck);
                    if (self->trans_conn_in(self, in_trans) != 0)
                    {
                        trans_delete(in_trans);
                    }
                }
                else
                {
                    g_tcp_close(in_sck);
                }
            }
        }
    }
    else /* connected server or client (2 or 3) */
    {
        if (self->si != 0 && self->si->source[self->my_source] > MAX_SBYTES)
        {
        }
        else if (self->trans_can_recv(self, self->sck, 0))
        {
            cur_source = 0;
            if (self->si != 0)
            {
                cur_source = self->si->cur_source;
                self->si->cur_source = self->my_source;
            }
            read_so_far = (int) (self->in_s->end - self->in_s->data);
            to_read = self->header_size - read_so_far;

            if (to_read > 0)
            {
                read_bytes = self->trans_recv(self, self->in_s->end, to_read);

                if (read_bytes == -1)
                {
                    if (g_tcp_last_error_would_block(self->sck))
                    {
                        /* ok, but shouldn't happen */
                    }
                    else
                    {
                        /* error */
                        self->status = TRANS_STATUS_DOWN;
                        if (self->si != 0)
                        {
                            self->si->cur_source = cur_source;
                        }
                        return 1;
                    }
                }
                else if (read_bytes == 0)
                {
                    /* error */
                    self->status = TRANS_STATUS_DOWN;
                    if (self->si != 0)
                    {
                        self->si->cur_source = cur_source;
                    }
                    return 1;
                }
                else
                {
                    self->in_s->end += read_bytes;
                }
            }

            read_so_far = (int) (self->in_s->end - self->in_s->data);

            if (read_so_far == self->header_size)
            {
                if (self->trans_data_in != 0)
                {
                    rv = self->trans_data_in(self);
                    if (self->no_stream_init_on_data_in == 0)
                    {
                        init_stream(self->in_s, 0);
                    }
                }
            }
            if (self->si != 0)
            {
                self->si->cur_source = cur_source;
            }
        }
        if (trans_send_waiting(self, 0) != 0)
        {
            /* error */
            self->status = TRANS_STATUS_DOWN;
            return 1;
        }
    }

    return rv;
}