Bugzilla – Attachment 224 Details for
Bug 2289
SeamlessRDP session sharing
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
rdesktop.patch
rdesktop.patch (text/plain), 10.89 KB, created by
Peter Åstrand
on 2006-12-18 09:04:16 CET
(
hide
)
Description:
rdesktop.patch
Filename:
MIME Type:
Creator:
Peter Åstrand
Created:
2006-12-18 09:04:16 CET
Size:
10.89 KB
patch
obsolete
>diff -Naur rdesktop/doc/rdesktop.1 rdesktop-modified/doc/rdesktop.1 >--- rdesktop/doc/rdesktop.1 2006-11-02 07:52:01.000000000 +1100 >+++ rdesktop-modified/doc/rdesktop.1 2006-12-18 00:46:09.000000000 +1100 >@@ -86,6 +86,22 @@ > > Example: rdesktop -A -s 'seamlessrdpshell notepad'. > .TP >+.BR "-M <control socket path>" >+Enable SeamlessRDP master mode. This mode allows additional applications to be >+launched from a single SeamlessRDP session as opposed to requiring one session >+per application. A control socket path must be specified for use by slave mode >+invocations. >+ >+Example: rdesktop -A -s 'seamlessrdpshell notepad' -M /tmp/rdesktop-socket >+.TP >+.BR "-l <command>" >+Use SeamlessRDP slave mode to execute an additional command within the master >+SeamlessRDP session. When using this option, a control socket path must be >+specified instead of a server, and all other options will be ignored. Note >+that a shell does not have to be specified, only the command to be executed. >+ >+Example: rdesktop -l 'notepad' /tmp/rdesktop-socket >+.TP > .BR "-B" > Use the BackingStore of the Xserver instead of the integrated one in > rdesktop. >diff -Naur rdesktop/proto.h rdesktop-modified/proto.h >--- rdesktop/proto.h 2006-12-08 02:23:45.000000000 +1100 >+++ rdesktop-modified/proto.h 2006-12-18 01:16:44.000000000 +1100 >@@ -303,6 +303,7 @@ > void seamless_select_timeout(struct timeval *tv); > unsigned int seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags); > unsigned int seamless_send_focus(unsigned long id, unsigned long flags); >+unsigned int seamless_send_spawn(char *cmdline); > /* scard.c */ > void scardSetInfo(uint32 device, uint32 id, uint32 bytes_out); > int scard_enum_devices(uint32 * id, char *optarg); >diff -Naur rdesktop/rdesktop.c rdesktop-modified/rdesktop.c >--- rdesktop/rdesktop.c 2006-11-07 10:05:39.000000000 +1100 >+++ rdesktop-modified/rdesktop.c 2006-12-18 01:16:45.000000000 +1100 >@@ -29,6 +29,7 @@ > #include <ctype.h> /* toupper */ > #include <errno.h> > #include "rdesktop.h" >+#include "seamless.h" > > #ifdef HAVE_LOCALE_H > #include <locale.h> >@@ -91,6 +92,12 @@ > BOOL g_owncolmap = False; > BOOL g_ownbackstore = True; /* We can't rely on external BackingStore */ > BOOL g_seamless_rdp = False; >+ >+/* Master socket identifier */ >+char *master_socket = NULL; >+/* Command line to execute in slave mode */ >+char *slave_cmdline = NULL; >+ > uint32 g_embed_wnd; > uint32 g_rdp5_performanceflags = > RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS; >@@ -122,6 +129,10 @@ > rdp2vnc_connect(char *server, uint32 flags, char *domain, char *password, > char *shell, char *directory); > #endif >+ >+// Send message to rdesktop running in SeamlessrRDP master mode >+void send_seamless_slave_message(char *cmdline); >+ > /* Display usage information */ > static void > usage(char *program) >@@ -131,6 +142,7 @@ > fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n"); > > fprintf(stderr, "Usage: %s [options] server[:port]\n", program); >+ fprintf(stderr, " %s -l <command> <control socket path>\n", program); > #ifdef RDP2VNC > fprintf(stderr, " -V: vnc port\n"); > fprintf(stderr, " -Q: defer time (ms)\n"); >@@ -149,6 +161,8 @@ > fprintf(stderr, " -L: local codepage\n"); > #endif > fprintf(stderr, " -A: enable SeamlessRDP mode\n"); >+ fprintf(stderr, " -M: SeamlessRDP master mode socket path\n"); >+ fprintf(stderr, " -l: <command> <control socket path>: SeamlessRDP slave mode\n"); > fprintf(stderr, " -B: use BackingStore of X-server (if available)\n"); > fprintf(stderr, " -e: disable encryption (French TS)\n"); > fprintf(stderr, " -E: disable encryption from client to server\n"); >@@ -443,6 +457,8 @@ > > g_num_devices = 0; > >+ slave_cmdline = NULL; >+ > #ifdef RDP2VNC > #define VNCOPT "V:Q:" > #else >@@ -450,7 +466,7 @@ > #endif > > while ((c = getopt(argc, argv, >- VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1) >+ VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045M:l:h?")) != -1) > { > switch (c) > { >@@ -783,6 +799,16 @@ > g_use_rdp5 = True; > break; > >+ case 'M': >+ master_socket = xmalloc(sizeof(char) * (strlen(optarg) + 1)); >+ STRNCPY(master_socket, optarg, sizeof(char) * (strlen(optarg) + 1)); >+ break; >+ >+ case 'l': >+ slave_cmdline = xmalloc(sizeof(char) * (strlen(optarg) + 1)); >+ STRNCPY(slave_cmdline, optarg, sizeof(char) * (strlen(optarg) + 1)); >+ break; >+ > case 'h': > case '?': > default: >@@ -800,6 +826,15 @@ > STRNCPY(server, argv[optind], sizeof(server)); > parse_server_and_port(server); > >+ /* If slave mode is being used, the 'server' variable contains the name >+ * of the control socket to use. */ >+ if (slave_cmdline != NULL) >+ { >+ seamless_socket_send(server, slave_cmdline); >+ xfree(slave_cmdline); >+ return 0; >+ } >+ > if (g_seamless_rdp) > { > if (g_win_button_size) >@@ -837,6 +872,10 @@ > g_grab_keyboard = False; > } > >+ /* If we're in master mode, create a socket and listen on it. */ >+ if (master_socket != NULL) >+ seamless_create_socket(master_socket); >+ > if (!username_option) > { > pw = getpwuid(getuid()); >@@ -980,6 +1019,12 @@ > > cache_save_state(); > ui_deinit(); >+ /* If we opened a socket, clean it up. */ >+ if (master_socket != NULL) >+ { >+ seamless_close_socket(master_socket); >+ xfree(master_socket); >+ } > > if (ext_disc_reason >= 2) > print_disconnect_reason(ext_disc_reason); >@@ -1624,3 +1669,10 @@ > return False; > return True; > } >+ >+// Send message to rdesktop running in SeamlessrRDP master mode >+void >+send_seamless_slave_message(char *cmdline) >+{ >+ fprintf(stderr, cmdline); >+} >diff -Naur rdesktop/rdp.c rdesktop-modified/rdp.c >--- rdesktop/rdp.c 2006-11-02 05:38:40.000000000 +1100 >+++ rdesktop-modified/rdp.c 2006-12-18 01:16:45.000000000 +1100 >@@ -22,6 +22,7 @@ > #include <errno.h> > #include <unistd.h> > #include "rdesktop.h" >+#include "seamless.h" > > #ifdef HAVE_ICONV > #ifdef HAVE_ICONV_H >@@ -51,6 +52,9 @@ > extern BOOL g_bitmap_cache_persist_enable; > extern BOOL g_numlock_sync; > >+/* SeamlessRDP master mode socket */ >+extern char *master_socket; >+ > uint8 *g_next_packet; > uint32 g_rdp_shareid; > >@@ -74,6 +78,7 @@ > static BOOL g_iconv_works = True; > #endif > >+ > /* Receive an RDP packet */ > static STREAM > rdp_recv(uint8 * type) >@@ -1361,7 +1366,10 @@ > rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason) > { > while (rdp_loop(deactivated, ext_disc_reason)) >- ; >+ { >+ if (master_socket != NULL) >+ seamless_check_socket(); >+ } > } > > /* used in uiports and rdp_main_loop, processes the rdp packets waiting */ >diff -Naur rdesktop/seamless.c rdesktop-modified/seamless.c >--- rdesktop/seamless.c 2006-04-28 17:55:36.000000000 +1000 >+++ rdesktop-modified/seamless.c 2006-12-18 01:16:45.000000000 +1100 >@@ -21,6 +21,11 @@ > #include "rdesktop.h" > #include <stdarg.h> > #include <assert.h> >+#include <sys/types.h> >+#include <sys/socket.h> >+#include <sys/un.h> >+#include <unistd.h> >+#include "seamless.h" > > /* #define WITH_DEBUG_SEAMLESS */ > >@@ -30,6 +35,9 @@ > #define DEBUG_SEAMLESS(args) > #endif > >+// Control socket file descriptor >+int sock; >+ > extern BOOL g_seamless_rdp; > static VCHANNEL *seamless_channel; > static unsigned int seamless_serial; >@@ -442,7 +450,6 @@ > } > > >- > unsigned int > seamless_send_focus(unsigned long id, unsigned long flags) > { >@@ -451,3 +458,150 @@ > > return seamless_send("FOCUS", "0x%08lx,0x%lx", id, flags); > } >+ >+/* Send client-to-server message to spawn a new process on the server. */ >+unsigned int >+seamless_send_spawn(char *cmdline) >+{ >+ if (!g_seamless_rdp) >+ return (unsigned int) -1; >+ >+ return seamless_send("SPAWN", cmdline); >+} >+ >+ >+/* Check seamless master mode socket and send spawn command if input found. >+ * Returns 0 if a slave connected and sent command, 1 otherwise. */ >+int >+seamless_check_socket() >+{ >+ fd_set rfds; >+ struct timeval tv; >+ int slaves, index, ns; >+ struct sockaddr_un fsaun; >+ char cmdline[256]; >+ socklen_t fromlen; >+ FILE *fp; >+ char c; >+ >+ FD_ZERO(&rfds); >+ FD_SET(sock, &rfds); >+ >+ /* Don't wait - set timeout to zero. */ >+ tv.tv_sec = 0; >+ tv.tv_usec = 0; >+ >+ /* See if any slaves are trying to connect. */ >+ slaves = select(sock + 1, &rfds, NULL, NULL, &tv); >+ >+ if (slaves == -1) >+ { >+ perror("Error checking socket: select()"); >+ return 1; >+ } >+ /* Return if no waiting slaves */ >+ else if (slaves == 0) >+ { >+ return 1; >+ } >+ >+ /* Accept connection */ >+ fromlen = sizeof(fsaun); >+ if ((ns = accept(sock, (struct sockaddr *) &fsaun, &fromlen)) < 0) >+ { >+ perror("server: accept"); >+ exit(1); >+ } >+ >+ /* Read command from client socket */ >+ fp = fdopen(ns, "r"); >+ index = 0; >+ while ((c = fgetc(fp)) != EOF && index < 256) >+ { >+ cmdline[index] = c; >+ >+ index++; >+ } >+ cmdline[index] = '\0'; >+ >+ /* Send spawn command to server-side SeamlessRDP component */ >+ seamless_send_spawn(cmdline); >+ >+ return 0; >+} >+ >+/* Create control socket */ >+void >+seamless_create_socket(char *socket_name) >+{ >+ struct sockaddr_un saun; >+ >+ /* Create socket */ >+ if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) >+ { >+ perror("Error creating socket: socket"); >+ exit(1); >+ } >+ >+ /* Bind to the socket. Any older socket with the same name will be >+ * unlinked first. */ >+ memset(&saun, 0, sizeof(struct sockaddr_un)); >+ saun.sun_family = AF_UNIX; >+ strncpy(saun.sun_path, socket_name, sizeof(saun.sun_path)); >+ unlink(socket_name); >+ if (bind(sock, (struct sockaddr *) &saun, sizeof(struct sockaddr_un)) < 0) >+ { >+ perror("Error binding to socket: bind"); >+ exit(1); >+ } >+ >+ /* Listen on the socket */ >+ if (listen(sock, 5) < 0) >+ { >+ perror("Error listening on socket: listen"); >+ exit(1); >+ } >+} >+ >+/* Close control socket */ >+void >+seamless_close_socket(char *socket_name) >+{ >+ close(sock); >+ unlink(socket_name); >+ >+ return; >+} >+ >+/* Send a command line to a master process via a socket. */ >+int >+seamless_socket_send(char *socket_name, char *cmdline) >+{ >+ register int s, len; >+ struct sockaddr_un saun; >+ >+ /* Create socket */ >+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) >+ { >+ perror("Error creating socket: socket"); >+ exit(1); >+ } >+ >+ /* Connect to server */ >+ saun.sun_family = AF_UNIX; >+ strcpy(saun.sun_path, socket_name); >+ len = sizeof(saun.sun_family) + strlen(saun.sun_path); >+ if (connect(s, (struct sockaddr *) &saun, len) < 0) >+ { >+ perror("Error connecting to socket: connect"); >+ exit(1); >+ } >+ >+ /* Send command */ >+ send(s, cmdline, strlen(cmdline), 0); >+ >+ /* Close socket */ >+ close(s); >+ >+ return 0; >+} >diff -Naur rdesktop/seamless.h rdesktop-modified/seamless.h >--- rdesktop/seamless.h 2006-03-27 18:17:33.000000000 +1000 >+++ rdesktop-modified/seamless.h 2006-12-18 01:16:44.000000000 +1100 >@@ -17,3 +17,12 @@ > along with this program; if not, write to the Free Software > Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > */ >+ >+/* Check seamless master mode socket and send spawn command if input found. */ >+int seamless_check_socket(); >+/* Create control socket */ >+void seamless_create_socket(char *socket_name); >+/* Close control socket */ >+void seamless_close_socket(char *socket_name); >+/* Send a command line to seamless master socket. */ >+int seamless_socket_send(char *socket_name, char *cmdline);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2289
: 224 |
225