remote.c revision 8108eb18
18108eb18Smrg/* $Xorg: remote.c,v 1.5 2001/02/09 02:06:01 xorgcvs Exp $ */ 28108eb18Smrg/****************************************************************************** 38108eb18Smrg 48108eb18SmrgCopyright 1993, 1998 The Open Group 58108eb18Smrg 68108eb18SmrgPermission to use, copy, modify, distribute, and sell this software and its 78108eb18Smrgdocumentation for any purpose is hereby granted without fee, provided that 88108eb18Smrgthe above copyright notice appear in all copies and that both that 98108eb18Smrgcopyright notice and this permission notice appear in supporting 108108eb18Smrgdocumentation. 118108eb18Smrg 128108eb18SmrgThe above copyright notice and this permission notice shall be included in 138108eb18Smrgall copies or substantial portions of the Software. 148108eb18Smrg 158108eb18SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 168108eb18SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 178108eb18SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 188108eb18SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 198108eb18SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 208108eb18SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 218108eb18Smrg 228108eb18SmrgExcept as contained in this notice, the name of The Open Group shall not be 238108eb18Smrgused in advertising or otherwise to promote the sale, use or other dealings 248108eb18Smrgin this Software without prior written authorization from The Open Group. 258108eb18Smrg******************************************************************************/ 268108eb18Smrg/* $XFree86: xc/programs/xsm/remote.c,v 1.4 2001/01/17 23:46:30 dawes Exp $ */ 278108eb18Smrg 288108eb18Smrg/* 298108eb18Smrg * We use the rstart protocol to restart clients on remote machines. 308108eb18Smrg */ 318108eb18Smrg 328108eb18Smrg#include "xsm.h" 338108eb18Smrg#include "log.h" 348108eb18Smrg 358108eb18Smrg#include <X11/ICE/ICEutil.h> 368108eb18Smrg 378108eb18Smrgstatic char *format_rstart_env(char *str); 388108eb18Smrg 398108eb18Smrgextern IceAuthDataEntry *authDataEntries; 408108eb18Smrgextern int numTransports; 418108eb18Smrg 428108eb18Smrg 438108eb18Smrgvoid 448108eb18Smrgremote_start(char *restart_protocol, char *restart_machine, char *program, 458108eb18Smrg char **args, char *cwd, char **env, 468108eb18Smrg char *non_local_display_env, char *non_local_session_env) 478108eb18Smrg{ 488108eb18Smrg FILE *fp; 498108eb18Smrg int pipefd[2]; 508108eb18Smrg char msg[256]; 518108eb18Smrg int i; 528108eb18Smrg 538108eb18Smrg if (strcmp (restart_protocol, "rstart-rsh") != 0) 548108eb18Smrg { 558108eb18Smrg if (verbose) 568108eb18Smrg printf ("Only rstart-rsh remote execution protocol supported.\n"); 578108eb18Smrg return; 588108eb18Smrg } 598108eb18Smrg 608108eb18Smrg if (!restart_machine) 618108eb18Smrg { 628108eb18Smrg if (verbose) 638108eb18Smrg printf ("Bad remote machine specified for remote execute.\n"); 648108eb18Smrg return; 658108eb18Smrg } 668108eb18Smrg 678108eb18Smrg if (verbose) 688108eb18Smrg printf ("Attempting to restart remote client on %s\n", 698108eb18Smrg restart_machine); 708108eb18Smrg 718108eb18Smrg if (pipe (pipefd) < 0) 728108eb18Smrg { 738108eb18Smrg sprintf (msg, "%s: pipe() error during remote start of %s", 748108eb18Smrg Argv[0], program); 758108eb18Smrg add_log_text (msg); 768108eb18Smrg perror (msg); 778108eb18Smrg } 788108eb18Smrg else 798108eb18Smrg { 808108eb18Smrg switch(fork()) 818108eb18Smrg { 828108eb18Smrg case -1: 838108eb18Smrg 848108eb18Smrg sprintf (msg, "%s: fork() error during remote start of %s", 858108eb18Smrg Argv[0], program); 868108eb18Smrg add_log_text (msg); 878108eb18Smrg perror (msg); 888108eb18Smrg break; 898108eb18Smrg 908108eb18Smrg case 0: /* kid */ 918108eb18Smrg 928108eb18Smrg close (pipefd[1]); 938108eb18Smrg close (0); 948108eb18Smrg dup (pipefd[0]); 958108eb18Smrg close (pipefd[0]); 968108eb18Smrg 978108eb18Smrg execlp (RSHCMD, restart_machine, "rstartd", (char *) 0); 988108eb18Smrg 998108eb18Smrg sprintf (msg, 1008108eb18Smrg "%s: execlp() of rstartd failed for remote start of %s", 1018108eb18Smrg Argv[0], program); 1028108eb18Smrg perror (msg); 1038108eb18Smrg /* 1048108eb18Smrg * TODO : We would like to send this log information to the 1058108eb18Smrg * log window in the parent. This would require using the 1068108eb18Smrg * pipe between the parent and child. The child would 1078108eb18Smrg * set close-on-exec. If the exec succeeds, the pipe will 1088108eb18Smrg * be closed. If it fails, the child can write a message 1098108eb18Smrg * to the parent. 1108108eb18Smrg */ 1118108eb18Smrg _exit(255); 1128108eb18Smrg 1138108eb18Smrg default: /* parent */ 1148108eb18Smrg 1158108eb18Smrg close (pipefd[0]); 1168108eb18Smrg fp = (FILE *) fdopen (pipefd[1], "w"); 1178108eb18Smrg 1188108eb18Smrg fprintf (fp, "CONTEXT X\n"); 1198108eb18Smrg fprintf (fp, "DIR %s\n", cwd); 1208108eb18Smrg fprintf (fp, "DETACH\n"); 1218108eb18Smrg 1228108eb18Smrg if (env) 1238108eb18Smrg { 1248108eb18Smrg /* 1258108eb18Smrg * The application saved its environment. 1268108eb18Smrg */ 1278108eb18Smrg 1288108eb18Smrg for (i = 0; env[i]; i++) 1298108eb18Smrg { 1308108eb18Smrg /* 1318108eb18Smrg * rstart requires that any spaces, backslashes, or 1328108eb18Smrg * non-printable characters inside of a string be 1338108eb18Smrg * represented by octal escape sequences. 1348108eb18Smrg */ 1358108eb18Smrg 1368108eb18Smrg char *temp = format_rstart_env (env[i]); 1378108eb18Smrg fprintf (fp, "MISC X %s\n", temp); 1388108eb18Smrg if (temp != env[i]) 1398108eb18Smrg XtFree (temp); 1408108eb18Smrg } 1418108eb18Smrg } 1428108eb18Smrg else 1438108eb18Smrg { 1448108eb18Smrg /* 1458108eb18Smrg * The application did not save its environment. 1468108eb18Smrg * The default PATH set up by rstart may not contain 1478108eb18Smrg * the program we want to restart. We play it safe 1488108eb18Smrg * and pass xsm's PATH. This will most likely contain 1498108eb18Smrg * the path we need. 1508108eb18Smrg */ 1518108eb18Smrg 1528108eb18Smrg char *path = (char *) getenv ("PATH"); 1538108eb18Smrg 1548108eb18Smrg if (path) 1558108eb18Smrg fprintf (fp, "MISC X PATH=%s\n", path); 1568108eb18Smrg } 1578108eb18Smrg 1588108eb18Smrg fprintf (fp, "MISC X %s\n", non_local_display_env); 1598108eb18Smrg fprintf (fp, "MISC X %s\n", non_local_session_env); 1608108eb18Smrg 1618108eb18Smrg /* 1628108eb18Smrg * Pass the authentication data. 1638108eb18Smrg * Each transport has auth data for ICE and XSMP. 1648108eb18Smrg * Don't pass local auth data. 1658108eb18Smrg */ 1668108eb18Smrg 1678108eb18Smrg for (i = 0; i < numTransports * 2; i++) 1688108eb18Smrg { 1698108eb18Smrg if (Strstr (authDataEntries[i].network_id, "local/")) 1708108eb18Smrg continue; 1718108eb18Smrg 1728108eb18Smrg fprintf (fp, "AUTH ICE %s \"\" %s %s ", 1738108eb18Smrg authDataEntries[i].protocol_name, 1748108eb18Smrg authDataEntries[i].network_id, 1758108eb18Smrg authDataEntries[i].auth_name); 1768108eb18Smrg 1778108eb18Smrg fprintfhex (fp, 1788108eb18Smrg authDataEntries[i].auth_data_length, 1798108eb18Smrg authDataEntries[i].auth_data); 1808108eb18Smrg 1818108eb18Smrg fprintf (fp, "\n"); 1828108eb18Smrg } 1838108eb18Smrg 1848108eb18Smrg /* 1858108eb18Smrg * And execute the program 1868108eb18Smrg */ 1878108eb18Smrg 1888108eb18Smrg fprintf (fp, "EXEC %s %s", program, program); 1898108eb18Smrg for (i = 1; args[i]; i++) 1908108eb18Smrg fprintf (fp, " %s", args[i]); 1918108eb18Smrg fprintf (fp, "\n\n"); 1928108eb18Smrg fclose (fp); 1938108eb18Smrg break; 1948108eb18Smrg } 1958108eb18Smrg } 1968108eb18Smrg} 1978108eb18Smrg 1988108eb18Smrg 1998108eb18Smrg 2008108eb18Smrg/* 2018108eb18Smrg * rstart requires that any spaces/backslashes/non-printable characters 2028108eb18Smrg * inside of a string be represented by octal escape sequences. 2038108eb18Smrg */ 2048108eb18Smrg 2058108eb18Smrgstatic char * 2068108eb18Smrgformat_rstart_env(char *str) 2078108eb18Smrg{ 2088108eb18Smrg int escape_count = 0, i; 2098108eb18Smrg char *temp = str; 2108108eb18Smrg 2118108eb18Smrg while (*temp != '\0') 2128108eb18Smrg { 2138108eb18Smrg if (!isgraph (*temp) || *temp == '\\') 2148108eb18Smrg escape_count++; 2158108eb18Smrg temp++; 2168108eb18Smrg } 2178108eb18Smrg 2188108eb18Smrg if (escape_count == 0) 2198108eb18Smrg return (str); 2208108eb18Smrg else 2218108eb18Smrg { 2228108eb18Smrg int len = strlen (str) + 1 + (escape_count * 3); 2238108eb18Smrg char *ret = (char *) XtMalloc (len); 2248108eb18Smrg char *ptr = ret; 2258108eb18Smrg 2268108eb18Smrg temp = str; 2278108eb18Smrg while (*temp != '\0') 2288108eb18Smrg { 2298108eb18Smrg if (!isgraph (*temp) || *temp == '\\') 2308108eb18Smrg { 2318108eb18Smrg char octal[3]; 2328108eb18Smrg sprintf (octal, "%o", *temp); 2338108eb18Smrg *(ptr++) = '\\'; 2348108eb18Smrg for (i = 0; i < (3 - (int) strlen (octal)); i++) 2358108eb18Smrg *(ptr++) = '0'; 2368108eb18Smrg strcpy (ptr, octal); 2378108eb18Smrg ptr += strlen (octal); 2388108eb18Smrg } 2398108eb18Smrg else 2408108eb18Smrg *(ptr++) = *temp; 2418108eb18Smrg 2428108eb18Smrg temp++; 2438108eb18Smrg } 2448108eb18Smrg 2458108eb18Smrg *ptr = '\0'; 2468108eb18Smrg return (ret); 2478108eb18Smrg } 2488108eb18Smrg} 249