void APP_CC g_set_term(int in_val) { if (in_val) { g_set_wait_obj(g_term_event); } else { g_reset_wait_obj(g_term_event); } }
/* wait for incoming connections */ int APP_CC xrdp_listen_main_loop(struct xrdp_listen* self) { int error; int robjs_count; int cont; char port[8]; tbus robjs[8]; tbus term_obj; tbus sync_obj; tbus sck_obj; tbus done_obj; struct xrdp_process* process; self->status = 1; xrdp_listen_get_port(port, sizeof(port)); self->sck = g_tcp_socket(); g_tcp_set_non_blocking(self->sck); error = g_tcp_bind(self->sck, port); if (error != 0) { g_writeln("bind error in xrdp_listen_main_loop"); g_tcp_close(self->sck); self->status = -1; return 1; } error = g_tcp_listen(self->sck); if (error == 0) { term_obj = g_get_term_event(); sync_obj = g_get_sync_event(); sck_obj = g_create_wait_obj_from_socket(self->sck, 0); 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++] = sck_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(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(sck_obj)) /* incomming connection */ { error = g_tcp_accept(self->sck); if ((error == -1) && g_tcp_last_error_would_block(self->sck)) { /* should not get here */ g_sleep(100); } else if (error == -1) { /* error, should not get here */ break; } else { process = xrdp_process_create(self, self->pro_done_event); if (xrdp_listen_add_pro(self, process) == 0) { /* start thread */ process->sck = error; g_process = process; tc_thread_create(xrdp_process_run, 0); tc_sem_dec(g_process_sem); /* this will wait */ } else { xrdp_process_delete(process); } } } if (g_is_wait_obj_set(done_obj)) /* pro_done_event */ { g_reset_wait_obj(done_obj); xrdp_listen_delete_done_pro(self); } } /* stop listening */ g_delete_wait_obj_from_socket(sck_obj); g_tcp_close(self->sck); /* 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; }
/* 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; }
/** * * @brief Starts sesman main loop * */ static void DEFAULT_CC sesman_main_loop(void) { int in_sck; int error; int robjs_count; int cont; tbus sck_obj; tbus robjs[8]; /*main program loop*/ log_message(&(g_cfg->log), LOG_LEVEL_INFO, "sesman[sesman_main_loop]: " "listening..."); g_sck = g_tcp_socket(); g_tcp_set_non_blocking(g_sck); error = scp_tcp_bind(g_sck, g_cfg->listen_address, g_cfg->listen_port); if (error == 0) { error = g_tcp_listen(g_sck); if (error == 0) { sck_obj = g_create_wait_obj_from_socket(g_sck, 0); cont = 1; while (cont) { /* build the wait obj list */ robjs_count = 0; robjs[robjs_count++] = sck_obj; robjs[robjs_count++] = g_term_event; robjs[robjs_count++] = g_sync_event; /* 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(g_term_event)) /* term */ { break; } if (g_is_wait_obj_set(g_sync_event)) /* sync */ { g_reset_wait_obj(g_sync_event); session_sync_start(); } if (g_is_wait_obj_set(sck_obj)) /* incomming connection */ { in_sck = g_tcp_accept(g_sck); if ((in_sck == -1) && g_tcp_last_error_would_block(g_sck)) { /* should not get here */ g_sleep(100); } else if (in_sck == -1) { /* error, should not get here */ break; } else { /* we've got a connection, so we pass it to scp code */ log_message(&(g_cfg->log), LOG_LEVEL_INFO, "sesman[sesman_main_loop]: " "new connection"); thread_scp_start(in_sck); /* todo, do we have to wait here ? */ } } } g_delete_wait_obj_from_socket(sck_obj); } else { log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "sesman[sesman_main_loop]: " "listen error %d (%s)", g_get_errno(), g_get_strerror()); } } else { log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "bind error on " "port '%s': %d (%s)", g_cfg->listen_port, g_get_errno(), g_get_strerror()); } g_tcp_close(g_sck); }
/* 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; }
int DEFAULT_CC main(int argc, char **argv) { tbus waiters[4]; int pid = 0; char text[256]; char *home_text; char *display_text; char log_file[256]; enum logReturns error; struct log_config logconfig; g_init("xrdp-chansrv"); /* os_calls */ home_text = g_getenv("HOME"); if (home_text == 0) { g_writeln("error reading HOME environment variable"); g_deinit(); return 1; } read_ini(); pid = g_getpid(); /* starting logging subsystem */ g_memset(&logconfig, 0, sizeof(struct log_config)); logconfig.program_name = "XRDP-Chansrv"; g_snprintf(log_file, 255, "%s/xrdp-chansrv.log", home_text); g_writeln("chansrv::main: using log file [%s]", log_file); if (g_file_exist(log_file)) { g_file_delete(log_file); } logconfig.log_file = log_file; logconfig.fd = -1; logconfig.log_level = LOG_LEVEL_ERROR; logconfig.enable_syslog = 0; logconfig.syslog_level = 0; error = log_start_from_param(&logconfig); if (error != LOG_STARTUP_OK) { switch (error) { case LOG_ERROR_MALLOC: g_writeln("error on malloc. cannot start logging. quitting."); break; case LOG_ERROR_FILE_OPEN: g_writeln("error opening log file [%s]. quitting.", getLogFile(text, 255)); break; default: g_writeln("log_start error"); break; } g_deinit(); return 1; } LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid)); /* set up signal handler */ g_signal_kill(term_signal_handler); /* SIGKILL */ g_signal_terminate(term_signal_handler); /* SIGTERM */ g_signal_user_interrupt(term_signal_handler); /* SIGINT */ g_signal_pipe(nil_signal_handler); /* SIGPIPE */ g_signal_child_stop(child_signal_handler); /* SIGCHLD */ display_text = g_getenv("DISPLAY"); LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text)); get_display_num_from_display(display_text); if (g_display_num == 0) { LOGM((LOG_LEVEL_ERROR, "main: error, display is zero")); g_deinit(); return 1; } LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num)); g_snprintf(text, 255, "xrdp_chansrv_%8.8x_main_term", pid); g_term_event = g_create_wait_obj(text); g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid); g_thread_done_event = g_create_wait_obj(text); g_snprintf(text, 255, "xrdp_chansrv_%8.8x_exec", pid); g_exec_event = g_create_wait_obj(text); g_exec_mutex = tc_mutex_create(); g_exec_sem = tc_sem_create(0); tc_thread_create(channel_thread_loop, 0); while (g_term_event > 0 && !g_is_wait_obj_set(g_term_event)) { waiters[0] = g_term_event; waiters[1] = g_exec_event; if (g_obj_wait(waiters, 2, 0, 0, 0) != 0) { LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); break; } if (g_is_wait_obj_set(g_term_event)) { break; } if (g_is_wait_obj_set(g_exec_event)) { g_reset_wait_obj(g_exec_event); run_exec(); } } while (g_thread_done_event > 0 && !g_is_wait_obj_set(g_thread_done_event)) { /* wait for thread to exit */ if (g_obj_wait(&g_thread_done_event, 1, 0, 0, 0) != 0) { LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); break; } } /* cleanup */ main_cleanup(); LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid)); g_deinit(); return 0; }
int xrdp_listen_main_loop(xrdpListener* self) { int i; int fds; int max_fds; int robjc; int wobjc; long sync_obj; long term_obj; long robjs[32]; int itimeout; int rcount; void* rfds[32]; fd_set rfds_set; freerdp_listener* listener; ZeroMemory(rfds, sizeof(rfds)); listener = (freerdp_listener*) self; listener->Open(listener, NULL, 3389); term_obj = g_get_term_event(); sync_obj = g_get_sync_event(); while (1) { rcount = 0; robjc = 0; wobjc = 0; itimeout = -1; robjs[robjc++] = term_obj; robjs[robjc++] = sync_obj; if (listener->GetFileDescriptor(listener, rfds, &rcount) != TRUE) { fprintf(stderr, "Failed to get FreeRDP file descriptor\n"); break; } max_fds = 0; FD_ZERO(&rfds_set); for (i = 0; i < rcount; i++) { fds = (int)(long)(rfds[i]); if (fds > max_fds) max_fds = fds; FD_SET(fds, &rfds_set); } for (i = 0; i < robjc; i++) { fds = robjs[i]; if (fds > max_fds) max_fds = fds; FD_SET(fds, &rfds_set); } if (max_fds == 0) break; if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1) { /* these are not really errors */ if (!((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EINTR))) /* signal occurred */ { fprintf(stderr, "select failed\n"); break; } } if (listener->CheckFileDescriptor(listener) != TRUE) { fprintf(stderr, "Failed to check FreeRDP file descriptor\n"); break; } if (g_is_wait_obj_set(term_obj)) { break; } if (g_is_wait_obj_set(sync_obj)) { g_reset_wait_obj(sync_obj); g_process_waiting_function(); } } listener->Close(listener); return 0; }