MPE/iX 5.5 CI Enhancements
by Jeff Vance CSY
Overview
The Command Interpreter (CI) has been improved in MPE/iX Release 5.5. In
addition to the Express 3 CI enhancements (X access for UDCs/command files,
POSIX-named command files and directories in HPPATH, console over LAN,
REDO enhancements, new CI variables), the following features were added to
the CI:
- To ease password management, the
JOBSECURITY
command was
enhanced to allow jobs to be streamed without embedded passwords and
without password prompting. This is described in a separate
Communicator article.
- Four new CI variables were added which contain
inbound IP addresses and socket port numbers. Now it is possible to
filter remote connections to your HP 3000 via a logon UDC that examines
the remote accessor's IP address and port number. This information is
also available via the AIFs and via the new SHOWCONN utility (please
see corresponding articles in this Communicator).
- In order to support the longer HFS names, CI string
variables are now 1024 characters long.
Additionally, approximately twice the number of user defined variables
can be created in 5.5.
- Parsing of of user input and command output is easier in Release 5.5.
There are five new CI evaluator functions and
3 enhanced functions.
- Online help is available for all CI variables and
evaluator functions.
There are four new predefined CI variables in Release 5.5.
HPREMIPADDR is a string variable that contains the IP address of a remotely
connected user (client). If the user is directly connected to the HP 3000
HPREMIPADDR is set to "" (empty string).
HPREMPORT is an integer variable that contains the TCP port number allocated
on the remote machine (client) for use on the incoming TCP connection.
If the user is directly connected to the HP 3000 HPREMPORT is zero.
HPLOCIPADDR is a string variable that contains the IP address of the HP 3000
local Network Interface (NI) that will be used for outbound data.
If the user is directly connected to the HP 3000, HPLOCIPADDR
is set to "". HP3000s support several network interface cards
and thus can have more than one IP address.
NOTE:
HPLOCIPADDR may not reflect the IP address of the NI used for inbound data
flow from the same client due to either network load balancing or a
misconfiguration.
HPLOCPORT is an integer variable that contains the local TCP port number
for the network service provided to the client. If the user is directly
connected to the HP 3000 HPLOCPORT is zero. For example, a telnet connection
uses port 23, NS/VT connections use ports 1537 and 1570, an ftp data connection
uses port 20.
Below is a sample logon UDC that filters logons based on time-of-day, inbound
IP addresses and inbound port number (service being used). Security on this
UDC is assigned so that only the file's creator has read/write access, all
others have only execute access.
SYSLOGON
OPTION LOGON, NOBREAK
# This system-wide logon UDC ensures that no one logs on "after hours"
# from outside our company via NS/VT.
# After hours are weekends and weekdays after 6pm and before 7am
setvar too_early 7
setvar too_late 6
# Currently only checking for VT connections, later will add telnet check
setvar msg_mode_VT 1537
setvar stream_mode_VT 1570
# Check weekday and time of day first
if word(hpdatef) = "SAT" or word(hpdatef) = "SUN" or &
(word(hptimef,,-1) = "PM" and ![word(hptimef,":")] > too_late) or &
(word(hptimef,,-1) = "AM" and ![word(hptimef,":")] > too_early) then
# It is too late or too early or the weekend.
# Check for an offsite IP address via NS/VT.
if HPREMIPADDR <> "" then
# A network connection
# Determine n/w mask based on host's IP address class
setvar class_octet ![word(HPLOCIPADDR,".")]
if class_octet < 128 then
# Class A addr
setvar nw_mask word(HPLOCIPADDR,".")
elseif class_octet < 192 then
# Class B addr
setvar nw_mask lft(HPLOCIPADDR,pos(".",HPLOCIPADDR,2)-1)
else
# Assume Class C addr
setvar nw_mask lft(HPLOCIPADDR,pos(".",HPLOCIPADDR,3)-1)
endif
# See if connection is outside the company
if lft(HPREMIPADDR,len(nw_mask)) <> nw_mask then
# Outside connection, check for NS/VT
if HPLOCPORT = msg_mode_VT or HPLOCPORT = stream_mode_VT then
echo Connection refused, please contact MIS.
bye
endif
endif
deletevar class_octet, nw_mask
endif
endif
deletevar too_early, too_late, msg_mode_VT, stream_mode_VT
echo Welcome to !HPSYSNAME.
*********
In Releases 5.0 and earlier, CI variable values were limited to 255
characters. Beginning in MPE/iX Release 5.5, CI variables can be up to 1024
characters long. Variable names can continue to be up to 255 characters long.
Also the CI's variable table can expand to accommodate approximately two times
more variables than previously. In Release 5.5 the maximum number of variables
that can be
created is approximately 10,700. This number is inversely related to the
length of the variable's name and the length of its value. In Release 5.5 the
maximum number of variables that can be created with 254 character names and
255 character values is 2,190, compared to 974 in Release 5.0.
To ease the parsing of the output of CI commands and of user input, five new
evaluator functions were added and three existing functions were enhanced in
Release 5.5:
word(),
edit(),
repl(),
delimpos(),
pmatch(),
str(),
rht(),
input()
WORD()
- general word extraction.
String function.
Syntax: word(str[,delims][,nth][,end_var][,start])
This new function extracts the nth word from str
beginning at start, delimited by one of the characters in
delims, placing the index of the delimiter that terminated the word
in a CI variable named by the end_var argument.
- str
- Required. str is any quoted string or string variable. This is
the source for the word extraction.
- delims
- Optional. delims is a string that contains a list of
characters that constitute the termination of a word. The default
delims are: space, comma, semicolon, equalsign, square
brackets, single and double quotes, parenthesis. All other characters in
str are considered part of a word.
- nth
- Optional. An integer indicating which word to extract from str.
The default value is 1, meaning parse the first word, scanning from left
to right. A value of 2 causes the second word in str to be
extracted. A negative value means extract a word starting at the end of
str, parsing from right to left. A value of -3 means to
extract the third from last word in str. A value of -1
indicates the last word in str.
- end_var
- Optional. The actual name of a variable to be set to the index in
str of the delimiter that terminated extracted word.
end_var cannot be a string expreession - the actual unquoted
name must be used. The default is to not set a variable. If the
nth word is not found end_var is not set. For
nth >= 0 the highest end_var value is
len(str)+1
, meaning the last word was found. For
nth < 0 the smallest end_var value is 0, meaning
the first word was found. Multiple spaces in str after the
extracted word are skipped.
- start
- Optional. An integer index into str where the word extraction
begins. The default start when nth >= 0 is 1,
and when nth < 0 is the index of the last byte in
str.
word()
starts at str[start] and scans str
looking for a word delimiter. The direction of the scan is determined by
nth. Positive nth values cause a left to right scan,
whereas negative values use a right to left scan. Initial spaces are skipped.
After the delimiter is found trailing spaces are also skipped until a non-space
delimiter is found, if any. end_var is set to the index of this
non-space delimiter. If one or more spaces are the only delimiter between words
then end_var is set to the index of last space in str
before the next word.
There are two cases when word()
can functionally return an empty
string:
1) when the nth word does not exist in str,
2) when the nth word exists but has no value.
Consider: setvar str "rec=10,,f"
.
word(str,,5)
returns "", since there are only four words
in str.
word(str,,3)
returns "", since the third word has no value
- the third word starts at str[8] and ends at the same index.
These two cases can be distinguished by passing the end_var
parameter.
word(str,,5,j)
does not set the variable J.
word(str,,3,j)
sets J to 8.
Examples:
word('file a=bb,old;rec=40,,f,ascii') = 'file'
word('file a=bb,old;rec=40,,f,ascii',,2) = 'a'
word('file a=bb,old;rec=40,,f,ascii',";,",,j,8) = 'bb', j=10
word('file a=bb,old;rec=40,,f,ascii',,-4,j) = '40', j=18
Here's how to parse every token in a string by incrementing the starting index:
setvar j 0
while setvar(j,j+1) <= len(str) do
setvar token word(str,,,j,j)
...
endwhile
Another way to parse a string by using nth and omitting
start:
setvar j 0
setvar cnt 0
while setvar(cnt,cnt+1) <= 9999 and j <= len(str) do
setvar token word(str,,cnt,j)
...
endwhile
EDIT()
- full REDO-like editing of a
string. String function.
Syntax: edit(str,editstr[,start])
This new function applies the edit contained in editstr to
str starting at start and functionally returns the result.
- str
- Required. str is any quoted string or string The edit is
applied to str.
- editstr
- Required. editstr is a string containing a REDO-like edit. For
example, " dddiXYZZY" would delete the 2nd, 3rd, and 4th characters in
str and then insert "XYZZY".
- start
- Optional. An integer index into str where editstr
is applied. The default start is 1.
edit()
starts at str[start] and applies the edit in
editstr exactly as the CI's REDO command edits a command line. The
edited string is functionally returned. The size of the string that can be
edited is limited to the size of the CI's command buffer, which is currently
512 bytes.
Examples:
edit('abcdefg','>dd') = 'abce'
edit('ab cd;g','dwd') = 'cd;g'
edit('abccd;g','c/c/AA/') = 'abAAAAd;g'
edit('abcdefg','^^',3) = 'abCDefg'
Here's how to provide REDO capability to an interactive command file:
...
# parse user input, buf, into "cmd" and "parms"
setvar cmd ups(word(buf))
...
if cmd = "REDO" then
# fetch command to redo from history stack
...
setvar buf history!index
echo !buf
setvar bufedit input()
while len(bufedit) > 0 do
setvar buf edit(buf,bufedit)
echo !buf
setvar bufedit input()
endwhile
endif
...
REPL()
- general string replacement.
String function.
Syntax: repl(str,oldstr,newstr[,cnt][,start])
This new function replaces cnt occurrences of oldstr in
str with newstr, starting at start.
- str
- Required. str is any quoted string or string variable. This is
the source for the replacement.
- oldstr
- Required. oldstr is the string searched for in str.
It will be replaced by newstr. No replacement occur if
oldstr is empty.
- newstr
- Required. newstr is the string that is substituted for
oldstr and it can be empty ("")
- cnt
- Optional. cnt is the number of replacements to be done in
str. The default cnt is zero meaning replace all
occurrences of oldstr in str. A positive cnt
indicates that the replacements are done from left to right, e.g., 1
means replace the first occurrence, 2 means replace the first two
occurrences, 3 indicates replace the first three occurrences, etc. A
negative cnt indicates right to left replacement, e.g., -1
means replace the last occurrence, -2 means the last two occurrences,
etc.
- start
- Optional. An integer index into str where the replacement
begins. The default start when cnt >= 0 is 1,
and when cnt < 0 is the index of the last byte in
str.
It is possible for the replace operation to overflow str. In that
case the maximum number of replacements are done prior to exceeding the maximum
size of a string variable (currently 1024 bytes).
Examples:
repl('aaabcaab','aa','X') = 'XabcXb'
repl('aaabcaab','ab','',-1) = 'aaabca'
repl('f*.*','*','@') = 'f@.@'
DELIMPOS()
- finds the position (index) of
a delimiter. Integer function.
Syntax: delimpos(str[,delims][,nth][,start])
This new function returns the position of the nth delimiter
in str beginning at start.
- str
- Required. str is any quoted string or string variable. This is
the source for the delimiter searching.
- delims
- Optional. delims is a string that contains a list of one or
more characters that are searched for in str. The default
delims are the same as for
word
: space, comma,
semicolon, tab, equalsign, square brackets, single and double quotes,
parenthesis.
- nth
- Optional. An integer indicating which delimiter occurrence to scan for.
The default value is 1, meaning find the position of the 1st delimiter
in str. A value of 2 means find the second delimiter, etc. A
negative value means search for the delimiter from right to left. A
value of -3 means to find the third from last delimiter in
str. A value of -1 indicates find the index of the last
delimiter in str.
- start
- Optional. An integer index into str where the delimiter
searching begins. The default start when nth
>= 0 is 1, and when nth < 0 is the index of the last
byte in str.
There are several differences between delimpos()
and
pos()
. The pos()
function supports the matching of
one or more characters, e.g., pos('abcd',str,2)
locates the index
in str of the second occurrence of "abcd". The
delimpos()
function only supports single character matches;
however, several characters can be tested for a match, e.g.,
delimpos(str,'abcd',2)
locates the index in str of the
second occurrence of EITHER an "a" OR "b" OR "c" OR "d". Typically the
delimiter string will be token separators like ";", ",", " ", etc. The
delimpos()
function also supports the start parameter which is not
available in pos()
.
Examples:
1 2 Funct Delim
12345678901234567890123456789 Rtn Found
delimpos('file a=bb,old;rec=40,,f,ascii') 5 ' '
delimpos('file a=bb,old;rec=40,,f,ascii',,3) 10 ','
delimpos('file a=bb,old;rec=40,,f,ascii',",;",-4) 14 ';'
delimpos('file a=bb,old;rec=40,,f,ascii',,,7) 7 '='
PMATCH()
- pattern matching.
Boolean function.
Syntax: pmatch(pattern,str[,start])
This new function returns TRUE if pattern is found in str,
starting at start.
- pattern
- Required. A string pattern to be matched in str. Wildcard
characters are supported.
- str
- Required. str is any quoted string or string variable. This is
the source that the pattern is matched against.
- start
- Optional. An integer index into str where the search for the
pattern begins. The default start is 1.
str[start] is scanned looking for pattern. If a match is
found then TRUE is returned, else FALSE is returned. The pattern can be
any MPE filename character, including all wildcards.
pmatch()
provides the same pattern matching used by LISTFILE
,
SHOWVAR
and STORE
(without the exception
fileset (minus) patterns).
pmatch()
is different from pos()
since wildcards are
supported, a start parameter is provided, which occurrence of
pattern to match cannot be specified, and true pattern matching is
performed. For example, pos('abc','aaabccc')
is 3.
pmatch('abc','aaabccc')
is FALSE; however
pmatch('@abc@','aaabccc')
is TRUE.
Both pattern and str are limited to 256 bytes due to
interface restrictions. If pattern xor str are empty (but
not both) then FALSE is returned. If both pattern and str
are empty then TRUE is returned.
Examples:
pmatch('f@','fread') = true
pmatch('f#','fabc') = false
pmatch('@f@,'abcdefg') = true
pmatch('abc','abcd') = false
pmatch('','abc') = false
STR()
- general string extraction.
String function.
Syntax: str(str1,start,cnt)
This existing function extracts cnt characters from
str1 starting at start.
The cnt parameter was enhanced to support an ending index rather
than only a byte count. If cnt is negative then the absolute value
of cnt is the ending index in str1 to stop the extraction.
If cnt is negative and -cnt is less than start
then an empty string is returned.
Examples:
str('abcde',2,3) = 'bcd'
str('abcde',2,-4) = 'bcd'
str('abcde',3,-3) = 'c'
str('abcde',3,-1) = ''
RHT()
- right-hand string extraction.
String function.
Syntax: rht(str1,cnt)
This existing function extracts the rightmost cnt
characters from str1.
The cnt parameter was modified to support a starting index rather
than only a byte count. If cnt is negative then the absolute value
of cnt is the starting index in str1 to start the
extraction, which includes all characters from str1[-cnt] to the
end of str1.
Examples:
rht('abcde',3) = 'cde'
rht('abcde',-4) = 'de'
rht('abcde',-1) = 'abcde'
INPUT()
- read from $STDIN.
String function.
Syntax: input([prompt][,wait][,cnt])
This existing function optionally writes prompt to $STDLIST,
reads from $STDIN, with the option of the read being a timed read of
wait seconds. The input from $STDIN is functionally returned.
The cnt parameter is new. If cnt is specified then
cnt bytes will be read from $STDIN. The default cnt is
the maximum size of a string variable, currently 1024 characters. If
cnt is specified and less than cnt characters are
supplied as input, the user must still use the RETURN key to send
the data.
Example:
input('Do this (Y/n)?',10,1) Prompts to $STDLIST, does a 10 second
timed read on $STDIN of 1 character.
Note: equivalent functionality is available to the INPUT
command
via the new READCNT= keyword.
Information about all CI variables has been supported via HELP since Release
5.0, but Release 5.5 also includes HELP for all CI evaluator functions.
For example:
HELP FUNCTIONS
- - shows a table of all evaluator functions.
HELP FINFO
- - shows the details of the FINFO function.
HELP WORD
- - describes the new WORD function.
HELP VARIABLES
- - shows a table of all CI variables.
HELP HPREMIPADDR
- - describes the new HPREMIPADDR variable.