| Mike,
I agree it would be nice if DEC would ship something that was sanctioned as
a supported DECnet mechanism for starting remote applications. What we've seen
here in the ACT is White Pine Software, has cloned the PCX$SERVER launching code
to start their remote applications from the MACintosh Xserver. Because it is
compatible with the PCX$SERVER code, it means you don't need to have 16 diff-
erent remote launching programs on each client machine in order to support
each application with its remote launching capabilities. I'm hoping that APPLE
will use the same syntax for remote launching with MAC-X.
Using DECnet, this feature is a "piece of cake". It's a bit tougher *from*
a Ultrix node, but not impossible. I think there is a note buried somewhere here
on a sample piece of code for starting remote apps from an ULTRIX node.
If you're on a VMS node, then you can mimic what the PC does with a simple
procedure like the one below:
All the pcx$server code wants is a string in a format like this:
49.761,DECW$MAIL REMOTE_NODE
...where 49.761 is the node of the Xserver, and DEC$mail is the application to
be run, on node REMOTE_NODE.
If someone could post similar code for ULTRIX-DECnet, it would be useful
for the ACTs/Demo centers
Cheers,
-Ken
-------------------------------------------------------------------------------
$! PCX.COM
$!
$! P1 should look like "destination_node_address,application"
$! P2, if supplied, is the host node running the client
$!
$ if p1 .eqs. "" then exit
$ if P2 .eqs. "" then inquire p2 "Remote node"
$ say:==write sys$output
$ Open/Write/Error=NET_ERROR X_NET 'p2'::"0=pcx$server"
$ Write/Error=NET_ERROR X_NET p1
$ Read/error=NET_ERROR X_NET pcx_mess
$ if pcx_mess .nes. "OK" then goto DEST_ERROR
$ SAY " Job ", p1, " started via DECnet to ", P2, "::"
$NET_FINISH:
$ Close/Error=FINISH X_NET
$
$FINISH:
$ Exit
$
$NET_ERROR:
$ ERR = $STATUS
$ SAY "% Network error connecting to ", P2, "::"
$ SAY f$message(ERR)
$ Goto NET_FINISH
$
$DEST_ERROR:
$ SAY "Remote node had trouble with the application requested: ", pcx_mess
$ Goto NET_FINISH
|
|
/*
This is the code used for ULTRIX...
just compile it and point to it with the DECnet object...we use PCX$SERVER as
the object name.
PC DECwindows distributes the executable form for VAX and DECstation.
We do plan to either ship the source or make this a shell script for our
next release. We also plan on extending the protocol to include other
parameters such as:
X11 protocol level, screen number, server number and transport
We already have it running with TCP/IP by using an Internet port instead of
a DECnet object. I will post that version when ready...
We are working closely with the MAC group here in PCSG (where they seem
to have control of remote startup for the MAC/X application.
*/
/* cc -o pcx_server.exe pcx_server.c -ldnet */
/************************************************************************
*
* MODULE: PCX_SERVER.C
*
* VERSION: X1.0-002
*
* ABSTRACT: This program gets executed when a remote PC (a DECwindows
* server) connects to an ULTRIX node and issues commands.
* The purpose of this program is for remote startup capability.
*
* AUTHOR: Michael J. Pfeffer
*
* CREATED: 31-MAR-1988
*
* CHANGE HISTORY:
*
* MJP001 9-AUG-1988 Modified so that @run is no longer needed.
* This is now the only file needed for remote
* startup on ULTRIX systems
*
* JGP002 25-NOV-1988 General Cleanup
*
* MJP003 30-NOV-1988 Add in checking for existance of file
* and checking if file is executable.
*
* JGP004 23-Jan-1989 Check for program before searching path
*
* JGP004 8-Feb-1989 Redirect stdin, stdout, stderr to /dev/null
************************************************************************/
/*
* Copyright (C) 1985, 1988 by
* Digital Equipment Corporation, Maynard, Mass.
*
* This software is furnished under a license and may be used and copied
* only in accordance with the terms of such license and with the
* inclusion of the above copyright notice. This software or any other
* copies thereof may not be provided or otherwise made available to any
* other person. No title to and ownership of the software is hereby
* transferred.
*
* The information in this software is subject to change without notice
* and should not be construed as a commitment by Digital Equipment
* Corporation.
*
* Digital assumes no responsibility for the use or reliability of its
* software on equipment which is not supplied by Digital.
*
*/
#include <stdio.h> /* standard i/o defintions */
#include <strings.h> /* string library definitions */
#include <sys/types.h> /* MJP */
#include <sys/stat.h> /* MJP */
#include <sys/file.h>
#define BUFF_SIZE 1024 /* buffer size */
char application[BUFF_SIZE]; /* MJP */
char command[BUFF_SIZE]; /* command buffer */
char buff[BUFF_SIZE + 1]; /* buffer read/writing */
char *exec_argv[] = {"/bin/sh", "-c", NULL, NULL};
char setenviron[100] = "DISPLAY=";
char **exec_arge;
char *env[100];
int env_index;
int dis_index = -1;
int path_index = -1;
main(argc, argv, arge)
int argc;
char *argv[];
char *arge[];
{
char *cp;
char *getenv();
seteuid(getuid()); /* don't run under set-uid */
/*
* save our shell name, and environment
*/
if (cp = getenv("SHELL"))
exec_argv[0] = cp;
env_index = 0;
while (arge[env_index])
{
env[env_index] = arge[env_index];
if (strncmp(env[env_index], "DISPLAY=", 8) == 0)
dis_index = env_index;
/* MJP */
if (strncmp(env[env_index], "PATH=", 5) == 0)
path_index = env_index;
env_index++;
}
exec_arge = arge; /* save environment commands */
pcx_server();
exit(0);
}
pcx_server()
{
char *cp;
char c;
int len;
/*
* get a command from our partner, and give it to the shell
*/
len = read(0, buff, sizeof(buff));
if (len == 0)
{
if (dnet_eof(0))
exit();
}
buff[len] = '\0';
cp = &(buff[0]);
while (*cp != ',') cp++;
*cp = '\0';
strcat(&setenviron[0], &buff[0]);
cp++;
/* this is the environment variable */
strcat(&setenviron[0], "::0");
/* putenv(setenviron); */
if (dis_index != -1)
env[dis_index] = setenviron;
else {
env[env_index] = setenviron;
env[++env_index] = 0;
}
sprintf(command, "(%s)", cp);
exec_argv[2] = command; /* application */
sscanf(cp, "%s", application);
/* MJP - check for file existence and executable type */
{
int cp_count;
char *ecp;
char *cp;
char path_string[256];
struct stat buf;
int retval;
int in, out, err;
if ((application[0] == '/') || (application[0] == '~'))
{
retval = stat(path_string, &buf);
}
else
{
if (path_index != -1)
{
cp = env[path_index];
cp = cp + 5;
while (*cp != '\0')
{
cp_count = 0;
ecp = cp;
while ((*cp != ':') && (*cp != '\0'))
{
cp_count++;
cp++;
}
strncpy(path_string, &ecp[0], cp_count);
path_string[cp_count] = '\0';
strcat(path_string, "/");
strcat(path_string, application);
retval = stat(path_string, &buf);
if (retval==0)
break;
cp++;
} /* end of while loop */
}
}
if ((retval==0) && ((S_IEXEC & buf.st_mode) == S_IEXEC))
{
write (0, "OK", 2);
}
else
{
write (0, "File not found", 14);
exit(1);
}
/*
* start up a shell, to execute the command
*/
close(0);
close(1);
close(2);
in = open("/dev/null", O_RDONLY|O_NDELAY);
out = open("/dev/null", O_WRONLY|O_NDELAY);
err = open("/dev/null", O_WRONLY|O_NDELAY);
dup2(in, 0);
dup2(out, 1);
dup2(err, 2);
execve(exec_argv[0], exec_argv, env);
}
}
|
| $ !
$ !
$ !
$ set noverify
$ !************************************************************************
$ ! *
$ ! PCX$SERVER.COM (Written by M. PFEFFER - 18-MAR 1988) *
$ ! *
$ ! Version 2.0 for PC DECwindows Display Facility 2.0 (23-SEP-1989) *
$ ! *
$ ! The purpose of this file is for Remote Startup of DECwindows clients. *
$ ! This .COM file will be executed when a server connects to object *
$ ! named: PCX$SERVER, number 0. *
$ ! *
$ !************************************************************************
$!
$!
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$! First check for DECNET username and disallow:
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$ IF f$edit(f$getjpi("", "USERNAME"), "COLLAPSE") .EQS. "DECNET" THEN exit
$ ON warning THEN goto security_risk
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$! Open the connection and redirect output
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$ ON error THEN goto shutdown
$ open/read/write pcx_server_link sys$net
$ set noon
$ purge/keep=3 netserver.log
$ is_DCL = 0
$ version53 = 0
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$! Read a command from the server
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$ read /end_of_file=shutdown /error=shutdown pcx_server_link cmd_string
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$! Parse the command string
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$ node = f$element(0, "," , cmd_string) ! Node name
$ cmd = f$element(1, "," , cmd_string) ! Full Command
$ exe = f$element(0, " ", cmd) ! Name of program or command file
$ rest_of_cmd = f$locate(" ",cmd) ! Save the command-line parameters
$ params = f$extract( rest_of_cmd, f$length(cmd), cmd)
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$! Check for DCL command
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$ dollar = f$locate("$", cmd)
$ IF dollar .eq. 0
$ THEN
$ is_DCL = 1
$ runfile = f$element(1, "$", cmd)
$ goto runit
$ ENDIF
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$! Check for COM file
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$ IF f$locate(".COM", f$edit(cmd, "UPCASE")) .lt. f$length(cmd)
$ THEN
$ comfile :== 'f$parse(exe, "", "sys$login:")
$ IF f$search(comfile) .EQS. ""
$ THEN
$ comfile :== 'f$parse(exe, "", "sys$system:")
$ if f$search(comfile) .EQS. "" THEN goto notfound
$ ENDIF
$ runfile :== @'comfile''params'
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$! We have an exe file, append .exe and search in login directory
$! and sys$system directory for file.
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$ ELSE
$ runfile :== 'f$parse(exe,".EXE","sys$login:")
$ IF f$search(runfile) .EQS. ""
$ THEN
$ runfile :== 'f$parse(exe,".EXE","sys$system:")
$ IF f$search(runfile) .EQS. "" THEN goto notfound
$ ENDIF
$ runfile :== $'runfile''params'
$ ENDIF
$ GOTO runit
$!
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$!
$! File not found error handler
$!
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$notfound:
$ write pcx_server_link "NOT FOUND"
$ close pcx_server_link
$ exit
$!
$runit:
$!
$ SET noon
$ DEF sys$error sys$output
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$! Parse the node name from the x.yyy format into xxxxx::
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$ area = f$element(0, ".", NODE)
$ address = f$element(1, ".", NODE)
$ node_name = area * 1024 + address
$ def decw$display 'node_name::0.0
$ set display /create /node='node_name
$ ON error THEN goto kill_display
$ SHOW DISPLAY
$ write pcx_server_link "OK"
$ close pcx_server_link
$ write sys$output "PCX$SERVER_MSG: Starting the following application:"
$ write sys$output ''runfile
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$! Special case for DECterm terminal emulator
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$ vmsversion = F$GETSYI("VERSION")
$ version_number = F$EXTRACT(1,3,vmsversion)
$ IF version_number .GES. "5.3" THEN version53 = 1
$!
$!
$ IF f$edit( f$parse(exe,,,"name","syntax_only"),"UPCASE") -
.EQS. "DECW$TERMINAL" THEN goto decterm_handler
$!
$ IF is_DCL .EQS. 1
$ THEN
$ 'runfile
$ ELSE
$ runfile
$ ENDIF
$ GOTO good_bye
$!
$decterm_handler:
$ IF version53 .EQS. 1
$ THEN
$ ''create/terminal/detach'
$ goto good_bye
$ ELSE
$! old decterm creation method - yuch!!!
$ parent_proc = f$process()
$ front = f$extract(0,4,parent_proc)
$ back = f$extract(9,10,parent_proc)
$ decterm_proc :== "''front'TERM''back'"
$ spawn/nowait/process='decterm_proc' run sys$system:decw$terminal.exe
$ runfile :== $sys$system:decw$mail_createDecterm.exe
$ runfile
$! check the decnet link, stay active until link is dropped
$ wait 00:00:30
$ assign/user 'decterm_proc'1.lis sys$output
$ mcr ncp show known links with node 'node
$ assign /user 'decterm_proc'2.lis sys$output
$ search 'decterm_proc'1.lis 'node
$ open linkname 'decterm_proc'2.lis /error=nolink
$ loop:
$ read /end_of_file=endfile linkname thisone
$ if f$locate("''decterm_proc'", thisone) .eq. f$length(thisone) THEN goto loop
$ rightone = thisone
$ endfile:
$ close linkname
$ nolink:
$ delete 'decterm_proc'1.lis;,'decterm_proc'2.lis;
$ rightone = f$edit(rightone,"TRIM,COMPRESS")
$ show symbol rightone
$ IF .not $status THEN goto good_bye
$! Loop, looking for connection to be terminated
$ linknumber = f$element(0," ",rightone)
$ islinkthere:
$ wait 00:07:00
$ mcr ncp show link 'linknumber'
$ IF $status THEN goto islinkthere
$ write sys$output "Link has gone away"
$ goto good_bye
$ ENDIF
$!
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$! Shutdown connection
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$good_bye:
$ IF version53 .EQS. 1
$ THEN
$ set display/delete
$ ELSE
$ set display/noperm
$ ENDIF
$ exit
$kill_display:
$ IF version53 .EQS. 1
$ THEN
$ set display/delete
$ ELSE
$ set display/noperm
$ ENDIF
$shutdown:
$ close pcx_server_link
$ exit
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$! Security_risk (error occured, write a message and exit)
$!
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$!
$security_risk:
$ write sys$output "PCX$SERVER_MSG: Error connecting to node (not allowed to LOGIN as DECNET)"
$ exit
$!
$!
|