From: zander@luke.atdiv.lanl.gov (Mark Zander)
Newsgroups: comp.os.vxworks
Subject: re: Executing shell scripts
Date: Thu, 28 Jan 93 12:20:31 MST
Organization: Lawrence Berkeley Laboratory, Berkeley CA
NNTP-Posting-Host: 128.3.112.16
Originator: daemon@vxw.ee.lbl.gov

Sorry it took so long, but I wanted to clear this before sending it.

Brian Quigley writes:

> I've got a need to execute a shell script from within a program I'm
> working on.  I figured I'd copy the startup shell script code since it
> does what I want.  Unfortunately, the code that I took from usrConfig.c
> does not behave the same when I put it my code.  The script does not execute.  
> 
> I've tried killing any existing shell before I start the new one. This
> doesn't seem to help.  Various messing with ioTaskSetStd, 
> shellOrigStdSet, and ioGlobalStdSet produce undesirable results.
> 
> Any hints would be appreciated.
> 
> Thanks.
> 
> (P.S. Hints for a Unix like "system()" call would also be appreciated.)

I've had a similar need to execute shell scripts from a unix shell.
The following code worked for that purpose.  I hope it can help you
as well.  Good luck!

/*	r s h d . c
*
*************************************************************************
*
*				L O S   A L A M O S
*			Los Alamos National Laboratory
*			 Los Alamos, New Mexico 87545
*
*	File Name:			rshd.c
*	Environment:		VxWorks V4.0
*	Developement:		Sun C, Sun OS 4.0, Sun 3/60
*	Make Description:
*
*
*	Modification History
*	------------ -------
*
*	Date		Programmer		Comments
*	----		----------		--------
*
*	1-Jun-90	Mark Zander		Borrowed from telnetLib
*
*************************************************************************
*/

/*
*       Source Code Control System Identifier
*/
static char SccsId[ ] = "@(#)rshd.c	1.1    11/20/91";
/*
*************************************************************************
*++
*	Name
*	----
*
*>>	rshd	- remote shell daemon for vxWorks
*
*	Purpose
*	-------
*
*
*	Subroutine List
*	---------- ----
*
*	rshInit		- initialize remote shell daemon
*	rshd		- remote shell daemon
*
*	Include Files
*	------- -----
*
*
*
*	See Also
*	--- ----
*
*
*--
*************************************************************************
*/
#include	"vxWorks.h"
#include	"types.h"
#include	"socket.h"
#include	"in.h"
#include	"ioLib.h"
#include	"taskLib.h"

/* login       513/tcp */
/* shell       514/tcp     cmd     # no passwords used */

#define		RSH_SERVICE			514				/* shell port number */

#define		STDIN_BUF_SIZE		512

static int	rshTaskOptions		= VX_SUPERVISOR_MODE | VX_UNBREAKABLE;
static int	rshTaskStackSize	= 1500;
static int	rshTaskPriority		= 2;

int			rshdId;								/* task id of rshd task */

static char	*rshShellName		= "shell";

static char	*ptyRshName			= "/pty/rsh.";
static char	*ptyRshNameM		= "/pty/rsh.M";	/* master side */
static char	*ptyRshNameS		= "/pty/rsh.S";	/* slave side */

VOID rshd( );

/*
*************************************************************************
*+
*	Name
*	----
*
*>	rshInit		- initialize remote shell daemon
*
*	Purpose
*	-------
*
*	Remote shell initialize.
*
*	Calling Sequence
*	------- --------
*
*	rshInit( );
*
*-
*************************************************************************
*/
VOID rshInit( )

{
	static BOOL done = FALSE;	/* FALSE = not done */

	if ( done ) {
		printErr( "rshInit: already initialized.\n" );
		return;
	}

	if ( ptyDrv( ) == ERROR ||
			ptyDevCreate( ptyRshName, 1024, 1024 ) == ERROR ) {
		printErr ("rshInit: unable to create pty device.\n");
		return;
	}

	rshdId = taskSpawn( "rshd", rshTaskPriority,
						rshTaskOptions, rshTaskStackSize,
						rshd, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );  

	if ( rshdId == ERROR ) {
		printErr( "rshInit: unable to spawn rshd.\n" );
	} else {
		done = TRUE;
	}
}

/*
*************************************************************************
*+
*	Name
*	----
*
*>	rshd		- remote shell daemon
*
*	Purpose
*	-------
*
*	Remote shell daemon.  Similar to telnetd.  Executes a shell command sent
*	via the shell socket from another machine.  Does not redirect input or
*	output of the given command and for this reason requires a special version
*	of the unix rshell command.  Started from routine "rshInit".
*
*	Calling Sequence
*	------- --------
*
*	rshd( );
*-
*************************************************************************
*/
VOID rshd( )

