From: CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 2-JUN-1989 08:50 To: MRGATE::"ARISIA::EVERHART" Subj: DECwindows hack Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Thu, 1 JUN 89 14:01:11 PDT Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Thu, 1 Jun 89 13:43:29 PDT Received: by ucbvax.Berkeley.EDU (5.61/1.36) id AA14757; Thu, 1 Jun 89 13:07:51 -0700 Received: from USENET by ucbvax.Berkeley.EDU with netnews for info-vax@kl.sri.com (info-vax@kl.sri.com) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 1 Jun 89 00:17:32 GMT From: oliveb!felix!dhw68k!cerritos!tanner@apple.com (Bruce Tanner) Organization: Cerritos College Subject: DECwindows hack Message-Id: <505@cerritos.uucp> Sender: info-vax-request@kl.sri.com To: info-vax@kl.sri.com We have a couple of VAXstation 2000s that just don't quite make it as standalone DECwindows machines. We have been using Kevin Carosso's DECW_LOGIN_SATELLITES.COM (thanks Kevin), but it has two unpleasant side effects; (1) if the satellite reboots, someone (with privs) has to go out and restart DECW$STARTLOGIN and (2) if the 'host' system reboots and the satellites don't, all the decwindows LOGINOUT processes run around looking for their satellites. I have come up with a method that allows the session manager to run on a satellite and automatically starts the other programs on another host. The trick is to start a DECnet task on the host to do a SET DISPLAY and then run the DECwindows application. Since the session manager still runs on the satellite, problems (1) and (2) go away because the standard DECW$STARTUP is used. The other nice thing is that anybody that doesn't modify DECW$LOGIN.COM is still running 'normal' DECwindows. Here's how you bring this up: Define a DECnet task DECW_SERVER as DECW_SERVER.COM on the host. On our system for we use UTL:, a directory for local utilities. NCP> DEFINE OBJECT NUMBER 0 NAME DECW_SERVER FILE DECW_SERVER.COM NCP> SET KNOWN OBJECTS ALL Put the files DECW_SERVER.COM, DECW_WAIT.COM, REMOTE_DECTERM.COM and CREATE_DECTERM.EXE in . See the VMS_SHARE file below. Note that you can do everything in the NETSERVER process instead of running a detached process, but you will double the number of DECnet links in use and also may run over NJOBLIM network jobs. For each DECwindows user, either use the Session Manager Customize Security window to add host::user or modify the user's DECW$SM_GENERAL.DAT with sm.host_list: host::user sm.num_hosts: 1 Turn off 'Create FileView Window' in the Customize Session Manager window or sm.create_vue: 0 Set 'Terminal Windows' in the Customize Session Manager window to zero or sm.create_terminal: 0 Finally, in the user's DECW$LOGIN.COM replace all the DCL spawn commands with copy commands to the DECnet task: $!decw$login.com $!must decw_wait in subprocess, otherwise you'll deadlock $ spawn/nowait/output=nl: @decw_startup $ exit $!decw_startup.com $!wait for session manager to establish security $ @decw_wait $! start a decterm $ copy/nolog sys$input host::"task=decw_server" DECterm $! run fileview $ copy/nolog sys$input host::"task=decw_server" run sys$system:vue$master $! run any other spawned applications $ copy/nolog sys$input host::"task=decw_server" run sys$system:decw$whatever $ exit For you system manager types, I also have the command in DECW$LOGIN.COM $ spawn/nowait/output=nl: @decw_reply_enable which executes the command file $!decw_login_enable.com $ @decw_wait $ define/user sys$command 'term' $ reply/enable $ exit so all the opcom messages go to my session manager window. -Bruce $! ................... Cut between dotted lines and save. ................... $!........................................................................... $! VAX/VMS archive file created by VMS_SHARE V06.10 7-FEB-1989. $! $! VMS_SHARE was written by James Gray (Gray:OSBUSouth@Xerox.COM) from $! VMS_SHAR by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au). $! $! To unpack, simply save, concatinate all parts into one file and $! execute (@) that file. $! $! This archive was created by user TANNER $! on 31-MAY-1989 17:08:39.01. $! $! It contains the following 4 files: $! DECW_SERVER.COM $! DECW_WAIT.COM $! REMOTE_DECTERM.COM $! CREATE_DECTERM.C $! $!============================================================================ $ SET SYMBOL/SCOPE=( NOLOCAL, NOGLOBAL ) $ VERSION = F$GETSYI( "VERSION" ) $ IF VERSION .GES "V4.4" THEN GOTO VERSION_OK $ WRITE SYS$OUTPUT "You are running VMS ''VERSION'; ", - "VMS_SHARE V06.10 7-FEB-1989 requires VMS V4.4 or higher." $ EXIT 44 ! SS$_ABORT $VERSION_OK: $ GOTO START $! $UNPACK_FILE: $ WRITE SYS$OUTPUT "Creating ''FILE_IS'" $ DEFINE/USER_MODE SYS$OUTPUT NL: $ EDIT/TPU/COMMAND=SYS$INPUT/NODISPLAY/OUTPUT='FILE_IS'/NOSECTION - VMS_SHARE_DUMMY.DUMMY b_part := CREATE_BUFFER( "{Part}", GET_INFO( COMMAND_LINE, "file_name" ) ) ; s_file_spec := GET_INFO( COMMAND_LINE, "output_file" ); SET( OUTPUT_FILE , b_part, s_file_spec ); b_errors := CREATE_BUFFER( "{Errors}" ); i_errors := 0; pat_beg_1 := ANCHOR & "-+-+-+ Beginning"; pat_beg_2 := LINE_BEGIN & "+-+-+-+ Beginning"; pat_end := ANCHOR & "+-+-+-+-+ End"; POSITION ( BEGINNING_OF( b_part ) ); LOOP EXITIF SEARCH( SPAN( ' ' )@r_trail & LINE_END, FORWARD) = 0; POSITION( r_trail ); ERASE( r_trail ); ENDLOOP ; POSITION( BEGINNING_OF( b_part ) ); i_append_line := 0; LOOP EXITIF MARK ( NONE ) = END_OF( b_part ); s_x := ERASE_CHARACTER( 1 ) ; IF s_x = '+' THEN r_skip := SEARCH( pat_beg_1, FORWARD, EXACT ); IF r_skip <> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ERASE_LINE; ENDIF ; ENDIF; IF s_x = '-' THEN r_skip := SEARCH( pat_end, FORWARD, EXACT ) ; IF r_skip <> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); m_skip := MARK( NONE ); r_skip := SEARCH( pat_beg_2, FORWARD, EXACT ); IF r_skip <> 0 THEN POSITION( END_OF( r_skip ) ); MOVE_HORIZONTAL( -CURRENT_OFFSET ) ; MOVE_VERTICAL( 1 ); MOVE_HORIZONTAL( -1 ); ELSE POSITION( END_OF( b_part ) ); ENDIF; ERASE( CREATE_RANGE( m_skip, MARK( NONE ), NONE ) ); ENDIF; ENDIF ; IF s_x = 'V' THEN s_x := ''; IF i_append_line <> 0 THEN APPEND_LINE ; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF; i_append_line := 1 ; MOVE_VERTICAL( 1 ); ENDIF; IF s_x = 'X' THEN s_x := ''; IF i_append_line <> 0 THEN APPEND_LINE; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF ; i_append_line := 0; MOVE_VERTICAL( 1 ); ENDIF; IF s_x <> '' THEN i_errors := i_errors + 1; s_text := CURRENT_LINE; POSITION( b_errors ); COPY_TEXT ( "The following line could not be unpacked properly:" ); SPLIT_LINE ; COPY_TEXT( s_x ); COPY_TEXT( s_text ); POSITION( b_part ); MOVE_VERTICAL ( 1 ); ENDIF; ENDLOOP; POSITION( BEGINNING_OF( b_part ) ); LOOP r_x := SEARCH ( "`", FORWARD, EXACT ); EXITIF r_x = 0; POSITION( r_x ); ERASE_CHARACTER( 1 ); COPY_TEXT( ASCII( INT( ERASE_CHARACTER( 3 ) ) ) ); ENDLOOP ; IF i_errors = 0 THEN SET( NO_WRITE, b_errors, ON ); ELSE POSITION ( BEGINNING_OF( b_errors ) ); COPY_TEXT( FAO ( "The following !UL errors were detected while unpacking !AS", i_errors , s_file_spec ) ); SPLIT_LINE; SET( OUTPUT_FILE, b_errors, "SYS$COMMAND" ) ; ENDIF; EXIT; $ DELETE VMS_SHARE_DUMMY.DUMMY;* $ CHECKSUM 'FILE_IS $ WRITE SYS$OUTPUT " CHECKSUM ", - F$ELEMENT( CHECKSUM_IS .EQ. CHECKSUM$CHECKSUM, ",", "failed!!,passed." ) $ RETURN $! $START: $ FILE_IS = "DECW_SERVER.COM" $ CHECKSUM_IS = 638244421 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X$! decw_server.com - set display and execute command `032 X$ set noon X$ time = f$extract(18,4,f$time()) - "." X$ node = f$trnlnm("sys$rem_node") - "::" X$ pid = f$extract(4,4,f$getjpi("","pid")) X$ login = f$trnlnm("sys$login") X$ open network sys$net X$ read network prog X$ close network X$ if prog .eqs. "DECterm" ! special case, already runs detached X$ then X$ write sys$output "Create DECterm for node " + node X$ @remote_decterm 'node' X$ exit X$ endif X$ open/write out decw_server_'pid''time'.com X$ write out "$ set noon" X$ write out "$ delete decw_server_" + pid + time + ".com;*" X$ write out "$ define/job sys$login ''login'" X$ write out "$ set display/crea/node=''node'" X$ write out "$ ''prog'" X$ write out "$ set display/noperm" X$ close out X$ type decw_server_'pid''time'.com X$ run/det/authorize/input=decw_server_'pid''time'.com/output=nl: - X /process="Server_''pid'''time'" sys$system:loginout X$ exit $ GOSUB UNPACK_FILE $ FILE_IS = "DECW_WAIT.COM" $ CHECKSUM_IS = 1933386507 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X$! decw_wait.com - wait for decwindows session manager to come up X$restart: X$ context = "" X$loop: X$ pid = f$pid(context) X$ if pid .eqs. "" then goto pause X$ if f$parse(f$getjpi(pid,"imagname"),,,"name") .eqs. "DECW$SESSION" X$ then X$ term == f$getjpi(pid,"terminal") X$ if term .eqs. "" then goto pause X$ exit X$ endif X$ goto loop X$pause: X$ wait 00:00:05 X$ goto restart $ GOSUB UNPACK_FILE $ FILE_IS = "REMOTE_DECTERM.COM" $ CHECKSUM_IS = 674773066 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X$! remote_decterm.com - start a remote decterm on node X$! from the VMS V5.1-1 release notes X$ set noon !don't fail on dup decterms X$ node = P1 X$ if node .eqs. "" then inquire node "Node name" X$ mailbox = f$trnlnm("decw$decterm_mailbox_" + node + "::0.0") X$ if mailbox .nes. "" X$ then X$ if f$getdvi(mailbox, "exists") then goto skip_run_controller X$ endif X$ term_file = "sys$scratch:term_" + f$getjpi("","pid") + ".tmp" X$ term_file = f$parse( term_file,,,,"no_conceal" ) X$ open/write term 'term_file' X$ write term "$ set noon" X$ write term "$ delete " + term_file X$ write term "$ set display/create/node=" + node + "::0.0" X$ write term "$ run sys$system:decw$terminal" X$ write term "$ set display/noperm" X$ close term X$ run/detach/input='term_file'- X /output=nl:- X /error=nl:- X /process="DECterm_''node'"- X sys$system:loginout.exe X$skip_run_controller: X$ mcr create_decterm 'node'::0.0 X$ exit $ GOSUB UNPACK_FILE $ FILE_IS = "CREATE_DECTERM.C" $ CHECKSUM_IS = 1947606198 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X/* X * create_decterm.c X * sort of from VMS V5.1-1 release notes X * X * compile with: cc/noopt create_decterm X * link with: link create_decterm, sys$input/opt X * sys$library:decw$dwtlibshr/share X * sys$share:vaxcrtl/share X * sys$share:decw$terminalshr/share X * Usage is: mcr sys$login:create_decterm node::screen X */ X X#include descrip /* descriptor definitions */ X#include ssdef /* system status codes */ X#include prcdef /* stsflg bits for creating process */ X#include time X Xmain( argc, argv ) X int argc; X char **argv; X`123 X int status, stsflg, time_val, baspri = 15; X struct tm *time_structure; X char device_name[50], process_name[15], spid[9]; V struct dsc$descriptor_s display = `123 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0 ` X125; X $DESCRIPTOR( command, "SYS$SYSTEM:LOGINOUT.EXE" ); X $DESCRIPTOR( device, device_name ); X $DESCRIPTOR( prcnam, process_name ); X X /* first parameter is the display name */ X display.dsc$a_pointer = argv[1]; X display.dsc$w_length = strlen( argv[1] ); X X /* make a (semi)unique process name */ X strcpy( process_name, "DECterm_" ); X time( &time_val ); X time_structure = localtime( &time_val ); X sprintf( spid, "%04X%02d", getpid() & 0xffff, time_structure->tm_sec ); X strcat( process_name, spid ); X X /* send the message to the controller */ X status = DECw$Term_Port( &display, 0, 0, &device, &device.dsc$w_length ); X if ( status != SS$_NORMAL ) X printf( "DECterm creation failed, status is %d\n", status ); X else X `123 /* create a process that is already logged in */ X /* make it detached, interactive, logged in */ X stsflg = PRC$M_DETACH `124 PRC$M_INTER `124 PRC$M_NOPASSWORD; X X /* create the process */ V status = sys$creprc( 0, &command, &device, &device, 0, 0, 0, &prcnam, bas Xpri, 0, 0, stsflg ); X if ( status != SS$_NORMAL ) X printf( "Could not run LOGINOUT.EXE, status is %d\n", status ); X `125 X`125 $ GOSUB UNPACK_FILE $ EXIT