|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T r
Length: 8499 (0x2133)
Types: TextFile
Names: »remote_sh.c«
└─⟦8ee07855d⟧ Bits:30000545 8mm tape, Rational 1000, DTIA 2_1_6
└─⟦0c25cb74a⟧ »DATA«
└─⟦038380b96⟧
└─⟦d0624311f⟧ Bits:30000529 8mm tape, Rational 1000, DTIA 2_1_7
└─⟦f494b5154⟧ »DATA«
└─⟦038380b96⟧
└─⟦this⟧ »remote_sh.c«
└─⟦8ee07855d⟧ Bits:30000545 8mm tape, Rational 1000, DTIA 2_1_6
└─⟦0c25cb74a⟧ »DATA«
└─⟦0732ea0cf⟧
└─⟦d0624311f⟧ Bits:30000529 8mm tape, Rational 1000, DTIA 2_1_7
└─⟦f494b5154⟧ »DATA«
└─⟦0732ea0cf⟧
└─⟦this⟧ »../../dtia/release_apollo_2.1/remote_sh.c«
└─⟦8ee07855d⟧ Bits:30000545 8mm tape, Rational 1000, DTIA 2_1_6
└─⟦0c25cb74a⟧ »DATA«
└─⟦25fab149a⟧
└─⟦d0624311f⟧ Bits:30000529 8mm tape, Rational 1000, DTIA 2_1_7
└─⟦f494b5154⟧ »DATA«
└─⟦25fab149a⟧
└─⟦this⟧ »../../dtia/release_sun_2.1/remote_sh.c«
└─⟦8ee07855d⟧ Bits:30000545 8mm tape, Rational 1000, DTIA 2_1_6
└─⟦0c25cb74a⟧ »DATA«
└─⟦be254d495⟧
└─⟦d0624311f⟧ Bits:30000529 8mm tape, Rational 1000, DTIA 2_1_7
└─⟦f494b5154⟧ »DATA«
└─⟦be254d495⟧
└─⟦this⟧ »../../dtia/release_aix_2.1/remote_sh.c«
└─⟦8ee07855d⟧ Bits:30000545 8mm tape, Rational 1000, DTIA 2_1_6
└─⟦0c25cb74a⟧ »DATA«
└─⟦c67979795⟧
└─⟦d0624311f⟧ Bits:30000529 8mm tape, Rational 1000, DTIA 2_1_7
└─⟦f494b5154⟧ »DATA«
└─⟦c67979795⟧
└─⟦this⟧ »../../dtia/release_hp_2.1/remote_sh.c«
#ifndef lint
#ifndef DEBUG
static char SCCS_id[] = "@(#)remote_sh.c 2.1 90/08/02 19:04:10 Copyright(c) 1990 by Rational.";
#else
static char SCCS_id[] = "@(#)remote_sh.c DEBUG 2.1 90/08/02 19:04:10 Copyright(c) 1990 by Rational.";
#endif
#endif
#define REMOTE_SH
#include "talk.h"
#undef REMOTE_SH
typedef int (*PFRI)(); /* Ptr to Fct Returning Integer */
typedef int (*PFRV)(); /* Ptr to Fct Returning Void */
static int shell_pid= -1; /* the pid of the remote shell */
static int pipe_in[2]; /* stdin of the remote shell */
static int pipe_out[2]; /* stdout of the remote shell */
static int pipe_err[2]; /* stderr of the remote shell */
static int eof_out=FALSE; /* Is stdout of RS finished? */
static int eof_err=FALSE; /* Is stderr of RS finished? */
#define NULL_FCT ((PFRI)NULL)
int is_eof_reached() {
return (
( shell_pid == -1 ) ||
( eof_out && eof_err)
);
}
static int my_write(fd,s,lg_total)
int fd;
char *s;
int lg_total;
{
int lg_wrote,lg;
lg_wrote=0;
while (lg_wrote<lg_total) {
lg = write(fd, s, lg_total - lg_wrote);
if (lg == -1) {
#ifdef DEBUG1
trace_msg("My_Write returns <-1>\n");
#endif
return -1;
} else {
lg_wrote += lg;
s += lg;
}
}
#ifdef DEBUG1
trace_msg2("My_Write returns <%d>\n",lg_wrote);
#endif
return lg_wrote;
}
static int my_read(fd,s,l)
int fd;
char *s;
int l;
{
int lg_read;
while ((lg_read=read(fd,s,l))==-1) {
if (errno==EINTR) continue;
}
return lg_read;
}
static void raz_remote_shell() {
shell_pid= -1;
close(pipe_in[1]);
close(pipe_out[0]);
close(pipe_err[0]);
eof_out=eof_err=FALSE;
}
int kill_remote_shell() {
/* In case of a problem a signal 9 will make sure that */
/* the remote shell is completely dead */
int retour=0;
int sh_pid;
if (shell_pid!= -1) {
sh_pid = shell_pid;
raz_remote_shell();
if (killpg(sh_pid,SIGKILL)== -1)
retour = -1;
else if (wait_pid(sh_pid)== -1)
retour = -2;
}
return retour;
}
extern char **environ;
static int init_remote_shell() {
#define MOVE_FD(f1,f2) if(f1-f2){dup2(f1,f2);close(f1);}
fd_set mask_w,mask_r;
/* Let's open the three pipes */
#ifdef DEBUG1
trace_msg("Entering Init_Remote_Shell\n");
#endif
if (pipe(pipe_in)== -1) return -1;
if (pipe(pipe_out)== -1) return -1;
if (pipe(pipe_err)== -1) return -1;
eof_out=eof_err=FALSE;
#ifdef DEBUG1
trace_msg("The three pipes are opened\n");
#endif
switch (shell_pid=fork()) {
case -1:
#ifdef DEBUG1
trace_msg("Fork failed\n");
#endif
return -1;
case 0:
/* The son */
/* Let's attach the three pipes to the */
/* stdin, stdout and stderr of the RS */
close(pipe_in[1]);
MOVE_FD(pipe_in[0],0);
close(pipe_out[0]);
MOVE_FD(pipe_out[1],1);
close(pipe_err[0]);
MOVE_FD(pipe_err[1],2);
/* The last six tricky lines are the */
/* "standard idiom" described chapter */
/* "Pipes" of "C Programmer's guide" */
if (setpgrp(0,getpid())== -1) {
return -1;
}
/* Process group set */
execle( get_user_shell(),
get_user_shell(),
(char *)NULL,environ);
/* Should never arrive here but if so ... */
return -1;
default:
/* The father */
close(pipe_in[0]);
close(pipe_out[1]);
close(pipe_err[1]);
/* Got rid of the pipes used by the son */
#ifdef DEBUG1
trace_msg("Fork Succeeded\n");
#endif
return 0;
}
}
static int write_secure(fd,s,l)
int fd;
char *s;
int l;
{
/* Before writing something, make sure somebody is listening */
int ret_select;
fd_set mask_w;
struct timeval t;
#ifdef DEBUG1
trace_msg("Entering Write_Secure\n");
#endif
t.tv_sec=0;
t.tv_usec=1000;
FD_ZERO(&mask_w);
FD_SET(fd,&mask_w);
while ((ret_select=select(getdtablesize(),(fd_set *)NULL,&mask_w,
(fd_set *)NULL,&t)) == -1) {
#ifdef DEBUG1
trace_msg("Select returns -1\n");
#endif
if (errno == EINTR) continue;
return -1;
}
#ifdef DEBUG1
trace_msg2("Select returns <%d>\n",ret_select);
#endif
if (ret_select==0) return -1;
return(my_write(fd,s,l));
}
static int write_remote(s,l)
char *s;
int l;
{
int lg= -1;
if (shell_pid!= -1) {
if ((lg=write_secure(pipe_in[1],s,l))== -1) {
kill_remote_shell();
}
}
#ifdef DEBUG1
trace_msg2("Write_Remote returns <%d>\n",lg);
#endif
return lg;
}
/* To send a signal to the Remote Shell */
int signal_to_remote_shell(sig)
int sig;
{
return (shell_pid == -1)?-2:killpg(shell_pid,sig);
}
/* To get the masks for expected fd */
/* to be read from the Remote Shell */
/* Useful for a select in the caller */
int set_remote_shell_masks_rw(mask_r,mask_w)
fd_set *mask_r;
fd_set *mask_w;
{
if (shell_pid!= -1) {
if (mask_r) {
if (!eof_out) {
FD_SET(pipe_out[0],mask_r);
}
if (!eof_err) {
FD_SET(pipe_err[0],mask_r);
}
}
if (mask_w) {
FD_SET(pipe_in[1],mask_w);
}
}
}
int is_it_remote_shell_read(mask)
fd_set *mask;
{
if (shell_pid!= -1)
return ( FD_ISSET(pipe_out[0],mask) ||
FD_ISSET(pipe_err[0],mask)
);
else return (FALSE);
}
/* Let's look at the Remote Shell's answer */
int read_remote_shell(mask,out_fct,err_fct,fin,fout)
fd_set *mask;
PFRI out_fct,err_fct;
int fin,fout;
{
#define MAX_SIZE_BUFFER 1000
static char buffer[MAX_SIZE_BUFFER];
int lg_buffer;
PFRI where_to_write;
int what_to_read;
int *what_eof;
#ifdef DEBUG1
trace_msg("Entering Read_Remote_Shell\n");
#endif
if (shell_pid!= -1) {
/* Is it a stdout or stderr message or an error */
if (FD_ISSET(pipe_err[0],mask)) { /* err */
where_to_write=err_fct;
what_to_read=pipe_err[0];
what_eof= &eof_err;
} else if (FD_ISSET(pipe_out[0],mask)) { /* out */
where_to_write=out_fct;
what_to_read=pipe_out[0];
what_eof= &eof_out;
} else { /* ??? */
where_to_write=NULL_FCT;
what_to_read= -1;
what_eof=(int *)NULL;
}
if (where_to_write==NULL_FCT) {
kill_remote_shell();
return -1;
} else {
lg_buffer=my_read(what_to_read,buffer,MAX_SIZE_BUFFER);
if (lg_buffer== -1) {
#ifdef DEBUG1
trace_msg("Read Failed\n");
#endif
kill_remote_shell();
return -1;
} else if (lg_buffer==0) {
/* EOF */
#ifdef DEBUG1
trace_msg("Read EOF\n");
#endif
*what_eof=TRUE;
return 0;
} else {
#ifdef DEBUG1
trace_msg2("Read <%d> Characters\n",lg_buffer);
#endif
(*where_to_write)(fin,fout,buffer,lg_buffer);
#ifdef DEBUG1
trace_msg("Where_To_Write Done\n");
#endif
return lg_buffer;
}
}
} else {
return -1;
}
#undef MAX_SIZE_BUFFER
}
static jmp_buf env_sig_pipe;
static void fct_sig_pipe() {
#ifdef DEBUG1
trace_msg("INTERRUPTED (SIGPIPE)\n");
#endif
longjmp(env_sig_pipe,1);
}
/* To feed the Remote Shell with an input */
int some_input_to_remote_shell(new_command,s,init_done)
int new_command;
char *s;
int *init_done;
{
PFRV old_fct_sig_pipe;
fd_set mask_w;
struct timeval t;
t.tv_sec=0;
t.tv_usec=1000;
FD_ZERO(&mask_w);
FD_SET(pipe_in[1],&mask_w);
if (init_done) *init_done=FALSE;
(void)wait_pid(shell_pid);
if ((shell_pid != -1) && (new_command)) {
/* Is the shell still THERE? */
if (kill(shell_pid,SIGINT) == -1) {
kill_remote_shell();
}
}
if (shell_pid== -1) {
if (init_remote_shell()== -1) {
raz_remote_shell();
return -1;
} else if (init_done) *init_done=TRUE;
}
if (shell_pid != -1) {
if (setjmp(env_sig_pipe)) {
#ifdef DEBUG1
trace_msg("Entering SIGPIPE Env\n");
#endif
kill_remote_shell();
if (init_remote_shell()==-1) {
raz_remote_shell();
return -1;
} else if (init_done) *init_done=TRUE;
(void)signal(SIGPIPE,old_fct_sig_pipe);
} else {
#ifdef DEBUG1
trace_msg("Env for SIGPIPE set\n");
#endif
old_fct_sig_pipe = (PFRV)signal(SIGPIPE,fct_sig_pipe);
}
}
if (write_remote(s,strlen(s))== -1) {
#ifdef DEBUG1
trace_msg2("Write Remote <%s> Failed\n",s);
#endif
old_fct_sig_pipe = (PFRV)signal(SIGPIPE,fct_sig_pipe);
return -1;
} else {
#ifdef DEBUG1
trace_msg2("Write Remote <%s> Succeeded\n",s);
#endif
old_fct_sig_pipe = (PFRV)signal(SIGPIPE,fct_sig_pipe);
return 0;
}
}
int get_status(status) int *status;
{
char c;
int i,l,res;
int minus=FALSE;
#define ECHO_STATUS "echo $exit_status\n"
#define BUFFER_SIZE 10
char buffer[BUFFER_SIZE];
*status = res = 0;
if (is_nilshell()) return (0);
if (write_remote(ECHO_STATUS,strlen(ECHO_STATUS)) == -1) return errno;
if ((l = read(pipe_out[0],buffer,BUFFER_SIZE)) <= 0) return errno;
if (buffer[0]=='-') minus=TRUE;
for (i = minus?1:0 ; i < l ; i++) {
c = buffer[i];
if (c < '0') break;
if (c > '9') break;
res *= 10;
res += (c - '0');
}
*status = minus?-res:res;
return (0);
}