summaryrefslogtreecommitdiff
path: root/app/xsm/remote.c
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 10:49:38 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 10:49:38 +0000
commit841f8331c93ff96bd798e9a74ba10fab155da5c5 (patch)
tree36661fb122f858a2f14b585a304bad58a2142628 /app/xsm/remote.c
parent8f41c760916495ea26d3c59795487ac6dfc77d75 (diff)
Importing from X.Org 7.2RC2
Diffstat (limited to 'app/xsm/remote.c')
-rw-r--r--app/xsm/remote.c248
1 files changed, 248 insertions, 0 deletions
diff --git a/app/xsm/remote.c b/app/xsm/remote.c
new file mode 100644
index 000000000..f161f96f2
--- /dev/null
+++ b/app/xsm/remote.c
@@ -0,0 +1,248 @@
+/* $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.
+******************************************************************************/
+/* $XFree86: xc/programs/xsm/remote.c,v 1.4 2001/01/17 23:46:30 dawes Exp $ */
+
+/*
+ * We use the rstart protocol to restart clients on remote machines.
+ */
+
+#include "xsm.h"
+#include "log.h"
+
+#include <X11/ICE/ICEutil.h>
+
+static char *format_rstart_env(char *str);
+
+extern IceAuthDataEntry *authDataEntries;
+extern int numTransports;
+
+
+void
+remote_start(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(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);
+ }
+}