DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400 Tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400 Tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T r

⟦5d5c7165d⟧ TextFile

    Length: 8499 (0x2133)
    Types: TextFile
    Names: »remote_sh.c«

Derivation

└─⟦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« 

TextFile

#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);
}