- Community Home
- >
- Servers and Operating Systems
- >
- Operating Systems
- >
- Operating System - OpenVMS
- >
- Re: If interested with this type of simple solutio...
Categories
Company
Local Language
Forums
Discussions
Forums
- Data Protection and Retention
- Entry Storage Systems
- Legacy
- Midrange and Enterprise Storage
- Storage Networking
- HPE Nimble Storage
Discussions
Discussions
Discussions
Forums
Discussions
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
- BladeSystem Infrastructure and Application Solutions
- Appliance Servers
- Alpha Servers
- BackOffice Products
- Internet Products
- HPE 9000 and HPE e3000 Servers
- Networking
- Netservers
- Secure OS Software for Linux
- Server Management (Insight Manager 7)
- Windows Server 2003
- Operating System - Tru64 Unix
- ProLiant Deployment and Provisioning
- Linux-Based Community / Regional
- Microsoft System Center Integration
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Community
Resources
Forums
Blogs
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-12-2011 09:49 AM
10-12-2011 09:49 AM
If interested with this type of simple solution when dealing with VMS logicals
Dear all,
The DCL solution proposed at http://vouters.dyndns.org/tima/OpenVMS-Java-CRTL-Cleanly_dealing_with_JAVA_and_DECC_logicals-A_proposed_solution.html might raise some VMS developers interest to confine logicals transparent settings to one application usage without possibly negatively impacting other applications later on executed.
This idea is Powell Hazzard's idea when he implemented ANT.COM. The solution here prposed is a complete redesign very looking to me as apparently a trivial implementation. This kind of solution may as well be extented to the global DCL symbols a DCL script needs to define and internally use. In such case you would use the f$type(symbol) lexicals function..
The intent of such type of solution is to provide a totally logicals "waterproof" solution completely transparent to the end-user whichever he prior or post does. This is only unless he prior defines logicals which negatively impact the solution being executed using this type of solution.
A very first "customer" of this type of solution is JRuby/VMS where it is on its way to be fully implemented and will shortly be avaialble for download.
In the very hope this Web document reveals itself useful to someone.
Thank for your attention.
Philippe
- Tags:
- DCL
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-12-2011 02:48 PM - edited 10-12-2011 08:20 PM
10-12-2011 02:48 PM - edited 10-12-2011 08:20 PM
Re: If interested with this type of simple solution when dealing with VMS logicals
Phillipe,
Maybe I don't understand the whole issue here. If the operation you want to perform is running an image - like the Java run time environment executing your class file, why doesn't this work?:
$ DEFINE/USER DECC$EFS_CHARSET ENABLED $ DEFINE/USER DECC$READDIR_DROPDOTNOTYPE TRUE $ DEFINE/USER DECC$EFS_CASE_PRESERVE TRUE $ DEFINE/USER JAVA$DELETE_ALL_VERSIONS TRUE $! $! perform your command requiring the logicals you have specifically set
If I understand correctly, your circumstance is exactly what DEFINE/USER is for. There won't be any USER mode logical names defined, as they're automatically deleted after any image exit. As long as you don't run any images between the DEFINE commands and your Java program, they should be seen and obeyed. The USER mode logical names are then deleted when the image exits, revealing whatever (if anything) was defined before.
That said, some comments about your DCL
I don't understand why you need loop1 and loop2? Why can't you (re)define the logical name in loop1?
I think this is a typo: f$trnlnm("''logical_name'","PROCESS") should be F$TRNLNM(logical_name,"LNM$PROCESS")
If /USER doesn't help, since I don't like duplicating code, I'd prefer a more general approach which would minimise the amount of code at the point of use. Consider this pair of simple procedures implementing logical name "stacks" stored in global symbols.
$ ! DEFINEPUSH.COM $ ! Save current value of a logical name and define a new one $ ! p1 = logical name $ ! p2 = new value (optional) $ $ IF p1.EQS."" THEN EXIT $ IF F$TYPE('p1'_N).EQS."" THEN 'p1'_N==0 $ 'p1'_N=='p1'_N+1 $ i='p1'_N $ 'p1''i'==F$TRNLNM(p1,"LNM$PROCESS") $ IF 'p1''i'.NES."" THEN DEASSIGN 'p1' $ IF p2.NES."" THEN DEFINE/NOLOG 'p1' 'p2' $ EXIT $! DEFINEPOP.COM $! Restore previous logical name value (if it exists) $! p1 = logical name $ $ IF p1.EQS."" THEN EXIT $ IF F$TRNLNM(p1).NES."" THEN DEASSIGN 'p1' $ IF F$TYPE('p1'_N).EQS."" THEN EXIT $ i='p1'_N $ IF i.LE.0 THEN EXIT $ 'p1'_N=='p1'_n-1 $ IF F$TYPE('p1''i').EQS."" THEN EXIT $ IF 'p1''i'.NES."" THEN DEFINE 'p1' &'p1''i' $ DELETEX/SYMBOL/GLOBAL 'p1''i' $ EXIT
Using these procedures, your example would be coded as:
$ @DEFINEPUSH DECC$EFS_CHARSET ENABLED $ @DEFINEPUSH DECC$READDIR_DROPDOTNOTYPE TRUE $ @DEFINEPUSH DECC$EFS_CASE_PRESERVE TRUE $ @DEFINEPUSH JAVA$DELETE_ALL_VERSIONS TRUE $! $! perform your command requiring the logicals you have specifically set $! $ @DEFINEPOP DECC$EFS_CHARSET $ @DEFINEPOP DECC$READDIR_DROPDOTNOTYPE $ @DEFINEPOP DECC$EFS_CASE_PRESERVE $ @DEFINEPOP JAVA$DELETE_ALL_VERSIONS
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-12-2011 03:08 PM
10-12-2011 03:08 PM
Re: If interested with this type of simple solution when dealing with VMS logicals
I wonder whether this application image feature-provisioning and image-signing swamp will get drained. Some sort of an application-provisioning tool and related mechanisms within VMS and the underlying libraries, and particularly a mechanism for bypassing these pesky feature logical names. And for allowing individual applications to be digitally signed, too.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-12-2011 04:48 PM - edited 10-12-2011 05:30 PM
10-12-2011 04:48 PM - edited 10-12-2011 05:30 PM
Re: If interested with this type of simple solution when dealing with VMS logicals
Hoff,
>Some sort of an application-provisioning tool and related mechanisms
What? Someone actually implement a new feature in DCL? Hah! In your dreams!
I'm having enough trouble getting simple bugs fixed. Here's my latest. It's a V1.0 bug in time parsing which affects ALL DCL commands which have a time related qualifier /AFTER, /BEFORE etc... I found a code path in the T4$COLLECT.COM procedure which leaves excess spaces on time strings passed to the SUBMIT command. The result is a syntax error for strings which end in 06 or higher, but a silent misinterpretation error for strings ending in 01, 02, 03, 04 or 05. This is trivially simple to reproduce:
$ submit/after="15:05 " login.com Job LOGIN (queue SYS$BATCH, entry 748) holding until 13-OCT-2011 15:50
Note the time is 15:50, not 15:05 as requested.
I've provided VMS engineering with a diagnosis, (the trailing blanks become zero, so "15:050"), identified the module and line number where the error occurs (LIB$CVT_ATIME), and proposed the simple solution of stripping trailing whitespace in the input string. Just a few instructions. Low risk and a whole class of potential bugs in numerous commands and countless command procedures are eliminated.
The response from VMS engineering?
Engineering further analyzed the problem and found that the specifying the trailing space in the absolute time specification is not a recommended format or use case. The formats for specifying the absolute time ("dd-mmm-yyyy hh:mm:ss.cc") is provided in the online help for Date_Time. Please refer online help on DATE_TIME for more details. We request the customer not to use the trailing space while specifying the absolute time.
As far as I'm concerned, it's either illegal syntax, in which case it should generate an error, or it should be accepted. The current behaviour of silently using an incorrect time is very un-VMSish. Compare with:
$ submit/after="15:06 " %DCL-W-IVATIME, invalid absolute time - use DD-MMM-YYYY:HH:MM:SS.CC format \15:06 \
Never mind that it's not ME who's using it, it's in T4$COLLECT, provided by OpenVMS engineering! For that matter, this is the least worst bug I've identified in T4$COLLECT. There are several that I can't get fixed, despite providing detailed diagnosis and proposed code.
From my experience of the past few years, the only "engineering" being done in OpenVMS is generating excuses as to why they don't want to actually fix anything.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-13-2011 02:47 AM
10-13-2011 02:47 AM
Re: If interested with this type of simple solution when dealing with VMS logicals
John,
Your reaction is pretty interesting for me. If this is unclear for you, this may be unclear for others. This simply means I did make things clear enough for my readers in my document.
Why I do use loop1, loop2 and loop3 ???? loop1 loop saves any previous logical setting for the logicals required by the application. loop2 loop sets all required logicals to their desired target values. The loop3 loop restores all application required logicals to their initial state.
Why do I use define instead of define/user ??? Because there can be more than one DCL command executed between loop2 loop and loop3 loop, some commands possibly requiring the exact same logicals settings.
As for your remark about a possible typo in the code (LNM$PROCESS instead of PROCESS for the f$trnlnm lexical), it has been checked that specifying "PROCESS" does perfectly the trick on a VMS IA64 V8.3-1H1 system. As a conclusion for this envisionned typo, if specifying "LNM$PROCESS" is the correct way to do, I can state after tests that specifying "PROCESS" is strictly synonymous to LNM$PROCESS in such a DCL context on the computers this DCL code has been tested on.
In the hope this clarifies your questions.
Best regards,
Philippe
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-13-2011 04:38 AM
10-13-2011 04:38 AM
Re: If interested with this type of simple solution when dealing with VMS logicals
John,
If your VMS application summarizes as this:
$ sho logical DECC$EFS_CHARSET
$ spawn/nowait sho logical DECC$EFS_CHARSET
then if the proposed DCL code in my corresponding document contains a define/user instead of a define, this is the result I observe:
$ @template.com
"DECC$EFS_CHARSET" = "ENABLED" (LNM$PROCESS_TABLE)
%DCL-S-SPAWNED, process PHV_7722 spawned
%SYSTEM-F-NOLOGNAM, no logical name match
$
%SHOW-S-NOTRAN, no translation for logical name DECC$EFS_CHARSET
The template.com DCL code here executed is nothing but the code I posted in my Web document.
You can achieve such a spawn DCL emulation using any Java code with calls Runtime.exec(cmd). It ought to underneath call either lib$spawn or one of the HP CRTL exec call.
Philippe
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-13-2011 06:41 AM
10-13-2011 06:41 AM
Re: If interested with this type of simple solution when dealing with VMS logicals
I'm not sure whether I understand what you are trying to say. For defining user mode logicals, have a look at the HELP file:
User-mode entries are deleted from the process logical name table
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-13-2011 01:39 PM
10-13-2011 01:39 PM
Re: If interested with this type of simple solution when dealing with VMS logicals
Phillipe,
I can see why you have two loops. Logically it makes sense, but DCL is interpretive and therefore slow. Once you've saved a value, you may as well redefine it in the first loop, while you're in the context of that list entry. You get shorter and faster code.
> I can state after tests that specifying "PROCESS" is strictly synonymous to LNM$PROCESS
If that's working on your system, I can only conclude that in your environment there's a logical name "PROCESS" defined in LNM$PROCESS_DIRECTORY which equates to LNM$PROCESS_TABLE. By DCL rules, there won't be any system defined logical names which do not contain a "$" character. If the logical name exists, it must have been defined by something site specific. There's nothing wrong with doing that, but don't expect it to be the same on other systems.
IA64 OpenVMS V8.3-1H1
$ define/process test process_value $ show log test "TEST" = "PROCESS_VALUE" (LNM$PROCESS_TABLE) $ write sys$output F$TRNLNM("TEST","PROCESS") $ write sys$output F$TRNLNM("TEST","LNM$PROCESS") PROCESS_VALUE $ define/table=lnm$process_directory process lnm$process_table $ write sys$output F$TRNLNM("TEST","PROCESS") PROCESS_VALUE
Alpha V8.3
$ define/process test process_value $ show log test "TEST" = "PROCESS_VALUE" (LNM$PROCESS_TABLE) $ write sys$output F$TRNLNM("TEST","PROCESS") $ write sys$output F$TRNLNM("TEST","LNM$PROCESS") PROCESS_VALUE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-13-2011 02:08 PM
10-13-2011 02:08 PM
Re: If interested with this type of simple solution when dealing with VMS logicals
Phillipe,
>Because there can be more than one DCL command executed between loop2 loop and loop3 loop
You're correct. If the actions that need to be performed while the logical names are defined involve multiple image activations, then /USER won't help. Regardless, if you're not familiar with the uses of DEFINE/USER, I'd suggest you experiment. It can be very useful, but has some pitfalls you need to know about. As Bob has pointed out SHOW USER runs an image, so is Heisenburgian ;-) You need to be very careful to preserve the state, especially when inserting debug code (WRITE SYS$OUTPUT F$TRNLNM is safe because it doesn't run an image).
Another approach to preserving state I use is with a subprocess. The SPAWNed subprocess inherits the parental environment of logical names and symbols, but don't return any changes. SPAWN can therefore be used to save state. Since PIPE creates a subprocess, and supports multiple statements on a line, a simpler way to code your example is:
$ PIPE (DEFINE/NOLOG DECC$EFS_CHARSET ENABLED ; - DEFINE/NOLOG DECC$READDIR_DROPDOTNOTYPE TRUE ; - DEFINE/NOLOG DECC$EFS_CASE_PRESERVE TRUE ; - DEFINE/NOLOG JAVA$DELETE_ALL_VERSIONS TRUE ; - YOUR-COMMAND(S) here )
This has the added benefit that you can easily capture the output of the whole command sequence, or pipe it into another command. Yes SPAWN is relatively expensive, but so are multiple loops saving and restoring context. You also need to think about unexpected events between your loop2 and loop3, will they result in failure to restore the context? Using PIPE eliminates that issue because the context of the caller has not been changed.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-13-2011 02:34 PM
10-13-2011 02:34 PM
Re: If interested with this type of simple solution when dealing with VMS logicals
Dear John,
I totally agree with your statements as long as the piped DCL command is short enough. How would you manage for such a much more complex DCL code which incorporates the solution I do propose in my article ? This is a JRuby/VMS DCL script we might propose to the JRuby/VMS end-users. For your knowledge, the time spent to execute the pure DCL code within this script is nuts compared to the time required by the Java code which will interpret the Ruby code even on simple Ruby code samples.
Here is the jruby.com Thierry Uso and I were working on:those past days.
.
[philippe@victor ~]$ cat jruby.com
$! +++
$!
$! JRUBY.COM
$!
$! Author : Thierry USO
$! Date : 30-JUL-2011
$! Object : run a ruby program
$!
$! Usage : @jruby [switches] [--] [programfile] [arguments]
$! @jruby "--help"
$! @jruby "--1.9" "./hello.rb"
$!
$! Modif : 10-OCT-2011 better management of logical names
$!
$! ---
$!
$ VERIFY = F$Verify(0)
$!
$ Parse_Style = f$getjpi("", "PARSE_STYLE_PERM")
$ set process/parse=extended
$!
$! ++++
$! get current settings for the logicals you wish to set
$! ----
$!
$ save_env_field1 = "DECC$EFS_CHARSET\ENABLE"
$ save_env_field2 = "DECC$ARGV_PARSE_STYLE\ENABLE"
$ save_env_field3 = "DECC$EFS_CASE_PRESERVE\ENABLE"
$ save_env_field4 = "JAVA$FILENAME_CONTROLS\8"
$ save_env_field5 = "JAVA$CREATE_DIR_WIDTH_OWNER_DELETE\TRUE"
$!
$ i = 1
$ loop1:
$ if f$type(save_env_field'i') .nes. ""
$ then
$ symName = save_env_field'i'
$ logical_name == f$extract(0,f$locate("\",symName),symName)
$ current_logical_value == f$trnlnm("''logical_name'","PROCESS")
$ old_env_field'i' = "''logical_name'\''current_logical_value'"
$ i = i + 1
$ goto loop1
$ endif
$!
$! +++
$! get your jruby directories
$! ---
$!
$ jruby = F$Environment("PROCEDURE")
$ jrubybin = F$Parse(jruby,,,"DEVICE") + F$Parse(jruby,,,"DIRECTORY")
$ jrubyhome = F$Extract(0,F$Locate(".bin]", jrubybin), jrubybin) + "]"
$ call VMS_to_UNIX "''jrubyhome'"
$ jrubyhome = "''UNIX_file_spec'"
$ jrubylib = "''UNIX_file_spec'lib"
$ jffi_home = "''UNIX_file_spec'lib/native/ia64-OpenVMS"
$ delete/symbol/global UNIX_file_spec
$!
$! +++
$! create opt.dat
$! ---
$!
$ open/write opt SYS$SCRATCH:opt.dat
$ write opt "-Djruby.memory.max=-Xmx500m"
$ write opt "-Djruby.stack.max=-Xss1024k"
$ write opt "-Xbootclasspath/a:jruby-1.6.3/lib/jruby-complete.jar"
$ write opt "-Xmx500M"
$ write opt "-Xss1024k"
$ write opt "-Djava.library.path=''jffi_home'"
$ write opt "-Djruby.home=''jrubyhome'"
$ write opt "-Djruby.lib=''jrubylib'"
$ write opt "-Djruby.script=jruby"
$ write opt "-Djruby.shell=/gnu/bin/sh"
$ write opt "-Duser.language=en"
$ write opt "-Duser.country=US"
$ write opt "-Djline.terminal=jline.UnsupportedTerminal"
$ close opt
$!
$! ++++
$! setup the jvm
$! ----
$!
$ if F$Type(JAVA) .eqs. "" then @sys$manager:java$60_setup ! or java$160_setup
$!
$! ++++
$! setup needed DECC and Java logicals
$! ----
$!
$ i = 1
$ loop2:
$ if f$type(save_env_field'i') .nes. ""
$ then
$ symName = save_env_field'i'
$ logical_name == f$extract(0,f$locate("\",symName),symName)
$ logical_value = f$extract(f$locate("\", symName) + 1,-
f$length(symName), symName)
$ define/nolog "''logical_name'" "''logical_value'"
$ i = i + 1
$ goto loop2
$ endif
$ !define/nolog decc$argv_parse_style ENABLE
$ !define/nolog decc$efs_case_preserve ENABLE
$ !define/nolog decc$efs_charset ENABLE
$ !define/job/nolog java$filename_controls "8"
$!
$ on error then continue
$!
$ define/user sys$input tt:
$ java -client -cp 'jrubylib'/jruby.jar:'jrubylib'/profile.jar -
"-V" SYS$SCRATCH:opt.dat "org.jruby.Main" -
'P1' 'P2' 'P3' 'P4' 'P5' 'P6' 'P7' 'P8'
$!
$ set process/parse='Parse_style'
$ delete/noconfirm/nolog SYS$SCRATCH:opt.dat;*
$!
$! ++++
$! restore used logicals to their initial value
$! ----
$!
$ i = 1
$ loop3:
$ if f$type(save_env_field'i') .nes. ""
$ then
$ symName = old_env_field'i'
$ logical_name = f$extract(0,f$locate("\",symName),symName)
$ logical_value = f$extract(f$locate("\",symName) +1,-
f$length(symName) - f$locate("\", symName) -1,symName)
$ if "''logical_value'" .eqs. ""
$ then
$ deassign "''logical_name'"
$ else
$ define/nolog "''logical_name'" "''logical_value'"
$ endif
$ i = i + 1
$ goto loop3
$ endif
$!
$ if F$Type(VERIFY) .nes. "" then VERIFY = F$Verify(VERIFY)
$!
$ exit
$!
$ VMS_to_UNIX: subroutine
$!
$!
$! We need the directory as a unix-style spec.
$!
$! Don't use f$parse, this way we can maintain ODS-5 syntax, including case
$! We need to let Java$filename_controls do the correct thing.
$!
$! unix_filename = "/" + f$parse(vms_filename,,,"device") - ":"
$!
$! already unix don't convert
$!
$ vms_filename = "''P1'"
$ if f$locate("/",vms_filename) .ne. f$length(vms_filename)
$ then
$ unix_filename = vms_filename
$ UNIX_file_spec :== "''unix_filename'"
$ return
$ endif
$! get the device name
$ if f$locate(":",vms_filename) .ne. f$length(vms_filename)
$ then
$ unix_filename = "/" + -
F$EXTRACT(0,F$LOCATE(":",vms_filename),vms_filename)
$else
$! relative path
$ unix_filename = "."
$ endif
$!
$!get the directory
$!
$ dir_start_delim = "["
$ dir_end_delim = "]"
$ if f$locate("<",vms_filename) .ne. f$length(vms_filename)
$ then
$ ! not using [foobar.foo]
$ vms_start_delim = "<"
$ vms_end_delim = ">"
$ endif
$ vms_self_dir = f$extract(f$locate("''dir_start_delim'",vms_filename)+1, -
f$locate("''dir_end_delim'",vms_filename) -
- f$locate("''dir_start_delim'",vms_filename), -
vms_filename) - "[" - "]" - "<" - ">"
$!show sym vms_self_dir
$!
$! Did we have a directory? No, got to the end
$ if "''vms_self_dir'" .eqs. "" then goto directory_done
$!
$! vms_self_dir = f$parse(vms_filename,,,"directory") - "[" - "]" - "<" - ">"
$ i=0
$uloop:
$ e=f$element(i,".",vms_self_dir)
$ if e .nes. "."
$ then
$ unix_filename = unix_filename + "/" + e
$ i=i+1
$ goto uloop
$ endif
$! put multi-dot back in (Oracle addition)
$! drobles begin
$ real_du = ""
$MULTIDOT_LOOP:
$ if f$length (unix_filename) .EQ. f$locate("^/", unix_filename) -
then goto END_MULTIDOT_LOOP
$ s = f$extract (0, f$locate ("^/", unix_filename), unix_filename)
$ real_du = real_du + s + "."
$ unix_filename = unix_filename - s - "^/"
$ goto MULTIDOT_LOOP
$ END_MULTIDOT_LOOP:
$ unix_filename = real_du + unix_filename
$! drobles end
$!
$! add trailing "/" for directory
$!
$ directory_done:
$ unix_filename = unix_filename + "/"
$!
$! finally let's get the filename
$!
$ get_filename:
$! unix_filename = f$edit(unix_filename,"lowercase")
$! unix_filename = unix_filename + f$parse(vms_filename,,,"NAME")
$ vms_filename_start = f$locate("''dir_end_delim'",vms_filename)
$!
$! if there wasn't a directory look for a device name
$ if vms_filename_start .eq. f$length(vms_filename) then -
vms_filename_start = f$locate(":",vms_filename)
$!
$! if we didn't find a directory or a device, just start from zero
$ if vms_filename_start .eq. f$length(vms_filename)
$ then
vms_filename_start = 0
$ else
$ vms_filename_start = vms_filename_start + 1 ! move beyond the delim
$ endif
$!
$ unix_filename = unix_filename + -
f$extract(vms_filename_start, -
f$length(vms_filename), vms_filename)
$ real_du = ""
$ MULTIDOT_LOOP_FILE:
$ if f$length (unix_filename) .EQ. f$locate("^.", unix_filename) then -
goto END_MULTIDOT_LOOP_FILE
$ s = f$extract (0, f$locate ("^.", unix_filename), unix_filename)
$ real_du = real_du + s + "."
$ unix_filename = unix_filename - s - "^."
$ goto MULTIDOT_LOOP_FILE
$ END_MULTIDOT_LOOP_FILE:
$ unix_filename = real_du + unix_filename
$ UNIX_file_spec :== "''unix_filename'"
$ return
$ endsubroutine