remote.c revision 8108eb18
1/* $Xorg: remote.c,v 1.5 2001/02/09 02:06:01 xorgcvs Exp $ */ 2/****************************************************************************** 3 4Copyright 1993, 1998 The Open Group 5 6Permission to use, copy, modify, distribute, and sell this software and its 7documentation for any purpose is hereby granted without fee, provided that 8the above copyright notice appear in all copies and that both that 9copyright notice and this permission notice appear in supporting 10documentation. 11 12The above copyright notice and this permission notice shall be included in 13all copies or substantial portions of the Software. 14 15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22Except as contained in this notice, the name of The Open Group shall not be 23used in advertising or otherwise to promote the sale, use or other dealings 24in this Software without prior written authorization from The Open Group. 25******************************************************************************/ 26/* $XFree86: xc/programs/xsm/remote.c,v 1.4 2001/01/17 23:46:30 dawes Exp $ */ 27 28/* 29 * We use the rstart protocol to restart clients on remote machines. 30 */ 31 32#include "xsm.h" 33#include "log.h" 34 35#include <X11/ICE/ICEutil.h> 36 37static char *format_rstart_env(char *str); 38 39extern IceAuthDataEntry *authDataEntries; 40extern int numTransports; 41 42 43void 44remote_start(char *restart_protocol, char *restart_machine, char *program, 45 char **args, char *cwd, char **env, 46 char *non_local_display_env, char *non_local_session_env) 47{ 48 FILE *fp; 49 int pipefd[2]; 50 char msg[256]; 51 int i; 52 53 if (strcmp (restart_protocol, "rstart-rsh") != 0) 54 { 55 if (verbose) 56 printf ("Only rstart-rsh remote execution protocol supported.\n"); 57 return; 58 } 59 60 if (!restart_machine) 61 { 62 if (verbose) 63 printf ("Bad remote machine specified for remote execute.\n"); 64 return; 65 } 66 67 if (verbose) 68 printf ("Attempting to restart remote client on %s\n", 69 restart_machine); 70 71 if (pipe (pipefd) < 0) 72 { 73 sprintf (msg, "%s: pipe() error during remote start of %s", 74 Argv[0], program); 75 add_log_text (msg); 76 perror (msg); 77 } 78 else 79 { 80 switch(fork()) 81 { 82 case -1: 83 84 sprintf (msg, "%s: fork() error during remote start of %s", 85 Argv[0], program); 86 add_log_text (msg); 87 perror (msg); 88 break; 89 90 case 0: /* kid */ 91 92 close (pipefd[1]); 93 close (0); 94 dup (pipefd[0]); 95 close (pipefd[0]); 96 97 execlp (RSHCMD, restart_machine, "rstartd", (char *) 0); 98 99 sprintf (msg, 100 "%s: execlp() of rstartd failed for remote start of %s", 101 Argv[0], program); 102 perror (msg); 103 /* 104 * TODO : We would like to send this log information to the 105 * log window in the parent. This would require using the 106 * pipe between the parent and child. The child would 107 * set close-on-exec. If the exec succeeds, the pipe will 108 * be closed. If it fails, the child can write a message 109 * to the parent. 110 */ 111 _exit(255); 112 113 default: /* parent */ 114 115 close (pipefd[0]); 116 fp = (FILE *) fdopen (pipefd[1], "w"); 117 118 fprintf (fp, "CONTEXT X\n"); 119 fprintf (fp, "DIR %s\n", cwd); 120 fprintf (fp, "DETACH\n"); 121 122 if (env) 123 { 124 /* 125 * The application saved its environment. 126 */ 127 128 for (i = 0; env[i]; i++) 129 { 130 /* 131 * rstart requires that any spaces, backslashes, or 132 * non-printable characters inside of a string be 133 * represented by octal escape sequences. 134 */ 135 136 char *temp = format_rstart_env (env[i]); 137 fprintf (fp, "MISC X %s\n", temp); 138 if (temp != env[i]) 139 XtFree (temp); 140 } 141 } 142 else 143 { 144 /* 145 * The application did not save its environment. 146 * The default PATH set up by rstart may not contain 147 * the program we want to restart. We play it safe 148 * and pass xsm's PATH. This will most likely contain 149 * the path we need. 150 */ 151 152 char *path = (char *) getenv ("PATH"); 153 154 if (path) 155 fprintf (fp, "MISC X PATH=%s\n", path); 156 } 157 158 fprintf (fp, "MISC X %s\n", non_local_display_env); 159 fprintf (fp, "MISC X %s\n", non_local_session_env); 160 161 /* 162 * Pass the authentication data. 163 * Each transport has auth data for ICE and XSMP. 164 * Don't pass local auth data. 165 */ 166 167 for (i = 0; i < numTransports * 2; i++) 168 { 169 if (Strstr (authDataEntries[i].network_id, "local/")) 170 continue; 171 172 fprintf (fp, "AUTH ICE %s \"\" %s %s ", 173 authDataEntries[i].protocol_name, 174 authDataEntries[i].network_id, 175 authDataEntries[i].auth_name); 176 177 fprintfhex (fp, 178 authDataEntries[i].auth_data_length, 179 authDataEntries[i].auth_data); 180 181 fprintf (fp, "\n"); 182 } 183 184 /* 185 * And execute the program 186 */ 187 188 fprintf (fp, "EXEC %s %s", program, program); 189 for (i = 1; args[i]; i++) 190 fprintf (fp, " %s", args[i]); 191 fprintf (fp, "\n\n"); 192 fclose (fp); 193 break; 194 } 195 } 196} 197 198 199 200/* 201 * rstart requires that any spaces/backslashes/non-printable characters 202 * inside of a string be represented by octal escape sequences. 203 */ 204 205static char * 206format_rstart_env(char *str) 207{ 208 int escape_count = 0, i; 209 char *temp = str; 210 211 while (*temp != '\0') 212 { 213 if (!isgraph (*temp) || *temp == '\\') 214 escape_count++; 215 temp++; 216 } 217 218 if (escape_count == 0) 219 return (str); 220 else 221 { 222 int len = strlen (str) + 1 + (escape_count * 3); 223 char *ret = (char *) XtMalloc (len); 224 char *ptr = ret; 225 226 temp = str; 227 while (*temp != '\0') 228 { 229 if (!isgraph (*temp) || *temp == '\\') 230 { 231 char octal[3]; 232 sprintf (octal, "%o", *temp); 233 *(ptr++) = '\\'; 234 for (i = 0; i < (3 - (int) strlen (octal)); i++) 235 *(ptr++) = '0'; 236 strcpy (ptr, octal); 237 ptr += strlen (octal); 238 } 239 else 240 *(ptr++) = *temp; 241 242 temp++; 243 } 244 245 *ptr = '\0'; 246 return (ret); 247 } 248} 249