{
	int					optval;
	struct sockaddr_in	myAddress;
	struct sockaddr_in	clientAddress;
	int					clientAddrLen;
	int					client;
	int					masterFd;
	int					slaveFd;
	int					sd;
    char				buf[ STDIN_BUF_SIZE ];
	int					n;
	int					shellInFd;
/*
*	Open a socket and wait for a client
*/
	sd = socket( AF_INET, SOCK_STREAM, 0 );
   
	bzero( (char *) &myAddress, sizeof( myAddress ) );
	myAddress.sin_family = AF_INET;
	myAddress.sin_port   = RSH_SERVICE;

	if ( bind( sd, (struct sockaddr *) &myAddress, sizeof( myAddress ) )
			== ERROR ) {
		printErr( "rshd: bind failed.\n" );
		return;
	}

	listen( sd, 5 );

	FOREVER {
/*
*	Wait for shell to exist
*/
		while ( taskNameToId( rshShellName ) == ERROR ) {
			taskDelay( sysClkRateGet( ) );
		}
		errnoSet( OK );		/* clear errno for pretty i() display */
/*
*	Now accept connection
*/
		clientAddrLen = sizeof( clientAddress );
		client = accept( sd, (struct sockaddr *) &clientAddress, &clientAddrLen );

		if ( client == ERROR ) {
			printErr( "rshd: accept failed - status = 0x%x\n", errnoGet( ) );
			continue;
		}
/*
*	create the pseudo terminal:
*		the master side is connected to the socket to the remote machine
*/

		if ( ( masterFd = open( ptyRshNameM, WRITE ) ) == ERROR ) {
			char *msg = "\r\nSorry, trouble with pty.\r\n";

			printErr( "rshd: error opening %s\n", ptyRshNameM );
			write( client, msg, strlen( msg ) );
			close( client );
			continue;
		}

		if ( ( slaveFd = open( ptyRshNameS, READ ) ) == ERROR ) {
			char *msg = "\r\nSorry, trouble with pty.\r\n";

			printErr( "rshd: error opening %s\n", ptyRshNameS );
			write( client, msg, strlen( msg ) );
			close( client );
			close( masterFd );
			continue;
		}
/*
*	Set up slave
*/
		ioctl( slaveFd, FIOOPTIONS, OPT_RAW );
		ioctl( slaveFd, FIOFLUSH );
/*
*	Save original standard in of shell
*/
		shellInFd  = ioGlobalStdGet( STD_IN );
/*
*	Redirect standard in of shell
*/
		shellOrigStdSet( STD_IN, slaveFd );
/*
*	Restart shell so it'll accept this command
*/
		taskRestart( taskNameToId( rshShellName ) );
/*
*	Get command form remote host and send it to shell
*/
		if ( ( n = read( client, buf, sizeof( buf ) ) ) > 0 ) {
			buf[n] = 0;
			write( masterFd, buf, n );
		}
/*
*	Set shell back to orginal standard in
*/
		shellOrigStdSet( STD_IN, shellInFd );
/*
*	Close connections to shell and remote host
*/
		close( masterFd );
		close( slaveFd );
		close( client );
	}
}


/*	v s h . c
*
*************************************************************************
*
*				L O S   A L A M O S
*			Los Alamos National Laboratory
*			 Los Alamos, New Mexico 87545
*
*	File Name:			vsh.c
*	Environment:		VxWorks V4.0
*	Developement:		Sun C, Sun OS 4.0, Sun 3/60
*	Make Description:
*
*
*	Modification History
*	------------ -------
*
*	Date		Programmer		Comments
*	----		----------		--------
*
*	4-Jun-90	Mark Zander		Original
*	21-Nov-91	me				change name from rsh to vsh to avoid name
*								clashes
*
*************************************************************************
*/

/*
*************************************************************************
*+
*	Name
*	----
*
*>	vsh		- execute remote shell command on a vxWorks system
*
*	Purpose
*	-------
*
*	Executes a remote shell command for a vxWorks system.  Sends one command
*	over the shell socket.  Is similar to the unix rsh command but does not
*	redirect stdin and stdout.
*
*	Command
*	-------
*
*	% vsh hostname cmd
*
*	or
*
*	% vsh
*	Host name? hostname
*	Command? cmd
*
*	Arguments
*	---------
*
*	hostname	name of host listed in yp directory
*	cmd			remote command to be executed
*
*	Example
*	-------
*
*
*	Special Comments
*	------- --------
*
*
*	See Also
*	--- ----
*
*
*-
*************************************************************************
*/
#include <string.h>

#define		RSH_SERVICE			514				/* shell port number */
/*
*	Source Code Control System Identifier
*/
static char SccsId[ ] = "@(#)vsh.c	1.3    11/21/91";

void main(argc, argv)
/*
*	Arguments
*/
	int			argc;				/* command line argument count */
	char		**argv;				/* command line arguments */
{
/*
*	Variables
*/
	int			argin;				/* argument index */
	char		hostname[100];		/* host name */
	char		cmd[300];			/* remote command */
	int			sock;				/* socket */
	int			i;					/* iteration counter */

	argin = 1;
	getarg("Host name? ", argc, argv, &argin, hostname);
	getarg("Command? ", argc, argv, &argin, cmd);
	for (i = argin; i < argc; i++) {
		strcat(cmd, " ");
		strcat(cmd, argv[i]);
	}
	strcat(cmd, "\n");
	sock = socClient(hostname, RSH_SERVICE);
	write(sock, cmd, strlen(cmd));
	close(sock);
}