summaryrefslogtreecommitdiffstats
path: root/xrdp
diff options
context:
space:
mode:
Diffstat (limited to 'xrdp')
-rw-r--r--xrdp/xrdp_listen.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c
new file mode 100644
index 00000000..2112a7ef
--- /dev/null
+++ b/xrdp/xrdp_listen.c
@@ -0,0 +1,138 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ Copyright (C) Jay Sorg 2004
+
+ listen for incoming connection
+
+*/
+
+#include "xrdp.h"
+
+static struct xrdp_process* g_process = 0;
+
+/*****************************************************************************/
+struct xrdp_listen* xrdp_listen_create(void)
+{
+ struct xrdp_listen* self;
+
+ self = (struct xrdp_listen*)g_malloc(sizeof(struct xrdp_listen), 1);
+ self->process_list_max = 100;
+ return self;
+}
+
+/*****************************************************************************/
+void xrdp_listen_delete(struct xrdp_listen* self)
+{
+ g_free(self);
+}
+
+/*****************************************************************************/
+int xrdp_listen_term_processes(struct xrdp_listen* self)
+{
+ int i;
+
+ /* tell all xrdp processes to end */
+ for (i = 0; i < self->process_list_count; i++)
+ if (self->process_list[i] != 0)
+ self->process_list[i]->term = 1;
+ /* make sure they are done */
+ for (i = 0; i < self->process_list_count; i++)
+ if (self->process_list[i] != 0)
+ while (self->process_list[i]->status > 0)
+ g_sleep(10);
+ /* free them all */
+ for (i = 0; i < self->process_list_count; i++)
+ if (self->process_list[i] != 0)
+ xrdp_process_delete(self->process_list[i]);
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+int xrdp_listen_add_pro(struct xrdp_listen* self)
+{
+ int i;
+
+ for (i = 0; i < self->process_list_max; i++)
+ {
+ /* add process in new slot */
+ if (self->process_list[i] == 0)
+ {
+ self->process_list[i] = g_process;
+ self->process_list_count++;
+ return 0;
+ }
+ /* add process in unused slot */
+ if (self->process_list[i]->status <= 0)
+ {
+ xrdp_process_delete(self->process_list[i]);
+ self->process_list[i] = g_process;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/*****************************************************************************/
+/* i can't get stupid in_val to work, hum using global var for now */
+void* xrdp_process_run(void* in_val)
+{
+ DEBUG(("process started\n\r"));
+ xrdp_process_main_loop(g_process);
+ DEBUG(("process done\n\r"));
+ return 0;
+}
+
+/*****************************************************************************/
+/* wait for incoming connections */
+int xrdp_listen_main_loop(struct xrdp_listen* self)
+{
+ int error;
+
+ self->status = 1;
+ self->sck = g_tcp_socket();
+ g_tcp_set_non_blocking(self->sck);
+ g_tcp_bind(self->sck, "3389");
+ error = g_tcp_listen(self->sck);
+ if (error == 0)
+ {
+ while (!g_is_term() && !self->term)
+ {
+ error = g_tcp_accept(self->sck);
+ if (error == -1 && g_tcp_last_error_would_block(self->sck))
+ g_sleep(100);
+ else if (error == -1)
+ break;
+ else
+ {
+ g_process = xrdp_process_create(self);
+ if (xrdp_listen_add_pro(self) == 0)
+ {
+ /* start thread */
+ g_process->sck = error;
+ g_thread_create(xrdp_process_run, 0);
+ g_sleep(100);
+ }
+ else
+ xrdp_process_delete(g_process);
+ }
+ }
+ }
+ xrdp_listen_term_processes(self);
+ g_tcp_close(self->sck);
+ self->status = -1;
+ return 0;
+}