~TELL.BCKeTELL.BCKBACKUP *.* [-]TELL.BCK/SAVE KINGSMILL ޛV6.2 _YAKKA::  _YAKKA$DKA300: V6.2 ~ %*[KINGSMILL.TEMP]FREEWARE_README.TXT;1+,F./ 4N-0123KPWO56m *۹789GHJ7TELL, UTILITIES, Issues DCL commands on remote machines? This command procedure will execute commands on a remote node." The command syntax for tell is :-> @TELL[/output=filename] NODENAME[,...] DCL-COMMAND [&] [|...] P1 - NODENAME:M More than one nodename can be specified, each being seperated by a comma.N Nodename can also be a symbol and the double colon (::) after the nodename is optional.2 "0" can be used to specify the local nodename.H If you do not have proxy access then you can specify access control 9 information as part of the nodename specification. A You can force a routing path by specifiy nodename of the from nodename::nodename::N If two or more nodenames are specified then on completion TELL displays a K summary listing of unreachable nodes. This feature can be disabled by, defining the logical name as follows:-6 $ DEFINE/PROCESS/NOLOG TELL_INHIBIT_SUMMARY TRUE P2 to P8 - DCL COMMAND: INTERACTIVE MODE:J If no DCL command is specified then you will be in interactive mode.L At that point you will have a DCL session in the context of the remoteK node. The standard EXIT command will return you to your local node. COMMAND MODE:H Here the DCL commands are specified in P2 to P8 and are separated I by a vertical bar "|". Quotes are optional and are only required to( reduce the number of P parameters. DETACHED MODE:A Jobs can be run in the background as a detached process by ? suffixing the & (unix background command) to any command.? This can be done from either Interactive or Command Mode.L Note that you cannot issue commands that require terminal input such as L EDIT etc. This is a restriction of the DECnet task-task software and notK of TELL itself. Some of these restrictions can be overcome by defining N the verb as a foreign command. This allows many commands to be entered on  a single line.& eg. $ AUTHORIZE :== $AUTHORIZE& $ AUTHORIZE SHOW KINGSMILL  QUALIFIERS:; /Output can be used to direct the output to a filename. EXAMPLES:# $ TELL :== @SYS$MANAGER:TELL.COMJ All the following examples assume that the tell symbol is defined.% Place this in your login.com. $ TELL MVAX SHOW ERROR5 This command relies on proxy access to MVAX. 2 It does a remote $show error on node MVAX.3 $ TELL/OUTPUT=SYS$LOGIN:TELL.OUT MVAX SHOW ERROR5 This command relies on proxy access to MVAX. A It does a remote $show error on node MVAX with the output2 directed to the file sys$login:tell.out/ $ TELL MVAX"KINGSMILL PASSWORD":: SHOW ERRORJ this command supplies access control to accounts that do not have  proxy access& $ TELL MVAX"KINGSMILL":: SHOW ERRORM Under VMS V5.x you can have a number of different proxy users pointedM to one account. This example show how to gain access to a non-defaultI proxy account. Note that only the username needs to be specified.# $ TELL MVAX,TVAX,SVAX SHOW ERRORA this command will do a show error on MVAX, TVAX and SVAX.$ $ DECA_CLUSTER :== MVAX,TVAX,SVAX# $ TELL 'DECA_CLUSTER' SHOW ERRORA this command will do a show error on MVAX, TVAX and SVAX.+ $ TELL MVAX,TVAX "SHOW ERROR"|"SHOW NET"K this command will do both a show error and a show net on both MVAX  and TVAX.F $ TELL MVAX,TVAX "SET DISPLAY/CREATE/NODE=MAXPS1" | "CREATE/TERM &"I this command will create a detached decterm on both MVAX and TVAX $ TELL MVAX MVAX_KINGSMILL>> SHOW ERROR& MVAX_KINGSMILL>> SET PROC/PRIV=OPER% MVAX_KINGSMILL>> MCR NCP SHOW EXEC MVAX_KINGSMILL>> EXIT $J This is an example of an interactive session. The prompt indicatesD the remote nodename and username, whilst the ">>" is used to8 distinguish between a local and remote session.  # $ TELL MVAX TELL TVAX SHOW ERROR! $ TELL MVAX::TVAX:: SHOW ERROR: Both of these commands perform the same function. I The first performs a nested TELL, ie. TELL node MVAX to TELL nodeE TVAX to do a $ show error. Only command mode is valid with I this syntax and you must specify the command as TELL not @tell.H The second example show how to do the same thing using Poor MansJ Routing (PMR). This is far more efficent than the first examples= and it supports both command and interactive modes. CONFIGURATION SETUPS:H TELL.COM needs to exist on both the local and remote nodes and requiresJ the user to either specify node access control or for the remote account J to be set up for proxy access. TELL can simply reside in sys$login on theG remote node, which requires each user to have their own copy -or- TELLK can be defined as a DECnet object, requiring each system to have only one  copy.H To install TELL as a network object the system manager should enter the following commands: $ MCR NCPG NCP> DEFINE OBJECT TELL NUMBER 0 FILE SYS$MANAGER:TELL.COM PROXY BOTH NCP> SET OBJECT TELL ALL NCP> EXIT $M If TELL is not installed as a network object then by default no other setupsM are required. However if the DECnet object task has been modified to disableJ proxy access then tell will fail. In this case the system manager should  enter the following commands: $ MCR NCP$ NCP> DEFINE OBJECT TASK PROXY BOTH NCP> SET OBJECT TASK ALL NCP> EXIT $E PROXY accounts allow one user direct access to another users accountE without having to specify username and password. The system manager9 can set up proxy account access from within AUTHORIZE.  Example: $ MCR AUTHORIZE>< UAF> ADD/PROXY MVAX::KINGSMILL KINGSMILL/DEFAULT1 UAF> ADD/PROXY MVAX::OLSENK KINGSMILL UAF> EXIT $D This examples allows remote user KINGSMILL and OLSENK on node MVAXE into the local KINGSMILL account. The default switch enables you to7 specify just the nodename when addressing this node:- eg. $ DIRECTORY TVAX::B If Default access is not specified then you need to specify the 3 nodename and username when addressing this node:-% eg. $ DIRECTORY TVAX"KINGSMILL"::> If you do not have proxy access then you need to specify theA nodename, username and password when addressing a remote node:-. eg. $ DIRECTORY TVAX"KINGSMILL password"::I The following logicals can be used to alter the default TELL behaviour.: TELL_INHIBIT_SUMMARY to disable the statistics printout. TROUBLESHOOTING:@ The following logicals can be used to aid in troubleshooting.H TELL_VERBOSE to display the progress of both local and remote events.K This can also be enabled by setting the version prefix from "V" to "X"- TELL_VERIFY to turn on verify and verbose.D NETSERVER.LOG on the remote node may also aid in troubleshooting.F TELL_'pid'*.COM temporary file on the remote node shows the created6 command file if detached qualifier was specified.C TELL.LOG temporary file on on the remote node showing the output from tell_'pid'.com*[KINGSMILL.TEMP]TELL.COM;2+,.8/ 4[85V-0123KPWO656B¥7B֔89GHJ\ $!TELL.COM&$ vb=f$verify(f$trnlnm("tell_verify"))$ version := V3.0$!($! AUTHOR: kingsmill@ripper.enet.dec.comM$! Version 1.1 Geoff Kingsmill - fixed a number of bugs and added a summary )$! report.E$! Version 2.0 Geoff Kingsmill - added an interactive mode and made *$! modifications to preserve quotes. 3$! Unfortunaly this version is not compatible 5$! with version 1.x. To overcome this problem in2$! the future a version check has been added.A$! Version 2.1 Geoff Kingsmill - modified to enable nested tell.I$! Version 3.0 Geoff Kingsmill - modified to allow remote jobs to run in0$! batch mode. This is done by adding (the 2$! unix qualifier) & to the end of a command.$!P$!------------------------------------------------------------------------------$!C$! TELL is supported on VMS 4.7 and greater. (yuk! no if-then-else)$!A$! This command procedure will execute commands on a remote node.$!K$! This file needs to exist on both the local and remote nodes and requiresO$! the user to either specify node access control or for the remote account to I$! be set up for proxy access. TELL can simply reside in sys$login on theI$! remote node, which requires each user to have their own copy -or- TELLM$! can be defined as a DECnet object, requiring each system to have only one $! copy.$!J$! To install TELL as a network object the system manager should enter the$! following commands: $! $ MCR NCPI$! NCP> DEFINE OBJECT TELL NUMBER 0 FILE SYS$MANAGER:TELL.COM PROXY BOTH$! NCP> SET OBJECT TELL ALL $! NCP> EXIT$! $$!O$! If TELL is not installed as a network object then by default no other setupsO$! are required. However if the DECnet object task has been modified to disableL$! proxy access then tell will fail. In this case the system manager should $! enter the following commands: $! $ MCR NCP&$! NCP> DEFINE OBJECT TASK PROXY BOTH$! NCP> SET OBJECT TASK ALL $! NCP> EXIT$! $$!G$! PROXY accounts allow one user direct access to another users accountG$! without having to specify username and password. The system manager;$! can set up proxy account access from within AUTHORIZE. $!$! Example: $ MCR AUTHORIZE>>$! UAF> ADD/PROXY MVAX::KINGSMILL KINGSMILL/DEFAULT3$! UAF> ADD/PROXY MVAX::OLSENK KINGSMILL$! UAF> EXIT$! $F$! This examples allows remote user KINGSMILL and OLSENK on node MVAXG$! into the local KINGSMILL account. The default switch enables you to9$! specify just the nodename when addressing this node:-$! eg. $ DIRECTORY TVAX::D$! If Default access is not specified then you need to specify the 5$! nodename and username when addressing this node:-'$! eg. $ DIRECTORY TVAX"KINGSMILL"::@$! If you do not have proxy access then you need to specify theC$! nodename, username and password when addressing a remote node:-0$! eg. $ DIRECTORY TVAX"KINGSMILL password"::$!$$! The command syntax for tell is :-@$! @TELL[/output=filename] NODENAME[,...] DCL-COMMAND [&] [|...]$!$! P1 - NODENAME:O$! More than one nodename can be specified, each being seperated by a comma.P$! Nodename can also be a symbol and the double colon (::) after the nodename$! is optional.4$! "0" can be used to specify the local nodename.J$! If you do not have proxy access then you can specify access control ;$! information as part of the nodename specification. C$! You can force a routing path by specifiy nodename of the from$! nodename::nodename::P$! If two or more nodenames are specified then on completion TELL displays a M$! summary listing of unreachable nodes. This feature can be disabled by.$! defining the logical name as follows:-8$! $ DEFINE/PROCESS/NOLOG TELL_INHIBIT_SUMMARY TRUE$!$! P2 to P8 - DCL COMMAND:$! INTERACTIVE MODE:L$! If no DCL command is specified then you will be in interactive mode.N$! At that point you will have a DCL session in the context of the remoteM$! node. The standard EXIT command will return you to your local node.$! COMMAND MODE:J$! Here the DCL commands are specified in P2 to P8 and are separated K$! by a vertical bar "|". Quotes are optional and are only required to*$! reduce the number of P parameters.$! DETACHED MODE:C$! Jobs can be run in the background as a detached process by A$! suffixing the & (unix background command) to any command.A$! This can be done from either Interactive or Command Mode.$!N$! Note that you cannot issue commands that require terminal input such as N$! EDIT etc. This is a restriction of the DECnet task-task software and notM$! of TELL itself. Some of these restrictions can be overcome by defining P$! the verb as a foreign command. This allows many commands to be entered on $! a single line.($! eg. $ AUTHORIZE :== $AUTHORIZE($! $ AUTHORIZE SHOW KINGSMILL$! $! QUALIFIERS:=$! /Output can be used to direct the output to a filename.$!$!$! EXAMPLES:$!%$! $ TELL :== @SYS$MANAGER:TELL.COML$! All the following examples assume that the tell symbol is defined.'$! Place this in your login.com.$!$! $ TELL MVAX SHOW ERROR7$! This command relies on proxy access to MVAX. 4$! It does a remote $show error on node MVAX.$!5$! $ TELL/OUTPUT=SYS$LOGIN:TELL.OUT MVAX SHOW ERROR7$! This command relies on proxy access to MVAX. C$! It does a remote $show error on node MVAX with the output4$! directed to the file sys$login:tell.out$!1$! $ TELL MVAX"KINGSMILL PASSWORD":: SHOW ERRORL$! this command supplies access control to accounts that do not have $! proxy access$!($! $ TELL MVAX"KINGSMILL":: SHOW ERRORO$! Under VMS V5.x you can have a number of different proxy users pointedO$! to one account. This example show how to gain access to a non-defaultK$! proxy account. Note that only the username needs to be specified.$!%$! $ TELL MVAX,TVAX,SVAX SHOW ERRORC$! this command will do a show error on MVAX, TVAX and SVAX.$!&$! $ DECA_CLUSTER :== MVAX,TVAX,SVAX%$! $ TELL 'DECA_CLUSTER' SHOW ERRORC$! this command will do a show error on MVAX, TVAX and SVAX.$!-$! $ TELL MVAX,TVAX "SHOW ERROR"|"SHOW NET"M$! this command will do both a show error and a show net on both MVAX $! and TVAX.$!H$! $ TELL MVAX,TVAX "SET DISPLAY/CREATE/NODE=MAXPS1" | "CREATE/TERM &"K$! this command will create a detached decterm on both MVAX and TVAX$!$! $ TELL MVAX $! MVAX_KINGSMILL>> SHOW ERROR($! MVAX_KINGSMILL>> SET PROC/PRIV=OPER'$! MVAX_KINGSMILL>> MCR NCP SHOW EXEC$! MVAX_KINGSMILL>> EXIT$! $L$! This is an example of an interactive session. The prompt indicatesF$! the remote nodename and username, whilst the ">>" is used to:$! distinguish between a local and remote session. $! %$! $ TELL MVAX TELL TVAX SHOW ERROR#$! $ TELL MVAX::TVAX:: SHOW ERROR<$! Both of these commands perform the same function. K$! The first performs a nested TELL, ie. TELL node MVAX to TELL nodeG$! TVAX to do a $ show error. Only command mode is valid with K$! this syntax and you must specify the command as TELL not @tell.J$! The second example show how to do the same thing using Poor MansL$! Routing (PMR). This is far more efficent than the first examples?$! and it supports both command and interactive modes.$!$! CONFIGURATION SETUPS:N$! The following logicals can be used to alter the default TELL behaviour.?$! TELL_INHIBIT_SUMMARY to disable the statistics printout.$!$! TROUBLESHOOTING:D$! The following logicals can be used to aid in troubleshooting.L$! TELL_VERBOSE to display the progress of both local and remote events.O$! This can also be enabled by setting the version prefix from "V" to "X"1$! TELL_VERIFY to turn on verify and verbose.H$! Netserver.log on the remote node may also aid in troubleshooting.J$! TELL_'pid'*.COM temporary file on the remote node shows the created:$! command file if detached qualifier was specified.G$! TELL.LOG temporary file on on the remote node showing the output$! from tell_'pid'.com$!P$!------------------------------------------------------------------------------$!O$! TELL_VERBOSE is used to display the progress of both local and remote events$!F$ verbose = f$trnlnm("tell_verbose") !verbose debug mode true or false8$! enable verbose if the current version is eXperimental;$ if f$extract(0,1,version) .eqs. "X" then verbose := true .$! enable verbose if verify has been turned on;$ if f$environment("verify_procedure") then verbose := true$!-$! define commonly used foreign commands here$!$ esc[0,8] = %x1b*$ bon = esc+"[1m" !turn on bold printing*$ boff = esc+"[0m" !turn off bold printing$ say := write sys$output$!I$! Define some commonly used System Manager commands as foreign to enable'$! them to be used in a single command.$!#$ install := $install/command_mode$ sysgen := $sysgen$ latcp := $latcp$ ncp := $ncp$ authorize := $authorize0$ tell := @'f$environment("procedure")'$+$ if f$trnlnm("sysuaf") .eqs. "" then -* define sysuaf sys$system:sysuaf.dat+$ if f$trnlnm("netproxy") .eqs. "" then -, define netproxy sys$system:netproxy.dat+$ if f$trnlnm("rightslist") .eqs. "" then -0 define rightslist sys$system:rightslist.dat$!1$! Find out who we are and who we're talking too.$!P$ remnode = f$extrac(0,f$locate("::",f$trnlnm("sys$net"))+2,f$trnlnm("sys$net"))!$ nodename = f$trnlnm("sys$node")$ node = nodename - "::"&$ cmdmode := true !assume command mode$!L$! If we are a network process (remote node) and we are not attempting to doI$! a nested tell (ie. tell_source logical not defined) then goto network.$!&$ if f$mode() .eqs. "NETWORK" .and. -D .not. f$trnlnm("tell_source",,,,,"terminal") then goto NETWORK$ $INTERACTIVE:$!>$! invoke this procedure to execute a command on a remote node$!,$ nodes = p1 !nodes to execute command onN$ command = P2+" "+P3+" "+P4+" "+P5+" "+P6+" "+P7+" "+P8 !command to execute$E$! nodename is a required parameter, request nodename if not supplied$ if nodes .eqs. "" then -B read/prompt="Nodes: "/end_of_file=loc_exit sys$command nodes 4$ if nodes .eqs. "" then nodes = tell_default_nodes $ nodes = f$edit(nodes,"upcase")$ $! initialize statistics symbolsJ$ tell_node_pcnt = 0 !the count on the number of nodes that were reachableL$ tell_node_fcnt = 0 !the count on the number of nodes that were unreachable<$ tell_node_plst = "" !the list of nodes that were reachable>$ tell_node_flst = "" !the list of nodes that were unreachable$ $ on control_y then goto loc_end$!2$! for each node in the list, execute each command$!$ found_nested_tell := false$ node_count = 0$LOC_PROCESS_ALL_NODES_LOOP:0$ on warning then goto loc_end !error handler3$ nested_tell := false !zero nested tell status($ node = f$element(node_count,",",nodes)<$ if node .eqs. "," then goto loc_end !last node completedM$ if f$extract(0,1,node) .eqs. "0" then - !translate node 0 to local nodename8 node = f$trnlnm("sys$node")-"::"+f$extract(1,255,node)($! ensure nodename has the colons suffixJ$ if f$extract(f$length(node)-2,2,node) .nes. "::" then node = node + "::"6$ sec_node = f$parse(node,,,"node") !secure password$!-$! start the server task on the remote node.O$! The TASK= command establishes a logical link from this machine to the node,K$! and defines the link name as SYS$NET for the remote task to establish a$! connection back to us. $!#$ say_rem := write tell_destination'$ on warning then goto loc_cleanup_fail$ say ""G$ say esc,"[1;4;7mEstablishing link to remote node ",sec_node,esc,"[0m"$ say ""4$ open/read/write tell_destination 'node'"task=tell"$P$!------------------------------------------------------------------------------$ cmd_count = 0$LOC_FLUSH_OUTPUT:$!K$! This section of code set's up a handshaking between the local and remoteL$! nodes. First we establish the %VERSION to handle any compatability issuesM$! between versions. The we find the remote version, nodename (to distinguishM$! cluster alias nodes) and username. Then we tell the remote node whether weL$! require verbose information (a step by step account of what's happening),K$! whether we're in command or interactive mode and finally the command to $! execute.$! K$! We we've done all commands for that node we close the network connection4$! and sequence through the remaining nodes (if any)$!$ read tell_destination record$$LOC_TRY_VERBOSE:6$ if record .nes. "%VERBOSE" then goto loc_try_versionO$ ! remode node is requesting whether we require a step by step account of what $ ! going on.$ say_rem verbose$ goto loc_flush_output$$LOC_TRY_VERSION:7$ if record .nes. "%VERSION" then goto loc_try_nodenameJ$ ! compare the local and remote versions of TELL. If a mistmatch is found-$ ! then give a warning message to the user. $ if verbose then say -A nodename," Requesting remote tell version on node ",sec_nodeA$ if verbose then say nodename," Local tell version is: ",version3$ if verbose then read tell_destination rem_message!$ if verbose then say rem_message#$ read tell_destination rem_version)$ if version .nes. rem_version then Say -1 bon,"WARNING, TELL version mismatch ",boff)$ if version .nes. rem_version then Say -I bon,"LOCAL VERSION: ",version," REMOTE VERSION: ",rem_version,boff*$ if version .nes. rem_version then Say ""$ goto loc_flush_output$$LOC_TRY_NODENAME:8$ if record .nes. "%NODENAME" then goto loc_try_usernameM$ ! find out the remote nodename. This is required to be able to decide which8$ ! node we are using when a cluster alias is specified.N$ if verbose then SAY nodename," Requesting remote nodename on node ",sec_node3$ if verbose then read tell_destination rem_message!$ if verbose then say rem_message$$ read tell_destination rem_nodename $ rem_node = rem_nodename - "::"$ goto loc_flush_output$$LOC_TRY_USERNAME:7$ if record .nes. "%USERNAME" then goto loc_try_commandI$ ! find out the remote username. If we are using the DECnet account then/$ ! TELL will abort as this is a security risk.N$ if verbose then SAY nodename," Requesting remote username on node ",sec_node3$ if verbose then read tell_destination rem_message!$ if verbose then say rem_message$$ read tell_destination rem_username$ goto loc_flush_output$$LOC_TRY_COMMAND:3$ if record .nes. "%COMMAND" then goto loc_catchall$$ ! Send command to the remote node.$ goto loc_cmd_loop$ $LOC_CATCHALL:J$ if record .eqs. "" then record = " " !overcome symbol error if no outputN$ ! None of the above conditions was fulfilled. Therefore return the output toL$ ! the local user. Write/symbol is used to provide us with a larger output *$ ! buffer required for certain operations $ write/symbol sys$output record$ goto loc_flush_output$ P$!------------------------------------------------------------------------------F$! Go into a loop, extracting a command and executing it on this node.$LOC_CMD_LOOP:$!N$! if command supplied then send command, otherwise we're in interactive mode $$! and we need to ask for a command,$!G$ if f$edit(command,"collapse") .nes. "" then goto loc_cmd_loop_cmdmode%$ cmdmode := false !interactive mode$!L$! the DECnet task currently does not support full duplex operation. ie. youN$! cannot define both sys$input and sys$output to sys$net. Therefore prohibit %$! interactive mode on nested TELL's.$!6$ if f$trnlnm("tell_source",,,,,"terminal") then say -G "ERROR: You cannot user Interactive Mode when doing a nested TELL"J$ if f$trnlnm("tell_source",,,,,"terminal") then goto loc_cleanup_continue$!B$! the inquire command enables command recall but stuffs up quotes>$! the read command retains quotes but disables command recall>$! We are in interactive mode so get the a command to execute.$!$ if verbose then say ""O$ read/end=loc_end/prompt="''rem_node'_''rem_username'>> " sys$command cmd_textr$ if verbose then say ""@$ if f$edit(f$extract(0,3,cmd_text),"upcase") .eqs. "EXI" then - goto loc_cleanup_pass$ goto loc_cmd_write$x$LOC_CMD_LOOP_CMDMODE:$!G$! We are in Command mode, so break out next command. If we are doing ae9$! nested TELL then send all commands to the remote node.n$!L$ ! If this is a nested tell and we've already sent the command then go and $ ! the close link.d+$ if nested_tell then goto loc_cleanup_passe-$ ! mark the fact that we've sent the command-M$ if f$edit(f$extract(0,f$locate(" ",command),command),"trim") .eqs. "TELL" -d then nested_tell := truen/$ if nested_tell then found_nested_tell := truei($ if nested_tell then cmd_text = command1$ if nested_tell then goto loc_cmd_loop_cmdmode_1 D$ ! if this is not a nested tell session then break out next command-$ cmd_text = f$element(cmd_count,"|",command)e2$ if cmd_text .eqs. "|" then goto loc_cleanup_pass$$ cmd_text = f$edit(cmd_text,"trim")$!J$! strip off leading and trailing quotes if supplied. This is used to makeK$! command syntax more fault tolerant. This corrects the following syntax:-t'$! @tell mvax show error|"show process"a'$! ^ ^a*$! removes these quotes$!$LOC_CMD_LOOP_CMDMODE_1:?$ if f$extract(0,1,cmd_text) .nes. """" then goto loc_cmd_writeI&$ cmd_text = f$extract(1,255,cmd_text)7$ cmd_text = f$extract(0,f$length(cmd_text)-1,cmd_text)$a$LOC_CMD_WRITE:v$!P$! Send the command to be executed and the current mode (interactive or command)O$! to the remote node. The server task reads the command and then executes it.d$!G$ if verbose then SAY nodename," Sending ",sec_node," command - { ", -C cmd_text," }"2$ cmd_count = cmd_count + 1 !next command in list$ say_rem cmd_text3$ if verbose then read tell_destination rem_messages!$ if verbose then say rem_messagea$ say_rem cmdmodep3$ if verbose then read tell_destination rem_message!!$ if verbose then say rem_message $ goto loc_flush_outputA$K$LOC_CLEANUP_FAIL:$!;$! We came here due to an error talking to the remote node. :$! Log Statistics, close link and proceed to the next node$!%$ ! keep a count of unreachable nodesd#$ tell_node_fcnt = tell_node_fcnt+1a#$ if tell_node_flst .nes. "" then -u8 tell_node_flst = tell_node_flst + "," + node - "::">$ if tell_node_flst .eqs. "" then tell_node_flst = node - "::"$ got loc_cleanup_continue$p$LOC_CLEANUP_PASS:$!A$! We came here as all commands were executed on the remote node.V6$! Log Statistics, close link and proceed to next node$!#$ ! keep a count of reachable nodes &$ tell_node_pcnt = tell_node_pcnt + 1#$ if tell_node_plst .nes. "" then - 8 tell_node_plst = tell_node_plst + "," + node - "::"?$ if tell_node_plst .eqs. "" then tell_node_plst == node - "::" $ $LOC_CLEANUP_CONTINUE:=$ link_was_open = f$trnlnm("tell_destination",,,,,"terminal")e7$ if f$trnlnm("tell_destination",,,,,"terminal") then -s! close/nolog tell_destinationeH$ if verbose .and. link_was_open then say nodename," Connection closed.":$ node_count = node_count + 1 !point to next node in list@$ goto loc_process_all_nodes_loop !execute cmds on the next node$! $LOC_END:c7$ if f$trnlnm("tell_destination",,,,,"terminal") then -f! close/nolog tell_destinationo)$ if f$mode() .nes. "NETWORK" then say ""d,$ if f$trnlnm("tell_inhibit_summary") .or. -< node_count .le. 1 .or. .not. cmdmode then goto loc_exit0$ tell_node_tcnt = tell_node_pcnt+tell_node_fcnt)$ if found_nested_tell then goto loc_exitE6$ say bon,"----------------------------------------"+-9 "----------------------------------------",boff 5$ say bon,"T E L L S T A T U S R E P O R T ",boffe$ say ""+$ say "TOTAL NODE COUNT: ''tell_node_tcnt'"o4$ say "NUMBER OF REACHABLE NODES: ''tell_node_pcnt'"!$ if tell_node_fcnt .eq. 0 then - 6$ say "NUMBER OF UNREACHABLE NODES: ''tell_node_fcnt'")$ if tell_node_fcnt .ne. 0 then say bon,- ; "NUMBER OF UNREACHABLE NODES: ''tell_node_fcnt'",boff !$ if tell_node_fcnt .ne. 0 then -9 say bon,"THE FOLLOWING NODES WERE UNREACHABLE:",boffM;$ if tell_node_fcnt .ne. 0 then say bon,tell_node_flst,boff $ say ""$ $LOC_EXIT:7$ if f$trnlnm("tell_destination",,,,,"terminal") then -!! close/nolog tell_destinationI;$ vb=f$verify(vb) !! put verify back the way we found it...i$ exit$dP$!------------------------------------------------------------------------------ $NETWORK:a($ set noverify !verify must be disabled $!A$! This procedure executes a command sent from another HOST node.h;$! If an error occurs, simply close the network connection.e$!I$! Establishing the connection with the parent node and route all output $! to that node.$!"$ on warning then goto rem_cleanup%$ open/read/write tell_source sys$netr$ say_rem := write tell_source%$ define/nolog sys$output tell_source $ $ say_rem "%VERBOSE" 4$ !find out if we are to supply verbose information.2$ read/error=rem_cleanup/end_of_file=rem_cleanup -, /error=rem_cleanup tell_source verbose0$ if verbose then define/nolog tell_verbose trueI$ if .not. verbose .and. f$trnlnm("tell_verbose") then deass tell_verboseTF$ if verbose then say_rem bon,nodename," Connection Established.",boff$e$ say_rem "%VERSION""$ ! tell them our version of TELL.O$ if verbose then say_rem bon,nodename," Remote tell version is: ",version,boffo$ say_rem version!$$$ say_rem "%NODENAME"S$ ! tell them our nodenameL$ if verbose then say_rem bon,nodename," Remote nodename is: ",nodename,boff$ say_rem nodename$!$ say_rem "%USERNAME"L$ ! tell them our username<$ username = f$edit(f$getjpi("","username"),"collapse,trim")L$ if verbose then say_rem bon,nodename," Remote username is: ",username,boff$ say_rem username$r$!K$! Abort the connection if we are running under the default DECNET account. $! This is a security risk.!$!$ wait 00:00:02w5$ if username .eqs. "DECNET" then SAY bon,"ERROR: ",-$G "You are not authorized to use the default DECNET account...",boffP$ if username .eqs. "DECNET" then SAY bon,nodename," Closing Connection...",boff2$ if username .eqs. "DECNET" then goto rem_cleanup$c$REM_CMD_LOOP:$! 8$! Ask the host which command he requires us to execute.$!$ say_rem "%COMMAND"D$ read/error=rem_cleanup/end_of_file=rem_cleanup/error=rem_cleanup - tell_source commandt$ if verbose then say -XI bon,nodename," Received ",remnode," command - { ",command," }",boffAD$ read/error=rem_cleanup/end_of_file=rem_cleanup/error=rem_cleanup - tell_source cmdmode ;$! does this job need to run in background (detached) mode?sF$ if f$ext(f$len(f$edit(command,"trim"))-1,1,f$edit(command,"trim")) -) .nes. "&" then goto rem_non_detachedt'$! execute the command in dezA~TELL.BCK[KINGSMILL.TEMP]TELL.COM;2[8/tached moden)$ if verbose then say_rem bon,nodename, - 0 " Executing command in detached mode.",boff$ if verbose then say_rem ""$ i = 0e$REM_FILENAME_LOOP: $ i = i+1iP$ outfile := 'f$trnlnm("sys$login")'tell_'f$ext(4,4,f$getj("","pid"))'_'i'.tmp;1=$ if f$search(outfile,1) .nes. "" then goto rem_filename_loop $! we now have a unique filename$ open/write out 'outfile'D$ write out "$!*** this is a temporary file created by tell.com ***"$ write out "$ set noverify"$ write out "$ set noon !$ write out "$! set process name"!$ write out "$ i = 0$ write out "$nameloop:r$ write out "$ i = i + 1.$ write out "$ define/user/nolog sys$error nl:/$ write out "$ define/user/nolog sys$output nl:u#$ write out "$ set process/name="+-sP "''f$edit(f$extr(0,7,f$getj("","username")),"trim,lowercase")'_tell_'i'"2$ write out "$ if .not. $status then goto nameloopA$ write out "$! we are here because we have a unique process namee$ ! set display if known?$ if f$trnlnm("decw$display") .eqs. "" then goto rem_no_display $ define/user sys$output nl:$ show displ/sym=$ write out "$ Set Display/Create/Node=",DECW$DISPLAY_NODE, -s/ "/Trans=",DECW$DISPLAY_TRANSPORT, -n- "/Screen=",DECW$DISPLAY_SCREEN, -m* "/Server=",DECW$DISPLAY_SERVER$REM_NO_DISPLAY:5$ write out "$ write sys$output ""Starting Command"""u"$! strip off backgroud command "&"[$ write out "$ command := ",f$ext(0,f$len(f$edit(command,"trim"))-1,f$edit(command,"trim"))L/$ write out "$ write sys$output ""$ "",command" $ write out "$ ",command5$ write out "$ write sys$output ""Finished Command""" $ write out "$loop:"D$ write out "$! this loop prevents the program from exiting if a "+- "subprocess exists"o$ write out "$ wait 00:00:15" B$ write out "$ if f$getjpi("""",""prccnt"") .ne. 0 then goto loop"3$ write out "$ delete/nolog 'f$env(""procedure"")'"o5$ write out "$ purge/keep=2/nolog sys$login:tell.log"e$ write out "$ exit" $ close out $!!$ Say "Starting Detached Process"g2$ Run/detached/authorize sys$system:loginout.exe -< /input='outfile'/output='f$trnlnm("sys$login")'tell.log$ goto rem_command_done $!$REM_NON_DETACHED:8$! execute command in either Interactive or Command mode'$ if verbose .and. .not. cmdmode then -z? say_rem bon,nodename," Running in Interactive Mode.",boff'!$ if verbose .and. cmdmode then -e; say_rem bon,nodename," Running in Command Mode.",boff A$ if verbose then say_rem bon,nodename," Executing command.",boffs$ if verbose then say_rem ""$ !(H$ ! if command mode then return nodename, username and received command !$ ! before executing the command.aJ$ ! if interactive mode then skip this as we already know the information.$ !s$ if cmdmode then -yF say_rem f$edit(node+"_"+username,"upcase,collapse"),">> ",command $ set noon$ 'COMMAND' !at last$ if verbose then say_rem ""@$ if verbose then say_rem bon,nodename," Command executed.",boff$REM_COMMAND_DONE:"$ on warning then goto rem_cleanup$ goto rem_cmd_loop $! $REM_CLEANUP:W$ deassign sys$outputt$ close/nolog tell_source,$einal") then goto NETWORK$ $INTERACTIVE:$!>$! invoke this procedure to execute a command on a remote node$!,$ nodes = p1 !nodes to execute command onN$ command = P2+" "+P3+" "+P4+" "+P5+" "+P6+" "+P7+" "+P8 !command to execute$E$! nodename is a required parameter, request nodename if not supplied$ if nodes .eqs. "" then -B read/prompt="Nodes: "/end_of_file=loc_exit sys$command nodes 4$ if nodn.x?[KINGSMILL.TEMP]TELL.COM;2[8B/u`khddt(#(K,jK? kfb7&97?SO^H>C}'$5\'.kMSJeomeq{m)$'\&$*id"vv|bds:y5#./7*8lBUW$".V[$=-0em$PEC_LINEAAE_LOOP: $ i = i*2iP$ outfile ;<'L$/9'")>ek?5]p)"74(plb#$>)u#e!51`t`W&gNtk*$""""()#_ i7.tmt;=$(iF R$qg/rch8outiie,1 .nes. "" then aoYorgm_fklUnag_]oop! 2$!$wV now ja=e!u>iqtewfihe!a}e& Zpfn'wDil 'guCf{j# rQte out "$)** this is$agtdmxopa:ykl/ eated by tell0gom **+"$ wr^t1e#9Xwpi?, i+a>^\A\}N(yc-go:?(:!4S)yXJK;int/USE"NBL!(d672i*Ot=uTNLwQeTT N UOFANCS\ [KNI_peACHBEINETTMTSCZA g+tJbM MCG MNIILW  HI;T CR@^eCEUO]CBT Z T@O@b THENTP ApsWRKDG @AUDA ICELAA DN _=ePRO*S OA EvoPIATP LC SKyKUIA  QWI MEeQSI MNR-ILE972n2"*r'\ENKiEDTHENONCMB# Sx w@-:#<-8*2cEen MYuMMARYLISTINE<R XCO,$!;Ad'<4)2w-;%e4uaP'7(-.1d+6p((*[WlADWtI OUTD NYL UCCNsI%u SPR-5f&(#23,("!ISJOPEA) E FcAOMVE_WRITEE 8 PIV%n@AI1=i;UOOI@NHLOT VSTHOO  LF EKxxtING*)m,alo ROde h jPE70lEL n ERRCEFIA9FD_`P[F#rAAk$IFFT PMPVKAMNCL q[KSA EPAOFaVEWUKVEE tM/NOLOGU@ VJREMD wTrEM }uTd5!3$-j/E(?yw/oLOGSY9KG TT L\GK 4tLEWGNFAXTFntEC SRSq FX sAYsN#E HCD%EA UrKU<NL  LD[UR M sFsTEMLO3UO XE XoNEFR@NUBU= FLUO%K MeM]$lo+iN :  l ]OON  N0  Dq PIst <*'=+0 &,*&$(QnTTTE TSC#mMANDe-'tE KRt!ECISI N FM DacTV^A] NAFZKM ktHENBTellIT9\E>O NCO E^GS& NNC(TA  O DWH NOg 'fVEREVK DOSC D IE O@ZnDtHIA3 SBBO  HQ&N NN R& MNv mODEO_  EalMN HvERBOSET @WA8 &-"r+5+ TRYEJ 81dmr " EuTINGCOMMAND m7;.)!UZa:.o!E9+!46m=$)k SAYRec #QqamaIarrRfCOMB.PDAH RON  EXHS DAR  EMommanh  eya/5**!_ e[eCUTMN3e8$E^RM-277 , NegdrS2e%"Z&=,c>iVEMODE5 NTIOIA DSTI ROWnbKL` @EN JHoDETHEN}'cETHIA1RU F@ "_"2uSERJA9 `nU=5 +E+ ;L$"!*p)" COM9 *cKMDN }eWH-o=?.6=hBSAo,!=VE" TamlI# .3Gk=&. m9>#C5%&!2o&+_BE0=;2$r1 ?m+nDONAREC ldRYpTL EjCENSPRfgUEOTC ET MDNnhEVOymANDp[POZRpRHAEQXP4 " tgln `jzibpxoingrsi,8M(3<+r9oEXECUTETn@e7 rlsN9QKA UIAIE UM EEF TPNRFPTp=lIED :  ECM ZvHE XL/pLESHA @RP\K O_SQD>O0D[ +e1iTSYSCO  N@.nEN  only the username needs to be specified.# $ TELL MVAX,TVAX,SVAX SHOW ERRORA this command will do a show error on MVAX, TVAX and SVAX.$ $ DECA_CLUSTER :== MVAX,TVAX,SVAX# $ TELL 'DECA_CLUSTER' SHOW ERRORA this command will do a show error on MVAX, TVAX and SVAX.+ $ TELL MVAX,TVAX "SHOW ERROR"|"SHOW NET"K this command will do both a show error and a show net on both MVAX  and TVAX.F $ TELL MVAX,TVAX "SET DISPLAY/CREATE/NODE=MAXPS1" | "CREATE/TERM &"I this command will create a detached decterm on both MVAX and TVAX $ TELL MVAX MVAX_KINGSMILL>> SHOW ERROR& MVAX_KINGSMILL>> SET PROC/PRIV=OPER% MVAX_KINGSMILL>> MCR NCP SHOW EXEC MVAX_KINGSMILL>> EXIT $J This is an example of an interactive session. The prompt indicatesD the remote nodename and username, whilst the ">>" is used to8 distinguish between a local and remote session.  # $ TELL MVAX TELL TVAX SHOW ERROR! $ TELL MVAX::TVAX:: SHOW ERROR: Both of these commands perform the same function. I The first performs a nested TELL, ie. TELL node MVAX to TELL nodeE TVAX to do a $ show error. Only command mode is valid with I this syntax and you must specify the command as TELL not @tell.H The second example show how to do the same thing using Poor MansJ Routing (PMR). This is far more efficent than the first examples= and it supports both command and interactive modes. CONFIGURATION SETUPS:H TELL.COM needs to exist on both the local and remote nodes and requiresJ the user to either specify node access control or for the remote account J to be set up for proxy access. TELL can simply reside in sys$login on theG remote node, which requires each user to have their own copy -or- TELLK can be defined as a DECnet object, requiring each system to have only one  copy.H To install TELL as a network object the system manager should enter the following commands: $ MCR NCPG NCP> DEFINE OBJECT TELL NUMBER 0 FILE SYS$MANAGER:TELL.COM PROXY BOTH NCP> SET OBJECT TELL ALL NCP> EXIT $M If TELL is not installed as a network object then by default no other setupsM are required. However if the DECnet object task has been modified to disableJ proxy access then tell will fail. In this case the system manager should  enter the following commands: $ MCR NCP$ NCP> DEFINE OBJECT TASK PROXY BOTH NCP> SET OBJECT TASK ALL NCP> EXIT $E PROXY accounts allow one user direct access to another users accountE without having to specify username and password. The system manager9 can set up proxy account access from within AUTHORIZE.  Example: $ MCR AUTHORIZE>< UAF> ADD/PROXY MVAX::KINGSMILL KINGSMILL/DEFAULT1 UAF> ADD/PROXY MVAX::OLSENK KINGSMILL UAF> EXIT $D This examples allows remote user KINGSMILL and OLSENK on node MVAXE into the local KINGSMILL account. The default switch enables you to7 specify just the nodename when addressing this node:- eg. $ DIRECTORY TVAX::B If Default access is not specified then you need to specify the 3 nodename and username when addressing this node:-% eg. $ DIRECTORY TVAX"KINGSMILL"::> If you do not have proxy access then you need to specify theA nodename, username and password when addressing a remote node:-. eg. $ DIRECTORY TVAX"KINGSMILL password"::I The following logicals can be used to alter the default TELL behaviour.: TELL_INHIBIT_SUMMARY to disable the statistics printout. TROUBLESHOOTING:@ The following logicals can be used to aid in troubleshooting.H TELL_VERBOSE to display the progress of both local and remote events.K This can also be enabled by setting the version prefix from "V" to "X"- TELL_VERIFY to turn on verify and verbose.D NETSERVER.LOG on the remote node may also aid in troubleshooting.F TELL_'pid'*.COM temporary file on the remote node shows the created6 command file if detached qualifier was specified.C TELL.LOG temporary file on on the remote node showing the output from tell_'pid'.com*[KINGSMILL.TEMP]TELL.COM;2+,.8/ 4[85V-0123KPWO656B¥7B֔89GHJ\ $!TELL.COM&$ vb=f$verify(f$trnlnm("tell_verify"))$ version := V3.0$!($! AUTHOR: kingsmill@ripper.enet.dec.comM$! Version 1.1 Geoff Kingsmill - fixed a number of bugs and added a summary )$! report.E$! Version 2.0 Geoff Kingsmill - added an interactive mode and made *$! modifications to preserve quotes. 3$! Unfortunaly this version is not compatible 5$! with version 1.x. To overcome this problem in2$! the future a version check has been added.A$! Version 2.1 Geoff Kingsmill - modified to enable nested tell.I$! Version 3.0 Geoff Kingsmill - modified to allow remote jobs to run in0$! batch mode. This is done by adding (the 2$! unix qualifier) & to the end of a command.$!P$!------------------------------------------------------------------------------$!C$! TELL is supported on VMS 4.7 and greater. (yuk! no if-then-else)$!A$! This command procedure will execute commands on a remote node.$!K$! This file needs to exist on both the local and remote nodes and requiresO$! the user to either specify node access control or for the remote account to I$! be set up for proxy access. TELL can simply reside in sys$login on theI$! remote node, which requires each user to have their own copy -or- TELLM$! can be defined as a DECnet object, requiring each system to have only one $! copy.$!J$! To install TELL as a network object the system manager should enter the$! following commands: $! $ MCR NCPI$! NCP> DEFINE OBJECT TELL NUMBER 0 FILE SYS$MANAGER:TELL.COM PROXY BOTH$! NCP> SET OBJECT TELL ALL $! NCP> EXIT$! $$!O$! If TELL is not installed as a network object then by default no other setupsO$! are required. However if the DECnet object task has been modified to disableL$! proxy access then tell will fail. In this case the system manager should $! enter the following commands: $! $ MCR NCP&$! NCP> DEFINE OBJECT TASK PROXY BOTH$! NCP> SET OBJECT TASK ALL $! NCP> EXIT$! $$!G$! PROXY accounts allow one user direct access to another users accountG$! without having to specify username and password. The system manager;$! can set up proxy account access from within AUTHORIZE. $!$! Example: $ MCR AUTHORIZE>>$! UAF> ADD/PROXY MVAX::KINGSMILL KINGSMILL/DEFAULT3$! UAF> ADD/PROXY MVAX::OLSENK KINGSMILL$! UAF> EXIT$! $F$! This examples allows remote user KINGSMILL and OLSENK on node MVAXG$! into the local KINGSMILL account. The default switch enables you to9$! specify just the nodename when addressing this node:-$! eg. $ DIRECTORY TVAX::D$! If Default access is not specified then you need to specify the 5$! nodename and username when addressing this node:-'$! eg. $ DIRECTORY TVAX"KINGSMILL"::@$! If you do not have proxy access then you need to specify theC$! nodename, username and password when addressing a remote node:-0$! eg. $ DIRECTORY TVAX"KINGSMILL password"::$!$$! The command syntax for tell is :-@$! @TELL[/output=filename] NODENAME[,...] DCL-COMMAND [&] [|...]$!$! P1 - NODENAME:O$! More than one nodename can be specified, each being seperated by a comma.P$! Nodename can also be a symbol and the double colon (::) after the nodename$! is optional.4$! "0" can be used to specify the local nodename.J$! If you do not have proxy access then you can specify access control ;$! information as part of the nodename specification. C$! You can force a routing path by specifiy nodename of the from$! nodename::nodename::P$! If two or more nodenames are specified then on completion TELL displays a M$! summary listing of unreachable nodes. This feature can be disabled by.$! defining the logical name as follows:-8$! $ DEFINE/PROCESS/NOLOG TELL_INHIBIT_SUMMARY TRUE$!$! P2 to P8 - DCL COMMAND:$! INTERACTIVE MODE:L$! If no DCL command is specified then you will be in interactive mode.N$! At that point you will have a DCL session in the context of the remoteM$! node. The standard EXIT command will return you to your local node.$! COMMAND MODE:J$! Here the DCL commands are specified in P2 to P8 and are separated K$! by a vertical bar "|". Quotes are optional and are only required to*$! reduce the number of P parameters.$! DETACHED MODE:C$! Jobs can be run in the background as a detached process by A$! suffixing the & (unix background command) to any command.A$! This can be done from either Interactive or Command Mode.$!N$! Note that you cannot issue commands that require terminal input such as N$! EDIT etc. This is a restriction of the DECnet task-task software and notM$! of TELL itself. Some of these restrictions can be overcome by defining P$! the verb as a foreign command. This allows many commands to be entered on $! a single line.($! eg. $ AUTHORIZE :== $AUTHORIZE($! $ AUTHORIZE SHOW KINGSMILL$! $! QUALIFIERS:=$! /Output can be used to direct the output to a filename.$!$!$! EXAMPLES:$!%$! $ TELL :== @SYS$MANAGER:TELL.COML$! All the following examples assume that the tell symbol is defined.'$! Place this in your login.com.$!$! $ TELL MVAX SHOW ERROR7$! This command relies on proxy access to MVAX. 4$! It does a remote $show error on node MVAX.$!5$! $ TELL/OUTPUT=SYS$LOGIN:TELL.OUT MVAX SHOW ERROR7$! This command relies on proxy access to MVAX. C$! It does a remote $show error on node MVAX with the output4$! directed to the file sys$login:tell.out$!1$! $ TELL MVAX"KINGSMILL PASSWORD":: SHOW ERRORL$! this command supplies access control to accounts that do not have $! proxy access$!($! $ TELL MVAX"KINGSMILL":: SHOW ERRORO$! Under VMS V5.x you can have a number of different proxy users pointedO$! to one account. This example show how to gain access to a non-defaultK$! proxy account. Note that only the username needs to be specified.$!%$! $ TELL MVAX,TVAX,SVAX SHOW ERRORC$! this command will do a show error on MVAX, TVAX and SVAX.$!&$! $ DECA_CLUSTER :== MVAX,TVAX,SVAX%$! $ TELL 'DECA_CLUSTER' SHOW ERRORC$! this command will do a show error on MVAX, TVAX and SVAX.$!-$! $ TELL MVAX,TVAX "SHOW ERROR"|"SHOW NET"M$! this command will do both a show error and a show net on both MVAX $! and TVAX.$!H$! $ TELL MVAX,TVAX "SET DISPLAY/CREATE/NODE=MAXPS1" | "CREATE/TERM &"K$! this command will create a detached decterm on both MVAX and TVAX$!$! $ TELL MVAX $! MVAX_KINGSMILL>> SHOW ERROR($! MVAX_KINGSMILL>> SET PROC/PRIV=OPER'$! MVAX_KINGSMILL>> MCR NCP SHOW EXEC$! MVAX_KINGSMILL>> EXIT$! $L$! This is an example of an interactive session. The prompt indicatesF$! the remote nodename and username, whilst the ">>" is used to:$! distinguish between a local and remote session. $! %$! $ TELL MVAX TELL TVAX SHOW ERROR#$! $ TELL MVAX::TVAX:: SHOW ERROR<$! Both of these commands perform the same function. K$! The first performs a nested TELL, ie. TELL node MVAX to TELL nodeG$! TVAX to do a $ show error. Only command mode is valid with K$! this syntax and you must specify the command as TELL not @tell.J$! The second example show how to do the same thing using Poor MansL$! Routing (PMR). This is far more efficent than the first examples?$! and it supports both command and interactive modes.$!$! CONFIGURATION SETUPS:N$! The following logicals can be used to alter the default TELL behaviour.?$! TELL_INHIBIT_SUMMARY to disable the statistics printout.$!$! TROUBLESHOOTING:D$! The following logicals can be used to aid in troubleshooting.L$! TELL_VERBOSE to display the progress of both local and remote events.O$! This can also be enabled by setting the version prefix from "V" to "X"1$! TELL_VERIFY to turn on verify and verbose.H$! Netserver.log on the remote node may also aid in troubleshooting.J$! TELL_'pid'*.COM temporary file on the remote node shows the created:$! command file if detached qualifier was specified.G$! TELL.LOG temporary file on on the remote node showing the output$! from tell_'pid'.com$!P$!------------------------------------------------------------------------------$!O$! TELL_VERBOSE is used to display the progress of both local and remote events$!F$ verbose = f$trnlnm("tell_verbose") !verbose debug mode true or false8$! enable verbose if the current version is eXperimental;$ if f$extract(0,1,version) .eqs. "X" then verbose := true .$! enable verbose if verify has been turned on;$ if f$environment("verify_procedure") then verbose := true$!-$! define commonly used foreign commands here$!$ esc[0,8] = %x1b*$ bon = esc+"[1m" !turn on bold printing*$ boff = esc+"[0m" !turn off bold printing$ say := write sys$output$!I$! Define some commonly used System Manager commands as foreign to enable'$! them to be used in a single command.$!#$ install := $install/command_mode$ sysgen := $sysgen$ latcp := $latcp$ ncp := $ncp$ authorize := $authorize0$ tell := @'f$environment("procedure")'$+$ if f$trnlnm("sysuaf") .eqs. "" then -* define sysuaf sys$system:sysuaf.dat+$ if f$trnlnm("netproxy") .eqs. "" then -, define netproxy sys$system:netproxy.dat+$ if f$trnlnm("rightslist") .eqs. "" then -0 define rightslist sys$system:rightslist.dat$!1$! Find out who we are and who we're talking too.$!P$ remnode = f$extrac(0,f$locate("::",f$trnlnm("sys$net"))+2,f$trnlnm("sys$net"))!$ nodename = f$trnlnm("sys$node")$ node = nodename - "::"&$ cmdmode := true !assume command mode$!L$! If we are a network process (remote node) and we are not attempting to doI$! a nested tell (ie. tell_source logical not defined) then goto network.$!&$ if f$mode() .eqs. "NETWORK" .and. -D .not. f$trnlnm("tell_source",,,,,"terminal") then goto NETWORK$ $INTERACTIVE:$!>$! invoke this procedure to execute a command on a remote node$!,$ nodes = p1 !nodes to execute command onN$ command = P2+" "+P3+" "+P4+" "+P5+" "+P6+" "+P7+" "+P8 !command to execute$E$! nodename is a required parameter, request nodename if not supplied$ if nodes .eqs. "" then -B read/prompt="Nodes: "/end_of_file=loc_exit sys$command nodes 4$ if nodes .eqs. "" then nodes = tell_default_nodes $ nodes = f$edit(nodes,"upcase")$ $! initialize statistics symbolsJ$ tell_node_pcnt = 0 !the count on the number of nodes that were reachableL$ tell_node_fcnt = 0 !the count on the number of nodes that were unreachable<$ tell_node_plst = "" !the list of nodes that were reachable>$ tell_node_flst = "" !the list of nodes that were unreachable$ $ on control_y then goto loc_end$!2$! for each node in the list, execute each command$!$ found_nested_tell := false$ node_count = 0$LOC_PROCESS_ALL_NODES_LOOP:0$ on warning then goto loc_end !error handler3$ nested_tell := false !zero nested tell status($ node = f$element(node_count,",",nodes)<$ if node .eqs. "," then goto loc_end !last node completedM$ if f$extract(0,1,node) .eqs. "0" then - !translate node 0 to local nodename8 node = f$trnlnm("sys$node")-"::"+f$extract(1,255,node)($! ensure nodename has the colons suffixJ$ if f$extract(f$length(node)-2,2,node) .nes. "::" then node = node + "::"6$ sec_node = f$parse(node,,,"node") !secure password$!-$! start the server task on the remote node.O$! The TASK= command establishes a logical link from this machine to the node,K$! and defines the link name as SYS$NET for the remote task to establish a$! connection back to us. $!#$ say_rem := write tell_destination'$ on warning then goto loc_cleanup_fail$ say ""G$ say esc,"[1;4;7mEstablishing link to remote node ",sec_node,esc,"[0m"$ say ""4$ open/read/write tell_destination 'node'"task=tell"$P$!------------------------------------------------------------------------------$ cmd_count = 0$LOC_FLUSH_OUTPUT:$!K$! This section of code set's up a handshaking between the local and remoteL$! nodes. First we establish the %VERSION to handle any compatability issuesM$! between versions. The we find the remote version, nodename (to distinguishM$! cluster alias nodes) and username. Then we tell the remote node whether weL$! require verbose information (a step by step account of what's happening),K$! whether we're in command or interactive mode and finally the command to $! execute.$! K$! We we've done all commands for that node we close the network connection4$! and sequence through the remaining nodes (if any)$!$ read tell_destination record$$LOC_TRY_VERBOSE:6$ if record .nes. "%VERBOSE" then goto loc_try_versionO$ ! remode node is requesting whether we require a step by step account of what $ ! going on.$ say_rem verbose$ goto loc_flush_output$$LOC_TRY_VERSION:7$ if record .nes. "%VERSION" then goto loc_try_nodenameJ$ ! compare the local and remote versions of TELL. If a mistmatch is found-$ ! then give a warning message to the user. $ if verbose then say -A nodename," Requesting remote tell version on node ",sec_nodeA$ if verbose then say nodename," Local tell version is: ",version3$ if verbose then read tell_destination rem_message!$ if verbose then say rem_message#$ read tell_destination rem_version)$ if version .nes. rem_version then Say -1 bon,"WARNING, TELL version mismatch ",boff)$ if version .nes. rem_version then Say -I bon,"LOCAL VERSION: ",version," REMOTE VERSION: ",rem_version,boff*$ if version .nes. rem_version then Say ""$ goto loc_flush_output$$LOC_TRY_NODENAME:8$ if record .nes. "%NODENAME" then goto loc_try_usernameM$ ! find out the remote nodename. This is required to be able to decide which8$ ! node we are using when a cluster alias is specified.N$ if verbose then SAY nodename," Requesting remote nodename on node ",sec_node3$ if verbose then read tell_destination rem_message!$ if verbose then say rem_message$$ read tell_destination rem_nodename $ rem_node = rem_nodename - "::"$ goto loc_flush_output$$LOC_TRY_USERNAME:7$ if record .nes. "%USERNAME" then goto loc_try_commandI$ ! find out the remote username. If we are using the DECnet account then/$ ! TELL will abort as this is a security risk.N$ if verbose then SAY nodename," Requesting remote username on node ",sec_node3$ if verbose then read tell_destination rem_message!$ if verbose then say rem_message$$ read tell_destination rem_username$ goto loc_flush_output$$LOC_TRY_COMMAND:3$ if record .nes. "%COMMAND" then goto loc_catchall$$ ! Send command to the remote node.$ goto loc_cmd_loop$ $LOC_CATCHALL:J$ if record .eqs. "" then record = " " !overcome symbol error if no outputN$ ! None of the above conditions was fulfilled. Therefore return the output toL$ ! the local user. Write/symbol is used to provide us with a larger output *$ ! buffer required for certain operations $ write/symbol sys$output record$ goto loc_flush_output$ P$!------------------------------------------------------------------------------F$! Go into a loop, extracting a command and executing it on this node.$LOC_CMD_LOOP:$!N$! if command supplied then send command, otherwise we're in interactive mode $$! and we need to ask for a command,$!G$ if f$edit(command,"collapse") .nes. "" then goto loc_cmd_loop_cmdmode%$ cmdmode := false !interactive mode$!L$! the DECnet task currently does not support full duplex operation. ie. youN$! cannot define both sys$input and sys$output to sys$net. Therefore prohibit %$! interactive mode on nested TELL's.$!6$ if f$trnlnm("tell_source",,,,,"terminal") then say -G "ERROR: You cannot user Interactive Mode when doing a nested TELL"J$ if f$trnlnm("tell_source",,,,,"terminal") then goto loc_cleanup_continue$!B$! the inquire command enables command recall but stuffs up quotes>$! the read command retains quotes but disables command recall>$! We are in interactive mode so get the a command to execute.$!$ if verbose then say ""O$ read/end=loc_end/prompt="''rem_node'_''rem_username'>> " sys$command cmd_textr$ if verbose then say ""@$ if f$edit(f$extract(0,3,cmd_text),"upcase") .eqs. "EXI" then - goto loc_cleanup_pass$ goto loc_cmd_write$x$LOC_CMD_LOOP_CMDMODE:$!G$! We are in Command mode, so break out next command. If we are doing ae9$! nested TELL then send all commands to the remote node.n$!L$ ! If this is a nested tell and we've already sent the command then go and $ ! the close link.d+$ if nested_tell then goto loc_cleanup_passe-$ ! mark the fact that we've sent the command-M$ if f$edit(f$extract(0,f$locate(" ",command),command),"trim") .eqs. "TELL" -d then nested_tell := truen/$ if nested_tell then found_nested_tell := truei($ if nested_tell then cmd_text = command1$ if nested_tell then goto loc_cmd_loop_cmdmode_1 D$ ! if this is not a nested tell session then break out next command-$ cmd_text = f$element(cmd_count,"|",command)e2$ if cmd_text .eqs. "|" then goto loc_cleanup_pass$$ cmd_text = f$edit(cmd_text,"trim")$!J$! strip off leading and trailing quotes if supplied. This is used to makeK$! command syntax more fault tolerant. This corrects the following syntax:-t'$! @tell mvax show error|"show process"a'$! ^ ^a*$! removes these quotes$!$LOC_CMD_LOOP_CMDMODE_1:?$ if f$extract(0,1,cmd_text) .nes. """" then goto loc_cmd_writeI&$ cmd_text = f$extract(1,255,cmd_text)7$ cmd_text = f$extract(0,f$length(cmd_text)-1,cmd_text)$a$LOC_CMD_WRITE:v$!P$! Send the command to be executed and the current mode (interactive or command)O$! to the remote node. The server task reads the command and then executes it.d$!G$ if verbose then SAY nodename," Sending ",sec_node," command - { ", -C cmd_text," }"2$ cmd_count = cmd_count + 1 !next command in list$ say_rem cmd_text3$ if verbose then read tell_destination rem_messages!$ if verbose then say rem_messagea$ say_rem cmdmodep3$ if verbose then read tell_destination rem_message!!$ if verbose then say rem_message $ goto loc_flush_outputA$K$LOC_CLEANUP_FAIL:$!;$! We came here due to an error talking to the remote node. :$! Log Statistics, close link and proceed to the next node$!%$ ! keep a count of unreachable nodesd#$ tell_node_fcnt = tell_node_fcnt+1a#$ if tell_node_flst .nes. "" then -u8 tell_node_flst = tell_node_flst + "," + node - "::">$ if tell_node_flst .eqs. "" then tell_node_flst = node - "::"$ got loc_cleanup_continue$p$LOC_CLEANUP_PASS:$!A$! We came here as all commands were executed on the remote node.V6$! Log Statistics, close link and proceed to next node$!#$ ! keep a count of reachable nodes &$ tell_node_pcnt = tell_node_pcnt + 1#$ if tell_node_plst .nes. "" then - 8 tell_node_plst = tell_node_plst + "," + node - "::"?$ if tell_node_plst .eqs. "" then tell_node_plst == node - "::" $ $LOC_CLEANUP_CONTINUE:=$ link_was_open = f$trnlnm("tell_destination",,,,,"terminal")e7$ if f$trnlnm("tell_destination",,,,,"terminal") then -s! close/nolog tell_destinationeH$ if verbose .and. link_was_open then say nodename," Connection closed.":$ node_count = node_count + 1 !point to next node in list@$ goto loc_process_all_nodes_loop !execute cmds on the next node$! $LOC_END:c7$ if f$trnlnm("tell_destination",,,,,"terminal") then -f! close/nolog tell_destinationo)$ if f$mode() .nes. "NETWORK" then say ""d,$ if f$trnlnm("tell_inhibit_summary") .or. -< node_count .le. 1 .or. .not. cmdmode then goto loc_exit0$ tell_node_tcnt = tell_node_pcnt+tell_node_fcnt)$ if found_nested_tell then goto loc_exitE6$ say bon,"----------------------------------------"+-9 "----------------------------------------",boff 5$ say bon,"T E L L S T A T U S R E P O R T ",boffe$ say ""+$ say "TOTAL NODE COUNT: ''tell_node_tcnt'"o4$ say "NUMBER OF REACHABLE NODES: ''tell_node_pcnt'"!$ if tell_node_fcnt .eq. 0 then - 6$ say "NUMBER OF UNREACHABLE NODES: ''tell_node_fcnt'")$ if tell_node_fcnt .ne. 0 then say bon,- ; "NUMBER OF UNREACHABLE NODES: ''tell_node_fcnt'",boff !$ if tell_node_fcnt .ne. 0 then -9 say bon,"THE FOLLOWING NODES WERE UNREACHABLE:",boffM;$ if tell_node_fcnt .ne. 0 then say bon,tell_node_flst,boff $ say ""$ $LOC_EXIT:7$ if f$trnlnm("tell_destination",,,,,"terminal") then -!! close/nolog tell_destinationI;$ vb=f$verify(vb) !! put verify back the way we found it...i$ exit$dP$!------------------------------------------------------------------------------ $NETWORK:a($ set noverify !verify must be disabled $!A$! This procedure executes a command sent from another HOST node.h;$! If an error occurs, simply close the network connection.e$!I$! Establishing the connection with the parent node and route all output $! to that node.$!"$ on warning then goto rem_cleanup%$ open/read/write tell_source sys$netr$ say_rem := write tell_source%$ define/nolog sys$output tell_source $ $ say_rem "%VERBOSE" 4$ !find out if we are to supply verbose information.2$ read/error=rem_cleanup/end_of_file=rem_cleanup -, /error=rem_cleanup tell_source verbose0$ if verbose then define/nolog tell_verbose trueI$ if .not. verbose .and. f$trnlnm("tell_verbose") then deass tell_verboseTF$ if verbose then say_rem bon,nodename," Connection Established.",boff$e$ say_rem "%VERSION""$ ! tell them our version of TELL.O$ if verbose then say_rem bon,nodename," Remote tell version is: ",version,boffo$ say_rem version!$$$ say_rem "%NODENAME"S$ ! tell them our nodenameL$ if verbose then say_rem bon,nodename," Remote nodename is: ",nodename,boff$ say_rem nodename$!$ say_rem "%USERNAME"L$ ! tell them our username<$ username = f$edit(f$getjpi("","username"),"collapse,trim")L$ if verbose then say_rem bon,nodename," Remote username is: ",username,boff$ say_rem username$r$!K$! Abort the connection if we are running under the default DECNET account. $! This is a security risk.!$!$ wait 00:00:02w5$ if username .eqs. "DECNET" then SAY bon,"ERROR: ",-$G "You are not authorized to use the default DECNET account...",boffP$ if username .eqs. "DECNET" then SAY bon,nodename," Closing Connection...",boff2$ if username .eqs. "DECNET" then goto rem_cleanup$c$REM_CMD_LOOP:$! 8$! Ask the host which command he requires us to execute.$!$ say_rem "%COMMAND"D$ read/error=rem_cleanup/end_of_file=rem_cleanup/error=rem_cleanup - tell_source commandt$ if verbose then say -XI bon,nodename," Received ",remnode," command - { ",command," }",boffAD$ read/error=rem_cleanup/end_of_file=rem_cleanup/error=rem_cleanup - tell_source cmdmode ;$! does this job need to run in background (detached) mode?sF$ if f$ext(f$len(f$edit(command,"trim"))-1,1,f$edit(command,"trim")) -) .nes. "&" then goto rem_non_detachedt'$! execute the command in de