diff options
author | Jay Sorg <jay.sorg@gmail.com> | 2012-08-19 19:45:31 -0700 |
---|---|---|
committer | Jay Sorg <jay.sorg@gmail.com> | 2012-08-19 19:45:31 -0700 |
commit | 087ea0176d386a4951e49bd6d71f9eb38919d776 (patch) | |
tree | d368f740dd6ab2adac6ead14c82b28377774fd2d /sesman/chansrv/chansrv.c | |
parent | f1f31fadef930442b51ce1b0ca7beef924ee0922 (diff) | |
download | xrdp-proprietary-087ea0176d386a4951e49bd6d71f9eb38919d776.tar.gz xrdp-proprietary-087ea0176d386a4951e49bd6d71f9eb38919d776.zip |
chansrv: work on image clipboard
Diffstat (limited to 'sesman/chansrv/chansrv.c')
-rw-r--r-- | sesman/chansrv/chansrv.c | 186 |
1 files changed, 140 insertions, 46 deletions
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 7c74bb4f..10a42ef9 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -69,59 +69,132 @@ struct xrdp_api_data }; /*****************************************************************************/ +/* 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 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 stream* s; + struct chan_out_data* cod; + int bytes_left; + int size; int chan_flags; - int total_size; - int sent; - int rv; + int error; - if (chan_id == -1) + if (chan_item->head == 0) { - return 1; + 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; } /*****************************************************************************/ @@ -131,7 +204,7 @@ send_init_response_message(void) { struct stream * s = (struct stream *)NULL; - LOGM((LOG_LEVEL_INFO,"send_init_response_message:")) + LOGM((LOG_LEVEL_INFO, "send_init_response_message:")); s = trans_get_out_s(g_con_trans, 8192); if (s == 0) { @@ -339,6 +412,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; } @@ -911,21 +985,41 @@ main(int argc, char** argv) { tbus waiters[4]; int pid = 0; - char text[256] = ""; - char* display_text = (char *)NULL; -#if XRDP_CHANNEL_LOG - char cfg_file[256]; + char text[256]; + char* home_text; + char* display_text; + char log_file[256]; enum logReturns error; -#endif + 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(); -#if XRDP_CHANNEL_LOG /* starting logging subsystem */ - g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - error = log_start(cfg_file,"XRDP-Chansrv"); + 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) @@ -942,10 +1036,9 @@ main(int argc, char** argv) break; } g_deinit(); - g_exit(1); + return 1; } LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid)); -#endif /* set up signal handler */ g_signal_kill(term_signal_handler); /* SIGKILL */ g_signal_terminate(term_signal_handler); /* SIGTERM */ @@ -958,6 +1051,7 @@ main(int argc, char** argv) if (g_display_num == 0) { LOGM((LOG_LEVEL_ERROR, "main: error, display is zero")); + g_deinit(); return 1; } LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num)); |