summaryrefslogtreecommitdiffstats
path: root/xrdp
diff options
context:
space:
mode:
Diffstat (limited to 'xrdp')
-rw-r--r--xrdp/xrdp.c77
-rw-r--r--xrdp/xrdp.h5
-rw-r--r--xrdp/xrdp.ini1
-rw-r--r--xrdp/xrdp_listen.c74
-rw-r--r--xrdp/xrdp_process.c4
-rw-r--r--xrdp/xrdp_types.h10
6 files changed, 140 insertions, 31 deletions
diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c
index 9fc10df6..ac2aae45 100644
--- a/xrdp/xrdp.c
+++ b/xrdp/xrdp.c
@@ -54,6 +54,7 @@ g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1,
if (tc_threadid_equal(tc_get_threadid(), g_threadid))
{
/* this is the main thread, call the function directly */
+ /* in fork mode, this always happens too */
sync_result = sync_func(sync_param1, sync_param2);
/*g_writeln("g_xrdp_sync processed IN main thread -> continue");*/
}
@@ -108,6 +109,32 @@ xrdp_shutdown(int sig)
}
/*****************************************************************************/
+void DEFAULT_CC
+xrdp_child(int sig)
+{
+ g_waitchild();
+}
+
+/*****************************************************************************/
+/* called in child just after fork */
+int APP_CC
+xrdp_child_fork(void)
+{
+ int pid;
+ char text[256];
+
+ /* close, don't delete these */
+ g_close_wait_obj(g_term_event);
+ g_close_wait_obj(g_sync_event);
+ pid = g_getpid();
+ g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid);
+ g_term_event = g_create_wait_obj(text);
+ g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid);
+ g_sync_event = g_create_wait_obj(text);
+ return 0;
+}
+
+/*****************************************************************************/
int APP_CC
g_is_term(void)
{
@@ -234,6 +261,12 @@ xrdp_process_params(int argc, char** argv,
startup_params->port);
}
}
+ else if ((g_strncasecmp(option, "-f", 255) == 0) ||
+ (g_strncasecmp(option, "--fork", 255) == 0))
+ {
+ startup_params->fork = 1;
+ g_writeln("--fork parameter found, ini override");
+ }
else
{
return 1;
@@ -318,7 +351,7 @@ main(int argc, char** argv)
}
if (fd == -1)
{
- g_writeln("problem opening to xrdp.pid");
+ g_writeln("problem opening to xrdp.pid [%s]", pid_file);
g_writeln("maybe its not running");
}
else
@@ -348,9 +381,11 @@ main(int argc, char** argv)
g_writeln("See http://xrdp.sourceforge.net for more information.");
g_writeln("");
g_writeln("Usage: xrdp [options]");
- g_writeln(" -h: show help");
- g_writeln(" -nodaemon: don't fork into background");
- g_writeln(" -kill: shut down xrdp");
+ g_writeln(" --help: show help");
+ g_writeln(" --nodaemon: don't fork into background");
+ g_writeln(" --kill: shut down xrdp");
+ g_writeln(" --port: tcp listen port");
+ g_writeln(" --fork: fork on new connection");
g_writeln("");
g_deinit();
g_exit(0);
@@ -375,6 +410,10 @@ main(int argc, char** argv)
}
if (!no_daemon)
{
+
+ /* make sure containing directory exists */
+ g_create_path(pid_file);
+
/* make sure we can write to pid file */
fd = g_file_open(pid_file); /* xrdp.pid */
if (fd == -1)
@@ -410,16 +449,6 @@ main(int argc, char** argv)
g_exit(0);
}
g_sleep(1000);
- g_file_close(0);
- g_file_close(1);
- g_file_close(2);
- g_file_open("/dev/null");
- g_file_open("/dev/null");
- g_file_open("/dev/null");
- /* end of daemonizing code */
- }
- if (!no_daemon)
- {
/* write the pid to file */
pid = g_getpid();
fd = g_file_open(pid_file); /* xrdp.pid */
@@ -435,6 +464,14 @@ main(int argc, char** argv)
g_file_write(fd, text, g_strlen(text));
g_file_close(fd);
}
+ g_sleep(1000);
+ g_file_close(0);
+ g_file_close(1);
+ g_file_close(2);
+ g_file_open("/dev/null");
+ g_file_open("/dev/null");
+ g_file_open("/dev/null");
+ /* end of daemonizing code */
}
g_threadid = tc_get_threadid();
g_listen = xrdp_listen_create();
@@ -442,6 +479,7 @@ main(int argc, char** argv)
g_signal_kill(xrdp_shutdown); /* SIGKILL */
g_signal_pipe(pipe_sig); /* SIGPIPE */
g_signal_terminate(xrdp_shutdown); /* SIGTERM */
+ g_signal_child_stop(xrdp_child); /* SIGCHLD */
g_sync_mutex = tc_mutex_create();
g_sync1_mutex = tc_mutex_create();
pid = g_getpid();
@@ -457,14 +495,19 @@ main(int argc, char** argv)
{
g_writeln("error creating g_sync_event");
}
- xrdp_listen_main_loop(g_listen, startup_params);
+ g_listen->startup_params = startup_params;
+ xrdp_listen_main_loop(g_listen);
xrdp_listen_delete(g_listen);
tc_mutex_delete(g_sync_mutex);
tc_mutex_delete(g_sync1_mutex);
g_delete_wait_obj(g_term_event);
g_delete_wait_obj(g_sync_event);
- /* delete the xrdp.pid file */
- g_file_delete(pid_file);
+ /* only main process should delete pid file */
+ if ((!no_daemon) && (pid == g_getpid()))
+ {
+ /* delete the xrdp.pid file */
+ g_file_delete(pid_file);
+ }
g_free(startup_params);
g_deinit();
return 0;
diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h
index 6c15ed8d..2ef81659 100644
--- a/xrdp/xrdp.h
+++ b/xrdp/xrdp.h
@@ -159,8 +159,7 @@ xrdp_listen_create(void);
void APP_CC
xrdp_listen_delete(struct xrdp_listen* self);
int APP_CC
-xrdp_listen_main_loop(struct xrdp_listen* self,
- struct xrdp_startup_params* startup_param);
+xrdp_listen_main_loop(struct xrdp_listen* self);
/* xrdp_region.c */
struct xrdp_region* APP_CC
@@ -384,6 +383,8 @@ int DEFAULT_CC
server_msg(struct xrdp_mod* mod, char* msg, int code);
int DEFAULT_CC
server_is_term(struct xrdp_mod* mod);
+int APP_CC
+xrdp_child_fork(void);
int DEFAULT_CC
server_set_clip(struct xrdp_mod* mod, int x, int y, int cx, int cy);
int DEFAULT_CC
diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini
index ee4652a9..af5f2650 100644
--- a/xrdp/xrdp.ini
+++ b/xrdp/xrdp.ini
@@ -6,6 +6,7 @@ port=3389
crypt_level=low
channel_code=1
max_bpp=24
+fork=yes
#black=000000
#grey=d6d3ce
#dark_grey=808080
diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c
index 18aed34f..b79ce1c2 100644
--- a/xrdp/xrdp_listen.c
+++ b/xrdp/xrdp_listen.c
@@ -28,21 +28,30 @@ static tbus g_process_sem = 0;
static struct xrdp_process* g_process = 0;
/*****************************************************************************/
-struct xrdp_listen* APP_CC
-xrdp_listen_create(void)
+static int
+xrdp_listen_create_pro_done(struct xrdp_listen* self)
{
- struct xrdp_listen* self;
int pid;
char text[256];
pid = g_getpid();
- self = (struct xrdp_listen*)g_malloc(sizeof(struct xrdp_listen), 1);
g_snprintf(text, 255, "xrdp_%8.8x_listen_pro_done_event", pid);
self->pro_done_event = g_create_wait_obj(text);
if(self->pro_done_event == 0)
{
g_writeln("Failure creating pro_done_event");
}
+ return 0;
+}
+
+/*****************************************************************************/
+struct xrdp_listen* APP_CC
+xrdp_listen_create(void)
+{
+ struct xrdp_listen* self;
+
+ self = (struct xrdp_listen*)g_malloc(sizeof(struct xrdp_listen), 1);
+ xrdp_listen_create_pro_done(self);
self->process_list = list_create();
if (g_process_sem == 0)
{
@@ -169,6 +178,17 @@ xrdp_listen_get_port_address(char* port, int port_bytes,
val = (char*)list_get_item(values, index);
g_strncpy(address, val, address_bytes - 1);
}
+ if (g_strcasecmp(val, "fork") == 0)
+ {
+ val = (char*)list_get_item(values, index);
+ if ((g_strcasecmp(val, "yes") == 0) ||
+ (g_strcasecmp(val, "on") == 0) ||
+ (g_strcasecmp(val, "true") == 0) ||
+ (g_atoi(val) != 0))
+ {
+ startup_param->fork = 1;
+ }
+ }
}
}
}
@@ -185,6 +205,41 @@ xrdp_listen_get_port_address(char* port, int port_bytes,
}
/*****************************************************************************/
+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;
+}
+
+/*****************************************************************************/
/* a new connection is coming in */
int DEFAULT_CC
xrdp_listen_conn_in(struct trans* self, struct trans* new_self)
@@ -193,6 +248,10 @@ xrdp_listen_conn_in(struct trans* self, struct trans* new_self)
struct xrdp_listen* lis;
lis = (struct xrdp_listen*)(self->callback_data);
+ if (lis->startup_params->fork)
+ {
+ return xrdp_listen_fork(lis, new_self);
+ }
process = xrdp_process_create(lis, lis->pro_done_event);
if (xrdp_listen_add_pro(lis, process) == 0)
{
@@ -212,8 +271,7 @@ xrdp_listen_conn_in(struct trans* self, struct trans* new_self)
/*****************************************************************************/
/* wait for incoming connections */
int APP_CC
-xrdp_listen_main_loop(struct xrdp_listen* self,
- struct xrdp_startup_params* startup_param)
+xrdp_listen_main_loop(struct xrdp_listen* self)
{
int error;
int robjs_count;
@@ -230,7 +288,7 @@ xrdp_listen_main_loop(struct xrdp_listen* self,
self->status = 1;
if (xrdp_listen_get_port_address(port, sizeof(port),
address, sizeof(address),
- startup_param) != 0)
+ self->startup_params) != 0)
{
g_writeln("xrdp_listen_main_loop: xrdp_listen_get_port failed");
self->status = -1;
@@ -282,7 +340,7 @@ xrdp_listen_main_loop(struct xrdp_listen* self,
/* Run the callback when accept() returns a new socket*/
if (trans_check_wait_objs(self->listen_trans) != 0)
{
- break;
+ break;
}
}
/* stop listening */
diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c
index 869cfd34..7a88d524 100644
--- a/xrdp/xrdp_process.c
+++ b/xrdp/xrdp_process.c
@@ -187,6 +187,10 @@ xrdp_process_main_loop(struct xrdp_process* self)
}
libxrdp_disconnect(self->session);
}
+ else
+ {
+ g_writeln("xrdp_process_main_loop: libxrdp_process_incomming failed");
+ }
xrdp_process_mod_end(self);
libxrdp_exit(self->session);
self->session = 0;
diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h
index ce646a66..0366fd83 100644
--- a/xrdp/xrdp_types.h
+++ b/xrdp/xrdp_types.h
@@ -310,6 +310,7 @@ struct xrdp_listen
struct trans* listen_trans; /* in tcp listen mode */
struct list* process_list;
tbus pro_done_event;
+ struct xrdp_startup_params* startup_params;
};
/* region */
@@ -395,12 +396,12 @@ struct xrdp_bitmap
#define DEFAULT_ELEMENT_TOP 35
#define DEFAULT_BUTTON_W 60
#define DEFAULT_BUTTON_H 23
-#define DEFAULT_COMBO_W 140
+#define DEFAULT_COMBO_W 210
#define DEFAULT_COMBO_H 21
-#define DEFAULT_EDIT_W 140
+#define DEFAULT_EDIT_W 210
#define DEFAULT_EDIT_H 21
-#define DEFAULT_WND_LOGIN_W 400
-#define DEFAULT_WND_LOGIN_H 200
+#define DEFAULT_WND_LOGIN_W 500
+#define DEFAULT_WND_LOGIN_H 250
#define DEFAULT_WND_HELP_W 340
#define DEFAULT_WND_HELP_H 300
#define DEFAULT_WND_LOG_W 400
@@ -431,4 +432,5 @@ struct xrdp_startup_params
int no_daemon;
int help;
int version;
+ int fork;
};