summaryrefslogtreecommitdiff
path: root/remote.c
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:55 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:55 +0000
commitc8ddd5d82a72167de6e0a544b55f9b03ab93053e (patch)
tree878ae3ddd67e48798427db3d709940a664801cd0 /remote.c
R6.6 is the Xorg base-lineXORG-MAIN
Diffstat (limited to 'remote.c')
-rw-r--r--remote.c259
1 files changed, 259 insertions, 0 deletions
diff --git a/remote.c b/remote.c
new file mode 100644
index 0000000..0b20bcc
--- /dev/null
+++ b/remote.c
@@ -0,0 +1,259 @@
+/* $Xorg: remote.c,v 1.5 2001/02/09 02:06:01 xorgcvs Exp $ */
+/******************************************************************************
+
+Copyright 1993, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+******************************************************************************/
+
+/*
+ * We use the rstart protocol to restart clients on remote machines.
+ */
+
+#include "xsm.h"
+
+#include <X11/ICE/ICEutil.h>
+
+static char *format_rstart_env();
+
+extern IceAuthDataEntry *authDataEntries;
+extern int numTransports;
+extern void fprintfhex ();
+
+
+void
+remote_start (restart_protocol, restart_machine, program, args, cwd, env,
+ non_local_display_env, non_local_session_env)
+
+char *restart_protocol;
+char *restart_machine;
+char *program;
+char **args;
+char *cwd;
+char **env;
+char *non_local_display_env;
+char *non_local_session_env;
+
+{
+ FILE *fp;
+ int pipefd[2];
+ char msg[256];
+ int i;
+
+ if (strcmp (restart_protocol, "rstart-rsh") != 0)
+ {
+ if (verbose)
+ printf ("Only rstart-rsh remote execution protocol supported.\n");
+ return;
+ }
+
+ if (!restart_machine)
+ {
+ if (verbose)
+ printf ("Bad remote machine specified for remote execute.\n");
+ return;
+ }
+
+ if (verbose)
+ printf ("Attempting to restart remote client on %s\n",
+ restart_machine);
+
+ if (pipe (pipefd) < 0)
+ {
+ sprintf (msg, "%s: pipe() error during remote start of %s",
+ Argv[0], program);
+ add_log_text (msg);
+ perror (msg);
+ }
+ else
+ {
+ switch(fork())
+ {
+ case -1:
+
+ sprintf (msg, "%s: fork() error during remote start of %s",
+ Argv[0], program);
+ add_log_text (msg);
+ perror (msg);
+ break;
+
+ case 0: /* kid */
+
+ close (pipefd[1]);
+ close (0);
+ dup (pipefd[0]);
+ close (pipefd[0]);
+
+ execlp (RSHCMD, restart_machine, "rstartd", (char *) 0);
+
+ sprintf (msg,
+ "%s: execlp() of rstartd failed for remote start of %s",
+ Argv[0], program);
+ perror (msg);
+ /*
+ * TODO : We would like to send this log information to the
+ * log window in the parent. This would require using the
+ * pipe between the parent and child. The child would
+ * set close-on-exec. If the exec succeeds, the pipe will
+ * be closed. If it fails, the child can write a message
+ * to the parent.
+ */
+ _exit(255);
+
+ default: /* parent */
+
+ close (pipefd[0]);
+ fp = (FILE *) fdopen (pipefd[1], "w");
+
+ fprintf (fp, "CONTEXT X\n");
+ fprintf (fp, "DIR %s\n", cwd);
+ fprintf (fp, "DETACH\n");
+
+ if (env)
+ {
+ /*
+ * The application saved its environment.
+ */
+
+ for (i = 0; env[i]; i++)
+ {
+ /*
+ * rstart requires that any spaces, backslashes, or
+ * non-printable characters inside of a string be
+ * represented by octal escape sequences.
+ */
+
+ char *temp = format_rstart_env (env[i]);
+ fprintf (fp, "MISC X %s\n", temp);
+ if (temp != env[i])
+ XtFree (temp);
+ }
+ }
+ else
+ {
+ /*
+ * The application did not save its environment.
+ * The default PATH set up by rstart may not contain
+ * the program we want to restart. We play it safe
+ * and pass xsm's PATH. This will most likely contain
+ * the path we need.
+ */
+
+ char *path = (char *) getenv ("PATH");
+
+ if (path)
+ fprintf (fp, "MISC X PATH=%s\n", path);
+ }
+
+ fprintf (fp, "MISC X %s\n", non_local_display_env);
+ fprintf (fp, "MISC X %s\n", non_local_session_env);
+
+ /*
+ * Pass the authentication data.
+ * Each transport has auth data for ICE and XSMP.
+ * Don't pass local auth data.
+ */
+
+ for (i = 0; i < numTransports * 2; i++)
+ {
+ if (Strstr (authDataEntries[i].network_id, "local/"))
+ continue;
+
+ fprintf (fp, "AUTH ICE %s \"\" %s %s ",
+ authDataEntries[i].protocol_name,
+ authDataEntries[i].network_id,
+ authDataEntries[i].auth_name);
+
+ fprintfhex (fp,
+ authDataEntries[i].auth_data_length,
+ authDataEntries[i].auth_data);
+
+ fprintf (fp, "\n");
+ }
+
+ /*
+ * And execute the program
+ */
+
+ fprintf (fp, "EXEC %s %s", program, program);
+ for (i = 1; args[i]; i++)
+ fprintf (fp, " %s", args[i]);
+ fprintf (fp, "\n\n");
+ fclose (fp);
+ break;
+ }
+ }
+}
+
+
+
+/*
+ * rstart requires that any spaces/backslashes/non-printable characters
+ * inside of a string be represented by octal escape sequences.
+ */
+
+static char *
+format_rstart_env (str)
+
+char *str;
+
+{
+ int escape_count = 0, i;
+ char *temp = str;
+
+ while (*temp != '\0')
+ {
+ if (!isgraph (*temp) || *temp == '\\')
+ escape_count++;
+ temp++;
+ }
+
+ if (escape_count == 0)
+ return (str);
+ else
+ {
+ int len = strlen (str) + 1 + (escape_count * 3);
+ char *ret = (char *) XtMalloc (len);
+ char *ptr = ret;
+
+ temp = str;
+ while (*temp != '\0')
+ {
+ if (!isgraph (*temp) || *temp == '\\')
+ {
+ char octal[3];
+ sprintf (octal, "%o", *temp);
+ *(ptr++) = '\\';
+ for (i = 0; i < (3 - (int) strlen (octal)); i++)
+ *(ptr++) = '0';
+ strcpy (ptr, octal);
+ ptr += strlen (octal);
+ }
+ else
+ *(ptr++) = *temp;
+
+ temp++;
+ }
+
+ *ptr = '\0';
+ return (ret);
+ }
+}