On Unix it is easy to get your numeric UID and the GIDs of your primary group and secondary groups. You call the program id
simply. On OpenVMS it is not such easy to retrieve your numeric UIC which is OpenVMS’s equivalent to Unix’ UID and GID. With a bit DCL magic you can write a command procedure which tells you the UIC as easy as id
tells you your UID and GID on Unix. By programming this little command procedure you will also get introduced to lexical functions in DCL.
If you want to know your UID, your groups and the corresponding GIDs on Unix you use the command id
. For example:
$ id
uid=1374(ogm) gid=20(users)
If you want to know only the numeric values of your UID and your (primary) GID you use the flags -u
and -g
:
$ id -u
1374
$ id -g
20
As a Unix guy challenged by the world of OpenVMS you will always hear something about the UIC (user identification code) on OpenVMS. It is a tuple [group,member]
which identifies an user or a group of users. With your Unix background you realize very soon it’s a similar concept to Unix’ UID and GID, but in some kind of a mixture. Unfortunately you do not find a command like Unix’ id
to display this UIC on OpenVMS’ DCL interpreter (DEC Command Language). So let’s explore how to get a command procedure which will display us the UIC in the form of [group,member]
for the current user.
Constructing a Solution
On the DCL you have several lexical functions available. They follow the format
F$Name([args,...])
F$
is a prefix indicating that the following is a lexiacal function. The Name
tells what function to call. Inside the always present parentheses the arguments of the function find their place.
BTW: A complete reference of all lexical functions you will find in the HP OpenVMS DCL Dictionary.
Our solution begins with determining current user’s name. This purpose serves the lexical function F$USER()
. You can put the result into a symbol and show it afterwards:
$ ME = F$USER()
$ SHOW SYMBOL ME
[OLIVER]
Or you can print it directly:
$ WRITE SYS$OUTPUT F$USER()
[OLIVER]
Now we need to map this determined user name to a numeric UIC. For this purpose exists the lexical function F$IDENTIFIER()
. For example:
$ UIC_INT = F$IDENTIFIER("OLIVER", "NAME_TO_NUMBER")
$ SHOW SYMBOL UIC_INT
UIC_INT = 4194305 Hex = 00400001 Octal = 00020000001
Now it is only one little step to convert this output into the required form of [group,member]
. To do so we use the lexical function F$FAO()
which converts characters and numeric values into ASCII strings. F$FAO()
operates in a similar way as printf
does on UNIX’ shell. To convert a long word integer to a numeric UIC in the format [group,member]
F$FAO()
provides the special sequence !%U
for its control string:
$ UIC = F$FAO("!%U", UIC_INT)
$ SHOW SYMBOL UIC
UIC = "[100,1]"
This looks well and looks like it can be composed with F$USER()
to one single command. Unfortunately there is one little detail to have an eye on.
Preparing the User Name
F$USER()
returns the user name in brackets. F$IDENTIFIER()
expects in its first argument the user name without brackets. So we need to remove the brackets to provide a working solution.
There is the lexical function F$EXTRACT()
which extracts substrings from a given string. Its syntax is as follows and very simple to understand:
F$EXTRACT(sub_start, sub_length, from_string)
sub_start
is the index of the first character of the substring within from_string
. sub_length
is the length of the resulting substring. from_string
is the string from which the substring shall be extracted. For example:
$ WRITE SYS$OUTPUT F$EXTRACT(6,4,"APPLE TREE")
TREE
Note: As you see the counting of characters in a string starts at zero.
With this lexical function it is easy to extract the user name and remove the brackets respectively from F$USER()
‘s output. To do so we simply need to determine the length of F$USER()
‘s output and subtract 2 (the brackets) from it.
The length of a string returns the lexical function F$LENGTH()
. To subtract 2 from the result we can use F$STRING()
. F$STRING()
evaluates the given string or numeric expression and returns the result as a string.
These ideas covered in DCL commands leads to this sequence:
$ WRITE SYS$OUTPUT F$USER()
[OLIVER]
$ WRITE SYS$OUTPUT F$LENGTH(F$USER())
8
$ WRITE SYS$OUTPUT F$STRING(F$LENGTH(F$USER())-2)
6
$ WRITE SYS$OUTPUT F$EXTRACT(1,F$STRING(F$LENGTH(F$USER())-2),F$USER())
OLIVER
The last one is exactly what we were looking for.
Final Command Procedure
All this combined in one single command results in this command procedure:
$! Program: GETUIC.COM
$! Purpose: Display UIC of current user.
$!
$! Copyright (c) 2013 Oliver Mueller, http://oliver-mueller.com
$! All rights reserved.
$!
$ WRITE SYS$OUTPUT F$FAO("!%U", -
F$IDENTIFIER( -
F$EXTRACT(1, F$STRING(F$LENGTH(F$USER())-2), F$USER()), -
"NAME_TO_NUMBER"))
Feel free to download GETUIC.COM
in this ZIP file.
Installation for All Users
Note: You will need the privilege SYSPRV
to install GETUIC.COM
for all users.
To install GETUIC.COM
copy it to the location where your utilities normally reside, e.g. your own directory like DKA0:[TOOLS]
, or a global one like SYS$COMMON:[SYSEXE]
. Afterward define a command by a symbol in SYS$COMMON:[SYSMGR]SYLOGIN.COM
. For example:
$ GETUIC :== @DKA0:[TOOLS]GETUIC.COM
or
$ GETUIC :== @SYS$COMMON:[SYSEXE]GETUIC.COM
You should restrict the access rights to this file by invoking this command:
$ SET SEC/PROT=(S:RWED,O:RWED,G:E,W:E) DKA0:[TOOLS]GETUIC.COM
or
$ SET SEC/PROT=(S:RWED,O:RWED,G:E,W:E) SYS$COMMON:[SYSEXE]GETUIC.COM
After a new login everybody is able to use GETUIC
as a command to determine her/his UIC. For example:
$ getuic
[100,1]
Installation Just for Your Own
An installation just for your own user is much simpler. Copy GETUIC.COM
to your SYS$LOGIN
folder. (This is the folder in which you reside after login.) Edit or create the file SYS$LOGIN:LOGIN.COM
and put this line into it:
$ GETUIC :== @SYS$LOGIN:GETUIC.COM
Logout, login again and you are done! You can use the command GETUIC
now. For example:
$ getuic
[100,1]
Hi, i have reading out and i will definitely bookmarrk your site, just wanted to say i liked this article.
whoah this blog is great i really like studying your posts. Stay up the good work! You know, lots of individuals are looking round for this info, you can help them greatly. |