VMS command interpreter.
abbes at usl.UUCP
Tue May 20 12:42:27 AEST 1986
The source (and doc) follows: 1700 lines.
===============================================================
INSTALLATION GUIDE
1) This command interpreter consists of a lot of small command
procedures, organized into directories. Find a place to put it,
such as a directory "tools" or the home directory of a dedicated
user.
Create a directory "bin" for the general purpose command files
(profile.com, def0.com, etc.) and a directory "vmx" with three
subdirectories: "bin" for the .com files, "help" for the help
files, "users" for the init files of all the users.
2) Make sure that any user willing to use it has correct logical
assignments in his login.com (and other init files run at login).
> !--> file LOGIN.COM
> set noverify
> assign disk0:[root.z.bin] bin
> @bin:profile -- other logical assignments
> vmx -- on the last line
> !<-- end LOGIN.COM
3) When you install this set of procedures for the first time,
make sure to comment out the lines
!on control_y then goto ...
So that if anything goes wrong, you can still abort everything by
^Y.
4) After you have tried all possible sorts of commands, remove
the exclam marks so that control_y is handled.
5) There is a command that any user can use to create his init
file.
=================================================================
--> list of the files that make up VMX and SHELL
========== ========== ========== ========== ========== ==========
DISK0:[ROOT.Z]BIN.DIR 2
DISK0:[ROOT.Z]LOGIN.COM 1
DISK0:[ROOT.Z]VMX.DIR 1
Total of 3 files, 4 blocks.
========== ========== ========== ========== ========== ==========
DISK0:[ROOT.Z.BIN]CD.COM 1
DISK0:[ROOT.Z.BIN]COPY1.PAS 1
DISK0:[ROOT.Z.BIN]COPY2.PAS 1
DISK0:[ROOT.Z.BIN]CWD.COM 1
DISK0:[ROOT.Z.BIN]DEF0.COM 1
DISK0:[ROOT.Z.BIN]DEF1.COM 3
DISK0:[ROOT.Z.BIN]DEF2.COM 1
DISK0:[ROOT.Z.BIN]DEF3.COM 1
DISK0:[ROOT.Z.BIN]EDTINI.EDT 1
DISK0:[ROOT.Z.BIN]MKDIR.COM 1
DISK0:[ROOT.Z.BIN]PROFILE.COM 1
DISK0:[ROOT.Z.BIN]RM.COM 1
DISK0:[ROOT.Z.BIN]RMDIR.COM 1
DISK0:[ROOT.Z.BIN]SLEEP.COM 1
DISK0:[ROOT.Z.BIN]UP.COM 1
Total of 15 files, 17 blocks.
========== ========== ========== ========== ========== ==========
DISK0:[ROOT.Z.VMX]BIN.DIR 1
DISK0:[ROOT.Z.VMX]HELP.DIR 1
DISK0:[ROOT.Z.VMX]USERS.DIR 1
Total of 3 files, 3 blocks.
========== ========== ========== ========== ========== ==========
DISK0:[ROOT.Z.VMX.BIN]DEBUG.COM 1
DISK0:[ROOT.Z.VMX.BIN]DELETE.COM 1
DISK0:[ROOT.Z.VMX.BIN]ECHERR.COM 3
DISK0:[ROOT.Z.VMX.BIN]ECHO.COM 3
DISK0:[ROOT.Z.VMX.BIN]EDIX.COM 2
DISK0:[ROOT.Z.VMX.BIN]EDTINI.EDT 1
DISK0:[ROOT.Z.VMX.BIN]EXEC.COM 2
DISK0:[ROOT.Z.VMX.BIN]FORK.COM 6
DISK0:[ROOT.Z.VMX.BIN]HELP.COM 2
DISK0:[ROOT.Z.VMX.BIN]HISTORY.COM 2
DISK0:[ROOT.Z.VMX.BIN]INITVMX.COM 4
DISK0:[ROOT.Z.VMX.BIN]NODEBUG.COM 1
DISK0:[ROOT.Z.VMX.BIN]PIPE.COM 13
DISK0:[ROOT.Z.VMX.BIN]SEND.COM 5
DISK0:[ROOT.Z.VMX.BIN]SH.COM 1
DISK0:[ROOT.Z.VMX.BIN]SHELL.COM 12
DISK0:[ROOT.Z.VMX.BIN]VMX.COM 10
DISK0:[ROOT.Z.VMX.BIN]VMXSHELL.COM 1
Total of 18 files, 70 blocks.
========== ========== ========== ========== ========== ==========
DISK0:[ROOT.Z.VMX.HELP]DEBUG.HLP 2
DISK0:[ROOT.Z.VMX.HELP]ECHO.HLP 1
DISK0:[ROOT.Z.VMX.HELP]EDIX.HLP 2
DISK0:[ROOT.Z.VMX.HELP]FILES.HLP 2
DISK0:[ROOT.Z.VMX.HELP]FORK.HLP 2
DISK0:[ROOT.Z.VMX.HELP]GRAMMAR.HLP 2
DISK0:[ROOT.Z.VMX.HELP]HELP.HLP 1
DISK0:[ROOT.Z.VMX.HELP]HS.HLP 2
DISK0:[ROOT.Z.VMX.HELP]NICE.HLP 2
DISK0:[ROOT.Z.VMX.HELP]PIPE.HLP 2
DISK0:[ROOT.Z.VMX.HELP]SEMANTIX.HLP 1
DISK0:[ROOT.Z.VMX.HELP]SEND.HLP 1
DISK0:[ROOT.Z.VMX.HELP]SH.HLP 2
DISK0:[ROOT.Z.VMX.HELP]SHELL.HLP 2
DISK0:[ROOT.Z.VMX.HELP]SYMBOL.HLP 2
DISK0:[ROOT.Z.VMX.HELP]TOPICS.HLP 1
DISK0:[ROOT.Z.VMX.HELP]VMX.HLP 3
DISK0:[ROOT.Z.VMX.HELP]VMXSHELL.HLP 2
Total of 18 files, 32 blocks.
========== ========== ========== ========== ========== ==========
DISK0:[ROOT.Z.VMX.USERS]JACK.INI 4
DISK0:[ROOT.Z.VMX.USERS]JEAN.INI 4
DISK0:[ROOT.Z.VMX.USERS]JOHN.INI 4
Total of 3 files, 12 blocks.
========== ========== ========== ========== ========== ==========
Grand total of 6 directories, 60 files, 138 blocks.
========== ========== ========== ========== ========== ==========
<-- end of list
!--> file LOGIN.COM ---------- ---------- ---------- --------->
$
set noverify
set term/dev=vt100
$
assign disk0:[root.z.bin] bin
@bin:profile
vmx
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file DEBUG.COM ---------- ---------- ---------- --------->
is_debug_'p1' :== true
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file DELETE.COM ---------- ---------- ---------- --------->
if f$search(p1) -
.nes. "" then delete 'p1'
$
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file ECHERR.COM ---------- ---------- ---------- --------->
arg_string = "''p1' ''p2' ''p3' ''p4' ''p5' ''p6' ''p7' ''p8'"
argument_line := 'arg_string
LOOP_ON_BLANK:
length = f$length(argument_line)
position = f$locate("\B", argument_line)
exists_blank = position .ne. length
if .not. exists_blank then goto EXIT_LOOP_ON_BLANK
argument_line = f$extract(0, position, argument_line) + " " + -
f$extract(2 + position, length, argument_line)
END_LOOP_ON_BLANK: goto LOOP_ON_BLANK
EXIT_LOOP_ON_BLANK:
LOOP_ON_NEWLINE:
length = f$length(argument_line)
position = f$locate("\N", argument_line)
exists_newline = position .ne. length
first_line = f$extract(0, position, argument_line)
argument_line = f$extract(2 + position, length, argument_line)
write sys$error first_line
if .not. exists_newline then exit
END_LOOP_ON_NEWLINE: goto LOOP_ON_NEWLINE
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file ECHO.COM ---------- ---------- ---------- --------->
arg_string = "''p1' ''p2' ''p3' ''p4' ''p5' ''p6' ''p7' ''p8'"
argument_line := 'arg_string
LOOP_ON_BLANK:
length = f$length(argument_line)
position = f$locate("\B", argument_line)
exists_blank = position .ne. length
if .not. exists_blank then goto EXIT_LOOP_ON_BLANK
argument_line = f$extract(0, position, argument_line) + " " + -
f$extract(2 + position, length, argument_line)
END_LOOP_ON_BLANK: goto LOOP_ON_BLANK
EXIT_LOOP_ON_BLANK:
LOOP_ON_NEWLINE:
length = f$length(argument_line)
position = f$locate("\N", argument_line)
exists_newline = position .ne. length
first_line = f$extract(0, position, argument_line)
argument_line = f$extract(2 + position, length, argument_line)
write sys$output first_line
if .not. exists_newline then exit
END_LOOP_ON_NEWLINE: goto LOOP_ON_NEWLINE
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file EDIX.COM ---------- ---------- ---------- --------->
user_id = f$getjpi("", "username")
user_name := 'user_id
user_init_file = "vmx_users_dir:" + user_name + ini_extension
if f$search(user_init_file) -
.eqs. "" then vmx_put_line "edix: creating ''user_init_file'"
if f$search(user_init_file) -
.eqs. "" then wait 0:0:3
if f$search(user_init_file) -
.eqs. "" then vmx_copy vmx_dir:initvmx.com 'user_init_file'
$
vmx_put_line "edix: opening ''user_init_file'"
vmx_put_line " type ^Z, then QUIT or EXIT to exit the editor"
wait 0:0:3
input_mode = f$logical("sys$input")
if input_mode .nes. "SYS$COMMAND:" then -
define/user_mode sys$input sys$command:
vmx_edit 'user_init_file'
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file EDTINI.EDT ---------- ---------- ---------- --------->
set mode change
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file EXEC.COM ---------- ---------- ---------- --------->
is_verify = f$verify(is_debug_exec)
$! procedure EXEC (P1 : STRING := "") is
on warning then goto WHEN_WARNING
on error then goto WHEN_ERROR
on severe_error then goto WHEN_SEVERE_ERROR
on control_y then goto WHEN_CONTROL_Y
argument_string := 'p1'
command_line = 'argument_string
'command_line 'p2' 'p3' 'p4' 'p5' 'p6' 'p7' 'p8'
$
EXCEPTION: goto RETURN
WHEN_WARNING:
vmx_put_error "exec: warning"
exit
WHEN_ERROR:
vmx_put_error "exec: error"
exit
WHEN_SEVERE_ERROR:
vmx_put_error "exec: severe_error"
exit
WHEN_CONTROL_Y:
vmx_put_error "exec: control_y"
$! end EXEC;
RETURN: is_verify = f$verify(is_verify)
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file FORK.COM ---------- ---------- ---------- --------->
is_verify = f$verify(is_debug_fork)
$! procedure FORK (P1 : STRING := "";
$! P2 : NATURAL := 0) is
is_new_input = false
is_new_output = false
is_to_fork = false
on warning then goto WHEN_WARNING
on error then goto WHEN_ERROR
on severe_error then goto WHEN_SEVERE_ERROR
on control_y then goto WHEN_CONTROL_Y
argument_string := 'p1'
fork_line = 'argument_string
second_argument = 'p2
if p2 .eqs. "" then second_argument = "000"
count_string := 'second_argument
initial_name = "fork" + count_string
fork_out_file = initial_name + out_extension
fork_com_file = initial_name + vmx_extension
message_in = "fork: <" + in_file
message_out = "fork: >" + fork_out_file
LOOP:
first_char = f$extract(0, 1, fork_line)
is_special = first_char .eqs. "<" .or. first_char .eqs. ">" .or. -
first_char .eqs. "&" .or. first_char .eqs. " "
if .not. is_special then goto EXIT_LOOP
if first_char .eqs. "<" then is_new_input = true
if first_char .eqs. ">" then is_new_output = true
if first_char .eqs. "&" then is_to_fork = true
fork_line = f$extract(1, f$length(fork_line), fork_line)
if first_char .eqs. "&" then goto EXIT_LOOP
END_LOOP: goto LOOP
EXIT_LOOP: if .not. is_to_fork then goto RETURN
if is_new_input then vmx_put_line message_in
if is_new_output then vmx_put_line message_out
first_def = "first_argument := " + """""""" + fork_line + """"""""
first_arg = "line_arg = 'first_argument"
second_def = "second_argument = " + count_string
second_arg = "count_arg := 'second_argument"
shell_call = "vmx_shell line_arg count_arg"
open/write logical_file 'fork_com_file
write logical_file first_def
write logical_file first_arg
write logical_file second_def
write logical_file second_arg
write logical_file shell_call
close logical_file
fork_line := 'vmx_spawn
if is_new_input then fork_line = fork_line + "/input=" + in_file
if is_new_output then fork_line = fork_line + "/output=" + fork_out_file
fork_line = fork_line + " @" + fork_com_file
vmx_exec fork_line
$
vmx_delete 'fork_com_file.*
$
EXCEPTION: goto RETURN
WHEN_WARNING:
vmx_put_error "fork: warning"
goto RETURN
WHEN_ERROR:
vmx_put_error "fork: error"
goto RETURN
WHEN_SEVERE_ERROR:
vmx_put_error "fork: severe_error"
goto RETURN
WHEN_CONTROL_Y:
vmx_put_error "fork: control_y"
$! end FORK;
RETURN: is_verify = f$verify(is_verify)
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file HELP.COM ---------- ---------- ---------- --------->
reply = p1
if reply .nes. "" then goto HAS_REPLY
ty vmx_help_dir:help.hlp
$
LOOP:
ty vmx_help_dir:topics.hlp
$
inquire/nopunctuation reply "Topic? "
if reply .eqs. "" then exit
HAS_REPLY:
help_file = "vmx_help_dir:" + reply + ".hlp"
if f$search(help_file) -
.nes. "" then ty 'help_file'
$
if f$search(help_file) -
.eqs. "" then vmx_put_line " Sorry, no documentation on ''reply'"
$
END_LOOP: goto LOOP
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file HISTORY.COM --------- ---------- ---------- --------->
is_verify = f$verify(is_debug_history)
$! procedure HISTORY (P1 : NATURAL) is
index = count - p1
if p1 .eqs. "" .or. p1 .gt. count then index = init_count - 1
if p1 .eqs. "" .and. count .ge. max_lines_for_hs - 1 then -
index = count - max_lines_for_hs
if p1 .nes. "" .and. 0 .ge. p1 then goto RETURN
LOOP_HISTORY:
index = 1 + index
history_string = tab + "when " + f$string(index) + -
" => " + tab + string_array'index
vmx_put_line history_string
modulo = index - modulo_for_hs * (index / modulo_for_hs)
if modulo .eq. modulo_for_hs - 1 then vmx_put_line ""
if index .ge. count then goto RETURN
END_LOOP_HISTORY: goto LOOP_HISTORY
$! end HISTORY;
RETURN: is_verify = f$verify(is_verify)
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file INITVMX.COM --------- ---------- ---------- --------->
vmx_extension :== ".vmx"
ini_extension :== ".ini"
com_extension :== ".com"
job_extension :== ".job"
in_file :== "temp.in"
out_extension :== ".out"
err_extension :== ".err"
res_extension :== ".res"
hx :== @vmx_dir:help
hs :== @vmx_dir:history
edix :== @vmx_dir:edix
debug :== @vmx_dir:debug
no_debug :== @vmx_dir:nodebug
sh :== @vmx_dir:sh
vmx_shell :== @vmx_dir:vmxshell
vmx_send :== @vmx_dir:send
vmx_fork :== @vmx_dir:fork
vmx_pipe :== @vmx_dir:pipe
vmx_exec :== @vmx_dir:exec
vmx_delete :== @vmx_dir:delete
vmx_nice :== submit/noprinter/delete/noid/log_file=[]'res_extension
vmx_spawn :== spawn/nowait/nolog
vmx_rename :== rename
vmx_copy :== copy
vmx_edit :== edit/edt/command=vmx_dir:edtini.edt
vmx_put_line :== write sys$error
vmx_put_help :== if is_help_message then write sys$error
vmx_put_warning :== if is_warning_message then write sys$error
vmx_put_error :== if is_error_message then write sys$error
max_control_y :== 3
max_count :== 333
init_count :== 0
max_lines_for_hs :== 15
constant_ps1 :== "_"
ps1 :== "''constant_ps1'"
constant_tab :== " "
tab :== "''constant_tab'"
false :== 0
true :== 1
is_help_message :== true
is_warning_message :== true
is_error_message :== true
is_vmx_wanted :== true
is_debug_vmx :== false
is_debug_shell :== false
is_debug_pipe :== false
is_debug_fork :== false
is_debug_send :== false
is_debug_nice :== false
is_debug_exec :== false
is_debug_history :== false
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file NODEBUG.COM --------- ---------- ---------- --------->
is_debug_'p1' :== false
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file PIPE.COM ---------- ---------- ---------- --------->
is_verify = f$verify(is_debug_pipe)
$! procedure PIPE (P1 : STRING := "";
$! P2 : NATURAL := 0) is
pipe_max_control_y = 3
control_y_count = 0
pipe_count = -1
on warning then goto WHEN_WARNING
on error then goto WHEN_ERROR
on severe_error then goto WHEN_SEVERE_ERROR
on control_y then goto WHEN_CONTROL_Y
argument_string := 'p1'
command_line = 'argument_string
second_argument = 'p2
if p2 .eqs. "" then second_argument = "000"
count_string := 'second_argument
initial_name = "pip" + count_string + "x"
message_in = "pipe: <" + in_file
in_pipe = "inpip" + count_string + vmx_extension
out_pipe = "outpip" + count_string + vmx_extension
com_pipe = "compip" + count_string + vmx_extension
deassign_sys_input = "deassign sys$input"
pipe_sys_command = "assign/user_mode " + in_pipe + " sys$command"
assign_sys_command = "assign/user_mode " + in_file + " sys$command"
assign_sys_input = "assign/user_mode sys$command: sys$input"
open_sys_error = "open/write sys$error: "
define_sys_error = "define sys$error sys$error:"
deassign_sys_error = "$deassign sys$error"
close_sys_error = "$close sys$error:"
is_a_pipe = false
LOOP:
was_a_pipe = is_a_pipe
length_line = f$length(command_line)
position_pipe = f$locate("|", command_line)
is_a_pipe = position_pipe .ne. length_line
p = length_line - position_pipe - 1
first_command = f$extract(0, position_pipe, command_line)
command_line = f$extract(1 + position_pipe, p, command_line)
if first_command .eqs. "" then goto END_EXEC_COM
open/write pipe_file 'com_pipe
if was_a_pipe then write pipe_file pipe_sys_command
write pipe_file deassign_sys_input
write pipe_file assign_sys_input
command_all = first_command
OUTER_LOOP:
is_new_input = false
is_new_output = false
is_new_error = false
is_a_job = false
pipe_count = 1 + pipe_count
prefix_file = initial_name + f$string(pipe_count)
com_file = prefix_file + vmx_extension
job_file = prefix_file + job_extension
out_file = prefix_file + out_extension
err_file = prefix_file + err_extension
open_sys_error_string = open_sys_error + err_file
length_all = f$length(command_all)
position = f$locate(";", command_all)
is_multiple = position .ne. length_all
p = length_line - position - 1
command_one = f$extract(0, position, command_all)
command_all = f$extract(1 + position, p, command_all)
if command_one .eqs. "" then goto END_MULTIPLE_COMMAND
INNER_LOOP:
first_char = f$extract(0, 1, command_one)
is_special = first_char .eqs. "<" .or. first_char .eqs. ">" .or. -
first_char .eqs. "?" .or. first_char .eqs. "+" .or. -
first_char .eqs. " "
if .not. is_special then goto EXIT_INNER_LOOP
if first_char .eqs. "<" then is_new_input = true
if first_char .eqs. ">" then is_new_output = true
if first_char .eqs. "?" then is_new_error = true
if first_char .eqs. "+" then is_a_job = true
command_one = f$extract(1, f$length(command_one), command_one)
END_INNER_LOOP: goto INNER_LOOP
EXIT_INNER_LOOP:
if .not. is_new_output .and. .not. is_a_job then goto STANDARD_OUTPUT
REDIRECT_OUTPUT:
change_dir = "$set def " + f$logical("sys$disk") + f$directory()
open/write logical_file 'com_file
if is_a_job then write logical_file change_dir
write logical_file "$''command_one'"
close logical_file
if is_new_output then command_one = "@" + com_file + "/out=" + out_file
if is_a_job then vmx_rename 'com_file 'job_file
$ if is_a_job then command_one = "vmx_nice " + job_file
STANDARD_OUTPUT:
message_out = "pipe: >" + out_file
message_err = "pipe: ?" + err_file
if is_new_input then deassign sys$input
if is_new_input then assign/user_mode in_file sys$input
if is_new_input then vmx_put_line message_in
if is_new_output then vmx_put_line message_out
if is_new_error then vmx_put_line message_err
if is_new_error then write pipe_file open_sys_error_string
if is_new_error then write pipe_file define_sys_error
write pipe_file "$''command_one'"
if is_new_error then write pipe_file deassign_sys_error
if is_new_error then write pipe_file close_sys_error
if .not. is_multiple then goto EXIT_OUTER_LOOP
END_MULTIPLE_COMMAND:
if command_all .eqs. "" then goto EXIT_OUTER_LOOP
END_OUTER_LOOP: goto OUTER_LOOP
EXIT_OUTER_LOOP:
close pipe_file
EXEC_COM:
command_one = "@''com_pipe'"
if is_a_pipe then command_one = command_one + "/out=''out_pipe'"
vmx_exec command_one
$ if is_a_pipe then vmx_rename 'out_pipe 'in_pipe
$ vmx_delete 'initial_name'*'vmx_extension'.*
$ vmx_delete 'com_pipe.*
$ if .not. is_a_pipe then vmx_delete 'in_pipe.*
$ if .not. is_a_pipe then goto RETURN
END_EXEC_COM:
if command_line .eqs. "" then goto RETURN
EXCEPTION: goto END_LOOP
WHEN_WARNING:
vmx_put_error "pipe: warning"
goto END_LOOP
WHEN_ERROR:
vmx_put_error "pipe: error"
goto END_LOOP
WHEN_SEVERE_ERROR:
vmx_put_error "pipe: severe_error"
goto END_LOOP
WHEN_CONTROL_Y:
control_y_string = "pipe: control_y"
control_y_count = 1 + control_y_count
if control_y_count .eq. 1 then -
control_y_string = control_y_string + " (only " + -
pipe_max_control_y + " allowed)"
if control_y_count .eq. pipe_max_control_y - 1 then -
control_y_string = control_y_string + " (next is last)"
if control_y_count .eq. pipe_max_control_y then -
control_y_string = control_y_string + " (last)"
if control_y_count .gt. pipe_max_control_y then -
control_y_string = control_y_string + " (exit)"
vmx_put_error control_y_string
if control_y_count .gt. pipe_max_control_y then goto RETURN
END_LOOP: goto LOOP
$! end PIPE;
RETURN: is_verify = f$verify(is_verify)
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file SEND.COM ---------- ---------- ---------- --------->
is_verify = f$verify(is_debug_send)
$! procedure SEND (P1 : STRING := "";
$! P2 : NATURAL := 0) is
on warning then goto WHEN_WARNING
on error then goto WHEN_ERROR
on severe_error then goto WHEN_SEVERE_ERROR
on control_y then goto WHEN_CONTROL_Y
argument_string := 'p1'
send_line = 'argument_string
second_argument = 'p2
if p2 .eqs. "" then second_argument = "000"
count_string := 'second_argument
is_to_send = false
initial_name = "send" + count_string
send_com_file = initial_name + vmx_extension
LOOP:
first_char = f$extract(0, 1, send_line)
is_special = first_char .eqs. "^" .or. first_char .eqs. " "
if .not. is_special then goto EXIT_LOOP
if first_char .eqs. "^" then is_to_send = true
send_line = f$extract(1, f$length(send_line), send_line)
END_LOOP: goto LOOP
EXIT_LOOP: if .not. is_to_send then goto RETURN
change_dir = "set def " + f$logical("sys$disk") + f$directory()
first_def = "first_argument := " + """""""" + send_line + """"""""
first_arg = "line_arg = 'first_argument"
second_def = "second_argument = " + count_string
second_arg = "count_arg := 'second_argument"
shell_call = "vmx_shell line_arg count_arg"
open/write logical_file 'send_com_file
write logical_file change_dir
write logical_file first_def
write logical_file first_arg
write logical_file second_def
write logical_file second_arg
write logical_file shell_call
close logical_file
send_line := "vmx_nice ''send_com_file'"
vmx_exec send_line
$
EXCEPTION: goto RETURN
WHEN_WARNING:
vmx_put_error "send: warning"
goto RETURN
WHEN_ERROR:
vmx_put_error "send: error"
goto RETURN
WHEN_SEVERE_ERROR:
vmx_put_error "send: severe_error"
goto RETURN
WHEN_CONTROL_Y:
vmx_put_error "send: control_y"
$! end SEND;
RETURN: is_verify = f$verify(is_verify)
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file SH.COM ---------- ---------- ---------- --------->
from_vmx = 0
@vmx_dir:shell 'p1' 'from_vmx' 'p2'
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file SHELL.COM ---------- ---------- ---------- --------->
is_verify = f$verify(is_debug_shell)
$! procedure SHELL (P1 : STRING := "";
$! P2 : BOOLEAN;
$! P3 : NATURAL := 0) is
on warning then goto WHEN_WARNING
on error then goto WHEN_ERROR
on severe_error then goto WHEN_SEVERE_ERROR
on control_y then goto WHEN_CONTROL_Y
shell_max_control_y = 3
control_y_count = 0
shell_count = -1
argument_string := 'p1'
if p2 then command_line = 'argument_string
if .not. p2 then command_line := 'p1'
if p3 .nes. "" then second_argument = 'p3
if p3 .eqs. "" then second_argument = "0"
count_string := 'second_argument
initial_name = count_string
message_in = "shell: <" + in_file
LOOP_ON_SPACE:
length = f$length(command_line)
position = f$locate("\S", command_line)
exists_space = position .ne. length
if .not. exists_space then goto EXIT_LOOP_ON_SPACE
command_line = f$extract(0, position, command_line) + " " + -
f$extract(2 + position, length, command_line)
END_LOOP_ON_SPACE: goto LOOP_ON_SPACE
EXIT_LOOP_ON_SPACE:
length_line = f$length(command_line)
SEND_A_JOB:
position = f$locate("^", command_line)
is_a_job = position .ne. length_line
if is_a_job then vmx_send command_line count_string
if is_a_job then goto RETURN
FORK_A_PROCESS:
position = f$locate("&", command_line)
is_a_process = position .ne. length_line
if is_a_process then vmx_fork command_line count_string
if is_a_process then goto RETURN
RUN_A_PIPE:
position = f$locate("|", command_line)
is_a_pipe = position .ne. length_line
if is_a_pipe then vmx_pipe command_line count_string
if is_a_pipe then goto RETURN
LOOP:
on warning then goto WHEN_WARNING
on error then goto WHEN_ERROR
on severe_error then goto WHEN_SEVERE_ERROR
on control_y then goto WHEN_CONTROL_Y
is_new_input = false
is_new_output = false
is_new_error = false
is_a_job = false
shell_count = 1 + shell_count
prefix_file = initial_name + "x" + f$string(shell_count)
com_file = prefix_file + vmx_extension
out_file = prefix_file + out_extension
err_file = prefix_file + err_extension
length_line = f$length(command_line)
position = f$locate(";", command_line)
is_multiple = position .ne. length_line
p = length_line - position - 1
first_command = f$extract(0, position, command_line)
command_line = f$extract(1 + position, p, command_line)
if first_command .eqs. "" then goto END_EXEC_COM
INNER_LOOP:
first_char = f$extract(0, 1, first_command)
is_special = first_char .eqs. "<" .or. first_char .eqs. ">" .or. -
first_char .eqs. "?" .or. first_char .eqs. "+" .or. -
first_char .eqs. " "
if .not. is_special then goto EXIT_INNER_LOOP
if first_char .eqs. "<" then is_new_input = true
if first_char .eqs. ">" then is_new_output = true
if first_char .eqs. "?" then is_new_error = true
if first_char .eqs. "+" then is_a_job = true
first_command = f$extract(1, f$length(first_command), first_command)
END_INNER_LOOP: goto INNER_LOOP
EXIT_INNER_LOOP:
if .not. is_new_output .and. .not. is_a_job then goto STANDARD_OUTPUT
REDIRECT_OUTPUT:
change_dir = "set def " + f$logical("sys$disk") + f$directory()
open/write logical_file 'com_file
if is_a_job then write logical_file change_dir
write logical_file first_command
close logical_file
if is_new_output then first_command = "@" + com_file + "/out=" + out_file
if is_a_job then first_command = "vmx_nice " + com_file
STANDARD_OUTPUT:
message_out = "shell: >" + out_file
message_err = "shell: ?" + err_file
if is_new_input then deassign sys$input
if is_new_input then assign/user_mode in_file sys$input
if is_new_input then vmx_put_line message_in
if is_new_output then vmx_put_line message_out
if is_new_error then vmx_put_line message_err
if is_new_error then open/write sys$error: 'err_file'
if is_new_error then define sys$error sys$error:
EXEC_COM:
vmx_exec first_command
$
if is_new_error then deassign sys$error
if is_new_error then close sys$error:
if is_new_output .and. .not. is_a_job then vmx_delete 'com_file.*
$
if .not. is_multiple then goto RETURN
END_EXEC_COM:
if command_line .eqs. "" then goto RETURN
EXCEPTION: goto END_LOOP
WHEN_WARNING:
vmx_put_error "shell: warning"
goto END_LOOP
WHEN_ERROR:
vmx_put_error "shell: error"
goto END_LOOP
WHEN_SEVERE_ERROR:
vmx_put_error "shell: severe_error"
goto END_LOOP
WHEN_CONTROL_Y:
control_y_string = "shell: control_y"
control_y_count = 1 + control_y_count
if control_y_count .eq. 1 then -
control_y_string = control_y_string + " (only " + -
shell_max_control_y + " allowed)"
if control_y_count .eq. shell_max_control_y - 1 then -
control_y_string = control_y_string + " (next is last)"
if control_y_count .eq. shell_max_control_y then -
control_y_string = control_y_string + " (last)"
if control_y_count .gt. shell_max_control_y then -
control_y_string = control_y_string + " (exit)"
vmx_put_error control_y_string
if control_y_count .gt. shell_max_control_y then goto RETURN
END_LOOP: goto LOOP
RETURN:
$! end SHELL;
is_verify = f$verify(is_verify)
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file VMX.COM ---------- ---------- ---------- --------->
INIT:
vmx_init_file = "vmx_dir:initvmx.com"
if f$search(vmx_init_file) -
.eqs. "" then exit
@'vmx_init_file
$
user_id = f$getjpi("", "username")
user_name := 'user_id
user_init_file = "vmx_users_dir:" + user_name + ini_extension
if f$search(user_init_file) -
.eqs. "" then -
vmx_put_warning "vmx: can't open ''user_init_file'; use EDIX"
if f$search(user_init_file) -
.nes. "" then @'user_init_file
$
END_INIT:
modulo_for_hs = max_lines_for_hs / 5
control_y_count = 0
count = init_count - 1
if f$mode() .nes. "INTERACTIVE" then exit
if .not. is_vmx_wanted then exit
vmx_put_help "vmx: type HX for help, EX to exit"
LOOP:
is_verify = f$verify(is_debug_vmx)
$! procedure VMX is
on warning then goto WHEN_WARNING
on error then goto WHEN_ERROR
on severe_error then goto WHEN_SEVERE_ERROR
on control_y then goto WHEN_CONTROL_Y
if count .ge. max_count then count = init_count - 1
count = 1 + count
count_string = f$string(count)
input_mode = f$logical("sys$input")
if input_mode .nes. "SYS$COMMAND:" then -
define/user_mode sys$input sys$command:
global_prompt = f$string('count) + PS1
prompt := 'global_prompt
string_array'count = "control_y"
inquire/nopunctuation command_line "''prompt' "
string_array'count = command_line
first_char = f$extract(0, 1, command_line)
is_a_digit = "0" .les. first_char .and. first_char .les. "9"
is_to_edit = first_char .eqs. "/"
is_previous = first_char .eqs. "\"
if is_previous then index = count - 1
if is_previous then command_line = string_array'index
if is_a_digit then command_line = string_array'command_line
if is_a_digit .or. is_previous then string_array'count = command_line
if is_a_digit .or. is_previous then vmx_put_line "''prompt' ''command_line'"
if .not. is_to_edit then goto NOT_TO_EDIT
BLOCK_EDIT:
old_com = "oldcom''count_string'" + vmx_extension
new_com = "newcom''count_string'" + vmx_extension
command_line = f$extract(1, f$length(command_line), command_line)
if command_line .eqs. "" then position = count - 1
if command_line .nes. "" then position = command_line
command_line = string_array'position
open/write logical_file 'new_com
close logical_file
open/write logical_file 'old_com
write logical_file command_line
close logical_file
command_line = ""
vmx_edit/nojournal/output='new_com 'old_com
$ open/read logical_file 'new_com
read logical_file command_line /end_of_file=WHEN_END_OF_FILE
input_mode = f$logical("sys$input")
if input_mode .nes. "SYS$COMMAND:" then -
define/user_mode sys$input sys$command:
EXCEPTION:
WHEN_END_OF_FILE:
close logical_file
string_array'count = command_line
vmx_delete 'old_com.*
$ vmx_delete 'new_com.*
$ vmx_put_line "''prompt' ''command_line'"
END_BLOCK_EDIT:
NOT_TO_EDIT:
length_line = f$length(command_line)
position_semicolon = f$locate(";", command_line)
exists_semicolon = position_semicolon .ne. length_line
is_for_shell = exists_semicolon
if is_for_shell then goto CALL_THE_SHELL
if command_line .eqs. "EX" then goto RETURN
if command_line .eqs. "INIX" then count = INIT_COUNT - 1
if command_line .eqs. "INYX" then control_y_count = 0
if command_line .eqs. "INIX" .or. -
command_line .eqs. "INYX" then goto END_LOOP
VMS_COMMAND:
vmx_exec command_line
$END_VMS_COMMAND: goto END_LOOP
CALL_THE_SHELL:
vmx_shell command_line count_string
END_CALL_THE_SHELL: goto END_LOOP
EXCEPTION:
WHEN_WARNING:
vmx_put_error "vmx: warning"
goto END_LOOP
WHEN_ERROR:
vmx_put_error "vmx: error"
goto END_LOOP
WHEN_SEVERE_ERROR:
vmx_put_error "vmx: severe_error"
goto END_LOOP
WHEN_CONTROL_Y:
control_y_string = "vmx: control_y"
control_y_count = 1 + control_y_count
if control_y_count .eq. 1 then -
control_y_string = control_y_string + " (only " + -
max_control_y + " allowed)"
if control_y_count .eq. max_control_y - 1 then -
control_y_string = control_y_string + " (next is last)"
if control_y_count .eq. max_control_y then -
control_y_string = control_y_string + " (last)"
if control_y_count .gt. max_control_y then -
control_y_string = control_y_string + " (exit)
vmx_put_error control_y_string
if control_y_count .gt. max_control_y then goto RETURN
END_LOOP:
$! end VMX;
goto LOOP
RETURN: is_verify = f$verify(is_verify)
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file VMXSHELL.COM -------- ---------- ---------- --------->
from_vmx = true
@vmx_dir:shell 'p1' 'from_vmx' 'p2'
!<-- end ---------- ---------- ---------- ---------- <---------
(help DEBUG) DEBUG turns the trace on in the command procedures that
implementVMX and SHELL. NO_DEBUG turns the trace off. This is useful
to locate the problem if anything goes wrong. It also helps understand
the behaviour of the command procedures.
Note that you can change the symbol DEBUG to, for instance,
DEBUG_ON in your init file.
The argument is one of:
VMX SHELL PIPE FORK
SEND NICE EXEC HISTORY
Note that you can set, for instance, is_debug_vmx :== true
in your init file. (end help)
(help ECHO) ECHO echoes its arguments (up to 8) on sys$output.
ECHERR does the same on sys$error.
To echo more than 8 arguments, use \b as a blank, and \n
as a newline to separate arguments.
ECHO is most useful as the first command in a pipe, as in:
echo send \n John \n\n How are you today\b? | mail;
-- sends a short message to user John. (end help)
(help EDIX) EDIX edits the file vmx_users_dir:USER_NAME.ini, if you're
user USER_NAME. The editor used is vmx_edit, EDT by default.
If the file doesn't exit, EDIX creates it, as a copy of the
file vmx_dir:initvmx.com.
Once the file exists, it is executed every time vmx is
invoked. It allows you to tailor the environment, including
values or symbols used by vmx.
res_extension :== ".ext" -- changes extension for batch log files
debux :== @vmx_dir:debug
vmx_nice :== submit/printer/delete/id/log_file=[]'res_extension
vmx_spawn :== spawn/nowait/log
vmx_edit :== edit/edt/command=MY_OWN_DIRECTORY:edtini.edt
max_count :== 99 -- maximum number of a command
constant_ps1 :== "%" -- changes prompt
is_help_message :== false -- gets rid of initial message
is_vmx_wanted :== false -- doesn't run vmx, but allows use of SH (end help)
(help FILES) SHELL creates temporary files (removed by vmx_delete) and output
files when IO redirection is specified. VMX also creates temporary
files when a previous command is being edited for modification.
To preserve the temporary files, simply define vmx_delete :== "!"
in your init file. Note that you can modify the file extensions.
Their meaning is as follows:
vmx_extension : used by VMX and SHELL for various files
ini_extension : used for the users init files (in vmx_users_dir)
com_extension : used for command files
job_extension : used by PIPE for batch jobs command files
in_file : used for input redirection
out_extension : used for output redirection
err_extension : used for error redirection
res_extension : used for the result file of a batch job (end help)
(help FORK) FORK creates parallel processes, which names are USER_NAME_1,
USER_NAME_2 etc. if you're user USER_NAME.
The input and/or output of the process can be redirected, as in:
>&command_line; <&command_line; <>&command_line;
The process can be created by a batch job, in which case its
output must be redirected:
^>&command_line; ^<>&command_line;
vmx_spawn can be changed in your init_file to:
vmx_spawn :== spawn/nowait/log
so as to notify you of the creation of the process.
use CPU (:== monitor processes/topcpu) to see which processes
are currently executing.
use STOP USER_NAME_1 to kill process USER_NAME_1. (end help)
(help GRAMMAR) command_line ::= new_command | old_command
new_command ::= fork_command | pipe_command | vmx_command
fork_command ::= [^] {<, >} [&] pipe_command
pipe_command ::= shell_command [ | pipe_command]
shell_command ::= next_command ; next_command
next_command ::= {<, >, ?, +} single_command [ ; shell_command]
single_command ::= "" | any VMS command
vmx_command ::= EDIX | INIX | INYX | HS | HX | EX
old_command ::= repeat_command | edit_command | single_command
repeat_command ::= "\" | number of a previous command
edit_command ::= "/" [number of a previous command] (end help)
(help HELP)
Format:
^ command_line; + command;
& command_line; < command;
command_1 | command_2; > command;
command_1 ; command_2; ? command;
[/] [number] \
HX (help) INIX (inits count) HS [number] (history)
EX (exit) INYX (inits control_y) EDIX (edits init_file) (end help)
(help HS) HS [number] prints the history of command lines.
By default, number is min (max_lines_for_hs, current_number)
INIX brings current_number back to init_count, 0 by default. This
also happens if current_number exceeds max_count. Otherwise you
might get the error message "Too many symbols defined"
INYX brings control_y_count back to 0. You are logged out of vmx
when you have typed more than max_control_y (3 by default) ^Ys. This
feature is there to prevent looping when vmx is recently installed.
EX is to exit vmx (the inner invocation only)
HX is the help for vmx. (end help)
(help NICE) NICE and SEND are used to send batch jobs.
NICE sends a job consisting of a single command:
+command;
To submit a command file in batch, simply use:
+ at command_file;
You can change vmx_nice in your init_file, so as to be notified
of the job being sent:
vmx_nice :== submit/id/log_file=[].res
And the extension of the log file:
res_extension :== ".log"
Use RMJOB (:== del sys$batch/entry=) to abort a job.
Use B (:== show queue sys$batch) to see the batch queue. (end help)
(help PIPE) PIPE creates a pipe between a group of command; the operator |
has lower precedence than ^ and &, but higher precedence than ; + < > ?
Several pipes can link filters, as in this batch process:
^ <>& echo hello, world | copy | reverse | copy;
Any command can appear in a group of commands, as in:
com_1 ; com_2 | <com_3 ; >?com_4 ; com_5 | com_6 ; +com_7
Don't forget a semicolon somewhere on the line:
echo send\n John \n\n How are you? | mail; -- sends mail to John
but
echo send\n John \n\n How are you? | mail -- no semicolon, will echo
"send
John
How are you today ? | mail" (end help)
(help SEMANTIX)
Any command line submitted to the shell from vmx, ie any command line
containing special characters, must contain at least one semicolon ";"
The semicolon serves to recognize which command lines are to be
interpreted by the shell.
The period "." must be used instead of the semicolon to indicate
the version number, as in file.dat.1 (end help)
(help SEND) NICE and SEND are used to send batch jobs.
SEND sends an entire command_line:
^command_line;
You can change vmx_nice in your init_file, so as to be notified
of the job being sent:
vmx_nice :== submit/id/log_file=[].res
And the extension of the log file:
res_extension :== ".log"
Use RMJOB (:== del sys$batch/entry=) to abort a job.
Use B (:== show queue sys$batch) to see the batch queue. (end help)
(help SH) SH is the interface to the shell, used when command_lines come
directly from a user. For instance, if you are using the VMS
history mechanism rather than VMX, you may wish to use the shell to
interpret a complicated (but powerful) command_line.
First solution: Call VMX, wait for a prompt, enter a command_line,
and exit with EX.
Second solution: Use SH. Only one string argument, no space allowed. Use
\s as a space, except maybe for ECHO (use \b). Semicolon not required.
An optional numeric second argument (equivalent to current_number in VMX.)
Exemple:
SH DIR/DATE
SH ECHO\sHello,\bWorld!
SH ECHO\sSEND\n\sJohn\s\n\n\sHow\sAre\sYou\sToday\b?\s|\sMail; -- a pipe
Third solution: Use VMX_SHELL (in general from a command procedure) (end help)
(help SHELL)
SHELL is an interpreter that accepts a command_line from a user (see SH)
or from VMX (if it contains a semicolon) and runs it according to the
special characters used (see GRAMMAR and SEMANTIX)
Exemples of command_lines:
<& com_1 | <? com_2 ; + com_3 | >? com_4 -- a process
^ >& command_line; -- a batch job
Exemples of groups of commands in pipes:
+ com_1; com_2 | <>? com_3 ; com_4 | com_5 -- double pipe
Exemples of single commands:
+ command; -- a batch job
< command; -- input from temp.in
> command; -- output to current_numberXX.out
? command; -- errors to current_numberXX.err
To redirect IO from/to a file, use mv (move = rename). This pipe:
23_ com_1 | com_2;
is equivalent (only in command number 23) to:
23_ > com_1 ; mv 23x0.out temp.in ; < com_2 (end help)
(help SYMBOL) A number of symbols are defined for use by VMX and SHELL. Note
that you are free to redefine them if you want to obtain a
different behaviour. Examples:
out_extension : extension for output files
vmx_pipe : the command file that implements pipes
vmx_edit : the editor used by EDIX and by VMX to edit a command
max_control_y : maximum number of ^Y allowed
max_count : maximum number of commands in VMX
init_count : number of the first command in VMX
max_lines_for_hs : number of previous commands displayed by HS
constant_ps1 : the prompt in VMX
constant_tab : the tab used in HS
false : a boolean constant
is_vmx_wanted : a boolean variable, true if you want SHELL but not VMX
is_debug_vmx : a boolean variable, changed by DEBUG and NO_DEBUG (end help)
(help TOPICS)
Additional information available:
DEBUG ECHO EDIX FILES FORK GRAMMAR
HELP HS NICE PIPE SEMANTIX SEND
SH SHELL SYMBOL VMX VMXSHELL (end help)
(help VMX) VMX is a command_line interpreter with a history mechanism. It
calls the shell to interpret command_lines containing a semicolon.
The other command_lines are run directly by VMS.
VMX begins its execution by running vmx_dir:initvmx.com. Then, for
user user_name, it runs vmx_users_dir:user_name.ini (file created or
modified by EDIX.) It then loops accepting command_lines. It catches
exceptions such as ^Y, severe_error, etc. It exits on EX, has a help
HX, a history HS.
To repeat a previous command, number 35 for instance, just type 35.
Type /35 to edit command number 35, it will be submitted when you
exit the editor with "EXIT" or ignored if you leave it with "QUIT"
Use \ to repeat the previous command, / to edit it.
VMX serves mainly as a driver for the shell. If you prefer to use the
VMS history mechanism, the shell is still available as SH. In any case,
the last line of your login.com file should be "vmx". This allows
interpretation of batch jobs when they log in. Set the boolean
is_vmx_wanted to false if necessary. (end help)
(help VMX_SHELL) VMX_SHELL is the interface to the shell used by VMX,
or by other command procedures when it is not convenient to use SH,
for instance, when it is not desirable to replace a space by \s.
The command procedure should include the following lines:
first_argument := """THE COMMAND LINE TO INTERPRET""" -- 3 double quotes
line_arg = 'first_argument
It can also contain the following two lines, otherwise the current_number
used by the shell to create temporary and output files will be 0 by default:
second_argument = ANY NUMBER BETWEEN 0 and 999
count_arg := 'second_argument
The call to shell is then of the form:
vmx_shell line_arg [count_arg]
Exemple: To avoid IO redirection to files with the same name:
...
vmx_shell first_command_line 1
vmx_shell second_command_line 2 (end help)
!--> file INITVMX.COM --------- ---------- ---------- --------->
vmx_extension :== ".vmx"
ini_extension :== ".ini"
com_extension :== ".com"
job_extension :== ".job"
in_file :== "temp.in"
out_extension :== ".out"
err_extension :== ".err"
res_extension :== ".res"
hx :== @vmx_dir:help
hs :== @vmx_dir:history
edix :== @vmx_dir:edix
debug :== @vmx_dir:debug
no_debug :== @vmx_dir:nodebug
sh :== @vmx_dir:sh
vmx_shell :== @vmx_dir:vmxshell
vmx_send :== @vmx_dir:send
vmx_fork :== @vmx_dir:fork
vmx_pipe :== @vmx_dir:pipe
vmx_exec :== @vmx_dir:exec
vmx_delete :== @vmx_dir:delete
vmx_nice :== submit/noprinter/delete/noid/log_file=[]'res_extension
vmx_spawn :== spawn/nowait/nolog
vmx_rename :== rename
vmx_copy :== copy
vmx_edit :== edit/edt/command=vmx_dir:edtini.edt
vmx_put_line :== write sys$error
vmx_put_help :== if is_help_message then write sys$error
vmx_put_warning :== if is_warning_message then write sys$error
vmx_put_error :== if is_error_message then write sys$error
max_control_y :== 3
max_count :== 333
init_count :== 0
max_lines_for_hs :== 15
constant_ps1 :== "_"
ps1 :== "''constant_ps1'"
constant_tab :== " "
tab :== "''constant_tab'"
false :== 0
true :== 1
is_help_message :== true
is_warning_message :== true
is_error_message :== true
is_vmx_wanted :== true
is_debug_vmx :== false
is_debug_shell :== false
is_debug_pipe :== false
is_debug_fork :== false
is_debug_send :== false
is_debug_nice :== false
is_debug_exec :== false
is_debug_history :== false
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file INITVMX.COM --------- ---------- ---------- --------->
vmx_extension :== ".vmx"
ini_extension :== ".ini"
com_extension :== ".com"
job_extension :== ".job"
in_file :== "temp.in"
out_extension :== ".out"
err_extension :== ".err"
res_extension :== ".res"
hx :== @vmx_dir:help
hs :== @vmx_dir:history
edix :== @vmx_dir:edix
debug :== @vmx_dir:debug
no_debug :== @vmx_dir:nodebug
sh :== @vmx_dir:sh
vmx_shell :== @vmx_dir:vmxshell
vmx_send :== @vmx_dir:send
vmx_fork :== @vmx_dir:fork
vmx_pipe :== @vmx_dir:pipe
vmx_exec :== @vmx_dir:exec
vmx_delete :== @vmx_dir:delete
vmx_nice :== submit/noprinter/delete/noid/log_file=[]'res_extension
vmx_spawn :== spawn/nowait/nolog
vmx_rename :== rename
vmx_copy :== copy
vmx_edit :== edit/edt/command=vmx_dir:edtini.edt
vmx_put_line :== write sys$error
vmx_put_help :== if is_help_message then write sys$error
vmx_put_warning :== if is_warning_message then write sys$error
vmx_put_error :== if is_error_message then write sys$error
max_control_y :== 3
max_count :== 333
init_count :== 0
max_lines_for_hs :== 15
constant_ps1 :== "_"
ps1 :== "''constant_ps1'"
constant_tab :== " "
tab :== "''constant_tab'"
false :== 0
true :== 1
is_help_message :== true
is_warning_message :== true
is_error_message :== true
is_vmx_wanted :== true
is_debug_vmx :== false
is_debug_shell :== false
is_debug_pipe :== false
is_debug_fork :== false
is_debug_send :== false
is_debug_nice :== false
is_debug_exec :== false
is_debug_history :== false
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file INITVMX.COM --------- ---------- ---------- --------->
vmx_extension :== ".vmx"
ini_extension :== ".ini"
com_extension :== ".com"
job_extension :== ".job"
in_file :== "temp.in"
out_extension :== ".out"
err_extension :== ".err"
res_extension :== ".res"
hx :== @vmx_dir:help
hs :== @vmx_dir:history
edix :== @vmx_dir:edix
debug :== @vmx_dir:debug
no_debug :== @vmx_dir:nodebug
sh :== @vmx_dir:sh
vmx_shell :== @vmx_dir:vmxshell
vmx_send :== @vmx_dir:send
vmx_fork :== @vmx_dir:fork
vmx_pipe :== @vmx_dir:pipe
vmx_exec :== @vmx_dir:exec
vmx_delete :== @vmx_dir:delete
vmx_nice :== submit/noprinter/delete/noid/log_file=[]'res_extension
vmx_spawn :== spawn/nowait/nolog
vmx_rename :== rename
vmx_copy :== copy
vmx_edit :== edit/edt/command=vmx_dir:edtini.edt
vmx_put_line :== write sys$error
vmx_put_help :== if is_help_message then write sys$error
vmx_put_warning :== if is_warning_message then write sys$error
vmx_put_error :== if is_error_message then write sys$error
max_control_y :== 3
max_count :== 333
init_count :== 0
max_lines_for_hs :== 15
constant_ps1 :== "_"
ps1 :== "''constant_ps1'"
constant_tab :== " "
tab :== "''constant_tab'"
false :== 0
true :== 1
is_help_message :== true
is_warning_message :== true
is_error_message :== true
is_vmx_wanted :== true
is_debug_vmx :== false
is_debug_shell :== false
is_debug_pipe :== false
is_debug_fork :== false
is_debug_send :== false
is_debug_nice :== false
is_debug_exec :== false
is_debug_history :== false
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file CD.COM ---------- ---------- ---------- --------->
set def [.'p1']
sho def
!<-- end ---------- ---------- ---------- ---------- <---------
(* COPY1.PAS *)
program copy1 (input, output);
var c : char;
begin
while not EOF do
begin
while not EOLN do
begin
read(c);
write('[', c, ']');
end;
readln;
writeln;
end;
end.
(* END *)
(* COPY2.PAS *)
program copy2 (input, output);
var c : char;
begin
while not EOF do
begin
while not EOLN do
begin
read(c);
write('{', c, '}');
end;
readln;
writeln;
end;
end.
(* END *)
!--> file CWD.COM ---------- ---------- ---------- --------->
set def 'p1'
sho def
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file DEF0.COM ---------- ---------- ---------- --------->
assign disk0:[root.z.vmx.bin] vmx_dir
assign disk0:[root.z.vmx.users] vmx_users_dir
assign disk0:[root.z.vmx.help] vmx_help_dir
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file DEF1.COM ---------- ---------- ---------- --------->
b :== show queue sys$batch
q :== show queue sys$print
p :== print/feed/header/noflag
rmjob :== del sys$batch/entry=
rmpri :== del sys$print/entry=
e :== edit/edt/command=bin:edtini.edt
pwd :== sho def
sd :== set def
cpu :== monitor processes/topcpu
l :== dir
ls :== dir
lr :== dir [...]
ll :== dir/date/size
llr :== dir/date/size [...]
llp :== dir/date/size/prot
sv :== set verify
sn :== set noverify
st :== sho term
stt :== set term/dev=vt100
who :== sho u
cp :== copy
mv :== rename
dl :== delete
sym :== sho sym
log :== sho log
k :== sho time
pro :== sho prot
sys :== sho syst
chmod :== set prot/prot=(system:wred, owner:wred, group:re, world:re)
chmid :== set prot/prot=(system:re, owner:re, group:re, world:re)
nomod :== set prot/prot=(system:wred, owner:wred, group:, world:)
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file DEF2.COM ---------- ---------- ---------- --------->
sleep :== @bin:sleep
up :== @bin:up
cd :== @bin:cd
cwd :== @bin:cwd
rmdir :== @bin:rmdir
mkdir :== @bin:mkdir
rm :== @bin:rm
go :== @bin:profile
d0 :== @bin:def0
d1 :== @bin:def1
d2 :== @bin:def2
d3 :== @bin:def3
copy_1 :== run bin:copy1
copy_2 :== run bin:copy2
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file DEF3.COM ---------- ---------- ---------- --------->
vmx :== @vmx_dir:vmx
sh :== @vmx_dir:sh
echo :== @vmx_dir:echo
echerr :== @vmx_dir:echerr
!<-- end ---------- ---------- ---------- ---------- <---------
set mode change
!--> file MKDIR.COM ---------- ---------- ---------- --------->
create/dir [.'p1']
$
dir 'p1'
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file PROFILE.COM --------- ---------- ---------- --------->
set protection=(system:wred, owner:wred, group:re, world:re)/default
@bin:def0
@bin:def1
@bin:def2
@bin:def3
write sys$error "start_up done"
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file RM.COM ---------- ---------- ---------- --------->
del 'p1'.*
$
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file RMDIR.COM ---------- ---------- ---------- --------->
set prot=(owner:wred) 'p1'.dir
$
del 'p1'.dir.*
$
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file SLEEP.COM ---------- ---------- ---------- --------->
if f$locate(":", p1) .ne. f$length(p1) then wait 0:'p1'
if f$locate(":", p1) .eq. f$length(p1) then wait 0:0:'p1'
!<-- end ---------- ---------- ---------- ---------- <---------
!--> file UP.COM ---------- ---------- ---------- --------->
if p1 .eqs. "" then p1 = 1
index = 0
LOOP:
index = 1 + index
if index .gt. p1 then goto RETURN
set def [-]
END_LOOP: goto LOOP
RETURN: sho def
!<-- end ---------- ---------- ---------- ---------- <---------
More information about the Comp.sources.unix
mailing list