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 358108eb18Smrgstatic char *format_rstart_env(char *str); 368108eb18Smrg 378108eb18Smrg 388108eb18Smrgvoid 395977a007Smrgremote_start(const char *restart_protocol, const char *restart_machine, 405977a007Smrg const char *program, char **args, const char *cwd, 415977a007Smrg char **env, const char *non_local_display_env, 425977a007Smrg const char *non_local_session_env) 438108eb18Smrg{ 448108eb18Smrg FILE *fp; 458108eb18Smrg int pipefd[2]; 468108eb18Smrg char msg[256]; 478108eb18Smrg int i; 488108eb18Smrg 498108eb18Smrg if (strcmp (restart_protocol, "rstart-rsh") != 0) 508108eb18Smrg { 518108eb18Smrg if (verbose) 528108eb18Smrg printf ("Only rstart-rsh remote execution protocol supported.\n"); 538108eb18Smrg return; 548108eb18Smrg } 558108eb18Smrg 568108eb18Smrg if (!restart_machine) 578108eb18Smrg { 588108eb18Smrg if (verbose) 598108eb18Smrg printf ("Bad remote machine specified for remote execute.\n"); 608108eb18Smrg return; 618108eb18Smrg } 628108eb18Smrg 638108eb18Smrg if (verbose) 648108eb18Smrg printf ("Attempting to restart remote client on %s\n", 658108eb18Smrg restart_machine); 668108eb18Smrg 678108eb18Smrg if (pipe (pipefd) < 0) 688108eb18Smrg { 691a650d1eSmrg snprintf (msg, sizeof(msg), 701a650d1eSmrg "%s: pipe() error during remote start of %s", 711a650d1eSmrg Argv[0], program); 728108eb18Smrg add_log_text (msg); 738108eb18Smrg perror (msg); 748108eb18Smrg } 758108eb18Smrg else 768108eb18Smrg { 778108eb18Smrg switch(fork()) 788108eb18Smrg { 798108eb18Smrg case -1: 808108eb18Smrg 811a650d1eSmrg snprintf (msg, sizeof(msg), 821a650d1eSmrg "%s: fork() error during remote start of %s", 831a650d1eSmrg Argv[0], program); 848108eb18Smrg add_log_text (msg); 858108eb18Smrg perror (msg); 868108eb18Smrg break; 878108eb18Smrg 888108eb18Smrg case 0: /* kid */ 898108eb18Smrg 908108eb18Smrg close (pipefd[1]); 918108eb18Smrg close (0); 928108eb18Smrg dup (pipefd[0]); 938108eb18Smrg close (pipefd[0]); 948108eb18Smrg 958108eb18Smrg execlp (RSHCMD, restart_machine, "rstartd", (char *) 0); 968108eb18Smrg 971a650d1eSmrg snprintf (msg, sizeof(msg), 981a650d1eSmrg "%s: execlp() of rstartd failed for remote start of %s", 991a650d1eSmrg Argv[0], program); 1008108eb18Smrg perror (msg); 1018108eb18Smrg /* 1028108eb18Smrg * TODO : We would like to send this log information to the 1038108eb18Smrg * log window in the parent. This would require using the 1048108eb18Smrg * pipe between the parent and child. The child would 1058108eb18Smrg * set close-on-exec. If the exec succeeds, the pipe will 1068108eb18Smrg * be closed. If it fails, the child can write a message 1078108eb18Smrg * to the parent. 1088108eb18Smrg */ 1098108eb18Smrg _exit(255); 1108108eb18Smrg 1118108eb18Smrg default: /* parent */ 1128108eb18Smrg 1138108eb18Smrg close (pipefd[0]); 1142bc08f26Swiz fcntl(pipefd[1], F_SETFD, FD_CLOEXEC); 1152bc08f26Swiz fp = fdopen (pipefd[1], "w"); 1168108eb18Smrg 1178108eb18Smrg fprintf (fp, "CONTEXT X\n"); 1188108eb18Smrg fprintf (fp, "DIR %s\n", cwd); 1198108eb18Smrg fprintf (fp, "DETACH\n"); 1208108eb18Smrg 1218108eb18Smrg if (env) 1228108eb18Smrg { 1238108eb18Smrg /* 1248108eb18Smrg * The application saved its environment. 1258108eb18Smrg */ 1268108eb18Smrg 1278108eb18Smrg for (i = 0; env[i]; i++) 1288108eb18Smrg { 1298108eb18Smrg /* 1308108eb18Smrg * rstart requires that any spaces, backslashes, or 1318108eb18Smrg * non-printable characters inside of a string be 1328108eb18Smrg * represented by octal escape sequences. 1338108eb18Smrg */ 1348108eb18Smrg 1358108eb18Smrg char *temp = format_rstart_env (env[i]); 1368108eb18Smrg fprintf (fp, "MISC X %s\n", temp); 1378108eb18Smrg if (temp != env[i]) 1388108eb18Smrg XtFree (temp); 1398108eb18Smrg } 1408108eb18Smrg } 1418108eb18Smrg else 1428108eb18Smrg { 1438108eb18Smrg /* 1448108eb18Smrg * The application did not save its environment. 1458108eb18Smrg * The default PATH set up by rstart may not contain 1468108eb18Smrg * the program we want to restart. We play it safe 1478108eb18Smrg * and pass xsm's PATH. This will most likely contain 1488108eb18Smrg * the path we need. 1498108eb18Smrg */ 1508108eb18Smrg 1518108eb18Smrg char *path = (char *) getenv ("PATH"); 1528108eb18Smrg 1538108eb18Smrg if (path) 1548108eb18Smrg fprintf (fp, "MISC X PATH=%s\n", path); 1558108eb18Smrg } 1568108eb18Smrg 1578108eb18Smrg fprintf (fp, "MISC X %s\n", non_local_display_env); 1588108eb18Smrg fprintf (fp, "MISC X %s\n", non_local_session_env); 1598108eb18Smrg 1608108eb18Smrg /* 1618108eb18Smrg * Pass the authentication data. 1628108eb18Smrg * Each transport has auth data for ICE and XSMP. 1638108eb18Smrg * Don't pass local auth data. 1648108eb18Smrg */ 1658108eb18Smrg 1668108eb18Smrg for (i = 0; i < numTransports * 2; i++) 1678108eb18Smrg { 1688108eb18Smrg if (Strstr (authDataEntries[i].network_id, "local/")) 1698108eb18Smrg continue; 1708108eb18Smrg 1718108eb18Smrg fprintf (fp, "AUTH ICE %s \"\" %s %s ", 1728108eb18Smrg authDataEntries[i].protocol_name, 1738108eb18Smrg authDataEntries[i].network_id, 1748108eb18Smrg authDataEntries[i].auth_name); 1758108eb18Smrg 1768108eb18Smrg fprintfhex (fp, 1778108eb18Smrg authDataEntries[i].auth_data_length, 1788108eb18Smrg authDataEntries[i].auth_data); 1798108eb18Smrg 1808108eb18Smrg fprintf (fp, "\n"); 1818108eb18Smrg } 1828108eb18Smrg 1838108eb18Smrg /* 1848108eb18Smrg * And execute the program 1858108eb18Smrg */ 1868108eb18Smrg 1878108eb18Smrg fprintf (fp, "EXEC %s %s", program, program); 1888108eb18Smrg for (i = 1; args[i]; i++) 1898108eb18Smrg fprintf (fp, " %s", args[i]); 1908108eb18Smrg fprintf (fp, "\n\n"); 1918108eb18Smrg fclose (fp); 1928108eb18Smrg break; 1938108eb18Smrg } 1948108eb18Smrg } 1958108eb18Smrg} 1968108eb18Smrg 1978108eb18Smrg 1988108eb18Smrg 1998108eb18Smrg/* 2008108eb18Smrg * rstart requires that any spaces/backslashes/non-printable characters 2018108eb18Smrg * inside of a string be represented by octal escape sequences. 2028108eb18Smrg */ 2038108eb18Smrg 2048108eb18Smrgstatic char * 2058108eb18Smrgformat_rstart_env(char *str) 2068108eb18Smrg{ 2078108eb18Smrg int escape_count = 0, i; 2088108eb18Smrg char *temp = str; 2098108eb18Smrg 2108108eb18Smrg while (*temp != '\0') 2118108eb18Smrg { 2128108eb18Smrg if (!isgraph (*temp) || *temp == '\\') 2138108eb18Smrg escape_count++; 2148108eb18Smrg temp++; 2158108eb18Smrg } 2168108eb18Smrg 2178108eb18Smrg if (escape_count == 0) 2188108eb18Smrg return (str); 2198108eb18Smrg else 2208108eb18Smrg { 2218108eb18Smrg int len = strlen (str) + 1 + (escape_count * 3); 2228108eb18Smrg char *ret = (char *) XtMalloc (len); 2238108eb18Smrg char *ptr = ret; 2248108eb18Smrg 2258108eb18Smrg temp = str; 2268108eb18Smrg while (*temp != '\0') 2278108eb18Smrg { 2288108eb18Smrg if (!isgraph (*temp) || *temp == '\\') 2298108eb18Smrg { 2301a650d1eSmrg char octal[4]; 2311a650d1eSmrg snprintf (octal, sizeof(octal), "%o", *temp); 2328108eb18Smrg *(ptr++) = '\\'; 2338108eb18Smrg for (i = 0; i < (3 - (int) strlen (octal)); i++) 2348108eb18Smrg *(ptr++) = '0'; 2358108eb18Smrg strcpy (ptr, octal); 2368108eb18Smrg ptr += strlen (octal); 2378108eb18Smrg } 2388108eb18Smrg else 2398108eb18Smrg *(ptr++) = *temp; 2408108eb18Smrg 2418108eb18Smrg temp++; 2428108eb18Smrg } 2438108eb18Smrg 2448108eb18Smrg *ptr = '\0'; 2458108eb18Smrg return (ret); 2468108eb18Smrg } 2478108eb18Smrg} 248