#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:
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);
_exit(255);
default:
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)
{
for (i = 0; env[i]; i++)
{
char *temp = format_rstart_env (env[i]);
fprintf (fp, "MISC X %s\n", temp);
if (temp != env[i])
XtFree (temp);
}
}
else
{
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);
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");
}
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;
}
}
}
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);
}
}