summaryrefslogtreecommitdiffstats
path: root/sesman
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-08-20 00:29:09 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-08-20 00:29:09 -0500
commit57029de2707808c3e7d12568af3de87eaca71828 (patch)
tree0dd7aca471ffddede7d6ec8d54d075e515a9ca9e /sesman
parentb62256d54dd71705a29da49bc8ee62d6ebd95230 (diff)
parentc5862f367ca68763dd3070598a36ea82db7f3566 (diff)
downloadxrdp-proprietary-57029de2707808c3e7d12568af3de87eaca71828.tar.gz
xrdp-proprietary-57029de2707808c3e7d12568af3de87eaca71828.zip
Merge remote-tracking branch 'origin/master'
Diffstat (limited to 'sesman')
-rw-r--r--sesman/access.c26
-rw-r--r--sesman/chansrv/Makefile.am20
-rw-r--r--sesman/chansrv/chansrv.c658
-rw-r--r--sesman/chansrv/chansrv.h47
-rw-r--r--sesman/chansrv/clipboard.c774
-rw-r--r--sesman/chansrv/clipboard.h38
-rw-r--r--sesman/chansrv/devredir.c35
-rw-r--r--sesman/chansrv/devredir.h17
-rw-r--r--sesman/chansrv/rail.c677
-rw-r--r--sesman/chansrv/rail.h35
-rw-r--r--sesman/chansrv/sound.c533
-rw-r--r--sesman/chansrv/sound.h60
-rw-r--r--sesman/chansrv/xcommon.c187
-rw-r--r--sesman/chansrv/xcommon.h34
-rw-r--r--sesman/config.c43
-rw-r--r--sesman/config.h5
-rw-r--r--sesman/env.c6
-rw-r--r--sesman/libscp/Makefile.am4
-rw-r--r--sesman/libscp/libscp_connection.c4
-rw-r--r--sesman/libscp/libscp_init.c10
-rw-r--r--sesman/libscp/libscp_init.h2
-rw-r--r--sesman/libscp/libscp_session.c51
-rw-r--r--sesman/libscp/libscp_tcp.c4
-rw-r--r--sesman/libscp/libscp_types.h4
-rw-r--r--sesman/libscp/libscp_v0.c107
-rw-r--r--sesman/libscp/libscp_v0.h9
-rw-r--r--sesman/libscp/libscp_v1c_mng.c38
-rw-r--r--sesman/libscp/libscp_v1s.c82
-rw-r--r--sesman/libscp/libscp_v1s_mng.c18
-rw-r--r--sesman/lock.c16
-rw-r--r--sesman/scp.c20
-rw-r--r--sesman/scp_v0.c31
-rw-r--r--sesman/scp_v1.c46
-rw-r--r--sesman/scp_v1_mng.c22
-rw-r--r--sesman/sesman.c33
-rw-r--r--sesman/sesman.ini4
-rw-r--r--sesman/session.c171
-rw-r--r--sesman/session.h4
-rw-r--r--sesman/sessvc/Makefile.am2
-rw-r--r--sesman/sig.c36
-rw-r--r--sesman/thread.c41
-rw-r--r--sesman/tools/Makefile.am19
-rw-r--r--sesman/tools/sesadmin.c10
-rw-r--r--sesman/tools/sestest.c4
-rw-r--r--sesman/tools/xcon.c35
-rw-r--r--sesman/verify_user.c18
46 files changed, 3253 insertions, 787 deletions
diff --git a/sesman/access.c b/sesman/access.c
index f4bfd30a..0037de3f 100644
--- a/sesman/access.c
+++ b/sesman/access.c
@@ -38,33 +38,33 @@ access_login_allowed(char* user)
if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root))
{
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING,
+ log_message(LOG_LEVEL_WARNING,
"ROOT login attempted, but root login is disabled");
return 0;
}
if (0 == g_cfg->sec.ts_users_enable)
{
- LOG_DBG(&(g_cfg->log), "Terminal Server Users group is disabled, allowing authentication",
+ LOG_DBG("Terminal Server Users group is disabled, allowing authentication",
1);
return 1;
}
if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0))
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "Cannot read user info! - login denied");
+ log_message(LOG_LEVEL_ERROR, "Cannot read user info! - login denied");
return 0;
}
if (g_cfg->sec.ts_users == gid)
{
- LOG_DBG(&(g_cfg->log), "ts_users is user's primary group");
+ LOG_DBG("ts_users is user's primary group");
return 1;
}
if (0 != g_check_user_in_group(user, g_cfg->sec.ts_users, &ok))
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "Cannot read group info! - login denied");
+ log_message(LOG_LEVEL_ERROR, "Cannot read group info! - login denied");
return 0;
}
@@ -73,7 +73,7 @@ access_login_allowed(char* user)
return 1;
}
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "login denied for user %s", user);
+ log_message(LOG_LEVEL_INFO, "login denied for user %s", user);
return 0;
}
@@ -87,33 +87,33 @@ access_login_mng_allowed(char* user)
if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root))
{
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING,
+ log_message(LOG_LEVEL_WARNING,
"[MNG] ROOT login attempted, but root login is disabled");
return 0;
}
if (0 == g_cfg->sec.ts_admins_enable)
{
- LOG_DBG(&(g_cfg->log), "[MNG] Terminal Server Admin group is disabled, allowing authentication",
- 1);
+ LOG_DBG("[MNG] Terminal Server Admin group is disabled,"
+ "allowing authentication",1);
return 1;
}
if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0))
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "[MNG] Cannot read user info! - login denied");
+ log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read user info! - login denied");
return 0;
}
if (g_cfg->sec.ts_admins == gid)
{
- LOG_DBG(&(g_cfg->log), "[MNG] ts_users is user's primary group");
+ LOG_DBG("[MNG] ts_users is user's primary group");
return 1;
}
if (0 != g_check_user_in_group(user, g_cfg->sec.ts_admins, &ok))
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "[MNG] Cannot read group info! - login denied");
+ log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read group info! - login denied");
return 0;
}
@@ -122,7 +122,7 @@ access_login_mng_allowed(char* user)
return 1;
}
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "[MNG] login denied for user %s", user);
+ log_message(LOG_LEVEL_INFO, "[MNG] login denied for user %s", user);
return 0;
}
diff --git a/sesman/chansrv/Makefile.am b/sesman/chansrv/Makefile.am
index 486d49a8..9d52d950 100644
--- a/sesman/chansrv/Makefile.am
+++ b/sesman/chansrv/Makefile.am
@@ -1,10 +1,21 @@
EXTRA_DIST = chansrv.h clipboard.h devredir.h sound.h
+EXTRA_DEFINES =
+EXTRA_INCLUDES =
+EXTRA_LIBS =
+EXTRA_FLAGS =
+
+if XRDP_SIMPLESOUND
+EXTRA_DEFINES += -DXRDP_SIMPLESOUND
+EXTRA_LIBS += -lpthread -lpulse -lpulse-simple
+endif
+
AM_CFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
- -DXRDP_PID_PATH=\"${localstatedir}/run\"
+ -DXRDP_PID_PATH=\"${localstatedir}/run\" \
+ $(EXTRA_DEFINES)
INCLUDES = \
-I$(top_srcdir)/common \
@@ -17,7 +28,12 @@ xrdp_chansrv_SOURCES = \
chansrv.c \
sound.c \
clipboard.c \
- devredir.c
+ devredir.c \
+ rail.c \
+ xcommon.c
+
+xrdp_chansrv_LDFLAGS = \
+ $(EXTRA_FLAGS)
xrdp_chansrv_LDADD = \
-L/usr/X11R6/lib \
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c
index eb892100..c7917d03 100644
--- a/sesman/chansrv/chansrv.c
+++ b/sesman/chansrv/chansrv.c
@@ -1,21 +1,20 @@
-/*
- 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.
-
- xrdp: A Remote Desktop Protocol server.
- Copyright (C) Jay Sorg 2009-2010
-*/
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
#include "arch.h"
#include "os_calls.h"
@@ -29,16 +28,22 @@
#include "list.h"
#include "file.h"
#include "file_loc.h"
+#include "log.h"
+#include "rail.h"
+#include "xcommon.h"
#include "libraptorsmiface.h"
static struct trans* g_lis_trans = 0;
static struct trans* g_con_trans = 0;
+static struct trans* g_api_lis_trans = 0;
+static struct trans* g_api_con_trans = 0;
static struct chan_item g_chan_items[32];
static int g_num_chan_items = 0;
static int g_cliprdr_index = -1;
static int g_rdpsnd_index = -1;
static int g_rdpdr_index = -1;
+static int g_rail_index = -1;
static tbus g_term_event = 0;
static tbus g_thread_done_event = 0;
@@ -49,6 +54,21 @@ int g_display_num = 0;
int g_cliprdr_chan_id = -1; /* cliprdr */
int g_rdpsnd_chan_id = -1; /* rdpsnd */
int g_rdpdr_chan_id = -1; /* rdpdr */
+int g_rail_chan_id = -1; /* rail */
+
+char* g_exec_name;
+tbus g_exec_event;
+tbus g_exec_mutex;
+tbus g_exec_sem;
+int g_exec_pid = 0;
+
+/* data in struct trans::callback_data */
+struct xrdp_api_data
+{
+ int chan_id;
+ char header[64];
+ int flags;
+};
//#if 0
#include <stdio.h>
@@ -77,55 +97,132 @@ void dprint(const char *fmt, ...)
//#endif
/*****************************************************************************/
+/* add data to chan_item, on its way to the client */
/* returns error */
-int APP_CC
-send_channel_data(int chan_id, char* data, int size)
+static int APP_CC
+add_data_to_chan_item(struct chan_item* chan_item, char* data, int size)
{
- struct stream * s = (struct stream *)NULL;
- int chan_flags = 0;
- int total_size = 0;
- int sent = 0;
- int rv = 0;
+ struct stream* s;
+ struct chan_out_data* cod;
+ make_stream(s);
+ init_stream(s, size);
+ g_memcpy(s->data, data, size);
+ s->end = s->data + size;
+ cod = (struct chan_out_data*)g_malloc(sizeof(struct chan_out_data), 1);
+ cod->s = s;
+ if (chan_item->tail == 0)
+ {
+ chan_item->tail = cod;
+ chan_item->head = cod;
+ }
+ else
+ {
+ chan_item->tail->next = cod;
+ chan_item->tail = cod;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+static int APP_CC
+send_data_from_chan_item(struct chan_item* chan_item)
+{
+ struct stream* s;
+ struct chan_out_data* cod;
+ int bytes_left;
+ int size;
+ int chan_flags;
+ int error;
+
+ if (chan_item->head == 0)
+ {
+ return 0;
+ }
+ cod = chan_item->head;
+ bytes_left = (int)(cod->s->end - cod->s->p);
+ size = MIN(1600, bytes_left);
+ chan_flags = 0;
+ if (cod->s->p == cod->s->data)
+ {
+ chan_flags |= 1; /* first */
+ }
+ if (cod->s->p + size >= cod->s->end)
+ {
+ chan_flags |= 2; /* last */
+ }
s = trans_get_out_s(g_con_trans, 8192);
- if (s == 0)
+ out_uint32_le(s, 0); /* version */
+ out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */
+ out_uint32_le(s, 8); /* msg id */
+ out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */
+ out_uint16_le(s, chan_item->id);
+ out_uint16_le(s, chan_flags);
+ out_uint16_le(s, size);
+ out_uint32_le(s, cod->s->size);
+ out_uint8a(s, cod->s->p, size);
+ s_mark_end(s);
+ LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: -- "
+ "size %d chan_flags 0x%8.8x", size, chan_flags));
+ error = trans_force_write(g_con_trans);
+ if (error != 0)
{
return 1;
}
- rv = 0;
- sent = 0;
- total_size = size;
- while (sent < total_size)
+ cod->s->p += size;
+ if (cod->s->p >= cod->s->end)
{
- size = MIN(1600, total_size - sent);
- chan_flags = 0;
- if (sent == 0)
+ free_stream(cod->s);
+ chan_item->head = chan_item->head->next;
+ if (chan_item->head == 0)
{
- chan_flags |= 1; /* first */
+ chan_item->tail = 0;
}
- if (size + sent == total_size)
+ g_free(cod);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+static int APP_CC
+check_chan_items(void)
+{
+ int index;
+
+ for (index = 0; index < g_num_chan_items; index++)
+ {
+ if (g_chan_items[index].head != 0)
{
- chan_flags |= 2; /* last */
+ send_data_from_chan_item(g_chan_items + index);
}
- out_uint32_le(s, 0); /* version */
- out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */
- out_uint32_le(s, 8); /* msg id */
- out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */
- out_uint16_le(s, chan_id);
- out_uint16_le(s, chan_flags);
- out_uint16_le(s, size);
- out_uint32_le(s, total_size);
- out_uint8a(s, data + sent, size);
- s_mark_end(s);
- rv = trans_force_write(g_con_trans);
- if (rv != 0)
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+int APP_CC
+send_channel_data(int chan_id, char* data, int size)
+{
+ int index;
+
+ LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: size %d", size));
+ if (chan_id == -1)
+ {
+ return 1;
+ }
+ for (index = 0; index < g_num_chan_items; index++)
+ {
+ if (g_chan_items[index].id == chan_id)
{
- break;
+ add_data_to_chan_item(g_chan_items + index, data, size);
+ check_chan_items();
+ return 0;
}
- sent += size;
- s = trans_get_out_s(g_con_trans, 8192);
}
- return rv;
+ return 1;
}
/*****************************************************************************/
@@ -135,7 +232,7 @@ send_init_response_message(void)
{
struct stream * s = (struct stream *)NULL;
- LOG(1, ("send_init_response_message:"));
+ LOGM((LOG_LEVEL_INFO, "send_init_response_message:"));
s = trans_get_out_s(g_con_trans, 8192);
if (s == 0)
{
@@ -157,7 +254,7 @@ send_channel_setup_response_message(void)
{
struct stream * s = (struct stream *)NULL;
- LOG(10, ("send_channel_setup_response_message:"));
+ LOGM((LOG_LEVEL_DEBUG, "send_channel_setup_response_message:"));
s = trans_get_out_s(g_con_trans, 8192);
if (s == 0)
{
@@ -178,7 +275,7 @@ send_channel_data_response_message(void)
{
struct stream * s = (struct stream *)NULL;
- LOG(10, ("send_channel_data_response_message:"));
+ LOGM((LOG_LEVEL_DEBUG, "send_channel_data_response_message:"));
s = trans_get_out_s(g_con_trans, 8192);
if (s == 0)
{
@@ -197,7 +294,7 @@ send_channel_data_response_message(void)
static int APP_CC
process_message_init(struct stream* s)
{
- LOG(10, ("process_message_init:"));
+ LOGM((LOG_LEVEL_DEBUG, "process_message_init:"));
return send_init_response_message();
}
@@ -206,21 +303,24 @@ process_message_init(struct stream* s)
static int APP_CC
process_message_channel_setup(struct stream* s)
{
- int num_chans = 0;
- int index = 0;
- int rv = 0;
- struct chan_item* ci = (struct chan_item *)NULL;
+ int num_chans;
+ int index;
+ int rv;
+ struct chan_item* ci;
g_num_chan_items = 0;
g_cliprdr_index = -1;
g_rdpsnd_index = -1;
g_rdpdr_index = -1;
+ g_rail_index = -1;
g_cliprdr_chan_id = -1;
g_rdpsnd_chan_id = -1;
g_rdpdr_chan_id = -1;
- LOG(10, ("process_message_channel_setup:"));
+ g_rail_chan_id = -1;
+ LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup:"));
in_uint16_le(s, num_chans);
- LOG(10, ("process_message_channel_setup: num_chans %d", num_chans));
+ LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: num_chans %d",
+ num_chans));
for (index = 0; index < num_chans; index++)
{
ci = &(g_chan_items[g_num_chan_items]);
@@ -228,8 +328,8 @@ process_message_channel_setup(struct stream* s)
in_uint8a(s, ci->name, 8);
in_uint16_le(s, ci->id);
in_uint16_le(s, ci->flags);
- LOG(10, ("process_message_channel_setup: chan name '%s' "
- "id %d flags %8.8x", ci->name, ci->id, ci->flags));
+ LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: chan name '%s' "
+ "id %d flags %8.8x", ci->name, ci->id, ci->flags));
if (g_strcasecmp(ci->name, "cliprdr") == 0)
{
g_cliprdr_index = g_num_chan_items;
@@ -245,6 +345,15 @@ process_message_channel_setup(struct stream* s)
g_rdpdr_index = g_num_chan_items;
g_rdpdr_chan_id = ci->id;
}
+ else if (g_strcasecmp(ci->name, "rail") == 0)
+ {
+ g_rail_index = g_num_chan_items;
+ g_rail_chan_id = ci->id;
+ }
+ else
+ {
+ LOG(10, ("other %s", ci->name));
+ }
g_num_chan_items++;
}
rv = send_channel_setup_response_message();
@@ -275,13 +384,15 @@ process_message_channel_data(struct stream* s)
int rv = 0;
int length = 0;
int total_length = 0;
+ struct stream* ls;
in_uint16_le(s, chan_id);
in_uint16_le(s, chan_flags);
in_uint16_le(s, length);
in_uint32_le(s, total_length);
- LOG(10, ("process_message_channel_data: chan_id %d "
- "chan_flags %d", chan_id, chan_flags));
+ LOGM((LOG_LEVEL_DEBUG,"process_message_channel_data: chan_id %d "
+ "chan_flags %d", chan_id, chan_flags));
+ LOG(10, ("process_message_channel_data"));
rv = send_channel_data_response_message();
if (rv == 0)
{
@@ -297,6 +408,27 @@ process_message_channel_data(struct stream* s)
{
rv = dev_redir_data_in(s, chan_id, chan_flags, length, total_length);
}
+ else if (chan_id == g_rail_chan_id)
+ {
+ rv = rail_data_in(s, chan_id, chan_flags, length, total_length);
+ }
+ else if (chan_id == ((struct xrdp_api_data*)
+ (g_api_con_trans->callback_data))->chan_id)
+ {
+ LOG(10, ("process_message_channel_data length %d total_length %d "
+ "chan_flags 0x%8.8x", length, total_length, chan_flags));
+ ls = g_api_con_trans->out_s;
+ if (chan_flags & 1) /* first */
+ {
+ init_stream(ls, total_length);
+ }
+ out_uint8a(ls, s->p, length);
+ if (chan_flags & 2) /* last */
+ {
+ s_mark_end(ls);
+ trans_force_write(g_api_con_trans);
+ }
+ }
}
return rv;
}
@@ -307,6 +439,7 @@ static int APP_CC
process_message_channel_data_response(struct stream* s)
{
LOG(10, ("process_message_channel_data_response:"));
+ check_chan_items();
return 0;
}
@@ -352,8 +485,8 @@ process_message(void)
rv = process_message_channel_data_response(s);
break;
default:
- LOG(0, ("process_message: error in process_message "
- "unknown msg %d", id));
+ LOGM((LOG_LEVEL_ERROR, "process_message: error in process_message ",
+ "unknown msg %d", id));
break;
}
if (rv != 0)
@@ -361,9 +494,7 @@ process_message(void)
LOG(0, ("process_message: error in process_message: rv %d", rv));
break;
}
- else {
- s->p = next_msg;
- }
+ s->p = next_msg;
}
return rv;
}
@@ -386,7 +517,7 @@ my_trans_data_in(struct trans* trans)
{
return 1;
}
- LOG(10, ("my_trans_data_in:"));
+ LOGM((LOG_LEVEL_DEBUG, "my_trans_data_in:"));
s = trans_get_in_s(trans);
in_uint32_le(s, id);
in_uint32_le(s, size);
@@ -400,6 +531,44 @@ my_trans_data_in(struct trans* trans)
}
/*****************************************************************************/
+/* returns error */
+int DEFAULT_CC
+my_api_trans_data_in(struct trans* trans)
+{
+ struct stream* s;
+ int error;
+ struct xrdp_api_data* ad;
+
+ LOG(10, ("my_api_trans_data_in:"));
+ if (trans == 0)
+ {
+ return 0;
+ }
+ if (trans != g_api_con_trans)
+ {
+ return 1;
+ }
+ LOGM((LOG_LEVEL_DEBUG, "my_api_trans_data_in:"));
+ s = trans_get_in_s(trans);
+ error = g_tcp_recv(trans->sck, s->data, 8192, 0);
+ if (error > 0)
+ {
+ LOG(10, ("my_api_trans_data_in: got data %d", error));
+ ad = (struct xrdp_api_data*)(trans->callback_data);
+ if (send_channel_data(ad->chan_id, s->data, error) != 0)
+ {
+ LOG(0, ("my_api_trans_data_in: send_channel_data failed"));
+ }
+ }
+ else
+ {
+ LOG(10, ("my_api_trans_data_in: g_tcp_recv failed, or disconnected"));
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
int DEFAULT_CC
my_trans_conn_in(struct trans* trans, struct trans* new_trans)
{
@@ -419,7 +588,7 @@ my_trans_conn_in(struct trans* trans, struct trans* new_trans)
{
return 1;
}
- LOG(10, ("my_trans_conn_in:"));
+ LOGM((LOG_LEVEL_DEBUG, "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;
@@ -430,6 +599,84 @@ my_trans_conn_in(struct trans* trans, struct trans* new_trans)
}
/*****************************************************************************/
+int DEFAULT_CC
+my_api_trans_conn_in(struct trans* trans, struct trans* new_trans)
+{
+ struct xrdp_api_data* ad;
+ int error;
+ int index;
+ int found;
+ struct stream* s;
+
+ if (trans == 0)
+ {
+ return 1;
+ }
+ if (trans != g_api_lis_trans)
+ {
+ return 1;
+ }
+ if (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);
+
+ found = 0;
+ if (ad->flags | 1) /* WTS_CHANNEL_OPTION_DYNAMIC */
+ {
+ /* TODO */
+ found = 0;
+ }
+ else
+ {
+ for (index = 0; index < g_num_chan_items; index++)
+ {
+ LOG(10, (" %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;
+ found = 1;
+ break;
+ }
+ }
+ }
+ LOG(10, ("my_api_trans_conn_in: found %d", found));
+ if (!found)
+ {
+ ad->chan_id = -1;
+ }
+
+ 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;
+}
+
+/*****************************************************************************/
static int APP_CC
setup_listen(void)
{
@@ -443,7 +690,8 @@ setup_listen(void)
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);
+ g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d",
+ 7200 + g_display_num);
}
else
{
@@ -454,7 +702,28 @@ setup_listen(void)
error = trans_listen(g_lis_trans, port);
if (error != 0)
{
- LOG(0, ("setup_listen: trans_listen failed for port %s", port));
+ LOGM((LOG_LEVEL_ERROR, "setup_listen: trans_listen failed for port %s",
+ port));
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+setup_api_listen(void)
+{
+ char port[256];
+ int error = 0;
+
+ g_api_lis_trans = trans_create(2, 8192, 8192);
+ g_snprintf(port, 255, "/tmp/.xrdp/xrdpapi_%d", g_display_num);
+ g_api_lis_trans->trans_conn_in = my_api_trans_conn_in;
+ error = trans_listen(g_api_lis_trans, port);
+ if (error != 0)
+ {
+ LOGM((LOG_LEVEL_ERROR, "setup_api_listen: trans_listen failed for port %s",
+ port));
return 1;
}
return 0;
@@ -465,13 +734,14 @@ THREAD_RV THREAD_CC
channel_thread_loop(void* in_val)
{
tbus objs[32];
- int num_objs = 0;
- int timeout = 0;
- int error = 0;
- THREAD_RV rv = 0;
+ int num_objs;
+ int timeout;
+ int error;
+ THREAD_RV rv;
- LOG(1, ("channel_thread_loop: thread start"));
+ LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start"));
rv = 0;
+ setup_api_listen();
error = setup_listen();
if (error == 0)
{
@@ -479,33 +749,37 @@ channel_thread_loop(void* in_val)
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_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))
{
- LOG(0, ("channel_thread_loop: g_term_event set"));
+ 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)
{
- LOG(0, ("channel_thread_loop: trans_check_wait_objs error"));
+ 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)
{
- LOG(0, ("channel_thread_loop: "
- "trans_check_wait_objs error resetting"));
+ 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;
@@ -519,16 +793,40 @@ channel_thread_loop(void* in_val)
}
}
}
- clipboard_check_wait_objs();
+ 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();
timeout = -1;
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);
+ 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);
}
@@ -537,7 +835,11 @@ channel_thread_loop(void* in_val)
g_lis_trans = 0;
trans_delete(g_con_trans);
g_con_trans = 0;
- LOG(0, ("channel_thread_loop: thread stop"));
+ 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;
}
@@ -546,7 +848,7 @@ channel_thread_loop(void* in_val)
void DEFAULT_CC
term_signal_handler(int sig)
{
- LOG(1, ("term_signal_handler: got signal %d", sig));
+ LOGM((LOG_LEVEL_INFO, "term_signal_handler: got signal %d", sig));
g_set_wait_obj(g_term_event);
}
@@ -554,26 +856,44 @@ term_signal_handler(int sig)
void DEFAULT_CC
nil_signal_handler(int sig)
{
- LOG(1, ("nil_signal_handler: got signal %d", sig));
- g_set_wait_obj(g_term_event);
+ LOGM((LOG_LEVEL_INFO, "nil_signal_handler: got signal %d", sig));
+}
+
+/*****************************************************************************/
+void DEFAULT_CC
+child_signal_handler(int sig)
+{
+ int i1;
+
+ LOG(10, ("child_signal_handler:"));
+ do
+ {
+ i1 = g_waitchild();
+ if (i1 == g_exec_pid)
+ {
+ LOG(0, ("child_signal_handler: found pid %d", i1));
+ //shutdownx();
+ }
+ LOG(10, (" %d", i1));
+ } while (i1 >= 0);
}
/*****************************************************************************/
static int APP_CC
-get_display_num_from_display(char * display_text)
+get_display_num_from_display(char* display_text)
{
- int index = 0;
- int mode = 0;
- int host_index = 0;
- int disp_index = 0;
- int scre_index = 0;
- char host[256] = "";
- char disp[256] = "";
- char scre[256] = "";
-
- g_memset(host,0,256);
- g_memset(disp,0,256);
- g_memset(scre,0,256);
+ int index;
+ int mode;
+ int host_index;
+ int disp_index;
+ int scre_index;
+ char host[256];
+ char disp[256];
+ char scre[256];
+
+ g_memset(host, 0, 256);
+ g_memset(disp, 0, 256);
+ g_memset(scre, 0, 256);
index = 0;
host_index = 0;
@@ -620,6 +940,8 @@ main_cleanup(void)
{
g_delete_wait_obj(g_term_event);
g_delete_wait_obj(g_thread_done_event);
+ g_delete_wait_obj(g_exec_event);
+ tc_mutex_delete(g_exec_mutex);
g_deinit(); /* os_calls */
return 0;
}
@@ -628,15 +950,14 @@ main_cleanup(void)
static int APP_CC
read_ini(void)
{
- char filename[256] = "";
- struct list* names = (struct list *)NULL;
- struct list* values = (struct list *)NULL;
- char* name = (char *)NULL;
- char* value = (char *)NULL;
- int index = 0;
-
- g_memset(filename,0,(sizeof(char)*256));
+ char filename[256];
+ struct list* names;
+ struct list* values;
+ char* name;
+ char* value;
+ int index;
+ g_memset(filename,0,(sizeof(char) * 256));
names = list_create();
names->auto_free = 1;
values = list_create();
@@ -666,51 +987,140 @@ read_ini(void)
}
/*****************************************************************************/
+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;
+}
+
+/*****************************************************************************/
int DEFAULT_CC
main(int argc, char** argv)
{
+ tbus waiters[4];
int pid = 0;
- char text[256] = "";
- char* display_text = (char *)NULL;
+ 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();
- LOG(1, ("main: app started pid %d(0x%8.8x)", pid, pid));
+ /* 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");
- LOG(1, ("main: DISPLAY env var set to %s", display_text));
+ 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)
{
- LOG(0, ("main: error, display is zero"));
+ LOGM((LOG_LEVEL_ERROR, "main: error, display is zero"));
+ g_deinit();
return 1;
}
- LOG(1, ("main: using DISPLAY %d", g_display_num));
+ 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))
{
- if (g_obj_wait(&g_term_event, 1, 0, 0, 0) != 0)
+ 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))
{
- LOG(0, ("main: error, g_obj_wait failed"));
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)
{
- LOG(0, ("main: error, g_obj_wait failed"));
+ LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed"));
break;
}
}
@@ -718,7 +1128,7 @@ main(int argc, char** argv)
raptor_sm_set_session_state(g_display_num, SM_STATUS_RUNNING);
/* cleanup */
main_cleanup();
- LOG(1, ("main: app exiting pid %d(0x%8.8x)", pid, pid));
+ LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid));
g_deinit();
return 0;
}
diff --git a/sesman/chansrv/chansrv.h b/sesman/chansrv/chansrv.h
index b265458f..ba593461 100644
--- a/sesman/chansrv/chansrv.h
+++ b/sesman/chansrv/chansrv.h
@@ -1,15 +1,41 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
#if !defined(CHANSRV_H)
#define CHANSRV_H
#include "arch.h"
#include "parse.h"
+#include "log.h"
+
+struct chan_out_data
+{
+ struct stream* s;
+ struct chan_out_data* next;
+};
struct chan_item
{
int id;
int flags;
char name[16];
+ struct chan_out_data* head;
+ struct chan_out_data* tail;
};
int APP_CC
@@ -28,4 +54,25 @@ main_cleanup(void);
} \
}
+#define LOGM(_args) do { log_message _args ; } while (0)
+
+#ifndef GSET_UINT8
+#define GSET_UINT8(_ptr, _offset, _data) \
+ *((unsigned char*) (((unsigned char*)(_ptr)) + (_offset))) = (unsigned char)(_data)
+#define GGET_UINT8(_ptr, _offset) \
+ (*((unsigned char*) (((unsigned char*)(_ptr)) + (_offset))))
+#define GSET_UINT16(_ptr, _offset, _data) \
+ GSET_UINT8(_ptr, _offset, _data); \
+ GSET_UINT8(_ptr, (_offset) + 1, (_data) >> 8)
+#define GGET_UINT16(_ptr, _offset) \
+ (GGET_UINT8(_ptr, _offset)) | \
+ ((GGET_UINT8(_ptr, (_offset) + 1)) << 8)
+#define GSET_UINT32(_ptr, _offset, _data) \
+ GSET_UINT16(_ptr, _offset, _data); \
+ GSET_UINT16(_ptr, (_offset) + 2, (_data) >> 16)
+#define GGET_UINT32(_ptr, _offset) \
+ (GGET_UINT16(_ptr, _offset)) | \
+ ((GGET_UINT16(_ptr, (_offset) + 2)) << 16)
+#endif
+
#endif
diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c
index cf601a8e..3bea9704 100644
--- a/sesman/chansrv/clipboard.c
+++ b/sesman/chansrv/clipboard.c
@@ -1,25 +1,30 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ * Copyright (C) Laxmikant Rashinkar 2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
/*
- 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.
-
- xrdp: A Remote Desktop Protocol server.
- Copyright (C) Jay Sorg 2009-2010
-
for help see
http://tronche.com/gui/x/icccm/sec-2.html#s-2
.../kde/kdebase/workspace/klipper/clipboardpoll.cpp
+ Revision:
+ Aug 05, 2012:
+ Laxmikant Rashinkar (LK dot Rashinkar at gmail.com)
+ added clipboard support for BMP images
*/
#include <X11/Xlib.h>
@@ -29,6 +34,29 @@
#include "parse.h"
#include "os_calls.h"
#include "chansrv.h"
+#include "clipboard.h"
+#include "xcommon.h"
+
+static char g_bmp_image_header[] =
+{
+ /* this is known to work */
+ //0x42, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+ /* THIS IS BEING SENT BY WIN2008 */
+ 0x42, 0x4d, 0x16, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00
+};
+
+extern int g_cliprdr_chan_id; /* in chansrv.c */
+
+extern Display* g_display; /* in xcommon.c */
+extern int g_x_socket; /* in xcommon.c */
+extern tbus g_x_wait_obj; /* in xcommon.c */
+extern Screen* g_screen; /* in xcommon.c */
+extern int g_screen_num; /* in xcommon.c */
+
+int g_clip_up = 0;
+int g_waiting_for_data_response = 0;
+int g_waiting_for_data_response_time = 0;
static Atom g_clipboard_atom = 0;
static Atom g_clip_property_atom = 0;
@@ -39,12 +67,9 @@ static Atom g_primary_atom = 0;
static Atom g_secondary_atom = 0;
static Atom g_get_time_atom = 0;
static Atom g_utf8_atom = 0;
-static int g_x_socket = 0;
-static tbus g_x_wait_obj = 0;
-static int g_clip_up = 0;
+static Atom g_image_bmp_atom = 0;
+
static Window g_wnd = 0;
-static Screen* g_screen = 0;
-static int g_screen_num = 0;
static int g_xfixes_event_base = 0;
static int g_last_clip_size = 0;
@@ -64,35 +89,20 @@ static int g_data_in_size = 0;
static int g_data_in_time = 0;
static int g_data_in_up_to_date = 0;
static int g_got_format_announce = 0;
-static int g_waiting_for_data_response = 0;
-static int g_waiting_for_data_response_time = 0;
-static Display* g_display = 0;
+/* for image data */
+static int g_want_image_data = 0;
+static XSelectionRequestEvent g_saved_selection_req_event;
-extern int g_cliprdr_chan_id; /* in chansrv.c */
+/* for clipboard INCR transfers */
+static Atom g_incr_atom;
+static Atom g_incr_atom_type;
+static Atom g_incr_atom_target;
+static char* g_incr_data = 0;
+static int g_incr_data_size = 0;
+static int g_incr_in_progress = 0;
-/*****************************************************************************/
-int DEFAULT_CC
-clipboard_error_handler(Display* dis, XErrorEvent* xer)
-{
- char text[256];
-
- XGetErrorText(dis, xer->error_code, text, 255);
- LOG(1, ("error [%s]", text));
- return 0;
-}
-
-/*****************************************************************************/
-/* The X server had an internal error. This is the last function called.
- Do any cleanup that needs to be done on exit, like removing temporary files.
- Don't worry about memory leaks */
-int DEFAULT_CC
-clipboard_fatal_handler(Display* dis)
-{
- LOG(1, ("fatal error, exiting"));
- main_cleanup();
- return 0;
-}
+static int clipboard_format_id = CB_FORMAT_UNICODETEXT;
/*****************************************************************************/
/* this is one way to get the current time from the x server */
@@ -100,10 +110,12 @@ static Time APP_CC
clipboard_get_server_time(void)
{
XEvent xevent;
+ unsigned char no_text[4];
/* append nothing */
+ no_text[0] = 0;
XChangeProperty(g_display, g_wnd, g_get_time_atom, XA_STRING, 8,
- PropModeAppend, "", 0);
+ PropModeAppend, no_text, 0);
/* wait for PropertyNotify */
do
{
@@ -137,39 +149,20 @@ clipboard_init(void)
int ver_min;
Status st;
- LOG(5, ("xrdp-chansrv: in clipboard_init"));
+ LOGM((LOG_LEVEL_DEBUG, "xrdp-chansrv: in clipboard_init"));
if (g_clip_up)
{
return 0;
}
+ xcommon_init();
clipboard_deinit();
rv = 0;
- /* setting the error handlers can cause problem when shutting down
- chansrv on some xlibs */
- //XSetErrorHandler(clipboard_error_handler);
- //XSetIOErrorHandler(clipboard_fatal_handler);
- g_display = XOpenDisplay(0);
- if (g_display == 0)
- {
- LOG(0, ("clipboard_init: XOpenDisplay failed"));
- rv = 1;
- }
- if (rv == 0)
- {
- g_x_socket = XConnectionNumber(g_display);
- if (g_x_socket == 0)
- {
- LOG(0, ("clipboard_init: XConnectionNumber failed"));
- rv = 2;
- }
- g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0);
- }
if (rv == 0)
{
g_clipboard_atom = XInternAtom(g_display, "CLIPBOARD", False);
if (g_clipboard_atom == None)
{
- LOG(0, ("clipboard_init: XInternAtom failed"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_init: XInternAtom failed"));
rv = 3;
}
}
@@ -177,17 +170,17 @@ clipboard_init(void)
{
if (!XFixesQueryExtension(g_display, &g_xfixes_event_base, &dummy))
{
- LOG(0, ("clipboard_init: no xfixes"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_init: no xfixes"));
rv = 5;
}
}
if (rv == 0)
{
- LOG(0, ("clipboard_init: g_xfixes_event_base %d", g_xfixes_event_base));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_init: g_xfixes_event_base %d",
+ g_xfixes_event_base));
st = XFixesQueryVersion(g_display, &ver_maj, &ver_min);
- LOG(0, ("clipboard_init st %d, maj %d min %d", st, ver_maj, ver_min));
- g_screen_num = DefaultScreen(g_display);
- g_screen = ScreenOfDisplay(g_display, g_screen_num);
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_init st %d, maj %d min %d", st,
+ ver_maj, ver_min));
g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM",
False);
g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM",
@@ -198,6 +191,15 @@ clipboard_init(void)
g_primary_atom = XInternAtom(g_display, "PRIMARY", False);
g_secondary_atom = XInternAtom(g_display, "SECONDARY", False);
g_utf8_atom = XInternAtom(g_display, "UTF8_STRING", False);
+
+ g_image_bmp_atom = XInternAtom(g_display, "image/bmp", False);
+ g_incr_atom = XInternAtom(g_display, "INCR", False);
+ if (g_image_bmp_atom == None)
+ {
+ LOGM((LOG_LEVEL_ERROR, "clipboard_init: g_image_bmp_atom was "
+ "not allocated"));
+ }
+
g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen),
0, 0, 4, 4, 0, 0, 0);
input_mask = StructureNotifyMask | PropertyChangeMask;
@@ -219,13 +221,13 @@ clipboard_init(void)
out_uint32_le(s, 0); /* extra 4 bytes ? */
s_mark_end(s);
size = (int)(s->end - s->data);
- LOG(5, ("clipboard_init: data out, sending "
- "CLIPRDR_CONNECT (clip_msg_id = 1)"));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_init: data out, sending "
+ "CLIPRDR_CONNECT (clip_msg_id = 1)"));
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
if (rv != 0)
{
- LOG(0, ("clipboard_init: send_channel_data failed "
- "rv = %d", rv));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_init: send_channel_data failed "
+ "rv = %d", rv));
rv = 4;
}
free_stream(s);
@@ -238,7 +240,7 @@ clipboard_init(void)
}
else
{
- LOG(0, ("xrdp-chansrv: clipboard_init: error on exit"));
+ LOGM((LOG_LEVEL_ERROR, "xrdp-chansrv: clipboard_init: error on exit"));
}
return rv;
}
@@ -247,27 +249,16 @@ clipboard_init(void)
int APP_CC
clipboard_deinit(void)
{
- if (g_x_wait_obj != 0)
- {
- g_delete_wait_obj_from_socket(g_x_wait_obj);
- g_x_wait_obj = 0;
- }
if (g_wnd != 0)
{
XDestroyWindow(g_display, g_wnd);
g_wnd = 0;
}
- g_x_socket = 0;
g_free(g_last_clip_data);
g_last_clip_data = 0;
g_last_clip_size = 0;
free_stream(g_ins);
g_ins = 0;
- if (g_display != 0)
- {
- XCloseDisplay(g_display);
- g_display = 0;
- }
g_clip_up = 0;
return 0;
}
@@ -279,12 +270,12 @@ clipboard_send_data_request(void)
struct stream* s;
int size;
int rv;
- int num_chars;
- LOG(5, ("clipboard_send_data_request:"));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_send_data_request:"));
if (!g_got_format_announce)
{
- LOG(0, ("clipboard_send_data_request: error, no format announce"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_request: error, "
+ "no format announce"));
return 0;
}
g_got_format_announce = 0;
@@ -293,11 +284,11 @@ clipboard_send_data_request(void)
out_uint16_le(s, 4); /* CLIPRDR_DATA_REQUEST */
out_uint16_le(s, 0); /* status */
out_uint32_le(s, 4); /* length */
- out_uint32_le(s, 0x0d);
+ out_uint32_le(s, clipboard_format_id);
s_mark_end(s);
size = (int)(s->end - s->data);
- LOG(5, ("clipboard_send_data_request: data out, sending "
- "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)"));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_send_data_request: data out, sending "
+ "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)"));
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
free_stream(s);
return rv;
@@ -319,16 +310,24 @@ clipboard_send_format_ack(void)
out_uint32_le(s, 0); /* extra 4 bytes ? */
s_mark_end(s);
size = (int)(s->end - s->data);
- LOG(5, ("clipboard_send_format_ack: data out, sending "
- "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)"));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_send_format_ack: data out, sending "
+ "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)"));
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
free_stream(s);
return rv;
}
+static char windows_native_format[] =
+{
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
/*****************************************************************************/
static int APP_CC
-clipboard_send_format_announce(void)
+clipboard_send_format_announce(tui32 format_id, char* format_name)
{
struct stream* s;
int size;
@@ -338,13 +337,13 @@ clipboard_send_format_announce(void)
init_stream(s, 8192);
out_uint16_le(s, 2); /* CLIPRDR_FORMAT_ANNOUNCE */
out_uint16_le(s, 0); /* status */
- out_uint32_le(s, 0x90); /* length */
- out_uint32_le(s, 0x0d); /* extra 4 bytes ? */
- out_uint8s(s, 0x90);
+ out_uint32_le(s, 4 + sizeof(windows_native_format)); /* length */
+ out_uint32_le(s, format_id);
+ out_uint8p(s, windows_native_format, sizeof(windows_native_format));
s_mark_end(s);
size = (int)(s->end - s->data);
- LOG(5, ("clipboard_send_format_announce: data out, sending "
- "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)"));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_send_format_announce: data out, sending "
+ "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)"));
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
free_stream(s);
return rv;
@@ -382,6 +381,39 @@ clipboard_out_unicode(struct stream* s, char* text, int num_chars)
/*****************************************************************************/
static int APP_CC
+clipboard_send_data_response_for_image(void)
+{
+ struct stream* s;
+ int size;
+ int rv;
+
+ LOG(10, ("clipboard_send_data_response_for_image: g_last_clip_size %d\n",
+ g_last_clip_size));
+ make_stream(s);
+ init_stream(s, 64 + g_last_clip_size);
+ out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */
+ out_uint16_le(s, 1); /* status */
+ out_uint32_le(s, g_last_clip_size); /* length */
+ /* insert image data */
+ if (g_last_clip_type == g_image_bmp_atom)
+ {
+ /* do not insert first header */
+ out_uint8p(s, g_last_clip_data + 14, g_last_clip_size - 14);
+ }
+ out_uint16_le(s, 0); /* nil for string */
+ out_uint32_le(s, 0);
+ out_uint32_le(s, 0);
+ out_uint32_le(s, 0);
+ s_mark_end(s);
+ size = (int)(s->end - s->data);
+ /* HANGING HERE WHEN IMAGE DATA IS TOO BIG!!!! */
+ rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
+ free_stream(s);
+ return rv;
+}
+
+/*****************************************************************************/
+static int APP_CC
clipboard_send_data_response(void)
{
struct stream* s;
@@ -393,12 +425,16 @@ clipboard_send_data_response(void)
num_chars = 0;
if (g_last_clip_data != 0)
{
+ if (g_last_clip_type == g_image_bmp_atom)
+ {
+ return clipboard_send_data_response_for_image();
+ }
if ((g_last_clip_type == XA_STRING) || (g_last_clip_type == g_utf8_atom))
{
num_chars = g_mbstowcs(0, g_last_clip_data, 0);
if (num_chars < 0)
{
- LOG(0, ("clipboard_send_data_response: bad string"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_response: bad string"));
num_chars = 0;
}
}
@@ -412,16 +448,16 @@ clipboard_send_data_response(void)
out_uint32_le(s, num_chars * 2 + 2); /* length */
if (clipboard_out_unicode(s, g_last_clip_data, num_chars) != num_chars * 2)
{
- LOG(0, ("clipboard_send_data_response: error "
- "clipboard_out_unicode didn't write right number of bytes"));
+ LOGM((LOG_LEVEL_ERROR,"clipboard_send_data_response: error "
+ "clipboard_out_unicode didn't write right number of bytes"));
}
out_uint16_le(s, 0); /* nil for string */
out_uint32_le(s, 0);
s_mark_end(s);
size = (int)(s->end - s->data);
- LOG(5, ("clipboard_send_data_response: data out, sending "
- "CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d num_chars %d",
- size, num_chars));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_send_data_response: data out, sending "
+ "CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d num_chars %d",
+ size, num_chars));
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
free_stream(s);
return rv;
@@ -487,60 +523,134 @@ clipboard_refuse_selection(XSelectionRequestEvent* req)
}
/*****************************************************************************/
+/* sent by client or server when its local system clipboard is
+ updated with new clipboard data; contains Clipboard Format ID
+ and name pairs of new Clipboard Formats on the clipboard. */
static int APP_CC
clipboard_process_format_announce(struct stream* s, int clip_msg_status,
int clip_msg_len)
{
- Window owner;
-
- LOG(5, ("clipboard_process_format_announce: CLIPRDR_FORMAT_ANNOUNCE"));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_process_format_announce: "
+ "CLIPRDR_FORMAT_ANNOUNCE"));
//g_hexdump(s->p, s->end - s->p);
clipboard_send_format_ack();
g_got_format_announce = 1;
g_data_in_up_to_date = 0;
if (clipboard_set_selection_owner() != 0)
{
- LOG(0, ("clipboard_process_format_announce: XSetSelectionOwner failed"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_process_format_announce: "
+ "XSetSelectionOwner failed"));
}
return 0;
}
/*****************************************************************************/
+/* response to CB_FORMAT_LIST; used to indicate whether
+ processing of the Format List PDU was successful */
static int APP_CC
clipboard_prcoess_format_ack(struct stream* s, int clip_msg_status,
int clip_msg_len)
{
- LOG(5, ("clipboard_prcoess_format_ack: CLIPRDR_FORMAT_ACK"));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_prcoess_format_ack: CLIPRDR_FORMAT_ACK"));
//g_hexdump(s->p, s->end - s->p);
return 0;
}
/*****************************************************************************/
+/* sent by recipient of CB_FORMAT_LIST; used to request data for one
+ of the formats that was listed in CB_FORMAT_LIST */
static int APP_CC
clipboard_process_data_request(struct stream* s, int clip_msg_status,
int clip_msg_len)
{
- LOG(5, ("clipboard_process_data_request: CLIPRDR_DATA_REQUEST"));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_request: "
+ "CLIPRDR_DATA_REQUEST"));
//g_hexdump(s->p, s->end - s->p);
clipboard_send_data_response();
return 0;
}
/*****************************************************************************/
+/* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate whether
+ processing of the CB_FORMAT_DATA_REQUEST was successful; if processing
+ was successful, CB_FORMAT_DATA_RESPONSE includes contents of requested
+ clipboard data. */
+static int APP_CC
+clipboard_process_data_response_for_image(struct stream * s,
+ int clip_msg_status,
+ int clip_msg_len)
+{
+ XSelectionRequestEvent* lxev = &g_saved_selection_req_event;
+ char* cptr;
+ char cdata;
+ int len;
+ int index;
+
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: "
+ "CLIPRDR_DATA_RESPONSE_FOR_IMAGE"));
+ g_waiting_for_data_response = 0;
+ len = (int)(s->end - s->p);
+ if (len < 1)
+ {
+ return 0;
+ }
+ if (g_last_clip_type == g_image_bmp_atom)
+ {
+ /* space for inserting bmp image header */
+ len += 14;
+ cptr = (char*)g_malloc(len, 0);
+ if (cptr == 0)
+ {
+ return 0;
+ }
+ g_memcpy(cptr, g_bmp_image_header, 14);
+ index = 14;
+ }
+ else
+ {
+ return 0;
+ }
+ while (s_check(s))
+ {
+ in_uint8(s, cdata);
+ cptr[index++] = cdata;
+ }
+ if (len >= 0)
+ {
+ g_data_in = cptr;
+ g_data_in_size = len;
+ g_data_in_time = clipboard_get_local_time();
+ g_data_in_up_to_date = 1;
+ }
+ clipboard_provide_selection(lxev, lxev->target, 8, cptr, len);
+ return 0;
+}
+
+/*****************************************************************************/
+/* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate whether
+ processing of the CB_FORMAT_DATA_REQUEST was successful; if processing was
+ successful, CB_FORMAT_DATA_RESPONSE includes contents of requested
+ clipboard data. */
+/*****************************************************************************/
static int APP_CC
clipboard_process_data_response(struct stream* s, int clip_msg_status,
int clip_msg_len)
{
- XEvent xev;
XSelectionRequestEvent* lxev;
twchar* wtext;
twchar wchr;
int len;
int index;
- int wtext_size;
int data_in_len;
- LOG(5, ("clipboard_process_data_response: CLIPRDR_DATA_RESPONSE"));
+ if (g_want_image_data)
+ {
+ g_want_image_data = 0;
+ clipboard_process_data_response_for_image(s, clip_msg_status, clip_msg_len);
+ return 0;
+ }
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_response: "
+ "CLIPRDR_DATA_RESPONSE"));
g_waiting_for_data_response = 0;
len = (int)(s->end - s->p);
if (len < 1)
@@ -580,7 +690,7 @@ clipboard_process_data_response(struct stream* s, int clip_msg_status,
}
g_data_in_size = len;
g_wcstombs(g_data_in, wtext, len + 1);
- g_data_in_time = clipboard_get_local_time();
+ g_data_in_time = xcommon_get_local_time();
g_data_in_up_to_date = 1;
}
if (g_data_in != 0)
@@ -591,8 +701,8 @@ clipboard_process_data_response(struct stream* s, int clip_msg_status,
lxev = &(g_selection_request_event[index]);
clipboard_provide_selection(lxev, lxev->target, 8, g_data_in,
data_in_len);
- LOG(5, ("clipboard_process_data_response: requestor %d data_in_len %d",
- lxev->requestor, data_in_len));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_response: requestor %d "
+ "data_in_len %d", lxev->requestor, data_in_len));
}
}
g_selection_request_event_count = 0;
@@ -641,24 +751,37 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
rv = 0;
switch (clip_msg_id)
{
- case 2: /* CLIPRDR_FORMAT_ANNOUNCE */
+ /* sent by client or server when its local system clipboard is */
+ /* updated with new clipboard data; contains Clipboard Format ID */
+ /* and name pairs of new Clipboard Formats on the clipboard. */
+ case CB_FORMAT_LIST: /* CLIPRDR_FORMAT_ANNOUNCE */
rv = clipboard_process_format_announce(ls, clip_msg_status,
clip_msg_len);
break;
- case 3: /* CLIPRDR_FORMAT_ACK */
+ /* response to CB_FORMAT_LIST; used to indicate whether */
+ /* processing of the Format List PDU was successful */
+ case CB_FORMAT_LIST_RESPONSE: /* CLIPRDR_FORMAT_ACK */
rv = clipboard_prcoess_format_ack(ls, clip_msg_status,
clip_msg_len);
break;
- case 4: /* CLIPRDR_DATA_REQUEST */
+ /* sent by recipient of CB_FORMAT_LIST; used to request data for one */
+ /* of the formats that was listed in CB_FORMAT_LIST */
+ case CB_FORMAT_DATA_REQUEST: /* CLIPRDR_DATA_REQUEST */
rv = clipboard_process_data_request(ls, clip_msg_status,
clip_msg_len);
break;
- case 5: /* CLIPRDR_DATA_RESPONSE */
+ /* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */
+ /* whether processing of the CB_FORMAT_DATA_REQUEST was */
+ /* successful; if processing was successful, */
+ /* CB_FORMAT_DATA_RESPONSE includes contents of requested */
+ /* clipboard data. */
+ case CB_FORMAT_DATA_RESPONSE: /* CLIPRDR_DATA_RESPONSE */
rv = clipboard_process_data_response(ls, clip_msg_status,
clip_msg_len);
break;
default:
- LOG(0, ("clipboard_data_in: unknown clip_msg_id %d", clip_msg_id));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_data_in: unknown clip_msg_id %d",
+ clip_msg_id));
break;
}
XFlush(g_display);
@@ -668,7 +791,8 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
/*****************************************************************************/
/* this happens when a new app copies something to the clipboard
'CLIPBOARD' Atom
- typedef struct {
+ typedef struct
+ {
int type;
unsigned long serial;
Bool send_event;
@@ -679,20 +803,20 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
Atom selection;
Time timestamp;
Time selection_timestamp;
-} XFixesSelectionNotifyEvent; */
+ } XFixesSelectionNotifyEvent; */
static int APP_CC
clipboard_event_selection_owner_notify(XEvent* xevent)
{
XFixesSelectionNotifyEvent* lxevent;
lxevent = (XFixesSelectionNotifyEvent*)xevent;
- LOG(5, ("clipboard_event_selection_owner_notify: "
- "window %d subtype %d owner %d g_wnd %d",
- lxevent->window, lxevent->subtype, lxevent->owner, g_wnd));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: "
+ "window %d subtype %d owner %d g_wnd %d",
+ lxevent->window, lxevent->subtype, lxevent->owner, g_wnd));
if (lxevent->owner == g_wnd)
{
- LOG(5, ("clipboard_event_selection_owner_notify: skipping, "
- "onwer == g_wnd"));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_owner_notify: skipping, "
+ "onwer == g_wnd"));
g_got_selection = 1;
return 0;
}
@@ -721,12 +845,28 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt,
XGetWindowProperty(g_display, g_wnd, prop, 0, 0, 0,
AnyPropertyType, &ltype, &lfmt, &ln_items,
&llen_after, &lxdata);
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
if (ltype == 0)
{
/* XGetWindowProperty failed */
return 1;
}
+
+ if (ltype == g_incr_atom)
+ {
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR start"));
+ g_incr_in_progress = 1;
+ g_incr_atom_type = prop;
+ g_incr_data_size = 0;
+ g_free(g_incr_data);
+ g_incr_data = 0;
+ XDeleteProperty(g_display, g_wnd, prop);
+ return 0;
+ }
+
if (llen_after < 1)
{
/* no data, ok */
@@ -740,20 +880,29 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt,
if (ltype == 0)
{
/* XGetWindowProperty failed */
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
return 1;
}
lxdata_size = (lfmt / 8) * ln_items;
if (lxdata_size < 1)
{
/* should not happen */
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
return 2;
}
if (llen_after > 0)
{
/* should not happen */
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
return 3;
}
if (xdata != 0)
@@ -761,7 +910,10 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt,
*xdata = (char*)g_malloc(lxdata_size, 0);
g_memcpy(*xdata, lxdata, lxdata_size);
}
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
if (xdata_size != 0)
{
*xdata_size = lxdata_size;
@@ -807,34 +959,50 @@ clipboard_event_selection_notify(XEvent* xevent)
int index;
int convert_to_string;
int convert_to_utf8;
+ int convert_to_bmp_image;
int send_format_announce;
int atom;
- int* atoms;
+ Atom* atoms;
Atom type;
+ tui32 format_id;
+ char format_name[32];
- LOG(5, ("clipboard_event_selection_notify:"));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify:"));
+ data_size = 0;
+ n_items = 0;
+ fmt = 0;
convert_to_string = 0;
convert_to_utf8 = 0;
+ convert_to_bmp_image = 0;
send_format_announce = 0;
+ format_id = 0;
rv = 0;
data = 0;
type = 0;
lxevent = (XSelectionEvent*)xevent;
+ g_memset(format_name, 0, 32);
if (lxevent->property == None)
{
- LOG(0, ("clipboard_event_selection_notify: clip could "
- "not be converted"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: clip could "
+ "not be converted"));
rv = 1;
}
if (rv == 0)
{
+ /* we need this if the call below turns out to be a
+ clipboard INCR operation */
+ if (!g_incr_in_progress)
+ {
+ g_incr_atom_target = lxevent->target;
+ }
+
rv = clipboard_get_window_property(lxevent->requestor, lxevent->property,
&type, &fmt,
&n_items, &data, &data_size);
if (rv != 0)
{
- LOG(0, ("clipboard_event_selection_notify: "
- "clipboard_get_window_property failed error %d", rv));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: "
+ "clipboard_get_window_property failed error %d", rv));
}
XDeleteProperty(g_display, lxevent->requestor, lxevent->property);
}
@@ -844,14 +1012,15 @@ clipboard_event_selection_notify(XEvent* xevent)
{
if (lxevent->target == g_targets_atom)
{
+ /* on a 64 bit machine, actual_format_return of 32 implies long */
if ((type == XA_ATOM) && (fmt == 32))
{
- atoms = (int*)data;
+ atoms = (Atom*)data;
for (index = 0; index < n_items; index++)
{
atom = atoms[index];
- LOG(5, ("clipboard_event_selection_notify: %d %s %d", atom,
- XGetAtomName(g_display, atom), XA_STRING));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: %d %s %d",
+ atom, XGetAtomName(g_display, atom), XA_STRING));
if (atom == g_utf8_atom)
{
convert_to_utf8 = 1;
@@ -860,47 +1029,71 @@ clipboard_event_selection_notify(XEvent* xevent)
{
convert_to_string = 1;
}
+ else if (atom == g_image_bmp_atom)
+ {
+ convert_to_bmp_image = 1;
+ }
}
}
else
{
- LOG(0, ("clipboard_event_selection_notify: error, target is "
- "'TARGETS' and type[%d] or fmt[%d] not right, should be "
- "type[%d], fmt[%d]", type, fmt, XA_ATOM, 32));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: error, "
+ "target is 'TARGETS' and type[%d] or fmt[%d] not right, "
+ "should be type[%d], fmt[%d]", type, fmt, XA_ATOM, 32));
}
}
else if (lxevent->target == g_utf8_atom)
{
- LOG(5, ("clipboard_event_selection_notify: UTF8_STRING data_size %d",
- data_size));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_notify: UTF8_STRING "
+ "data_size %d", data_size));
g_free(g_last_clip_data);
+ g_last_clip_data = 0;
g_last_clip_size = data_size;
g_last_clip_data = g_malloc(g_last_clip_size + 1, 0);
g_last_clip_type = g_utf8_atom;
g_memcpy(g_last_clip_data, data, g_last_clip_size);
g_last_clip_data[g_last_clip_size] = 0;
send_format_announce = 1;
+ format_id = CB_FORMAT_UNICODETEXT;
}
else if (lxevent->target == XA_STRING)
{
- LOG(5, ("clipboard_event_selection_notify: XA_STRING data_size %d",
- data_size));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_notify: XA_STRING "
+ "data_size %d", data_size));
g_free(g_last_clip_data);
+ g_last_clip_data = 0;
g_last_clip_size = data_size;
g_last_clip_data = g_malloc(g_last_clip_size + 1, 0);
g_last_clip_type = XA_STRING;
g_memcpy(g_last_clip_data, data, g_last_clip_size);
g_last_clip_data[g_last_clip_size] = 0;
send_format_announce = 1;
+ format_id = CB_FORMAT_UNICODETEXT;
+ }
+ else if (lxevent->target == g_image_bmp_atom)
+ {
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: image/bmp "
+ "data_size %d", data_size));
+ g_free(g_last_clip_data);
+ g_last_clip_data = 0;
+ g_last_clip_size = data_size;
+ g_last_clip_data = g_malloc(data_size, 0);
+ g_last_clip_type = g_image_bmp_atom;
+ g_memcpy(g_last_clip_data, data, data_size);
+ send_format_announce = 1;
+ format_id = CB_FORMAT_DIB;
+ g_strcpy(format_name, "image/bmp");
}
else
{
- LOG(0, ("clipboard_event_selection_notify: unknown target"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: "
+ "unknown target"));
}
}
else
{
- LOG(0, ("clipboard_event_selection_notify: unknown selection"));
+ LOGM((LOG_LEVEL_ERROR,"clipboard_event_selection_notify: "
+ "unknown selection"));
}
}
if (convert_to_utf8)
@@ -913,9 +1106,14 @@ clipboard_event_selection_notify(XEvent* xevent)
XConvertSelection(g_display, g_clipboard_atom, XA_STRING,
g_clip_property_atom, g_wnd, lxevent->time);
}
+ else if (convert_to_bmp_image)
+ {
+ XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom,
+ g_clip_property_atom, g_wnd, lxevent->time);
+ }
if (send_format_announce)
{
- if (clipboard_send_format_announce() != 0)
+ if (clipboard_send_format_announce(format_id, format_name) != 0)
{
rv = 4;
}
@@ -939,12 +1137,17 @@ clipboard_event_selection_notify(XEvent* xevent)
Atom property;
Time time;
} XSelectionRequestEvent; */
+/*
+ * When XGetWindowProperty and XChangeProperty talk about "format 32" it
+ * doesn't mean a 32bit value, but actually a long. So 32 means 4 bytes on
+ * a 32bit machine and 8 bytes on a 64 machine
+ */
static int APP_CC
clipboard_event_selection_request(XEvent* xevent)
{
- XEvent xev;
XSelectionRequestEvent* lxev;
- tui32 ui32[8];
+ XEvent xev;
+ Atom atom_buf[10];
Atom type;
int fmt;
int n_items;
@@ -952,52 +1155,58 @@ clipboard_event_selection_request(XEvent* xevent)
char* xdata;
lxev = (XSelectionRequestEvent*)xevent;
- LOG(5, ("clipboard_event_selection_request: g_wnd %d, "
- ".requestor %d .owner %d .selection %d '%s' .target %d .property %d",
- g_wnd, lxev->requestor, lxev->owner, lxev->selection,
- XGetAtomName(g_display, lxev->selection),
- lxev->target, lxev->property));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_wnd %d, "
+ ".requestor %d .owner %d .selection %d '%s' .target %d .property %d",
+ g_wnd, lxev->requestor, lxev->owner, lxev->selection,
+ XGetAtomName(g_display, lxev->selection),
+ lxev->target, lxev->property));
if (lxev->property == None)
{
- LOG(5, ("clipboard_event_selection_request: lxev->property is None"));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
+ "lxev->property is None"));
}
else if (lxev->target == g_targets_atom)
{
/* requestor is asking what the selection can be converted to */
- LOG(5, ("clipboard_event_selection_request: g_targets_atom"));
- ui32[0] = g_targets_atom;
- ui32[1] = g_timestamp_atom;
- ui32[2] = g_multiple_atom;
- ui32[3] = XA_STRING;
- ui32[4] = g_utf8_atom;
- return clipboard_provide_selection(lxev, XA_ATOM, 32, (char*)ui32, 5);
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
+ "g_targets_atom"));
+ atom_buf[0] = g_targets_atom;
+ atom_buf[1] = g_timestamp_atom;
+ atom_buf[2] = g_multiple_atom;
+ atom_buf[3] = XA_STRING;
+ atom_buf[4] = g_utf8_atom;
+ atom_buf[5] = g_image_bmp_atom;
+ return clipboard_provide_selection(lxev, XA_ATOM, 32, (char*)atom_buf, 6);
}
else if (lxev->target == g_timestamp_atom)
{
/* requestor is asking the time I got the selection */
- LOG(5, ("clipboard_event_selection_request: g_timestamp_atom"));
- ui32[0] = g_selection_time;
- return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char*)ui32, 1);
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
+ "g_timestamp_atom"));
+ atom_buf[0] = g_selection_time;
+ return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char*)atom_buf, 1);
}
else if (lxev->target == g_multiple_atom)
{
/* target, property pairs */
- LOG(5, ("clipboard_event_selection_request: g_multiple_atom"));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
+ "g_multiple_atom"));
if (clipboard_get_window_property(xev.xselection.requestor,
xev.xselection.property,
&type, &fmt, &n_items, &xdata,
&xdata_size) == 0)
{
- LOG(5, ("clipboard_event_selection_request: g_multiple_atom "
- "n_items %d", n_items));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_multiple_atom "
+ "n_items %d", n_items));
/* todo */
g_free(xdata);
}
}
else if ((lxev->target == XA_STRING) || (lxev->target == g_utf8_atom))
{
- LOG(5, ("clipboard_event_selection_request: %s",
- XGetAtomName(g_display, lxev->target)));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: %s",
+ XGetAtomName(g_display, lxev->target)));
+ clipboard_format_id = CB_FORMAT_UNICODETEXT;
if (g_data_in_up_to_date)
{
return clipboard_provide_selection(lxev, lxev->target, 8,
@@ -1005,7 +1214,8 @@ clipboard_event_selection_request(XEvent* xevent)
}
if (g_selection_request_event_count > 10)
{
- LOG(0, ("clipboard_event_selection_request: error, too many requests"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: error, "
+ "too many requests"));
}
else
{
@@ -1015,16 +1225,28 @@ clipboard_event_selection_request(XEvent* xevent)
{
clipboard_send_data_request();
g_waiting_for_data_response = 1;
- g_waiting_for_data_response_time = clipboard_get_local_time();
+ g_waiting_for_data_response_time = xcommon_get_local_time();
}
g_selection_request_event_count++;
return 0;
}
}
+ else if (lxev->target == g_image_bmp_atom)
+ {
+ g_memcpy(&g_saved_selection_req_event, lxev,
+ sizeof(g_saved_selection_req_event));
+ g_last_clip_type = g_image_bmp_atom;
+ g_want_image_data = 1;
+ clipboard_format_id = CB_FORMAT_DIB;
+ clipboard_send_data_request();
+ g_waiting_for_data_response = 1;
+ g_waiting_for_data_response_time = clipboard_get_local_time();
+ return 0;
+ }
else
{
- LOG(0, ("clipboard_event_selection_request: unknown "
- "target %s", XGetAtomName(g_display, lxev->target)));
+ LOGM((LOG_LEVEL_ERROR,"clipboard_event_selection_request: unknown "
+ "target %s", XGetAtomName(g_display, lxev->target)));
}
clipboard_refuse_selection(lxev);
return 0;
@@ -1045,7 +1267,7 @@ clipboard_event_selection_request(XEvent* xevent)
static int APP_CC
clipboard_event_selection_clear(XEvent* xevent)
{
- LOG(5, ("clipboard_event_selection_clear:"));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_clear:"));
return 0;
}
@@ -1064,92 +1286,132 @@ clipboard_event_selection_clear(XEvent* xevent)
static int APP_CC
clipboard_event_property_notify(XEvent* xevent)
{
+ Atom actual_type_return;
+ int actual_format_return;
+ unsigned long nitems_returned;
+ unsigned long bytes_left;
+ unsigned char* data;
+ int rv;
+ int format_in_bytes;
+ int new_data_len;
+ char* cptr;
+ char format_name[32];
+
LOG(10, ("clipboard_check_wait_objs: PropertyNotify .window %d "
".state %d .atom %d", xevent->xproperty.window,
xevent->xproperty.state, xevent->xproperty.atom));
- return 0;
-}
-
-/*****************************************************************************/
-/* returns error
- this is called to get any wait objects for the main loop
- timeout can be nil */
-int APP_CC
-clipboard_get_wait_objs(tbus* objs, int* count, int* timeout)
-{
- int lcount;
-
- if ((!g_clip_up) || (objs == 0) || (count == 0))
+ if (g_incr_in_progress &&
+ (xevent->xproperty.atom == g_incr_atom_type) &&
+ (xevent->xproperty.state == PropertyNewValue))
{
- return 0;
+ rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, 0, 0,
+ AnyPropertyType, &actual_type_return, &actual_format_return,
+ &nitems_returned, &bytes_left, (unsigned char **) &data);
+ if (data != 0)
+ {
+ XFree(data);
+ data = 0;
+ }
+ if (bytes_left <= 0)
+ {
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR done"));
+ g_memset(format_name, 0, 32);
+ /* clipboard INCR cycle has completed */
+ g_incr_in_progress = 0;
+ g_last_clip_size = g_incr_data_size;
+ g_last_clip_data = g_incr_data;
+ g_incr_data = 0;
+ g_last_clip_type = g_incr_atom_target;
+ if (g_incr_atom_target == g_image_bmp_atom)
+ {
+ g_snprintf(format_name, 31, "image/bmp");
+ clipboard_send_format_announce(CB_FORMAT_DIB, format_name);
+ }
+ XDeleteProperty(g_display, g_wnd, g_incr_atom_type);
+ }
+ else
+ {
+ rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, bytes_left, 0,
+ AnyPropertyType, &actual_type_return, &actual_format_return,
+ &nitems_returned, &bytes_left, (unsigned char **) &data);
+
+ format_in_bytes = actual_format_return / 8;
+ if ((actual_format_return == 32) && (sizeof(long) == 8))
+ {
+ /* on a 64 bit machine, actual_format_return of 32 implies long */
+ format_in_bytes = 8;
+ }
+ new_data_len = nitems_returned * format_in_bytes;
+ cptr = (char*)g_malloc(g_incr_data_size + new_data_len, 0);
+ g_memcpy(cptr, g_incr_data, g_incr_data_size);
+ g_free(g_incr_data);
+ if (cptr == NULL)
+ {
+ g_incr_data = 0;
+ /* cannot add any more data */
+ if (data != 0)
+ {
+ XFree(data);
+ }
+ XDeleteProperty(g_display, g_wnd, g_incr_atom_type);
+ return 0;
+ }
+ g_incr_data = cptr;
+ g_memcpy(g_incr_data + g_incr_data_size, data, new_data_len);
+ g_incr_data_size += new_data_len;
+ if (data)
+ {
+ XFree(data);
+ }
+ XDeleteProperty(g_display, g_wnd, g_incr_atom_type);
+ }
}
- lcount = *count;
- objs[lcount] = g_x_wait_obj;
- lcount++;
- *count = lcount;
return 0;
}
/*****************************************************************************/
+/* returns 0, event handled, 1 unhandled */
int APP_CC
-clipboard_check_wait_objs(void)
+clipboard_xevent(void* xevent)
{
- XEvent xevent;
- int time_diff;
+ XEvent* lxevent;
if (!g_clip_up)
{
- return 0;
+ return 1;
}
- if (g_is_wait_obj_set(g_x_wait_obj))
+ lxevent = (XEvent*)xevent;
+ switch (lxevent->type)
{
- if (XPending(g_display) < 1)
- {
- /* something is wrong, should not get here */
- LOG(0, ("clipboard_check_wait_objs: sck closed"));
- return 0;
- }
- if (g_waiting_for_data_response)
- {
- time_diff = clipboard_get_local_time() -
- g_waiting_for_data_response_time;
- if (time_diff > 1000)
- {
- LOG(0, ("clipboard_check_wait_objs: warning, waiting for "
- "data response too long"));
- }
- }
- while (XPending(g_display) > 0)
- {
- XNextEvent(g_display, &xevent);
- switch (xevent.type)
+ case SelectionNotify:
+ clipboard_event_selection_notify(lxevent);
+ break;
+ case SelectionRequest:
+ clipboard_event_selection_request(lxevent);
+ break;
+ case SelectionClear:
+ clipboard_event_selection_clear(lxevent);
+ break;
+ case MappingNotify:
+ break;
+ case PropertyNotify:
+ clipboard_event_property_notify(lxevent);
+ break;
+ case UnmapNotify:
+ LOG(0, ("chansrv::clipboard_xevent: got UnmapNotify"));
+ break;
+ case ClientMessage:
+ LOG(0, ("chansrv::clipboard_xevent: got ClientMessage"));
+ break;
+ default:
+ if (lxevent->type == g_xfixes_event_base +
+ XFixesSetSelectionOwnerNotify)
{
- case SelectionNotify:
- clipboard_event_selection_notify(&xevent);
- break;
- case SelectionRequest:
- clipboard_event_selection_request(&xevent);
- break;
- case SelectionClear:
- clipboard_event_selection_clear(&xevent);
- break;
- case MappingNotify:
- break;
- case PropertyNotify:
- clipboard_event_property_notify(&xevent);
- break;
- default:
- if (xevent.type == g_xfixes_event_base +
- XFixesSetSelectionOwnerNotify)
- {
- clipboard_event_selection_owner_notify(&xevent);
- break;
- }
- LOG(0, ("clipboard_check_wait_objs unknown type %d",
- xevent.type));
- break;
+ clipboard_event_selection_owner_notify(lxevent);
+ break;
}
- }
+ /* we didn't handle this message */
+ return 1;
}
return 0;
}
diff --git a/sesman/chansrv/clipboard.h b/sesman/chansrv/clipboard.h
index d6c74403..2fe1d194 100644
--- a/sesman/chansrv/clipboard.h
+++ b/sesman/chansrv/clipboard.h
@@ -1,3 +1,21 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ * Copyright (C) Laxmikant Rashinkar 2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
#if !defined(CLIPBOARD_H)
#define CLIPBOARD_H
@@ -5,6 +23,22 @@
#include "arch.h"
#include "parse.h"
+#define CB_FORMAT_LIST 2
+#define CB_FORMAT_LIST_RESPONSE 3
+#define CB_FORMAT_DATA_REQUEST 4
+#define CB_FORMAT_DATA_RESPONSE 5
+
+/* Clipboard Formats */
+
+#define CB_FORMAT_RAW 0x0000
+#define CB_FORMAT_TEXT 0x0001
+#define CB_FORMAT_DIB 0x0008
+#define CB_FORMAT_UNICODETEXT 0x000D
+#define CB_FORMAT_HTML 0xD010
+#define CB_FORMAT_PNG 0xD011
+#define CB_FORMAT_JPEG 0xD012
+#define CB_FORMAT_GIF 0xD013
+
int APP_CC
clipboard_init(void);
int APP_CC
@@ -13,8 +47,6 @@ int APP_CC
clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
int total_length);
int APP_CC
-clipboard_get_wait_objs(tbus* objs, int* count, int* timeout);
-int APP_CC
-clipboard_check_wait_objs(void);
+clipboard_xevent(void* xevent);
#endif
diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c
index 8e660a49..dd244572 100644
--- a/sesman/chansrv/devredir.c
+++ b/sesman/chansrv/devredir.c
@@ -1,21 +1,20 @@
-/*
- 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.
-
- xrdp: A Remote Desktop Protocol server.
- Copyright (C) Jay Sorg 2009-2010
-*/
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
#include "arch.h"
#include "parse.h"
diff --git a/sesman/chansrv/devredir.h b/sesman/chansrv/devredir.h
index e0279093..3ec08a51 100644
--- a/sesman/chansrv/devredir.h
+++ b/sesman/chansrv/devredir.h
@@ -1,3 +1,20 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
#if !defined(DEVREDIR_H)
#define DEVREDIR_H
diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c
new file mode 100644
index 00000000..6b47f867
--- /dev/null
+++ b/sesman/chansrv/rail.c
@@ -0,0 +1,677 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ window manager info
+ http://www.freedesktop.org/wiki/Specifications/wm-spec
+*/
+
+#include <X11/Xlib.h>
+#include "chansrv.h"
+#include "rail.h"
+#include "xcommon.h"
+#include "log.h"
+#include "os_calls.h"
+#include "thread_calls.h"
+
+extern int g_rail_chan_id; /* in chansrv.c */
+extern int g_display_num; /* in chansrv.c */
+extern char* g_exec_name; /* in chansrv.c */
+extern tbus g_exec_event; /* in chansrv.c */
+extern tbus g_exec_mutex; /* in chansrv.c */
+extern tbus g_exec_sem; /* in chansrv.c */
+
+extern Display* g_display; /* in xcommon.c */
+extern Screen* g_screen; /* in xcommon.c */
+extern Window g_root_window; /* in xcommon.c */
+extern Atom g_wm_delete_window_atom; /* in xcommon.c */
+extern Atom g_wm_protocols_atom; /* in xcommon.c */
+
+int g_rail_up = 0;
+
+/* for rail_is_another_wm_running */
+static int g_rail_running = 1;
+
+/* Indicates a Client Execute PDU from client to server. */
+#define TS_RAIL_ORDER_EXEC 0x0001
+/* Indicates a Client Activate PDU from client to server. */
+#define TS_RAIL_ORDER_ACTIVATE 0x0002
+/* Indicates a Client System Parameters Update PDU from client
+ to server or a Server System Parameters Update PDU
+ from server to client. */
+#define TS_RAIL_ORDER_SYSPARAM 0x0003
+/* Indicates a Client System Command PDU from client to server. */
+#define TS_RAIL_ORDER_SYSCOMMAND 0x0004
+/* Indicates a bi-directional Handshake PDU. */
+#define TS_RAIL_ORDER_HANDSHAKE 0x0005
+/* Indicates a Client Notify Event PDU from client to server. */
+#define TS_RAIL_ORDER_NOTIFY_EVENT 0x0006
+/* Indicates a Client Window Move PDU from client to server. */
+#define TS_RAIL_ORDER_WINDOWMOVE 0x0008
+/* Indicates a Server Move/Size Start PDU and a Server Move/Size
+ End PDU from server to client. */
+#define TS_RAIL_ORDER_LOCALMOVESIZE 0x0009
+/* Indicates a Server Min Max Info PDU from server to client. */
+#define TS_RAIL_ORDER_MINMAXINFO 0x000a
+/* Indicates a Client Information PDU from client to server. */
+#define TS_RAIL_ORDER_CLIENTSTATUS 0x000b
+/* Indicates a Client System Menu PDU from client to server. */
+#define TS_RAIL_ORDER_SYSMENU 0x000c
+/* Indicates a Server Language Bar Information PDU from server to
+ client, or a Client Language Bar Information PDU from client to server. */
+#define TS_RAIL_ORDER_LANGBARINFO 0x000d
+/* Indicates a Server Execute Result PDU from server to client. */
+#define TS_RAIL_ORDER_EXEC_RESULT 0x0080
+/* Indicates a Client Get Application ID PDU from client to server. */
+#define TS_RAIL_ORDER_GET_APPID_REQ 0x000E
+/* Indicates a Server Get Application ID Response PDU from
+ server to client. */
+#define TS_RAIL_ORDER_GET_APPID_RESP 0x000F
+
+/* Resize the window. */
+#define SC_SIZE 0xF000
+/* Move the window. */
+#define SC_MOVE 0xF010
+/* Minimize the window. */
+#define SC_MINIMIZE 0xF020
+/* Maximize the window. */
+#define SC_MAXIMIZE 0xF030
+/* Close the window. */
+#define SC_CLOSE 0xF060
+/* The ALT + SPACE key combination was pressed; display
+ the window's system menu. */
+#define SC_KEYMENU 0xF100
+/* Restore the window to its original shape and size. */
+#define SC_RESTORE 0xF120
+/* Perform the default action of the window's system menu. */
+#define SC_DEFAULT 0xF160
+
+/******************************************************************************/
+static int APP_CC
+is_window_valid_child_of_root(unsigned int window_id)
+{
+ int found;
+ unsigned int i;
+ unsigned int nchild;
+ Window r;
+ Window p;
+ Window* children;
+
+ found = 0;
+ XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild);
+ for (i = 0; i < nchild; i++)
+ {
+ if (window_id == children[i])
+ {
+ found = 1;
+ break;
+ }
+ }
+ XFree(children);
+ return found;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_send_init(void)
+{
+ struct stream* s;
+ int bytes;
+ char* size_ptr;
+
+ LOG(10, ("chansrv::rail_send_init:"));
+ make_stream(s);
+ init_stream(s, 8182);
+ out_uint16_le(s, TS_RAIL_ORDER_HANDSHAKE);
+ size_ptr = s->p;
+ out_uint16_le(s, 0); /* size, set later */
+ out_uint32_le(s, 1); /* build number */
+ s_mark_end(s);
+ bytes = (int)((s->end - s->data) - 4);
+ size_ptr[0] = bytes;
+ size_ptr[1] = bytes >> 8;
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rail_chan_id, s->data, bytes);
+ free_stream(s);
+ return 0;
+}
+
+/******************************************************************************/
+static int DEFAULT_CC
+anotherWMRunning(Display* display, XErrorEvent* xe)
+{
+ g_rail_running = 0;
+ return -1;
+}
+
+/******************************************************************************/
+static int APP_CC
+rail_is_another_wm_running(void)
+{
+ XErrorHandler old;
+
+ g_rail_running = 1;
+ old = XSetErrorHandler((XErrorHandler)anotherWMRunning);
+ XSelectInput(g_display, g_root_window,
+ PropertyChangeMask | StructureNotifyMask |
+ SubstructureRedirectMask | ButtonPressMask |
+ SubstructureNotifyMask | FocusChangeMask |
+ EnterWindowMask | LeaveWindowMask);
+ XSync(g_display, 0);
+ XSetErrorHandler((XErrorHandler)old);
+ g_rail_up = g_rail_running;
+ if (!g_rail_up)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+rail_init(void)
+{
+ LOG(10, ("chansrv::rail_init:"));
+ xcommon_init();
+ if (rail_is_another_wm_running())
+ {
+ log_message(LOG_LEVEL_ERROR, "rail_init: another window manager "
+ "is running");
+ }
+ rail_send_init();
+ g_rail_up = 1;
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+rail_deinit(void)
+{
+ if (g_rail_up)
+ {
+ /* no longer window manager */
+ XSelectInput(g_display, g_root_window, 0);
+ g_rail_up = 0;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static char* APP_CC
+read_uni(struct stream* s, int num_chars)
+{
+ twchar* rchrs;
+ char* rv;
+ int index;
+ int lchars;
+
+ rchrs = 0;
+ rv = 0;
+ if (num_chars > 0)
+ {
+ rchrs = (twchar*)g_malloc((num_chars + 1) * sizeof(twchar), 0);
+ for (index = 0; index < num_chars; index++)
+ {
+ in_uint16_le(s, rchrs[index]);
+ }
+ rchrs[num_chars] = 0;
+ lchars = g_wcstombs(0, rchrs, 0);
+ if (lchars > 0)
+ {
+ rv = (char*)g_malloc((lchars + 1) * 4, 0);
+ g_wcstombs(rv, rchrs, lchars);
+ rv[lchars] = 0;
+ }
+ }
+ g_free(rchrs);
+ return rv;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_exec(struct stream* s, int size)
+{
+ int pid;
+ int flags;
+ int ExeOrFileLength;
+ int WorkingDirLength;
+ int ArgumentsLen;
+ char* ExeOrFile;
+ char* WorkingDir;
+ char* Arguments;
+
+ LOG(0, ("chansrv::rail_process_exec:"));
+ in_uint16_le(s, flags);
+ in_uint16_le(s, ExeOrFileLength);
+ in_uint16_le(s, WorkingDirLength);
+ in_uint16_le(s, ArgumentsLen);
+ ExeOrFile = read_uni(s, ExeOrFileLength);
+ WorkingDir = read_uni(s, WorkingDirLength);
+ Arguments = read_uni(s, ArgumentsLen);
+ LOG(10, (" flags 0x%8.8x ExeOrFileLength %d WorkingDirLength %d "
+ "ArgumentsLen %d ExeOrFile [%s] WorkingDir [%s] "
+ "Arguments [%s]", flags, ExeOrFileLength, WorkingDirLength,
+ ArgumentsLen, ExeOrFile, WorkingDir, Arguments));
+ if (g_strlen(ExeOrFile) > 0)
+ {
+ LOG(10, ("rail_process_exec: pre"));
+ /* ask main thread to fork */
+ tc_mutex_lock(g_exec_mutex);
+ g_exec_name = ExeOrFile;
+ g_set_wait_obj(g_exec_event);
+ tc_sem_dec(g_exec_sem);
+ tc_mutex_unlock(g_exec_mutex);
+ LOG(10, ("rail_process_exec: post"));
+ }
+ g_free(ExeOrFile);
+ g_free(WorkingDir);
+ g_free(Arguments);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_activate(struct stream* s, int size)
+{
+ int window_id;
+ int enabled;
+
+ LOG(10, ("chansrv::rail_process_activate:"));
+ in_uint32_le(s, window_id);
+ in_uint8(s, enabled);
+ LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled));
+ if (enabled)
+ {
+ LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id));
+ XRaiseWindow(g_display, window_id);
+ LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id));
+ XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_system_param(struct stream* s, int size)
+{
+ int system_param;
+
+ LOG(10, ("chansrv::rail_process_system_param:"));
+ in_uint32_le(s, system_param);
+ LOG(10, (" system_param 0x%8.8x", system_param));
+ return 0;
+}
+
+/******************************************************************************/
+static int APP_CC
+rail_close_window(int window_id)
+{
+ XEvent ce;
+
+ LOG(0, ("chansrv::rail_close_window:"));
+ g_memset(&ce, 0, sizeof(ce));
+ ce.xclient.type = ClientMessage;
+ ce.xclient.message_type = g_wm_protocols_atom;
+ ce.xclient.display = g_display;
+ ce.xclient.window = window_id;
+ ce.xclient.format = 32;
+ ce.xclient.data.l[0] = g_wm_delete_window_atom;
+ ce.xclient.data.l[1] = CurrentTime;
+ XSendEvent(g_display, window_id, False, NoEventMask, &ce);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_system_command(struct stream* s, int size)
+{
+ int window_id;
+ int command;
+
+ LOG(10, ("chansrv::rail_process_system_command:"));
+ in_uint32_le(s, window_id);
+ in_uint16_le(s, command);
+ switch (command)
+ {
+ case SC_SIZE:
+ LOG(10, (" window_id 0x%8.8x SC_SIZE", window_id));
+ break;
+ case SC_MOVE:
+ LOG(10, (" window_id 0x%8.8x SC_MOVE", window_id));
+ break;
+ case SC_MINIMIZE:
+ LOG(10, (" window_id 0x%8.8x SC_MINIMIZE", window_id));
+ break;
+ case SC_MAXIMIZE:
+ LOG(10, (" window_id 0x%8.8x SC_MAXIMIZE", window_id));
+ break;
+ case SC_CLOSE:
+ LOG(10, (" window_id 0x%8.8x SC_CLOSE", window_id));
+ rail_close_window(window_id);
+ break;
+ case SC_KEYMENU:
+ LOG(10, (" window_id 0x%8.8x SC_KEYMENU", window_id));
+ break;
+ case SC_RESTORE:
+ LOG(10, (" window_id 0x%8.8x SC_RESTORE", window_id));
+ break;
+ case SC_DEFAULT:
+ LOG(10, (" window_id 0x%8.8x SC_DEFAULT", window_id));
+ break;
+ default:
+ LOG(10, (" window_id 0x%8.8x unknown command command %d",
+ window_id, command));
+ break;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_handshake(struct stream* s, int size)
+{
+ int build_number;
+
+ LOG(10, ("chansrv::rail_process_handshake:"));
+ in_uint32_le(s, build_number);
+ LOG(10, (" build_number 0x%8.8x", build_number));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_notify_event(struct stream* s, int size)
+{
+ int window_id;
+ int notify_id;
+ int message;
+
+ LOG(10, ("chansrv::rail_process_notify_event:"));
+ in_uint32_le(s, window_id);
+ in_uint32_le(s, notify_id);
+ in_uint32_le(s, message);
+ LOG(10, (" window_id 0x%8.8x notify_id 0x%8.8x message 0x%8.8x",
+ window_id, notify_id, message));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_window_move(struct stream* s, int size)
+{
+ int window_id;
+ int left;
+ int top;
+ int right;
+ int bottom;
+
+ LOG(10, ("chansrv::rail_process_window_move:"));
+ in_uint32_le(s, window_id);
+ in_uint16_le(s, left);
+ in_uint16_le(s, top);
+ in_uint16_le(s, right);
+ in_uint16_le(s, bottom);
+ LOG(10, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d",
+ window_id, left, top, right, bottom, right - left, bottom - top));
+ XMoveResizeWindow(g_display, window_id, left, top, right - left, bottom - top);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_local_move_size(struct stream* s, int size)
+{
+ int window_id;
+ int is_move_size_start;
+ int move_size_type;
+ int pos_x;
+ int pos_y;
+
+ LOG(10, ("chansrv::rail_process_local_move_size:"));
+ in_uint32_le(s, window_id);
+ in_uint16_le(s, is_move_size_start);
+ in_uint16_le(s, move_size_type);
+ in_uint16_le(s, pos_x);
+ in_uint16_le(s, pos_y);
+ LOG(10, (" window_id 0x%8.8x is_move_size_start %d move_size_type %d "
+ "pos_x %d pos_y %d", window_id, is_move_size_start, move_size_type,
+ pos_x, pos_y));
+ return 0;
+}
+
+/*****************************************************************************/
+/* server to client only */
+static int APP_CC
+rail_process_min_max_info(struct stream* s, int size)
+{
+ LOG(10, ("chansrv::rail_process_min_max_info:"));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_client_status(struct stream* s, int size)
+{
+ int flags;
+
+ LOG(10, ("chansrv::rail_process_client_status:"));
+ in_uint32_le(s, flags);
+ LOG(10, (" flags 0x%8.8x", flags));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_sys_menu(struct stream* s, int size)
+{
+ int window_id;
+ int left;
+ int top;
+
+ LOG(10, ("chansrv::rail_process_sys_menu:"));
+ in_uint32_le(s, window_id);
+ in_uint16_le(s, left);
+ in_uint16_le(s, top);
+ LOG(10, (" window_id 0x%8.8x left %d top %d", window_id, left, top));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_lang_bar_info(struct stream* s, int size)
+{
+ int language_bar_status;
+
+ LOG(10, ("chansrv::rail_process_lang_bar_info:"));
+ in_uint32_le(s, language_bar_status);
+ LOG(10, (" language_bar_status 0x%8.8x", language_bar_status));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_appid_req(struct stream* s, int size)
+{
+ LOG(10, ("chansrv::rail_process_appid_req:"));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_appid_resp(struct stream* s, int size)
+{
+ LOG(10, ("chansrv::rail_process_appid_resp:"));
+ return 0;
+}
+
+/*****************************************************************************/
+/* server to client only */
+static int APP_CC
+rail_process_exec_result(struct stream* s, int size)
+{
+ LOG(10, ("chansrv::rail_process_exec_result:"));
+ return 0;
+}
+
+/*****************************************************************************/
+/* data in from client ( client -> xrdp -> chansrv ) */
+int APP_CC
+rail_data_in(struct stream* s, int chan_id, int chan_flags, int length,
+ int total_length)
+{
+ int code;
+ int size;
+
+ LOG(10, ("chansrv::rail_data_in:"));
+ in_uint8(s, code);
+ in_uint8s(s, 1);
+ in_uint16_le(s, size);
+ switch (code)
+ {
+ case TS_RAIL_ORDER_EXEC: /* 1 */
+ rail_process_exec(s, size);
+ break;
+ case TS_RAIL_ORDER_ACTIVATE: /* 2 */
+ rail_process_activate(s, size);
+ break;
+ case TS_RAIL_ORDER_SYSPARAM: /* 3 */
+ rail_process_system_param(s, size);
+ break;
+ case TS_RAIL_ORDER_SYSCOMMAND: /* 4 */
+ rail_process_system_command(s, size);
+ break;
+ case TS_RAIL_ORDER_HANDSHAKE: /* 5 */
+ rail_process_handshake(s, size);
+ break;
+ case TS_RAIL_ORDER_NOTIFY_EVENT: /* 6 */
+ rail_process_notify_event(s, size);
+ break;
+ case TS_RAIL_ORDER_WINDOWMOVE: /* 8 */
+ rail_process_window_move(s, size);
+ break;
+ case TS_RAIL_ORDER_LOCALMOVESIZE: /* 9 */
+ rail_process_local_move_size(s, size);
+ break;
+ case TS_RAIL_ORDER_MINMAXINFO: /* 10 */
+ rail_process_min_max_info(s, size);
+ break;
+ case TS_RAIL_ORDER_CLIENTSTATUS: /* 11 */
+ rail_process_client_status(s, size);
+ break;
+ case TS_RAIL_ORDER_SYSMENU: /* 12 */
+ rail_process_sys_menu(s, size);
+ break;
+ case TS_RAIL_ORDER_LANGBARINFO: /* 13 */
+ rail_process_lang_bar_info(s, size);
+ break;
+ case TS_RAIL_ORDER_GET_APPID_REQ: /* 14 */
+ rail_process_appid_req(s, size);
+ break;
+ case TS_RAIL_ORDER_GET_APPID_RESP: /* 15 */
+ rail_process_appid_resp(s, size);
+ break;
+ case TS_RAIL_ORDER_EXEC_RESULT: /* 128 */
+ rail_process_exec_result(s, size);
+ break;
+ default:
+ LOG(10, ("rail_data_in: unknown code %d size %d", code, size));
+ break;
+ }
+ XFlush(g_display);
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns 0, event handled, 1 unhandled */
+int APP_CC
+rail_xevent(void* xevent)
+{
+ XEvent* lxevent;
+ XWindowChanges xwc;
+ int rv;
+ int nchildren_return = 0;
+ Window root_return;
+ Window parent_return;
+ Window *children_return;
+ Window wreturn;
+ int revert_to;
+ XWindowAttributes wnd_attributes;
+
+ LOG(10, ("chansrv::rail_xevent:"));
+ if (!g_rail_up)
+ {
+ return 1;
+ }
+ rv = 1;
+ lxevent = (XEvent*)xevent;
+ switch (lxevent->type)
+ {
+ case ConfigureRequest:
+ LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window));
+ g_memset(&xwc, 0, sizeof(xwc));
+ xwc.x = lxevent->xconfigurerequest.x;
+ xwc.y = lxevent->xconfigurerequest.y;
+ xwc.width = lxevent->xconfigurerequest.width;
+ xwc.height = lxevent->xconfigurerequest.height;
+ xwc.border_width = lxevent->xconfigurerequest.border_width;
+ xwc.sibling = lxevent->xconfigurerequest.above;
+ xwc.stack_mode = lxevent->xconfigurerequest.detail;
+ XConfigureWindow(g_display,
+ lxevent->xconfigurerequest.window,
+ lxevent->xconfigurerequest.value_mask,
+ &xwc);
+ rv = 0;
+ break;
+
+ case MapRequest:
+ LOG(10, (" got MapRequest"));
+ XMapWindow(g_display, lxevent->xmaprequest.window);
+ rv = 0;
+ break;
+
+ case MapNotify:
+ LOG(10, (" got MapNotify"));
+ break;
+
+ case UnmapNotify:
+ LOG(10, (" got UnmapNotify"));
+ break;
+
+ case ConfigureNotify:
+ LOG(10, (" got ConfigureNotify"));
+ break;
+
+ case FocusIn:
+ LOG(10, (" got FocusIn"));
+ break;
+
+ case ButtonPress:
+ LOG(10, (" got ButtonPress"));
+ break;
+
+ case EnterNotify:
+ LOG(10, (" got EnterNotify"));
+ break;
+
+ case LeaveNotify:
+ LOG(10, (" got LeaveNotify"));
+ break;
+
+ }
+ return rv;
+}
diff --git a/sesman/chansrv/rail.h b/sesman/chansrv/rail.h
new file mode 100644
index 00000000..7dbcbc5a
--- /dev/null
+++ b/sesman/chansrv/rail.h
@@ -0,0 +1,35 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _RAIL_H_
+#define _RAIL_H_
+
+#include "arch.h"
+#include "parse.h"
+
+int APP_CC
+rail_init(void);
+int APP_CC
+rail_deinit(void);
+int APP_CC
+rail_data_in(struct stream* s, int chan_id, int chan_flags,
+ int length, int total_length);
+int APP_CC
+rail_xevent(void* xevent);
+
+#endif
diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c
index 8cca641d..e4d54bb0 100644
--- a/sesman/chansrv/sound.c
+++ b/sesman/chansrv/sound.c
@@ -1,32 +1,346 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sound.h"
+#include "thread_calls.h"
+
+extern int g_rdpsnd_chan_id; /* in chansrv.c */
+extern int g_display_num; /* in chansrv.c */
+
+static struct trans *g_audio_l_trans = 0; // listener
+static struct trans *g_audio_c_trans = 0; // connection
+static int g_training_sent_time = 0;
+static int g_cBlockNo = 0;
+
+#if defined(XRDP_SIMPLESOUND)
+static void* DEFAULT_CC
+read_raw_audio_data(void* arg);
+#endif
+
+/*****************************************************************************/
+static int APP_CC
+sound_send_server_formats(void)
+{
+ struct stream* s;
+ int bytes;
+ char* size_ptr;
+
+ print_got_here();
+
+ make_stream(s);
+ init_stream(s, 8182);
+ out_uint16_le(s, SNDC_FORMATS);
+ size_ptr = s->p;
+ out_uint16_le(s, 0); /* size, set later */
+ out_uint32_le(s, 0); /* dwFlags */
+ out_uint32_le(s, 0); /* dwVolume */
+ out_uint32_le(s, 0); /* dwPitch */
+ out_uint16_le(s, 0); /* wDGramPort */
+ out_uint16_le(s, 1); /* wNumberOfFormats */
+ out_uint8(s, g_cBlockNo); /* cLastBlockConfirmed */
+ out_uint16_le(s, 2); /* wVersion */
+ out_uint8(s, 0); /* bPad */
+
+ /* sndFormats */
+ /*
+ wFormatTag 2 byte offset 0
+ nChannels 2 byte offset 2
+ nSamplesPerSec 4 byte offset 4
+ nAvgBytesPerSec 4 byte offset 8
+ nBlockAlign 2 byte offset 12
+ wBitsPerSample 2 byte offset 14
+ cbSize 2 byte offset 16
+ data variable offset 18
+ */
+
+ /* examples
+ 01 00 02 00 44 ac 00 00 10 b1 02 00 04 00 10 00 ....D...........
+ 00 00
+ 01 00 02 00 22 56 00 00 88 58 01 00 04 00 10 00 ...."V...X......
+ 00 00
+ */
+
+ out_uint16_le(s, 1); // wFormatTag - WAVE_FORMAT_PCM
+ out_uint16_le(s, 2); // num of channels
+ out_uint32_le(s, 44100); // samples per sec
+ out_uint32_le(s, 176400); // avg bytes per sec
+ out_uint16_le(s, 4); // block align
+ out_uint16_le(s, 16); // bits per sample
+ out_uint16_le(s, 0); // size
+
+ s_mark_end(s);
+ bytes = (int)((s->end - s->data) - 4);
+ size_ptr[0] = bytes;
+ size_ptr[1] = bytes >> 8;
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
+ free_stream(s);
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+sound_send_training(void)
+{
+ struct stream* s;
+ int bytes;
+ int time;
+ char* size_ptr;
+
+ print_got_here();
+
+ make_stream(s);
+ init_stream(s, 8182);
+ out_uint16_le(s, SNDC_TRAINING);
+ size_ptr = s->p;
+ out_uint16_le(s, 0); /* size, set later */
+ time = g_time2();
+ g_training_sent_time = time;
+ out_uint16_le(s, time);
+ out_uint16_le(s, 1024);
+ out_uint8s(s, (1024 - 4));
+ s_mark_end(s);
+ bytes = (int)((s->end - s->data) - 4);
+ size_ptr[0] = bytes;
+ size_ptr[1] = bytes >> 8;
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
+ free_stream(s);
+ return 0;
+}
+
+/*****************************************************************************/
/*
- 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.
-
- xrdp: A Remote Desktop Protocol server.
- Copyright (C) Jay Sorg 2009-2010
+ 0000 07 02 26 00 03 00 80 00 ff ff ff ff 00 00 00 00 ..&.............
+ 0010 00 00 01 00 00 02 00 00 01 00 02 00 44 ac 00 00 ............D...
+ 0020 10 b1 02 00 04 00 10 00 00 00
*/
-#include "arch.h"
-#include "parse.h"
-#include "os_calls.h"
+static int APP_CC
+sound_process_formats(struct stream* s, int size)
+{
+ int num_formats;
+
+ print_got_here();
+
+ LOG(0, ("sound_process_formats:"));
+ if (size < 16)
+ {
+ return 1;
+ }
+ in_uint8s(s, 14);
+ in_uint16_le(s, num_formats);
+ if (num_formats > 0)
+ {
+ sound_send_training();
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+sound_send_wave_data(char* data, int data_bytes)
+{
+ struct stream* s;
+ int bytes;
+ int time;
+ char* size_ptr;
+
+ print_got_here();
+
+ if ((data_bytes < 4) || (data_bytes > 32 * 1024))
+ {
+ LOG(0, ("sound_send_wave_data: bad data_bytes %d", data_bytes));
+ }
+
+ /* part one of 2 PDU wave info */
+
+ LOG(10, ("sound_send_wave_data: sending %d bytes", data_bytes));
+
+ make_stream(s);
+ init_stream(s, data_bytes);
+ out_uint16_le(s, SNDC_WAVE);
+ size_ptr = s->p;
+ out_uint16_le(s, 0); /* size, set later */
+ time = g_time2();
+ out_uint16_le(s, time);
+ out_uint16_le(s, 0); /* wFormatNo */
+ g_cBlockNo++;
+ out_uint8(s, g_cBlockNo);
+
+ LOG(10, ("sound_send_wave_data: sending time %d, g_cBlockNo %d",
+ time & 0xffff, g_cBlockNo & 0xff));
+
+ out_uint8s(s, 3);
+ out_uint8a(s, data, 4);
+ s_mark_end(s);
+ bytes = (int)((s->end - s->data) - 4);
+ bytes += data_bytes;
+ bytes -= 4;
+ size_ptr[0] = bytes;
+ size_ptr[1] = bytes >> 8;
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
+
+ /* part two of 2 PDU wave info */
+ init_stream(s, data_bytes);
+ out_uint32_le(s, 0);
+ out_uint8a(s, data + 4, data_bytes - 4);
+ s_mark_end(s);
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
+ free_stream(s);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+sound_process_training(struct stream* s, int size)
+{
+ int time_diff;
+
+ print_got_here();
+
+ time_diff = g_time2() - g_training_sent_time;
+ LOG(0, ("sound_process_training: round trip time %u", time_diff));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+sound_process_wave_confirm(struct stream* s, int size)
+{
+ int wTimeStamp;
+ int cConfirmedBlockNo;
+
+ print_got_here();
-extern int g_rdpsnd_chan_id; /* in chansrv.c */
+ in_uint16_le(s, wTimeStamp);
+ in_uint8(s, cConfirmedBlockNo);
+
+ LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, cConfirmedBlockNo %d",
+ wTimeStamp, cConfirmedBlockNo));
+
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+process_pcm_message(int id, int size, struct stream* s)
+{
+ print_got_here();
+
+ sound_send_wave_data(s->p, size);
+ return 0;
+}
+
+/*****************************************************************************/
+/* data coming in from audio source, eg pulse, alsa */
+static int DEFAULT_CC
+sound_trans_audio_data_in(struct trans* trans)
+{
+ struct stream *s;
+ int id;
+ int size;
+ int error;
+
+ if (trans == 0)
+ {
+ return 0;
+ }
+ if (trans != g_audio_c_trans)
+ {
+ return 1;
+ }
+ s = trans_get_in_s(trans);
+ in_uint32_le(s, id);
+ in_uint32_le(s, size);
+ if ((id != 0) || (size > 32 * 1024 + 8) || (size < 1))
+ {
+ LOG(0, ("sound_trans_audio_data_in: bad message id %d size %d", id, size));
+ return 1;
+ }
+ error = trans_force_read(trans, size - 8);
+ if (error == 0)
+ {
+ /* here, the entire message block is read in, process it */
+ error = process_pcm_message(id, size - 8, s);
+ }
+ return error;
+}
+
+/*****************************************************************************/
+static int DEFAULT_CC
+sound_trans_audio_conn_in(struct trans *trans, struct trans *new_trans)
+{
+ 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;
+}
/*****************************************************************************/
int APP_CC
sound_init(void)
{
+ char port[256];
+ int error;
+
+ print_got_here();
+ LOG(0, ("sound_init:"));
+
+ sound_send_server_formats();
+ g_audio_l_trans = trans_create(2, 33 * 1024, 8192);
+ g_snprintf(port, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num);
+ g_audio_l_trans->trans_conn_in = sound_trans_audio_conn_in;
+ error = trans_listen(g_audio_l_trans, port);
+ if (error != 0)
+ {
+ LOG(0, ("sound_init: trans_listen failed"));
+ }
+
+#if defined(XRDP_SIMPLESOUND)
+
+ /* start thread to read raw audio data from pulseaudio device */
+ tc_thread_create(read_raw_audio_data, 0);
+
+#endif
+
return 0;
}
@@ -34,14 +348,54 @@ sound_init(void)
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_l_trans = 0;
+ }
+
return 0;
}
/*****************************************************************************/
+/* data in from client ( clinet -> xrdp -> chansrv ) */
int APP_CC
sound_data_in(struct stream* s, int chan_id, int chan_flags, int length,
int total_length)
{
+ int code;
+ int size;
+
+ print_got_here();
+
+ in_uint8(s, code);
+ in_uint8s(s, 1);
+ in_uint16_le(s, size);
+ switch (code)
+ {
+ case SNDC_WAVECONFIRM:
+ sound_process_wave_confirm(s, size);
+ break;
+
+ case SNDC_TRAINING:
+ sound_process_training(s, size);
+ break;
+
+ case SNDC_FORMATS:
+ sound_process_formats(s, size);
+ break;
+
+ default:
+ LOG(0, ("sound_data_in: unknown code %d size %d", code, size));
+ break;
+ }
return 0;
}
@@ -49,6 +403,20 @@ sound_data_in(struct stream* s, int chan_id, int chan_flags, int length,
int APP_CC
sound_get_wait_objs(tbus* objs, int* count, int* timeout)
{
+ int lcount;
+
+ lcount = *count;
+ if (g_audio_l_trans != 0)
+ {
+ objs[lcount] = g_audio_l_trans->sck;
+ lcount++;
+ }
+ if (g_audio_c_trans != 0)
+ {
+ objs[lcount] = g_audio_c_trans->sck;
+ lcount++;
+ }
+ *count = lcount;
return 0;
}
@@ -56,5 +424,130 @@ sound_get_wait_objs(tbus* objs, int* count, int* timeout)
int APP_CC
sound_check_wait_objs(void)
{
+ if (g_audio_l_trans != 0)
+ {
+ trans_check_wait_objs(g_audio_l_trans);
+ }
+
+ if (g_audio_c_trans != 0)
+ {
+ trans_check_wait_objs(g_audio_c_trans);
+ }
+
+ return 0;
+}
+
+#if defined(XRDP_SIMPLESOUND)
+
+static int DEFAULT_CC
+sttrans_data_in(struct trans* self)
+{
+ LOG(0, ("sttrans_data_in:\n"));
return 0;
}
+
+/**
+ * read raw audio data from pulseaudio device and write it
+ * to a unix domain socket on which trans server is listening
+ */
+
+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;
+}
+
+#endif
diff --git a/sesman/chansrv/sound.h b/sesman/chansrv/sound.h
index 45448a5a..8171680d 100644
--- a/sesman/chansrv/sound.h
+++ b/sesman/chansrv/sound.h
@@ -1,20 +1,70 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
-#if !defined(SOUND_H)
-#define SOUND_H
+#ifndef _SOUND_H_
+#define _SOUND_H_
+
+#if defined(XRDP_SIMPLESOUND)
+#include <pulse/simple.h>
+#include <pulse/error.h>
+#endif
#include "arch.h"
#include "parse.h"
+#include "os_calls.h"
+#include "chansrv.h"
+#include "trans.h"
+
+#define _DEBUG_RDPSND
+
+#ifdef DEBUG_RDPSND
+#include <stdio.h>
+#define print_got_here() printf("****** got here: %s : %s : %d\n", \
+ __FILE__, __func__, __LINE__);
+#else
+#define print_got_here()
+#endif
+
+#define AUDIO_BUF_SIZE 2048
+
+#define SNDC_CLOSE 0x01
+#define SNDC_WAVE 0x02
+#define SNDC_SETVOLUME 0x03
+#define SNDC_SETPITCH 0x04
+#define SNDC_WAVECONFIRM 0x05
+#define SNDC_TRAINING 0x06
+#define SNDC_FORMATS 0x07
+#define SNDC_CRYPTKEY 0x08
+#define SNDC_WAVEENCRYPT 0x09
+#define SNDC_UDPWAVE 0x0A
+#define SNDC_UDPWAVELAST 0x0B
+#define SNDC_QUALITYMODE 0x0C
int APP_CC
sound_init(void);
int APP_CC
sound_deinit(void);
int APP_CC
-sound_data_in(struct stream* s, int chan_id, int chan_flags, int length,
- int total_length);
-int APP_CC
sound_get_wait_objs(tbus* objs, int* count, int* timeout);
int APP_CC
sound_check_wait_objs(void);
+int APP_CC
+sound_data_in(struct stream* s, int chan_id, int chan_flags,
+ int length, int total_length);
#endif
diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c
new file mode 100644
index 00000000..70b52694
--- /dev/null
+++ b/sesman/chansrv/xcommon.c
@@ -0,0 +1,187 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <X11/Xlib.h>
+#include "arch.h"
+#include "parse.h"
+#include "os_calls.h"
+#include "chansrv.h"
+#include "log.h"
+#include "clipboard.h"
+#include "rail.h"
+
+extern int g_clip_up; /* in clipboard.c */
+extern int g_waiting_for_data_response; /* in clipboard.c */
+extern int g_waiting_for_data_response_time; /* in clipboard.c */
+
+extern int g_rail_up; /* in rail.c */
+
+Display* g_display = 0;
+int g_x_socket = 0;
+tbus g_x_wait_obj = 0;
+Screen* g_screen = 0;
+int g_screen_num = 0;
+Window g_root_window = 0;
+Atom g_wm_delete_window_atom = 0;
+Atom g_wm_protocols_atom = 0;
+
+/*****************************************************************************/
+static int DEFAULT_CC
+xcommon_error_handler(Display* dis, XErrorEvent* xer)
+{
+ char text[256];
+
+ XGetErrorText(dis, xer->error_code, text, 255);
+ LOGM((LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d "
+ "resource 0x%lx", text, xer->error_code,
+ xer->request_code, xer->minor_code, xer->resourceid));
+ return 0;
+}
+
+/*****************************************************************************/
+/* The X server had an internal error. This is the last function called.
+ Do any cleanup that needs to be done on exit, like removing temporary files.
+ Don't worry about memory leaks */
+static int DEFAULT_CC
+xcommon_fatal_handler(Display* dis)
+{
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns time in miliseconds
+ this is like g_time2 in os_calls, but not miliseconds since machine was
+ up, something else
+ this is a time value similar to what the xserver uses */
+int APP_CC
+xcommon_get_local_time(void)
+{
+ return g_time3();
+}
+
+/******************************************************************************/
+/* this should be called first */
+int APP_CC
+xcommon_init(void)
+{
+ if (g_display != 0)
+ {
+ LOG(10, ("xcommon_init: xcommon_init already called"));
+ return 0;
+ }
+ g_display = XOpenDisplay(0);
+ if (g_display == 0)
+ {
+ LOGM((LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed"));
+ return 1;
+ }
+
+ LOG(0, ("xcommon_init: connected to display ok"));
+
+ /* setting the error handlers can cause problem when shutting down
+ chansrv on some xlibs */
+ XSetErrorHandler(xcommon_error_handler);
+ //XSetIOErrorHandler(xcommon_fatal_handler);
+
+ g_x_socket = XConnectionNumber(g_display);
+ if (g_x_socket == 0)
+ {
+ LOGM((LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed"));
+ return 1;
+ }
+
+ g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0);
+ g_screen_num = DefaultScreen(g_display);
+ g_screen = ScreenOfDisplay(g_display, g_screen_num);
+
+ g_root_window = RootWindowOfScreen(g_screen);
+
+ g_wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", 0);
+ g_wm_protocols_atom = XInternAtom(g_display, "WM_PROTOCOLS", 0);
+
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error
+ this is called to get any wait objects for the main loop
+ timeout can be nil */
+int APP_CC
+xcommon_get_wait_objs(tbus* objs, int* count, int* timeout)
+{
+ int lcount;
+
+ if (((!g_clip_up) && (!g_rail_up)) || (objs == 0) || (count == 0))
+ {
+ LOG(10, ("xcommon_get_wait_objs: nothing to do"));
+ return 0;
+ }
+ lcount = *count;
+ objs[lcount] = g_x_wait_obj;
+ lcount++;
+ *count = lcount;
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+xcommon_check_wait_objs(void)
+{
+ XEvent xevent;
+ int time_diff;
+ int clip_rv;
+ int rail_rv;
+
+ if ((!g_clip_up) && (!g_rail_up))
+ {
+ LOG(10, ("xcommon_check_wait_objs: nothing to do"));
+ return 0;
+ }
+ if (g_is_wait_obj_set(g_x_wait_obj))
+ {
+ if (XPending(g_display) < 1)
+ {
+ /* something is wrong, should not get here */
+ LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: sck closed"));
+ return 0;
+ }
+ if (g_waiting_for_data_response)
+ {
+ time_diff = xcommon_get_local_time() -
+ g_waiting_for_data_response_time;
+ if (time_diff > 10000)
+ {
+ LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: warning, "
+ "waiting for data response too long"));
+ }
+ }
+ while (XPending(g_display) > 0)
+ {
+ g_memset(&xevent, 0, sizeof(xevent));
+ XNextEvent(g_display, &xevent);
+
+ clip_rv = clipboard_xevent(&xevent);
+ rail_rv = rail_xevent(&xevent);
+ if ((clip_rv == 1) && (rail_rv == 1))
+ {
+ LOG(10, ("xcommon_check_wait_objs unknown xevent type %d", xevent.type));
+ }
+ }
+ }
+ return 0;
+}
diff --git a/sesman/chansrv/xcommon.h b/sesman/chansrv/xcommon.h
new file mode 100644
index 00000000..d5aa7e46
--- /dev/null
+++ b/sesman/chansrv/xcommon.h
@@ -0,0 +1,34 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if !defined(XCOMMON_H)
+#define XCOMMON_H
+
+#include "arch.h"
+#include "parse.h"
+
+int APP_CC
+xcommon_get_local_time(void);
+int APP_CC
+xcommon_init(void);
+int APP_CC
+xcommon_get_wait_objs(tbus* objs, int* count, int* timeout);
+int APP_CC
+xcommon_check_wait_objs(void);
+
+#endif
diff --git a/sesman/config.c b/sesman/config.c
index d81f7968..a4342676 100644
--- a/sesman/config.c
+++ b/sesman/config.c
@@ -29,28 +29,11 @@
#include "list.h"
#include "file.h"
#include "sesman.h"
+#include "log.h"
extern struct config_sesman* g_cfg; /* in sesman.c */
-/******************************************************************************/
-/**
- *
- * @brief Reads sesman configuration
- * @param s translates the strings "1", "true" and "yes" in 1 (true) and other strings in 0
- * @return 0 on success, 1 on failure
- *
- */
-static int APP_CC
-text2bool(char* s)
-{
- if (0 == g_strcasecmp(s, "1") ||
- 0 == g_strcasecmp(s, "true") ||
- 0 == g_strcasecmp(s, "yes"))
- {
- return 1;
- }
- return 0;
-}
+
/******************************************************************************/
int DEFAULT_CC
@@ -66,16 +49,16 @@ config_read(struct config_sesman* cfg)
fd = g_file_open(cfg_file);
if (-1 == fd)
{
- if (g_cfg->log.fd >= 0)
- {
+ //if (g_cfg->log.fd >= 0)
+ //{
/* logging is already active */
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "error opening %s in \
+ log_message(LOG_LEVEL_ALWAYS, "error opening %s in \
config_read", cfg_file);
- }
- else
- {
+ //}
+ //else
+ //{
g_printf("error opening %s in config_read", cfg_file);
- }
+ //}
return 1;
}
g_memset(cfg, 0, sizeof(struct config_sesman));
@@ -95,7 +78,7 @@ config_read(struct config_sesman* cfg)
config_read_rdp_params(fd, cfg, param_n, param_v);
/* read logging config */
- config_read_logging(fd, &(cfg->log), param_n, param_v);
+ // config_read_logging(fd, &(cfg->log), param_n, param_v);
/* read security config */
config_read_security(fd, &(cfg->sec), param_n, param_v);
@@ -190,7 +173,7 @@ config_read_globals(int file, struct config_sesman* cf, struct list* param_n,
return 0;
}
-/******************************************************************************/
+/******************************************************************************
int DEFAULT_CC
config_read_logging(int file, struct log_config* lc, struct list* param_n,
struct list* param_v)
@@ -201,7 +184,7 @@ config_read_logging(int file, struct log_config* lc, struct list* param_n,
list_clear(param_v);
list_clear(param_n);
- /* setting defaults */
+ // setting defaults
lc->program_name = g_strdup("sesman");
lc->log_file = 0;
lc->fd = 0;
@@ -244,7 +227,7 @@ config_read_logging(int file, struct log_config* lc, struct list* param_n,
return 0;
}
-
+*/
/******************************************************************************/
int DEFAULT_CC
config_read_security(int file, struct config_security* sc,
diff --git a/sesman/config.h b/sesman/config.h
index 2a4ebd28..73fab38f 100644
--- a/sesman/config.h
+++ b/sesman/config.h
@@ -45,12 +45,13 @@
#define SESMAN_CFG_RDP_PARAMS "X11rdp"
#define SESMAN_CFG_VNC_PARAMS "Xvnc"
+/*
#define SESMAN_CFG_LOGGING "Logging"
#define SESMAN_CFG_LOG_FILE "LogFile"
#define SESMAN_CFG_LOG_LEVEL "LogLevel"
#define SESMAN_CFG_LOG_ENABLE_SYSLOG "EnableSyslog"
#define SESMAN_CFG_LOG_SYSLOG_LEVEL "SyslogLevel"
-
+*/
#define SESMAN_CFG_SECURITY "Security"
#define SESMAN_CFG_SEC_LOGIN_RETRY "MaxLoginRetry"
#define SESMAN_CFG_SEC_ALLOW_ROOT "AllowRootLogin"
@@ -186,7 +187,7 @@ struct config_sesman
* @var log
* @brief Log configuration struct
*/
- struct log_config log;
+ //struct log_config log;
/**
* @var sec
* @brief Security configuration options struct
diff --git a/sesman/env.c b/sesman/env.c
index 4bcb22e8..f7abe120 100644
--- a/sesman/env.c
+++ b/sesman/env.c
@@ -47,7 +47,7 @@ env_check_password_file(char* filename, char* password)
fd = g_file_open(filename);
if (fd == -1)
{
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING,
+ log_message(LOG_LEVEL_WARNING,
"can't read vnc password file - %s",
filename);
return 1;
@@ -112,13 +112,13 @@ env_set_user(char* username, char* passwd_file, int display)
/* we use auth_file_path as requested */
g_sprintf(passwd_file, g_cfg->auth_file_path, username);
}
- LOG_DBG(&(g_cfg->log), "pass file: %s", passwd_file);
+ LOG_DBG("pass file: %s", passwd_file);
}
}
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR,
+ log_message(LOG_LEVEL_ERROR,
"error getting user info for user %s", username);
}
return error;
diff --git a/sesman/libscp/Makefile.am b/sesman/libscp/Makefile.am
index de8513f8..eaf518a8 100644
--- a/sesman/libscp/Makefile.am
+++ b/sesman/libscp/Makefile.am
@@ -1,5 +1,5 @@
EXTRA_DIST = libscp_connection.h libscp_commands.h libscp.h libscp_session.h libscp_types_mng.h libscp_v1c_mng.h libscp_vX.h libscp_commands_mng.h libscp_init.h libscp_tcp.h libscp_v0.h libscp_v1s.h libscp_lock.h \
-libscp_types.h libscp_v1c.h libscp_v1s_mng.h
+libscp_types.h libscp_v1c.h libscp_v1s_mng.h
AM_CFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
@@ -27,5 +27,5 @@ libscp_la_SOURCES = \
libscp_vX.c
libscp_la_LIBADD = \
- $(top_srcdir)/common/libcommon.la \
+ $(top_builddir)/common/libcommon.la \
-lpthread
diff --git a/sesman/libscp/libscp_connection.c b/sesman/libscp/libscp_connection.c
index 0b09852e..bf49fb84 100644
--- a/sesman/libscp/libscp_connection.c
+++ b/sesman/libscp/libscp_connection.c
@@ -27,7 +27,7 @@
#include "libscp_connection.h"
-extern struct log_config* s_log;
+//extern struct log_config* s_log;
struct SCP_CONNECTION*
scp_connection_create(int sck)
@@ -38,7 +38,7 @@ scp_connection_create(int sck)
if (0 == conn)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[connection:%d] connection create: malloc error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[connection:%d] connection create: malloc error", __LINE__);
return 0;
}
diff --git a/sesman/libscp/libscp_init.c b/sesman/libscp/libscp_init.c
index 22497ac2..4c48fb1f 100644
--- a/sesman/libscp/libscp_init.c
+++ b/sesman/libscp/libscp_init.c
@@ -27,22 +27,24 @@
#include "libscp_init.h"
-struct log_config* s_log;
+//struct log_config* s_log;
/* server API */
int DEFAULT_CC
-scp_init(struct log_config* log)
+scp_init()
{
+/*
if (0 == log)
{
return 1;
}
+*/
- s_log = log;
+ //s_log = log;
scp_lock_init();
- log_message(s_log, LOG_LEVEL_WARNING, "[init:%d] libscp initialized", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[init:%d] libscp initialized", __LINE__);
return 0;
}
diff --git a/sesman/libscp/libscp_init.h b/sesman/libscp/libscp_init.h
index 5ac0ba02..92dbc659 100644
--- a/sesman/libscp/libscp_init.h
+++ b/sesman/libscp/libscp_init.h
@@ -42,7 +42,7 @@
*
*/
int DEFAULT_CC
-scp_init(struct log_config* log);
+scp_init();
#endif
diff --git a/sesman/libscp/libscp_session.c b/sesman/libscp/libscp_session.c
index 8ac94d25..3ed5070a 100644
--- a/sesman/libscp/libscp_session.c
+++ b/sesman/libscp/libscp_session.c
@@ -31,7 +31,7 @@
#include <sys/socket.h>
#include <arpa/inet.h>
-extern struct log_config* s_log;
+//extern struct log_config* s_log;
/*******************************************************************/
struct SCP_SESSION*
@@ -42,7 +42,7 @@ scp_session_create()
s = (struct SCP_SESSION*)g_malloc(sizeof(struct SCP_SESSION), 1);
if (0 == s)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] session create: malloc error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] session create: malloc error", __LINE__);
return 0;
}
return s;
@@ -60,17 +60,20 @@ scp_session_set_type(struct SCP_SESSION* s, tui8 type)
case SCP_SESSION_TYPE_XRDP:
s->type = SCP_SESSION_TYPE_XRDP;
break;
+ case SCP_GW_AUTHENTICATION:
+ s->type = SCP_GW_AUTHENTICATION;
+ break;
case SCP_SESSION_TYPE_MANAGE:
s->type = SCP_SESSION_TYPE_MANAGE;
s->mng = (struct SCP_MNG_DATA*)g_malloc(sizeof(struct SCP_MNG_DATA), 1);
if (NULL == s->mng)
{
- log_message(s_log, LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__);
+ log_message(LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__);
return 1;
}
break;
default:
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__);
return 1;
}
return 0;
@@ -89,7 +92,7 @@ scp_session_set_version(struct SCP_SESSION* s, tui32 version)
s->version = 1;
break;
default:
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_version: unknown version", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_version: unknown version", __LINE__);
return 1;
}
return 0;
@@ -149,7 +152,7 @@ scp_session_set_locale(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_locale: null locale", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_locale: null locale", __LINE__);
s->locale[0]='\0';
return 1;
}
@@ -164,7 +167,7 @@ scp_session_set_username(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_username: null username", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: null username", __LINE__);
return 1;
}
if (0 != s->username)
@@ -174,7 +177,7 @@ scp_session_set_username(struct SCP_SESSION* s, char* str)
s->username = g_strdup(str);
if (0 == s->username)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_username: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: strdup error", __LINE__);
return 1;
}
return 0;
@@ -186,7 +189,7 @@ scp_session_set_password(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_password: null password", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: null password", __LINE__);
return 1;
}
if (0 != s->password)
@@ -196,7 +199,7 @@ scp_session_set_password(struct SCP_SESSION* s, char* str)
s->password = g_strdup(str);
if (0 == s->password)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_password: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: strdup error", __LINE__);
return 1;
}
return 0;
@@ -208,7 +211,7 @@ scp_session_set_domain(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_domain: null domain", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: null domain", __LINE__);
return 1;
}
if (0 != s->domain)
@@ -218,7 +221,7 @@ scp_session_set_domain(struct SCP_SESSION* s, char* str)
s->domain = g_strdup(str);
if (0 == s->domain)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_domain: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: strdup error", __LINE__);
return 1;
}
return 0;
@@ -230,7 +233,7 @@ scp_session_set_program(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_program: null program", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: null program", __LINE__);
return 1;
}
if (0 != s->program)
@@ -240,7 +243,7 @@ scp_session_set_program(struct SCP_SESSION* s, char* str)
s->program = g_strdup(str);
if (0 == s->program)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_program: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: strdup error", __LINE__);
return 1;
}
return 0;
@@ -252,7 +255,7 @@ scp_session_set_directory(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_directory: null directory", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: null directory", __LINE__);
return 1;
}
if (0 != s->directory)
@@ -262,7 +265,7 @@ scp_session_set_directory(struct SCP_SESSION* s, char* str)
s->directory = g_strdup(str);
if (0 == s->directory)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_directory: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: strdup error", __LINE__);
return 1;
}
return 0;
@@ -274,7 +277,7 @@ scp_session_set_client_ip(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_client_ip: null ip", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: null ip", __LINE__);
return 1;
}
if (0 != s->client_ip)
@@ -284,7 +287,7 @@ scp_session_set_client_ip(struct SCP_SESSION* s, char* str)
s->client_ip = g_strdup(str);
if (0 == s->client_ip)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_client_ip: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: strdup error", __LINE__);
return 1;
}
return 0;
@@ -296,7 +299,7 @@ scp_session_set_hostname(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_hostname: null hostname", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: null hostname", __LINE__);
return 1;
}
if (0 != s->hostname)
@@ -306,7 +309,7 @@ scp_session_set_hostname(struct SCP_SESSION* s, char* str)
s->hostname = g_strdup(str);
if (0 == s->hostname)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_hostname: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: strdup error", __LINE__);
return 1;
}
return 0;
@@ -318,7 +321,7 @@ scp_session_set_errstr(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_errstr: null string", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: null string", __LINE__);
return 1;
}
if (0 != s->errstr)
@@ -328,7 +331,7 @@ scp_session_set_errstr(struct SCP_SESSION* s, char* str)
s->errstr = g_strdup(str);
if (0 == s->errstr)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_errstr: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: strdup error", __LINE__);
return 1;
}
return 0;
@@ -359,7 +362,7 @@ scp_session_set_addr(struct SCP_SESSION* s, int type, void* addr)
ret = inet_pton(AF_INET, addr, &ip4);
if (ret == 0)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__);
inet_pton(AF_INET, "127.0.0.1", &ip4);
g_memcpy(&(s->ipv4addr), &(ip4.s_addr), 4);
return 1;
@@ -375,7 +378,7 @@ scp_session_set_addr(struct SCP_SESSION* s, int type, void* addr)
ret = inet_pton(AF_INET6, addr, &ip6);
if (ret == 0)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__);
inet_pton(AF_INET, "::1", &ip6);
g_memcpy(s->ipv6addr, &(ip6.s6_addr), 16);
return 1;
diff --git a/sesman/libscp/libscp_tcp.c b/sesman/libscp/libscp_tcp.c
index 6ffa4693..459992fe 100644
--- a/sesman/libscp/libscp_tcp.c
+++ b/sesman/libscp/libscp_tcp.c
@@ -42,7 +42,7 @@ scp_tcp_force_recv(int sck, char* data, int len)
int rcvd;
int block;
- LOG_DBG(s_log, "scp_tcp_force_recv()");
+ LOG_DBG("scp_tcp_force_recv()");
block = scp_lock_fork_critical_section_start();
while (len > 0)
@@ -84,7 +84,7 @@ scp_tcp_force_send(int sck, char* data, int len)
int sent;
int block;
- LOG_DBG(s_log, "scp_tcp_force_send()");
+ LOG_DBG("scp_tcp_force_send()");
block = scp_lock_fork_critical_section_start();
while (len > 0)
diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h
index 7a54545a..e6521741 100644
--- a/sesman/libscp/libscp_types.h
+++ b/sesman/libscp/libscp_types.h
@@ -42,6 +42,10 @@
#define SCP_SESSION_TYPE_XVNC 0x00
#define SCP_SESSION_TYPE_XRDP 0x01
#define SCP_SESSION_TYPE_MANAGE 0x02
+/* SCP_GW_AUTHENTICATION can be used when XRDP + sesman act as a gateway
+ * XRDP sends this command to let sesman verify if the user is allowed
+ * to use the gateway */
+#define SCP_GW_AUTHENTICATION 0x04
#define SCP_ADDRESS_TYPE_IPV4 0x00
#define SCP_ADDRESS_TYPE_IPV6 0x01
diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c
index d46d6afa..f8b5a9d6 100644
--- a/sesman/libscp/libscp_v0.c
+++ b/sesman/libscp/libscp_v0.c
@@ -43,7 +43,7 @@ scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
init_stream(c->in_s, c->in_s->size);
init_stream(c->out_s, c->in_s->size);
- LOG_DBG(s_log, "[v0:%d] starting connection", __LINE__);
+ LOG_DBG("[v0:%d] starting connection", __LINE__);
g_tcp_set_non_blocking(c->in_sck);
g_tcp_set_no_delay(c->in_sck);
s_push_layer(c->out_s, channel_hdr, 8);
@@ -59,7 +59,7 @@ scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
}
else
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
sz = g_strlen(s->username);
@@ -83,27 +83,27 @@ scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (0 != version)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__);
return SCP_CLIENT_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
if (size < 14)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: packet size error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: packet size error", __LINE__);
return SCP_CLIENT_STATE_SIZE_ERR;
}
@@ -111,7 +111,7 @@ scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
init_stream(c->in_s, c->in_s->size);
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
@@ -119,7 +119,7 @@ scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
in_uint16_be(c->in_s, sz);
if (3 != sz)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
@@ -127,14 +127,14 @@ scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
in_uint16_be(c->in_s, sz);
if (1 != sz)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: connection denied", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: connection denied", __LINE__);
return SCP_CLIENT_STATE_CONNECTION_DENIED;
}
in_uint16_be(c->in_s, sz);
s->display = sz;
- LOG_DBG(s_log, "[v0:%d] connection terminated", __LINE__);
+ LOG_DBG("[v0:%d] connection terminated", __LINE__);
return SCP_CLIENT_STATE_END;
}
@@ -152,20 +152,20 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
if (!skipVchk)
{
- LOG_DBG(s_log, "[v0:%d] starting connection", __LINE__);
+ LOG_DBG("[v0:%d] starting connection", __LINE__);
if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
c->in_s->end = c->in_s->data + 8;
in_uint32_be(c->in_s, version);
if (version != 0)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__);
return SCP_SERVER_STATE_VERSION_ERR;
}
}
else
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
}
@@ -175,7 +175,7 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
init_stream(c->in_s, 8196);
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
c->in_s->end = c->in_s->data + (size - 8);
@@ -187,7 +187,7 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
session = scp_session_create();
if (0 == session)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -208,7 +208,7 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
if (0 != scp_session_set_username(session, buf))
{
scp_session_destroy(session);
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -219,7 +219,7 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
if (0 != scp_session_set_password(session, buf))
{
scp_session_destroy(session);
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -277,9 +277,45 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
}
}
}
+ else if (code == SCP_GW_AUTHENTICATION)
+ {
+ /* g_writeln("Command is SCP_GW_AUTHENTICATION"); */
+ session = scp_session_create();
+ if (0 == session)
+ {
+ /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);*/
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
+
+ scp_session_set_version(session, version);
+ scp_session_set_type(session, SCP_GW_AUTHENTICATION);
+ /* reading username */
+ in_uint16_be(c->in_s, sz);
+ buf[sz]='\0';
+ in_uint8a(c->in_s, buf, sz);
+ /* g_writeln("Received user name: %s",buf); */
+ if (0 != scp_session_set_username(session, buf))
+ {
+ scp_session_destroy(session);
+ /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);*/
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
+
+ /* reading password */
+ in_uint16_be(c->in_s, sz);
+ buf[sz] = '\0';
+ in_uint8a(c->in_s, buf, sz);
+ /* g_writeln("Received password: %s",buf); */
+ if (0 != scp_session_set_password(session, buf))
+ {
+ scp_session_destroy(session);
+ /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); */
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
+ }
else
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
@@ -300,11 +336,11 @@ scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d)
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
- LOG_DBG(s_log, "[v0:%d] connection terminated (allowed)", __LINE__);
+ LOG_DBG("[v0:%d] connection terminated (allowed)", __LINE__);
return SCP_SERVER_STATE_OK;
}
@@ -315,16 +351,39 @@ scp_v0s_deny_connection(struct SCP_CONNECTION* c)
out_uint32_be(c->out_s, 0); /* version */
out_uint32_be(c->out_s, 14); /* size */
out_uint16_be(c->out_s, 3); /* cmd */
- out_uint16_be(c->out_s, 0); /* data */
- out_uint16_be(c->out_s, 0); /* data */
+ out_uint16_be(c->out_s, 0); /* data = 0 - means NOT ok*/
+ out_uint16_be(c->out_s, 0); /* reserved for display number*/
+ s_mark_end(c->out_s);
+
+ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
+ {
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ LOG_DBG("[v0:%d] connection terminated (denied)", __LINE__);
+ return SCP_SERVER_STATE_OK;
+}
+
+/******************************************************************************/
+enum SCP_SERVER_STATES_E
+scp_v0s_replyauthentication(struct SCP_CONNECTION* c, unsigned short int value)
+{
+ out_uint32_be(c->out_s, 0); /* version */
+ out_uint32_be(c->out_s, 14); /* size */
+ /* cmd SCP_GW_AUTHENTICATION means authentication reply */
+ out_uint16_be(c->out_s, SCP_GW_AUTHENTICATION);
+ out_uint16_be(c->out_s, value); /* reply code */
+ out_uint16_be(c->out_s, 0); /* dummy data */
s_mark_end(c->out_s);
+ /* g_writeln("Total number of bytes that will be sent %d",c->out_s->end - c->out_s->data);*/
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); */
return SCP_SERVER_STATE_NETWORK_ERR;
}
- LOG_DBG(s_log, "[v0:%d] connection terminated (denied)", __LINE__);
+ /* until syslog merge LOG_DBG(s_log, "[v0:%d] connection terminated (scp_v0s_deny_authentication)", __LINE__);*/
return SCP_SERVER_STATE_OK;
}
diff --git a/sesman/libscp/libscp_v0.h b/sesman/libscp/libscp_v0.h
index 7c6fd4b2..92b835f0 100644
--- a/sesman/libscp/libscp_v0.h
+++ b/sesman/libscp/libscp_v0.h
@@ -73,5 +73,14 @@ scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d);
enum SCP_SERVER_STATES_E
scp_v0s_deny_connection(struct SCP_CONNECTION* c);
+/**
+ * @brief send reply to an authentication request
+ * @param c connection descriptor
+ * @param value the reply code 0 means ok
+ * @return
+ */
+enum SCP_SERVER_STATES_E
+scp_v0s_replyauthentication(struct SCP_CONNECTION* c, unsigned short int value);
+
#endif
diff --git a/sesman/libscp/libscp_v1c_mng.c b/sesman/libscp/libscp_v1c_mng.c
index bb54bc79..88f86f4f 100644
--- a/sesman/libscp/libscp_v1c_mng.c
+++ b/sesman/libscp/libscp_v1c_mng.c
@@ -30,7 +30,7 @@
#include <stdlib.h>
#include <stdio.h>
-extern struct log_config* s_log;
+//extern struct log_config* s_log;
static enum SCP_CLIENT_STATES_E
_scp_v1c_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
@@ -91,7 +91,7 @@ scp_v1c_mng_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
@@ -127,7 +127,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION* c, int* scount,
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
@@ -137,42 +137,42 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION* c, int* scount,
init_stream(c->in_s, c->in_s->size);
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version != 1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
return SCP_CLIENT_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
if (size < 12)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: size error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: size error", __LINE__);
return SCP_CLIENT_STATE_SIZE_ERR;
}
init_stream(c->in_s, c->in_s->size);
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_COMMAND_SET_MANAGE)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_CMD_MNG_LIST) /* session list */
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
@@ -188,14 +188,14 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION* c, int* scount,
(*scount) = sescnt;
(*s) = NULL;
- LOG_DBG(s_log, "[v1c_mng] end list - no session on TS");
+ LOG_DBG("[v1c_mng] end list - no session on TS");
return SCP_CLIENT_STATE_LIST_OK;
}
ds = g_malloc(sizeof(struct SCP_DISCONNECTED_SESSION) * sescnt, 0);
if (ds == 0)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: internal error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: internal error", __LINE__);
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
}
@@ -240,7 +240,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION* c, int* scount,
(*scount) = sescnt;
(*s) = ds;
- LOG_DBG(s_log, "[v1c_mng] end list");
+ LOG_DBG("[v1c_mng] end list");
return SCP_CLIENT_STATE_LIST_OK;
}
@@ -350,14 +350,14 @@ _scp_v1c_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
init_stream(c->in_s, c->in_s->size);
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version != 1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
return SCP_CLIENT_STATE_VERSION_ERR;
}
@@ -367,21 +367,21 @@ _scp_v1c_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
/* read the rest of the packet */
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_COMMAND_SET_MANAGE)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd == SCP_CMD_MNG_LOGIN_ALLOW) /* connection ok */
{
- log_message(s_log, LOG_LEVEL_INFO, "[v1c_mng:%d] connection ok", __LINE__);
+ log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection ok", __LINE__);
return SCP_CLIENT_STATE_OK;
}
else if (cmd == SCP_CMD_MNG_LOGIN_DENY) /* connection denied */
@@ -391,10 +391,10 @@ _scp_v1c_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
in_uint8a(c->in_s, buf, dim);
scp_session_set_errstr(s, buf);
- log_message(s_log, LOG_LEVEL_INFO, "[v1c_mng:%d] connection denied: %s", __LINE__ , s->errstr);
+ log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection denied: %s", __LINE__ , s->errstr);
return SCP_CLIENT_STATE_CONNECTION_DENIED;
}
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c-mng:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c-mng:%d] connection aborted: sequence error", __LINE__);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
diff --git a/sesman/libscp/libscp_v1s.c b/sesman/libscp/libscp_v1s.c
index e57a907e..e10af26c 100644
--- a/sesman/libscp/libscp_v1s.c
+++ b/sesman/libscp/libscp_v1s.c
@@ -30,7 +30,7 @@
#include "libscp_v1s.h"
-extern struct log_config* s_log;
+//extern struct log_config* s_log;
/* server API */
enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
@@ -46,18 +46,18 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
if (!skipVchk)
{
- if (0==scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
+ if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
in_uint32_be(c->in_s, version);
if (version != 1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
return SCP_SERVER_STATE_VERSION_ERR;
}
}
else
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
}
@@ -65,14 +65,14 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
in_uint32_be(c->in_s, size);
if (size < 12)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
init_stream(c->in_s, c->in_s->size);
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
@@ -82,7 +82,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
/* if we are starting a management session */
if (cmdset == SCP_COMMAND_SET_MANAGE)
{
- log_message(s_log, LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__);
+ log_message(LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__);
/* should return SCP_SERVER_STATE_START_MANAGE */
return scp_v1s_mng_accept(c, s);
}
@@ -90,7 +90,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
/* if we started with resource sharing... */
if (cmdset == SCP_COMMAND_SET_RSR)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
@@ -98,14 +98,14 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
in_uint16_be(c->in_s, cmd);
if (cmd != 1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
session = scp_session_create();
if (0 == session)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (malloc returned NULL)", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (malloc returned NULL)", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
scp_session_set_version(session, 1);
@@ -114,7 +114,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
if ((sz != SCP_SESSION_TYPE_XVNC) && (sz != SCP_SESSION_TYPE_XRDP))
{
scp_session_destroy(session);
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__);
return SCP_SERVER_STATE_SESSION_TYPE_ERR;
}
scp_session_set_type(session, sz);
@@ -151,7 +151,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
if (0 != scp_session_set_hostname(session, buf))
{
scp_session_destroy(session);
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -162,7 +162,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
if (0 != scp_session_set_username(session, buf))
{
scp_session_destroy(session);
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -173,7 +173,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
if (0 != scp_session_set_password(session, buf))
{
scp_session_destroy(session);
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -208,7 +208,7 @@ scp_v1s_deny_connection(struct SCP_CONNECTION* c, char* reason)
if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, rlen+14))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
@@ -250,49 +250,49 @@ scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char*
if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, 14+rlen))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
/* receive password & username */
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version!=1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
return SCP_SERVER_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
if (size<12)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
init_stream(c->in_s, c->in_s->size);
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmdset);
if (cmdset != SCP_COMMAND_SET_DEFAULT)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != 4)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
@@ -304,7 +304,7 @@ scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char*
if (0 != scp_session_set_username(s, buf))
{
scp_session_destroy(s);
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -315,7 +315,7 @@ scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char*
if (0 != scp_session_set_password(s, buf))
{
scp_session_destroy(s);
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -356,7 +356,7 @@ scp_v1s_connect_new_session(struct SCP_CONNECTION* c, SCP_DISPLAY d)
if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, 14))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
@@ -410,7 +410,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNEC
if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
@@ -420,42 +420,42 @@ scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNEC
init_stream(c->in_s, c->in_s->size);
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version!=1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
return SCP_SERVER_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
if (size<12)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
init_stream(c->in_s, c->in_s->size);
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_COMMAND_SET_DEFAULT)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != 41)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
@@ -542,7 +542,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNEC
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
}
@@ -551,21 +551,21 @@ scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNEC
init_stream(c->in_s, c->in_s->size);
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (8)))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version != 1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
return SCP_SERVER_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
if (size < 12)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
@@ -573,14 +573,14 @@ scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNEC
init_stream(c->in_s, c->in_s->size);
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_COMMAND_SET_DEFAULT)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
@@ -603,7 +603,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNEC
/* if we got here, the requested sid wasn't one from the list we sent */
/* we should kill the connection */
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (no such session in list)", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (no such session in list)", __LINE__);
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
else if (cmd == 44)
@@ -619,7 +619,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNEC
else
{
/* wrong response */
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
@@ -656,7 +656,7 @@ scp_v1s_reconnect_session(struct SCP_CONNECTION* c, SCP_DISPLAY d)
if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
diff --git a/sesman/libscp/libscp_v1s_mng.c b/sesman/libscp/libscp_v1s_mng.c
index 266c9962..599545ab 100644
--- a/sesman/libscp/libscp_v1s_mng.c
+++ b/sesman/libscp/libscp_v1s_mng.c
@@ -30,7 +30,7 @@
#include "libscp_v1s_mng.h"
-extern struct log_config* s_log;
+//extern struct log_config* s_log;
static enum SCP_SERVER_STATES_E
_scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
@@ -259,7 +259,7 @@ scp_v1s_mng_list_sessions(struct SCP_CONNECTION* c, struct SCP_SESSION* s,
if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
}
@@ -279,14 +279,14 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
init_stream(c->in_s, c->in_s->size);
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version != 1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: version error", __LINE__);
return SCP_SERVER_STATE_VERSION_ERR;
}
@@ -296,21 +296,21 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
/* read the rest of the packet */
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_COMMAND_SET_MANAGE)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd == SCP_CMD_MNG_LIST_REQ) /* request session list */
{
- log_message(s_log, LOG_LEVEL_INFO, "[v1s_mng:%d] request session list", __LINE__);
+ log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] request session list", __LINE__);
return SCP_SERVER_STATE_MNG_LISTREQ;
}
else if (cmd == SCP_CMD_MNG_ACTION) /* execute an action */
@@ -320,7 +320,7 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
in_uint8a(c->in_s, buf, dim);
scp_session_set_errstr(s, buf);*/
- log_message(s_log, LOG_LEVEL_INFO, "[v1s_mng:%d] action request", __LINE__);
+ log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] action request", __LINE__);
return SCP_SERVER_STATE_MNG_ACTION;
}
/* else if (cmd == 20) / * password change * /
@@ -334,7 +334,7 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
return SCP_SERVER_STATE_SESSION_LIST;
}*/
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
diff --git a/sesman/lock.c b/sesman/lock.c
index d5a91af6..83023cba 100644
--- a/sesman/lock.c
+++ b/sesman/lock.c
@@ -55,7 +55,7 @@ void APP_CC
lock_chain_acquire(void)
{
/* lock the chain */
- LOG_DBG(&(g_cfg->log), "lock_chain_acquire()");
+ LOG_DBG("lock_chain_acquire()");
tc_mutex_lock(g_lock_chain);
}
@@ -64,7 +64,7 @@ void APP_CC
lock_chain_release(void)
{
/* unlock the chain */
- LOG_DBG(&(g_cfg->log), "lock_chain_release()");
+ LOG_DBG("lock_chain_release()");
tc_mutex_unlock(g_lock_chain);
}
@@ -73,7 +73,7 @@ void APP_CC
lock_socket_acquire(void)
{
/* lock socket variable */
- LOG_DBG(&(g_cfg->log), "lock_socket_acquire()");
+ LOG_DBG("lock_socket_acquire()");
tc_sem_dec(g_lock_socket);
}
@@ -82,7 +82,7 @@ void APP_CC
lock_socket_release(void)
{
/* unlock socket variable */
- LOG_DBG(&(g_cfg->log), "lock_socket_release()");
+ LOG_DBG("lock_socket_release()");
tc_sem_inc(g_lock_socket);
}
@@ -91,7 +91,7 @@ void APP_CC
lock_sync_acquire(void)
{
/* lock sync variable */
- LOG_DBG(&(g_cfg->log), "lock_sync_acquire()");
+ LOG_DBG("lock_sync_acquire()");
tc_mutex_lock(g_sync_mutex);
}
@@ -100,7 +100,7 @@ void APP_CC
lock_sync_release(void)
{
/* unlock socket variable */
- LOG_DBG(&(g_cfg->log), "lock_sync_release()");
+ LOG_DBG("lock_sync_release()");
tc_mutex_unlock(g_sync_mutex);
}
@@ -109,7 +109,7 @@ void APP_CC
lock_sync_sem_acquire(void)
{
/* dec sem */
- LOG_DBG(&(g_cfg->log), "lock_sync_sem_acquire()");
+ LOG_DBG("lock_sync_sem_acquire()");
tc_sem_dec(g_sync_sem);
}
@@ -118,6 +118,6 @@ void APP_CC
lock_sync_sem_release(void)
{
/* inc sem */
- LOG_DBG(&(g_cfg->log), "lock_sync_sem_release()");
+ LOG_DBG("lock_sync_sem_release()");
tc_sem_inc(g_sync_sem);
}
diff --git a/sesman/scp.c b/sesman/scp.c
index 439c046c..bbe495ea 100644
--- a/sesman/scp.c
+++ b/sesman/scp.c
@@ -43,7 +43,7 @@ scp_process_start(void* sck)
/* making a local copy of the socket (it's on the stack) */
/* probably this is just paranoia */
scon.in_sck = g_thread_sck;
- LOG_DBG(&(g_cfg->log), "started scp thread on socket %d", scon.in_sck);
+ LOG_DBG("started scp thread on socket %d", scon.in_sck);
/* unlocking g_thread_sck */
lock_socket_release();
@@ -60,40 +60,40 @@ scp_process_start(void* sck)
if (sdata->version == 0)
{
/* starts processing an scp v0 connection */
- LOG_DBG(&(g_cfg->log), "accept ok, go on with scp v0\n",0);
+ LOG_DBG("accept ok, go on with scp v0\n",0);
scp_v0_process(&scon, sdata);
}
else
{
- LOG_DBG(&(g_cfg->log), "accept ok, go on with scp v1\n",0);
- /*LOG_DBG(&(g_cfg->log), "user: %s\npass: %s",sdata->username, sdata->password);*/
+ LOG_DBG("accept ok, go on with scp v1\n",0);
+ /*LOG_DBG("user: %s\npass: %s",sdata->username, sdata->password);*/
scp_v1_process(&scon, sdata);
}
break;
case SCP_SERVER_STATE_START_MANAGE:
/* starting a management session */
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING,
+ log_message(LOG_LEVEL_WARNING,
"starting a sesman management session...");
scp_v1_mng_process(&scon, sdata);
break;
case SCP_SERVER_STATE_VERSION_ERR:
/* an unknown scp version was requested, so we shut down the */
/* connection (and log the fact) */
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING,
+ log_message(LOG_LEVEL_WARNING,
"unknown protocol version specified. connection refused.");
break;
case SCP_SERVER_STATE_NETWORK_ERR:
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "libscp network error.");
+ log_message(LOG_LEVEL_WARNING, "libscp network error.");
break;
case SCP_SERVER_STATE_SEQUENCE_ERR:
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "libscp sequence error.");
+ log_message(LOG_LEVEL_WARNING, "libscp sequence error.");
break;
case SCP_SERVER_STATE_INTERNAL_ERR:
/* internal error occurred (eg. malloc() error, ecc.) */
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "libscp internal error occurred.");
+ log_message(LOG_LEVEL_ERROR, "libscp internal error occurred.");
break;
default:
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()");
+ log_message(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()");
}
g_tcp_close(scon.in_sck);
free_stream(scon.in_s);
diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c
index 886aaa29..092585cf 100644
--- a/sesman/scp_v0.c
+++ b/sesman/scp_v0.c
@@ -40,8 +40,7 @@ scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
struct session_item* s_item;
data = auth_userpass(s->username, s->password);
-
- if (data)
+ if (s->type == SCP_GW_AUTHENTICATION)
{
s_item = session_get_bydata(s->username, s->width, s->height, s->bpp, s->type);
@@ -60,42 +59,51 @@ scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
display = s_item->display;
if (0 != s->client_ip)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, s_item->pid, s->client_ip);
+ log_message( LOG_LEVEL_INFO, "++ reconnected session: username %s, "
+ "display :%d.0, session_pid %d, ip %s",
+ s->username, display, s_item->pid, s->client_ip);
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, s_item->pid);
+ log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, "
+ "display :%d.0, session_pid %d", s->username, display,
+ s_item->pid);
}
+ session_reconnect(display, s->username);
auth_end(data);
/* don't set data to null here */
}
else
{
- LOG_DBG(&(g_cfg->log), "pre auth");
+ LOG_DBG("pre auth");
if (1 == access_login_allowed(s->username))
{
if (0 != s->client_ip)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip);
+ log_message(LOG_LEVEL_INFO, "++ created session (access granted): "
+ "username %s, ip %s", s->username, s->client_ip);
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username);
+ log_message(LOG_LEVEL_INFO, "++ created session (access granted): "
+ "username %s", s->username);
}
if (SCP_SESSION_TYPE_XVNC == s->type)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting Xvnc session...");
+ log_message( LOG_LEVEL_INFO, "starting Xvnc session...");
display = session_start(s->width, s->height, s->bpp, s->username,
s->password, data, SESMAN_SESSION_TYPE_XVNC,
- s->domain, s->program, s->directory, s->client_ip);
+ s->domain, s->program, s->directory,
+ s->client_ip);
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting X11rdp session...");
+ log_message(LOG_LEVEL_INFO, "starting X11rdp session...");
display = session_start(s->width, s->height, s->bpp, s->username,
s->password, data, SESMAN_SESSION_TYPE_XRDP,
- s->domain, s->program, s->directory, s->client_ip);
+ s->domain, s->program, s->directory,
+ s->client_ip);
}
}
else
@@ -118,4 +126,3 @@ scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
scp_v0s_deny_connection(c);
}
}
-
diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c
index beb1c36b..d83dd7bc 100644
--- a/sesman/scp_v1.c
+++ b/sesman/scp_v1.c
@@ -58,9 +58,11 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
while ((!data) && ((retries == 0) || (current_try > 0)))
{
- LOG_DBG(&(g_cfg->log), "data %d - retry %d - currenttry %d - expr %d", data, retries, current_try, ((!data) && ((retries==0) || (current_try>0))));
+ LOG_DBG("data %d - retry %d - currenttry %d - expr %d",
+ data, retries, current_try,
+ ((!data) && ((retries == 0) || (current_try > 0))));
- e=scp_v1s_request_password(c,s,"Wrong username and/or password");
+ e = scp_v1s_request_password(c, s, "Wrong username and/or password");
switch (e)
{
@@ -85,7 +87,7 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
if (!data)
{
scp_v1s_deny_connection(c, "Login failed");
- log_message(&(g_cfg->log), LOG_LEVEL_INFO,
+ log_message( LOG_LEVEL_INFO,
"Login failed for user %s. Connection terminated", s->username);
scp_session_destroy(s);
return;
@@ -95,7 +97,7 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
if (0 == access_login_allowed(s->username))
{
scp_v1s_deny_connection(c, "Access to Terminal Server not allowed.");
- log_message(&(g_cfg->log), LOG_LEVEL_INFO,
+ log_message(LOG_LEVEL_INFO,
"User %s not allowed on TS. Connection terminated", s->username);
scp_session_destroy(s);
return;
@@ -116,24 +118,26 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
if (scount == 0)
{
/* no disconnected sessions - start a new one */
+ log_message(LOG_LEVEL_DEBUG,"No disconnected sessions for this user"
+ "- we create a new one");
if (0 != s->client_ip)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip);
+ log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip);
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username);
+ log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username);
}
if (SCP_SESSION_TYPE_XVNC == s->type)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting Xvnc session...");
+ log_message(LOG_LEVEL_INFO, "starting Xvnc session...");
display = session_start(s->width, s->height, s->bpp, s->username,
s->password, data, SESMAN_SESSION_TYPE_XVNC,
s->domain, s->program, s->directory, s->client_ip);
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting X11rdp session...");
+ log_message(LOG_LEVEL_INFO, "starting X11rdp session...");
display = session_start(s->width, s->height, s->bpp, s->username,
s->password, data, SESMAN_SESSION_TYPE_XRDP,
s->domain, s->program, s->directory, s->client_ip);
@@ -161,28 +165,28 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
/*case SCP_SERVER_STATE_FORCE_NEW:*/
/* we should check for MaxSessions */
case SCP_SERVER_STATE_SELECTION_CANCEL:
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "Connection cancelled after session listing");
+ log_message( LOG_LEVEL_INFO, "Connection cancelled after session listing");
break;
case SCP_SERVER_STATE_OK:
/* ok, reconnecting... */
sitem=session_get_bypid(sid);
- if (0==sitem)
+ if (0 == sitem)
{
- e=scp_v1s_connection_error(c, "Internal error");
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "Cannot find session item on the chain");
+ e = scp_v1s_connection_error(c, "Internal error");
+ log_message(LOG_LEVEL_INFO, "Cannot find session item on the chain");
}
else
{
- display=sitem->display;
+ display = sitem->display;
/*e=scp_v1s_reconnect_session(c, sitem, display);*/
e=scp_v1s_reconnect_session(c, display);
if (0 != s->client_ip)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, sitem->pid, s->client_ip);
+ log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, sitem->pid, s->client_ip);
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, sitem->pid);
+ log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, sitem->pid);
}
g_free(sitem);
}
@@ -211,27 +215,27 @@ static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f)
switch (e)
{
case SCP_SERVER_STATE_VERSION_ERR:
- LOG_DBG(&(g_cfg->log), "version error")
+ LOG_DBG("version error")
case SCP_SERVER_STATE_SIZE_ERR:
/* an unknown scp version was requested, so we shut down the */
/* connection (and log the fact) */
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING,
+ log_message(LOG_LEVEL_WARNING,
"protocol violation. connection closed.");
break;
case SCP_SERVER_STATE_NETWORK_ERR:
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "libscp network error.");
+ log_message(LOG_LEVEL_WARNING, "libscp network error.");
break;
case SCP_SERVER_STATE_SEQUENCE_ERR:
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "libscp sequence error.");
+ log_message(LOG_LEVEL_WARNING, "libscp sequence error.");
break;
case SCP_SERVER_STATE_INTERNAL_ERR:
/* internal error occurred (eg. malloc() error, ecc.) */
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "libscp internal error occurred.");
+ log_message(LOG_LEVEL_ERROR, "libscp internal error occurred.");
break;
default:
/* dummy: scp_v1s_request_password won't generate any other */
/* error other than the ones before */
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "unknown return from %s", f);
+ log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f);
break;
}
}
diff --git a/sesman/scp_v1_mng.c b/sesman/scp_v1_mng.c
index a1773225..e4d97b77 100644
--- a/sesman/scp_v1_mng.c
+++ b/sesman/scp_v1_mng.c
@@ -49,7 +49,7 @@ scp_v1_mng_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
if (!data)
{
scp_v1s_mng_deny_connection(c, "Login failed");
- log_message(&(g_cfg->log), LOG_LEVEL_INFO,
+ log_message(LOG_LEVEL_INFO,
"[MNG] Login failed for user %s. Connection terminated", s->username);
scp_session_destroy(s);
auth_end(data);
@@ -60,7 +60,7 @@ scp_v1_mng_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
if (0 == access_login_mng_allowed(s->username))
{
scp_v1s_mng_deny_connection(c, "Access to Terminal Server not allowed.");
- log_message(&(g_cfg->log), LOG_LEVEL_INFO,
+ log_message(LOG_LEVEL_INFO,
"[MNG] User %s not allowed on TS. Connection terminated", s->username);
scp_session_destroy(s);
auth_end(data);
@@ -75,18 +75,18 @@ scp_v1_mng_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
switch (e)
{
case SCP_SERVER_STATE_MNG_ACTION:
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "Connection cancelled after session listing");
+ log_message(LOG_LEVEL_INFO, "Connection cancelled after session listing");
break;
case SCP_SERVER_STATE_MNG_LISTREQ:
/* list disconnected sessions */
slist = session_get_byuser(NULL, &scount, SESMAN_SESSION_STATUS_ALL);
- LOG_DBG(&(g_cfg->log), "sessions on TS: %d (slist: %x)", scount, slist);
+ LOG_DBG("sessions on TS: %d (slist: %x)", scount, slist);
if (0 == slist)
{
// e=scp_v1s_connection_error(c, "Internal error");
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "No sessions on Terminal Server");
+ log_message(LOG_LEVEL_INFO, "No sessions on Terminal Server");
end = 0;
}
else
@@ -114,27 +114,27 @@ static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f)
switch (e)
{
case SCP_SERVER_STATE_VERSION_ERR:
- LOG_DBG(&(g_cfg->log), "version error")
+ LOG_DBG("version error")
case SCP_SERVER_STATE_SIZE_ERR:
/* an unknown scp version was requested, so we shut down the */
/* connection (and log the fact) */
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING,
+ log_message(LOG_LEVEL_WARNING,
"protocol violation. connection closed.");
break;
case SCP_SERVER_STATE_NETWORK_ERR:
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "libscp network error.");
+ log_message(LOG_LEVEL_WARNING, "libscp network error.");
break;
case SCP_SERVER_STATE_SEQUENCE_ERR:
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "libscp sequence error.");
+ log_message(LOG_LEVEL_WARNING, "libscp sequence error.");
break;
case SCP_SERVER_STATE_INTERNAL_ERR:
/* internal error occurred (eg. malloc() error, ecc.) */
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "libscp internal error occurred.");
+ log_message(LOG_LEVEL_ERROR, "libscp internal error occurred.");
break;
default:
/* dummy: scp_v1s_request_password won't generate any other */
/* error other than the ones before */
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "unknown return from %s", f);
+ log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f);
break;
}
}
diff --git a/sesman/sesman.c b/sesman/sesman.c
index 5a230417..b882c49d 100644
--- a/sesman/sesman.c
+++ b/sesman/sesman.c
@@ -54,7 +54,7 @@ sesman_main_loop(void)
tbus robjs[8];
/*main program loop*/
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "listening...");
+ log_message(LOG_LEVEL_INFO, "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);
@@ -103,7 +103,7 @@ sesman_main_loop(void)
else
{
/* we've got a connection, so we pass it to scp code */
- LOG_DBG(&(g_cfg->log), "new connection");
+ LOG_DBG("new connection");
thread_scp_start(in_sck);
/* todo, do we have to wait here ? */
}
@@ -113,13 +113,13 @@ sesman_main_loop(void)
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "listen error %d (%s)",
+ log_message(LOG_LEVEL_ERROR, "listen error %d (%s)",
g_get_errno(), g_get_strerror());
}
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "bind error on "
+ log_message(LOG_LEVEL_ERROR, "bind error on "
"port '%s': %d (%s)", g_cfg->listen_port,
g_get_errno(), g_get_strerror());
}
@@ -131,12 +131,13 @@ int DEFAULT_CC
main(int argc, char** argv)
{
int fd;
- int error;
+ enum logReturns error;
int daemon = 1;
int pid;
char pid_s[8];
char text[256];
char pid_file[256];
+ char cfg_file[256];
g_init("xrdp-sesman");
g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH);
@@ -242,7 +243,7 @@ main(int argc, char** argv)
g_deinit();
g_exit(1);
}
- g_cfg->log.fd = -1; /* don't use logging before reading its config */
+ //g_cfg->log.fd = -1; /* don't use logging before reading its config */
if (0 != config_read(g_cfg))
{
g_printf("error reading config: %s\nquitting.\n", g_get_strerror());
@@ -250,18 +251,21 @@ main(int argc, char** argv)
g_exit(1);
}
+ g_snprintf(cfg_file,255,"%s/sesman.ini",XRDP_CFG_PATH);
+
/* starting logging subsystem */
- error = log_start(&(g_cfg->log));
+ error = log_start(cfg_file,"XRDP-sesman");
if (error != LOG_STARTUP_OK)
{
switch (error)
{
case LOG_ERROR_MALLOC:
- g_printf("error on malloc. cannot start logging. quitting.\n");
+ g_writeln("error on malloc. cannot start logging. quitting.");
break;
case LOG_ERROR_FILE_OPEN:
- g_printf("error opening log file [%s]. quitting.\n", g_cfg->log.log_file);
+ g_writeln("error opening log file [%s]. quitting.",
+ getLogFile(text, 255));
break;
}
g_deinit();
@@ -269,7 +273,7 @@ main(int argc, char** argv)
}
/* libscp initialization */
- scp_init(&(g_cfg->log));
+ scp_init();
if (daemon)
{
@@ -317,10 +321,10 @@ main(int argc, char** argv)
fd = g_file_open(pid_file);
if (-1 == fd)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR,
+ log_message(LOG_LEVEL_ERROR,
"error opening pid file[%s]: %s",
pid_file, g_get_strerror());
- log_end(&(g_cfg->log));
+ log_end();
g_deinit();
g_exit(1);
}
@@ -330,7 +334,7 @@ main(int argc, char** argv)
}
/* start program main loop */
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,
+ log_message(LOG_LEVEL_ALWAYS,
"starting sesman with pid %d", g_pid);
/* make sure the /tmp/.X11-unix directory exist */
@@ -358,10 +362,9 @@ main(int argc, char** argv)
if (!daemon)
{
- log_end(&(g_cfg->log));
+ log_end();
}
g_deinit();
return 0;
}
-
diff --git a/sesman/sesman.ini b/sesman/sesman.ini
index 1d1d16bf..7f194074 100644
--- a/sesman/sesman.ini
+++ b/sesman/sesman.ini
@@ -19,9 +19,9 @@ IdleTimeLimit=0
DisconnectedTimeLimit=0
[Logging]
-LogFile=/var/log/xrdp-sesman.log
+LogFile=xrdp-sesman.log
LogLevel=DEBUG
-EnableSyslog=0
+EnableSyslog=1
SyslogLevel=DEBUG
#[X11rdp]
diff --git a/sesman/session.c b/sesman/session.c
index 81484b80..46037187 100644
--- a/sesman/session.c
+++ b/sesman/session.c
@@ -60,6 +60,40 @@ static char* g_sync_client_ip;
static tbus g_sync_data;
static tui8 g_sync_type;
static int g_sync_result;
+static int g_sync_cmd;
+
+/**
+ * Creates a string consisting of all parameters that is hosted in the param list
+ * @param self
+ * @param outstr, allocate this buffer before you use this function
+ * @param len the allocated len for outstr
+ * @return
+ */
+char* APP_CC
+dumpItemsToString(struct list* self, char *outstr, int len)
+{
+ g_memset(outstr,0,len);
+ int index;
+ tbus item;
+ int totalLen= 0;
+
+ if (self->count == 0)
+ {
+ g_writeln("List is empty");
+ }
+ for (index = 0; index < self->count; index++)
+ {
+ /* +1 = one space*/
+ totalLen = totalLen + g_strlen((char*)list_get_item(self, index))+1;
+ if(len>totalLen)
+ {
+ g_strcat(outstr,(char*)list_get_item(self, index));
+ g_strcat(outstr," ");
+ }
+ }
+ return outstr ;
+}
+
/******************************************************************************/
struct session_item* DEFAULT_CC
@@ -267,7 +301,7 @@ x_server_running(int display)
/******************************************************************************/
static void DEFAULT_CC
-session_start_sessvc(int xpid, int wmpid, long data)
+session_start_sessvc(int xpid, int wmpid, long data, char* username, int display)
{
struct list * sessvc_params = (struct list *)NULL;
char wmpid_str[25];
@@ -283,7 +317,7 @@ session_start_sessvc(int xpid, int wmpid, long data)
/* new style waiting for clients */
g_sprintf(wmpid_str, "%d", wmpid);
g_sprintf(xpid_str, "%d", xpid);
- log_message(&(g_cfg->log), LOG_LEVEL_INFO,
+ log_message(LOG_LEVEL_INFO,
"starting xrdp-sessvc - xpid=%s - wmpid=%s",
xpid_str, wmpid_str);
@@ -298,23 +332,25 @@ session_start_sessvc(int xpid, int wmpid, long data)
list_add_item(sessvc_params, (long)g_strdup(wmpid_str));
list_add_item(sessvc_params, 0); /* mandatory */
+ env_set_user(username, 0, display);
+
/* executing sessvc */
g_execvp(exe_path, ((char**)sessvc_params->items));
/* should not get here */
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,
+ log_message(LOG_LEVEL_ALWAYS,
"error starting xrdp-sessvc - pid %d - xpid=%s - wmpid=%s",
g_getpid(), xpid_str, wmpid_str);
/* logging parameters */
/* no problem calling strerror for thread safety: other threads
are blocked */
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "errno: %d, description: %s",
+ log_message(LOG_LEVEL_DEBUG, "errno: %d, description: %s",
errno, g_get_strerror());
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "execve parameter list:");
+ log_message(LOG_LEVEL_DEBUG, "execve parameter list:");
for (i = 0; i < (sessvc_params->count); i++)
{
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, " argv[%d] = %s", i,
+ log_message(LOG_LEVEL_DEBUG, " argv[%d] = %s", i,
(char*)list_get_item(sessvc_params, i));
}
list_delete(sessvc_params);
@@ -372,7 +408,7 @@ session_get_aval_display_from_chain(void)
display++;
}
lock_chain_release();
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "X server -- no display in range is available");
+ log_message(LOG_LEVEL_ERROR, "X server -- no display in range is available");
return 0;
}
@@ -391,7 +427,7 @@ wait_for_xserver(int display)
i++;
if (i > 60)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR,
+ log_message(LOG_LEVEL_ERROR,
"X server for display %d startup timeout",
display);
break;
@@ -474,6 +510,7 @@ session_start_fork(int width, int height, int bpp, char* username,
struct list * xserver_params = (struct list *)NULL;
time_t ltime;
struct tm stime;
+ char execvpparams[2048];
/* initialize (zero out) local variables: */
g_memset(&ltime,0,sizeof(time_t));
@@ -489,7 +526,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
/* check to limit concurrent sessions */
if (g_session_count >= g_cfg->sess.max_sessions)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "max concurrent session limit "
+ log_message(LOG_LEVEL_INFO, "max concurrent session limit "
"exceeded. login for user %s denied", username);
return 0;
}
@@ -497,7 +534,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
temp = (struct session_chain*)g_malloc(sizeof(struct session_chain), 0);
if (temp == 0)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "cannot create new chain "
+ log_message(LOG_LEVEL_ERROR, "cannot create new chain "
"element - user %s", username);
return 0;
}
@@ -505,7 +542,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
if (temp->item == 0)
{
g_free(temp);
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "cannot create new session "
+ log_message(LOG_LEVEL_ERROR, "cannot create new session "
"item - user %s", username);
return 0;
}
@@ -599,7 +636,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
if (program[0] != 0)
{
g_execlp3(program, program, 0);
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,
+ log_message(LOG_LEVEL_ALWAYS,
"error starting program %s for user %s - pid %d",
program, username, g_getpid());
}
@@ -611,16 +648,16 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
if (g_file_exist(text))
{
g_execlp3(text, g_cfg->user_wm, 0);
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,"error starting user "
+ log_message(LOG_LEVEL_ALWAYS,"error starting user "
"wm for user %s - pid %d", username, g_getpid());
/* logging parameters */
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "errno: %d, "
+ log_message(LOG_LEVEL_DEBUG, "errno: %d, "
"description: %s", errno, g_get_strerror());
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG,"execlp3 parameter "
+ log_message(LOG_LEVEL_DEBUG,"execlp3 parameter "
"list:");
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, " argv[0] = %s",
+ log_message(LOG_LEVEL_DEBUG, " argv[0] = %s",
text);
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, " argv[1] = %s",
+ log_message(LOG_LEVEL_DEBUG, " argv[1] = %s",
g_cfg->user_wm);
}
}
@@ -629,25 +666,25 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
g_sprintf(text, "%s/%s", XRDP_CFG_PATH, g_cfg->default_wm);
g_execlp3(text, g_cfg->default_wm, 0);
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,"error starting default "
+ log_message( LOG_LEVEL_ALWAYS,"error starting default "
"wm for user %s - pid %d", username, g_getpid());
/* logging parameters */
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "errno: %d, description: "
+ log_message( LOG_LEVEL_DEBUG, "errno: %d, description: "
"%s", errno, g_get_strerror());
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG,"execlp3 parameter list:");
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, " argv[0] = %s",
+ log_message(LOG_LEVEL_DEBUG,"execlp3 parameter list:");
+ log_message(LOG_LEVEL_DEBUG, " argv[0] = %s",
text);
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, " argv[1] = %s",
+ log_message(LOG_LEVEL_DEBUG, " argv[1] = %s",
g_cfg->default_wm);
/* still a problem starting window manager just start xterm */
g_execlp3("xterm", "xterm", 0);
/* should not get here */
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,"error starting xterm "
+ log_message(LOG_LEVEL_ALWAYS,"error starting xterm "
"for user %s - pid %d", username, g_getpid());
/* logging parameters */
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "errno: %d, description: "
+ log_message(LOG_LEVEL_DEBUG, "errno: %d, description: "
"%s", errno, g_get_strerror());
}
else
@@ -656,7 +693,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "another Xserver is "
"already active on display %d", display);
}
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG,"aborting connection...");
+ log_message(LOG_LEVEL_DEBUG,"aborting connection...");
g_exit(0);
}
else /* parent (child sesman) */
@@ -691,6 +728,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
/* make sure it ends with a zero */
list_add_item(xserver_params, 0);
pp1 = (char**)xserver_params->items;
+ log_message(LOG_LEVEL_INFO,"Xvnc start:%s",dumpItemsToString(xserver_params, execvpparams, 2048));
g_execvp("Xvnc", pp1);
}
else if (type == SESMAN_SESSION_TYPE_XRDP)
@@ -743,24 +781,24 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "bad session type - "
+ log_message(LOG_LEVEL_ALWAYS, "bad session type - "
"user %s - pid %d", username, g_getpid());
g_exit(1);
}
/* should not get here */
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "error starting X server "
+ log_message(LOG_LEVEL_ALWAYS, "error starting X server "
"- user %s - pid %d", username, g_getpid());
/* logging parameters */
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "errno: %d, description: "
+ log_message(LOG_LEVEL_DEBUG, "errno: %d, description: "
"%s", errno, g_get_strerror());
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "execve parameter list: "
+ log_message(LOG_LEVEL_DEBUG, "execve parameter list size: "
"%d", (xserver_params)->count);
for (i=0; i<(xserver_params->count); i++)
{
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, " argv[%d] = %s",
+ log_message(LOG_LEVEL_DEBUG, " argv[%d] = %s",
i, (char*)list_get_item(xserver_params, i));
}
list_delete(xserver_params);
@@ -777,7 +815,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
g_snprintf(text, 255, ":%d.0", display);
g_setenv("DISPLAY", text, 1);
/* new style waiting for clients */
- session_start_sessvc(xpid, wmpid, data);
+ session_start_sessvc(xpid, wmpid, data, username, display);
}
}
}
@@ -813,6 +851,31 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
}
/******************************************************************************/
+/* called with the main thread */
+static int APP_CC
+session_reconnect_fork(int display, char* username)
+{
+ int pid;
+ char text[256];
+
+ pid = g_fork();
+ if (pid == -1)
+ {
+ }
+ else if (pid == 0)
+ {
+ env_set_user(username, 0, display);
+ g_snprintf(text, 255, "%s/%s", XRDP_CFG_PATH, "reconnectwm.sh");
+ if (g_file_exist(text))
+ {
+ g_execlp3(text, g_cfg->default_wm, 0);
+ }
+ g_exit(0);
+ }
+ return display;
+}
+
+/******************************************************************************/
/* called by a worker thread, ask the main thread to call session_sync_start
and wait till done */
int DEFAULT_CC
@@ -826,6 +889,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 258.0] In session_star
/* lock mutex */
lock_sync_acquire();
/* set shared vars */
+ g_sync_cmd = 0;
g_sync_width = width;
g_sync_height = height;
g_sync_bpp = bpp;
@@ -849,6 +913,27 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 258.0] In session_star
}
/******************************************************************************/
+/* called by a worker thread, ask the main thread to call session_sync_start
+ and wait till done */
+int DEFAULT_CC
+session_reconnect(int display, char* username)
+{
+ /* lock mutex */
+ lock_sync_acquire();
+ /* set shared vars */
+ g_sync_cmd = 1;
+ g_sync_width = display;
+ g_sync_username = username;
+ /* set event for main thread to see */
+ g_set_wait_obj(g_sync_event);
+ /* wait for main thread to get done */
+ lock_sync_sem_acquire();
+ /* unlock mutex */
+ lock_sync_release();
+ return 0;
+}
+
+/******************************************************************************/
/* called with the main thread */
int APP_CC
session_sync_start(void)
@@ -879,7 +964,7 @@ session_kill(int pid)
{
if (tmp->item == 0)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "session descriptor for "
+ log_message(LOG_LEVEL_ERROR, "session descriptor for "
"pid %d is null!", pid);
if (prev == 0)
{
@@ -899,7 +984,7 @@ session_kill(int pid)
if (tmp->item->pid == pid)
{
/* deleting the session */
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ terminated session: username %s, display :%d.0, session_pid %d, ip %s", tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->client_ip);
+ log_message(LOG_LEVEL_INFO, "++ terminated session: username %s, display :%d.0, session_pid %d, ip %s", tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->client_ip);
g_free(tmp->item);
if (prev == 0)
{
@@ -943,7 +1028,7 @@ session_sigkill_all()
{
if (tmp->item == 0)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "found null session "
+ log_message(LOG_LEVEL_ERROR, "found null session "
"descriptor!");
}
else
@@ -969,7 +1054,7 @@ session_get_bypid(int pid)
dummy = g_malloc(sizeof(struct session_item), 1);
if (0 == dummy)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "internal error", pid);
+ log_message(LOG_LEVEL_ERROR, "internal error", pid);
return 0;
}
@@ -981,7 +1066,7 @@ session_get_bypid(int pid)
{
if (tmp->item == 0)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "session descriptor for "
+ log_message(LOG_LEVEL_ERROR, "session descriptor for "
"pid %d is null!", pid);
/*THREAD-FIX release chain lock */
lock_chain_release();
@@ -1015,7 +1100,7 @@ session_get_byuser(char* user, int* cnt, unsigned char flags)
int count;
int index;
- count=0;
+ count = 0;
/*THREAD-FIX require chain lock */
lock_chain_acquire();
@@ -1023,10 +1108,10 @@ session_get_byuser(char* user, int* cnt, unsigned char flags)
tmp = g_sessions;
while (tmp != 0)
{
- LOG_DBG(&(g_cfg->log), "user: %s", user);
+ LOG_DBG("user: %s", user);
if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256)))
{
- LOG_DBG(&(g_cfg->log), "session_get_byuser: status=%d, flags=%d, "
+ LOG_DBG("session_get_byuser: status=%d, flags=%d, "
"result=%d", (tmp->item->status), flags,
((tmp->item->status) & flags));
if ((tmp->item->status) & flags)
@@ -1039,9 +1124,9 @@ session_get_byuser(char* user, int* cnt, unsigned char flags)
tmp=tmp->next;
}
- if (count==0)
+ if (count == 0)
{
- (*cnt)=0;
+ (*cnt) = 0;
/*THREAD-FIX release chain lock */
lock_chain_release();
return 0;
@@ -1049,9 +1134,9 @@ session_get_byuser(char* user, int* cnt, unsigned char flags)
/* malloc() an array of disconnected sessions */
sess=g_malloc(count * sizeof(struct SCP_DISCONNECTED_SESSION),1);
- if (sess==0)
+ if (sess == 0)
{
- (*cnt)=0;
+ (*cnt) = 0;
/*THREAD-FIX release chain lock */
lock_chain_release();
return 0;
diff --git a/sesman/session.h b/sesman/session.h
index 23aed823..a8de90d5 100644
--- a/sesman/session.h
+++ b/sesman/session.h
@@ -107,6 +107,9 @@ session_start(int width, int height, int bpp, char* username, char* password,
long data, tui8 type, char* domain, char* program,
char* directory, char* client_ip);
+int DEFAULT_CC
+session_reconnect(int display, char* username);
+
/**
*
* @brief starts a session
@@ -156,4 +159,3 @@ struct SCP_DISCONNECTED_SESSION*
session_get_byuser(char* user, int* cnt, unsigned char flags);
#endif
-
diff --git a/sesman/sessvc/Makefile.am b/sesman/sessvc/Makefile.am
index 67740781..8ba24abd 100644
--- a/sesman/sessvc/Makefile.am
+++ b/sesman/sessvc/Makefile.am
@@ -15,4 +15,4 @@ xrdp_sessvc_SOURCES = \
sessvc.c
xrdp_sessvc_LDADD = \
- $(top_srcdir)/common/libcommon.la
+ $(top_builddir)/common/libcommon.la
diff --git a/sesman/sig.c b/sesman/sig.c
index 24f2e81c..151c0c57 100644
--- a/sesman/sig.c
+++ b/sesman/sig.c
@@ -40,15 +40,15 @@ sig_sesman_shutdown(int sig)
{
char pid_file[256];
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "shutting down sesman %d", 1);
+ log_message(LOG_LEVEL_INFO, "shutting down sesman %d", 1);
if (g_getpid() != g_pid)
{
- LOG_DBG(&(g_cfg->log), "g_getpid() [%d] differs from g_pid [%d]", (g_getpid()), g_pid);
+ LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", (g_getpid()), g_pid);
return;
}
- LOG_DBG(&(g_cfg->log), " - getting signal %d pid %d", sig, g_getpid());
+ LOG_DBG(" - getting signal %d pid %d", sig, g_getpid());
g_set_wait_obj(g_term_event);
@@ -66,51 +66,55 @@ sig_sesman_reload_cfg(int sig)
{
int error;
struct config_sesman *cfg;
+ char cfg_file[256];
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "receiving SIGHUP %d", 1);
+ log_message(LOG_LEVEL_WARNING, "receiving SIGHUP %d", 1);
if (g_getpid() != g_pid)
{
- LOG_DBG(&(g_cfg->log), "g_getpid() [%d] differs from g_pid [%d]", g_getpid(), g_pid);
+ LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", g_getpid(), g_pid);
return;
}
cfg = g_malloc(sizeof(struct config_sesman), 1);
if (0 == cfg)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "error creating new config: - keeping old cfg");
+ log_message(LOG_LEVEL_ERROR, "error creating new config: - keeping old cfg");
return;
}
if (config_read(cfg) != 0)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "error reading config - keeping old cfg");
+ log_message(LOG_LEVEL_ERROR, "error reading config - keeping old cfg");
return;
}
/* stop logging subsystem */
- log_end(&(g_cfg->log));
+ log_end();
/* replace old config with new readed one */
g_cfg = cfg;
+
+ g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH);
/* start again logging subsystem */
- error = log_start(&(g_cfg->log));
+ error = log_start(cfg_file,"XRDP-sesman");
if (error != LOG_STARTUP_OK)
{
+ char buf[256];
switch (error)
{
case LOG_ERROR_MALLOC:
g_printf("error on malloc. cannot restart logging. log stops here, sorry.\n");
break;
case LOG_ERROR_FILE_OPEN:
- g_printf("error reopening log file [%s]. log stops here, sorry.\n", g_cfg->log.log_file);
+ g_printf("error reopening log file [%s]. log stops here, sorry.\n", getLogFile(buf,255));
break;
}
}
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "configuration reloaded, log subsystem restarted");
+ log_message(LOG_LEVEL_INFO, "configuration reloaded, log subsystem restarted");
}
/******************************************************************************/
@@ -166,27 +170,27 @@ sig_handler_thread(void* arg)
case SIGHUP:
//reload cfg
//we must stop & restart logging, or copy logging cfg!!!!
- LOG_DBG(&(g_cfg->log), "sesman received SIGHUP", 0);
+ LOG_DBG("sesman received SIGHUP", 0);
//return 0;
break;
case SIGCHLD:
/* a session died */
- LOG_DBG(&(g_cfg->log), "sesman received SIGCHLD", 0);
+ LOG_DBG("sesman received SIGCHLD", 0);
sig_sesman_session_end(SIGCHLD);
break;
case SIGINT:
/* we die */
- LOG_DBG(&(g_cfg->log), "sesman received SIGINT", 0);
+ LOG_DBG("sesman received SIGINT", 0);
sig_sesman_shutdown(recv_signal);
break;
case SIGKILL:
/* we die */
- LOG_DBG(&(g_cfg->log), "sesman received SIGKILL", 0);
+ LOG_DBG("sesman received SIGKILL", 0);
sig_sesman_shutdown(recv_signal);
break;
case SIGTERM:
/* we die */
- LOG_DBG(&(g_cfg->log), "sesman received SIGTERM", 0);
+ LOG_DBG("sesman received SIGTERM", 0);
sig_sesman_shutdown(recv_signal);
break;
}
diff --git a/sesman/thread.c b/sesman/thread.c
index 986a5d27..98a92533 100644
--- a/sesman/thread.c
+++ b/sesman/thread.c
@@ -22,7 +22,7 @@
* @file thread.c
* @brief thread stuff...
* @author Simone Fedele
- *
+ *
*/
#include "sesman.h"
@@ -62,14 +62,14 @@ thread_sighandler_start(void)
sigaddset(&waitmask, SIGFPE);
pthread_sigmask(SIG_UNBLOCK, &waitmask, NULL);
- log_message(&(g_cfg->log), LOG_LEVEL_INFO,"starting signal handling thread...");
+ log_message(LOG_LEVEL_INFO,"starting signal handling thread...");
ret = pthread_create(&g_thread_sighandler, NULL, sig_handler_thread, "");
pthread_detach(g_thread_sighandler);
if (ret == 0)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "signal handler thread started successfully");
+ log_message(LOG_LEVEL_INFO, "signal handler thread started successfully");
return 0;
}
@@ -77,16 +77,16 @@ thread_sighandler_start(void)
switch (ret)
{
case EINVAL:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "invalid attributes for signal handling thread (creation returned EINVAL)");
+ log_message(LOG_LEVEL_ERROR, "invalid attributes for signal handling thread (creation returned EINVAL)");
break;
case EAGAIN:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "not enough resources to start signal handling thread (creation returned EAGAIN)");
+ log_message(LOG_LEVEL_ERROR, "not enough resources to start signal handling thread (creation returned EAGAIN)");
break;
case EPERM:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "invalid permissions for signal handling thread (creation returned EPERM)");
+ log_message(LOG_LEVEL_ERROR, "invalid permissions for signal handling thread (creation returned EPERM)");
break;
default:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "unknown error starting signal handling thread");
+ log_message(LOG_LEVEL_ERROR, "unknown error starting signal handling thread");
}
return 1;
@@ -100,13 +100,13 @@ thread_session_update_start(void)
int ret;
//starts the session update thread
//that checks for idle time, destroys sessions, ecc...
-
-#warning this thread should always request lock_fork before read or write
+
+#warning this thread should always request lock_fork before read or write
#warning (so we can Fork() In Peace)
ret = pthread_create(&g_thread_updater, NULL, , "");
pthread_detach(g_thread_updater);
- if (ret==0)
+ if (ret == 0)
{
log_message(&(g_cfg->log), LOG_LEVEL_INFO, "session update thread started successfully");
return 0;
@@ -116,16 +116,16 @@ thread_session_update_start(void)
switch (ret)
{
case EINVAL:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "invalid attributes for session update thread (creation returned EINVAL)");
+ log_message(LOG_LEVEL_ERROR, "invalid attributes for session update thread (creation returned EINVAL)");
break;
case EAGAIN:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "not enough resources to start session update thread (creation returned EAGAIN)");
+ log_message(LOG_LEVEL_ERROR, "not enough resources to start session update thread (creation returned EAGAIN)");
break;
case EPERM:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "invalid permissions for session update thread (creation returned EPERM)");
+ log_message(LOG_LEVEL_ERROR, "invalid permissions for session update thread (creation returned EPERM)");
break;
default:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "unknown error starting session update thread");
+ log_message(LOG_LEVEL_ERROR, "unknown error starting session update thread");
}
return 1;
@@ -148,9 +148,9 @@ thread_scp_start(int skt)
//ret = pthread_create(&th, NULL, scp_process_start, (void*) (&g_thread_sck));
pthread_detach(th);
- if (ret == 0)
+ if (ret == 0)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "scp thread on sck %d started successfully", skt);
+ log_message(LOG_LEVEL_INFO, "scp thread on sck %d started successfully", skt);
return 0;
}
@@ -158,18 +158,17 @@ thread_scp_start(int skt)
switch (ret)
{
case EINVAL:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "invalid attributes for scp thread on sck %d (creation returned EINVAL)", skt);
+ log_message(LOG_LEVEL_ERROR, "invalid attributes for scp thread on sck %d (creation returned EINVAL)", skt);
break;
case EAGAIN:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "not enough resources to start scp thread on sck %d (creation returned EAGAIN)", skt);
+ log_message(LOG_LEVEL_ERROR, "not enough resources to start scp thread on sck %d (creation returned EAGAIN)", skt);
break;
case EPERM:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "invalid permissions for scp thread on sck %d (creation returned EPERM)", skt);
+ log_message(LOG_LEVEL_ERROR, "invalid permissions for scp thread on sck %d (creation returned EPERM)", skt);
break;
default:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "unknown error starting scp thread on sck %d");
+ log_message(LOG_LEVEL_ERROR, "unknown error starting scp thread on sck %d");
}
return 1;
}
-
diff --git a/sesman/tools/Makefile.am b/sesman/tools/Makefile.am
index a48b0f11..ab3612d0 100644
--- a/sesman/tools/Makefile.am
+++ b/sesman/tools/Makefile.am
@@ -15,7 +15,8 @@ bin_PROGRAMS = \
xrdp-sesrun \
xrdp-sestest \
xrdp-sesadmin \
- xrdp-dis
+ xrdp-dis \
+ xrdp-xcon
xrdp_sesrun_SOURCES = \
sesrun.c \
@@ -31,14 +32,20 @@ xrdp_sesadmin_SOURCES = \
xrdp_dis_SOURCES = \
dis.c
+xrdp_xcon_SOURCES = \
+ xcon.c
+
xrdp_sesrun_LDADD = \
- $(top_srcdir)/common/libcommon.la
+ $(top_builddir)/common/libcommon.la
xrdp_sestest_LDADD = \
- $(top_srcdir)/common/libcommon.la \
- $(top_srcdir)/sesman/libscp/libscp.la
+ $(top_builddir)/common/libcommon.la \
+ $(top_builddir)/sesman/libscp/libscp.la
xrdp_sesadmin_LDADD = \
- $(top_srcdir)/common/libcommon.la \
- $(top_srcdir)/sesman/libscp/libscp.la
+ $(top_builddir)/common/libcommon.la \
+ $(top_builddir)/sesman/libscp/libscp.la
+xrdp_xcon_LDADD = \
+ -L/usr/X11R6/lib \
+ -lX11
diff --git a/sesman/tools/sesadmin.c b/sesman/tools/sesadmin.c
index 4c612316..22f20c23 100644
--- a/sesman/tools/sesadmin.c
+++ b/sesman/tools/sesadmin.c
@@ -50,7 +50,7 @@ int main(int argc, char** argv)
logging.log_file = g_strdup("xrdp-sesadmin.log");
logging.log_level = LOG_LEVEL_DEBUG;
logging.enable_syslog = 0;
- log_start(&logging);
+ log_start_from_param(&logging);
for (idx = 0; idx < argc; idx++)
{
@@ -110,11 +110,11 @@ int main(int argc, char** argv)
s = scp_session_create();
c = scp_connection_create(sock);
- LOG_DBG(&logging, "Connecting to %s:%s with user %s (%s)\n", serv, port, user, pass);
+ LOG_DBG("Connecting to %s:%s with user %s (%s)\n", serv, port, user, pass);
if (0 != g_tcp_connect(sock, serv, port))
{
- LOG_DBG(&logging, "g_tcp_connect() error\n");
+ LOG_DBG("g_tcp_connect() error\n");
return 1;
}
@@ -127,7 +127,7 @@ int main(int argc, char** argv)
if (SCP_CLIENT_STATE_OK != e)
{
- LOG_DBG(&logging, "libscp error connecting: %s %d\n", s->errstr, (int)e);
+ LOG_DBG("libscp error connecting: %s %d\n", s->errstr, (int)e);
}
if (0 == g_strncmp(cmnd, "list", 5))
@@ -142,7 +142,7 @@ int main(int argc, char** argv)
g_tcp_close(sock);
scp_session_destroy(s);
scp_connection_destroy(c);
- log_end(&logging);
+ log_end();
return 0;
}
diff --git a/sesman/tools/sestest.c b/sesman/tools/sestest.c
index 4382e160..c0784ba3 100644
--- a/sesman/tools/sestest.c
+++ b/sesman/tools/sestest.c
@@ -34,7 +34,7 @@ int main(int argc, char** argv)
log.log_level=99;
log.program_name=g_strdup("sestest");
log.log_file=g_strdup("sestest.log");
- log_start(&log);
+ log_start_from_param(&log);
scp_init(&log);
sock=g_tcp_socket();
@@ -206,7 +206,7 @@ menuSelect(tui32 choices)
ret = scanf("%u", &sel);
- while ((ret==0) || (sel > choices))
+ while ((ret == 0) || (sel > choices))
{
g_printf("invalid choice.");
ret = scanf("%u", &sel);
diff --git a/sesman/tools/xcon.c b/sesman/tools/xcon.c
new file mode 100644
index 00000000..7a45a1cd
--- /dev/null
+++ b/sesman/tools/xcon.c
@@ -0,0 +1,35 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+
+Display* g_display = 0;
+int g_x_socket = 0;
+
+int main(int argc, char** argv)
+{
+ fd_set rfds;
+ int i1;
+ XEvent xevent;
+
+ g_display = XOpenDisplay(0);
+ if (g_display == 0)
+ {
+ printf("XOpenDisplay failed\n");
+ return 0;
+ }
+ g_x_socket = XConnectionNumber(g_display);
+ while (1)
+ {
+ FD_ZERO(&rfds);
+ FD_SET(g_x_socket, &rfds);
+ i1 = select(g_x_socket + 1, &rfds, 0, 0, 0);
+ if (i1 < 0)
+ {
+ break;
+ }
+ XNextEvent(g_display, &xevent);
+ }
+ return 0;
+}
diff --git a/sesman/verify_user.c b/sesman/verify_user.c
index cdc60b47..aaa1515c 100644
--- a/sesman/verify_user.c
+++ b/sesman/verify_user.c
@@ -302,21 +302,21 @@ auth_account_disabled(struct spwd* stp)
{
int today;
- if (0==stp)
+ if (0 == stp)
{
/* if an invalid struct was passed we assume a disabled account */
return 1;
}
- today=g_time1()/SECS_PER_DAY;
+ today = g_time1() / SECS_PER_DAY;
- LOG_DBG(&(g_cfg->log), "last %d",stp->sp_lstchg);
- LOG_DBG(&(g_cfg->log), "min %d",stp->sp_min);
- LOG_DBG(&(g_cfg->log), "max %d",stp->sp_max);
- LOG_DBG(&(g_cfg->log), "inact %d",stp->sp_inact);
- LOG_DBG(&(g_cfg->log), "warn %d",stp->sp_warn);
- LOG_DBG(&(g_cfg->log), "expire %d",stp->sp_expire);
- LOG_DBG(&(g_cfg->log), "today %d",today);
+ LOG_DBG("last %d",stp->sp_lstchg);
+ LOG_DBG("min %d",stp->sp_min);
+ LOG_DBG("max %d",stp->sp_max);
+ LOG_DBG("inact %d",stp->sp_inact);
+ LOG_DBG("warn %d",stp->sp_warn);
+ LOG_DBG("expire %d",stp->sp_expire);
+ LOG_DBG("today %d",today);
if ((stp->sp_expire != -1) && (today >= stp->sp_expire))
{