ODS-5 (or VMS/Posix) symlinks: The easy part: a symbolic link file is special. It has the file organization FAT_SPECIAL and the record attribute FAT_SYMBOLIC_LINK. The contents is a text pointing to another file. So far so good. Now, the text is a Posix file specification! $ CREATE/SYMLINK="../hello" WORLD creates a symbolic link, the symbolic link file is WORLD.;1 and the symbolic link points to the file hello in the parent directory. Obviously the symbolic link is not an ODS-5 file specification. How is the target found? With translating it to an ODS-5 file, the latest version of it. For example $ DIRECTORY [-] HELLO.;7 Hello.;16 Hello.;15 hello.;3 hello.DIR;1 and $ TYPE WORLD. prints the contents of the file hello.;3 $ DIR [.WORLD] gives the files in the directory [-.hello] If hello.;3 is deleted, then $ TYPE WORLD. fails or prints the contents of the file HELLO.;7 This all depends on the VMS process context. If the context is case sensitive, then the target is not found and a VMS error FNF is returned. If the context is case blind, the default, then the contents of the file HELLO.;7 is printed. Similar, if the context is case blind and if HELLO.;7 is deleted, $ TYPE WORLD. prints the contents of the file Hello.;16 So far so good(?). One user may have created symbolic links in the case blind context, expecting "../hello" being matched with "[-]HELLO.;7" (This is usually the case because users tend to type all commands and filenames in lowercase: '$ create/symlink="../hello" world' and create/symlink creates a lowercase link text !!!.) On the same disk another user may have created other symbolic links in the case sensitive context. In other words, looking up the target is not determined by the file system on the disk. A Linux file system for ODS-5 can't pick up the right or a one-fits-all context. It also can't change the context based on the process. A Linux process has a case sensitive context. Therefore the lookup and match in the file system for ODS-5 is case sensitive. There is no exception and no option at mount time. If the VMS user got it wrong, it will not work, here. The developer of this kernel module decided to treat each version of an ODS-5 file as an own file. The reason is simple. The target was to get to all files on an ODS-5 disk. Some tools or utilities which present VMS files to Unix hide the version and some hide the version if there is only one version of the file. These tools also convert the ';' to a '.'. The above ODS-5 directory then is listed by such tools as HELLO Hello..16 Hello..15 hello HELLO.DIR Or, if the directories are "typeless" HELLO..7 Hello..16 Hello..15 hello HELLO The developer of this kernel module didn't like that. Imagine the file Hello..15 is deleted, then the file Hello..16 becomes Hello. OK, deleting a file will not happen, here, because this is a read-only Linux file system for ODS-5. On the other hand, ODS-5 has a file header for each version of a file. The header contains the version in the filename. So strictly speaking there are no file versions in the file system. That's another reason to always use/display file versions in this Linux implementation of the ODS-5 file system. There are only versions in the directory. In a directory there is only one filename which does not include a version. Then there are version entries to that filename. Each entry holds the file id (which is an index in the fileheader file - INDEXF.SYS - addressing the file header with the filename including the version). However, with symlinks the ODS-5 module has to find the right target, which is specified as a file name without version but is matched as one with a version. This can be hidden for following a link and accessing the target inside the ODS-5 module. So # ls -l WORLD.;1 shows lrwxr-x--- 1 bin bin 8 Oct 8 12:33 WORLD.;1 -> ../hello and # cat WORLD.;1 will print the contents of hello.;3. But then # file WORLD.;1 is broken. The symbolic link as shown and as returned in a readlink() is "../hello" and the file utility does a stat() on "../hello" which is not an ODS-5 file in the parent directory! This is a dilemma which requires a compromise. On one hand, if stat("../hello") is allowed to work because of a result of reading a symbolic link, an # ls WORLD will also work. Inside stat() and the ODS-5 function it uses, it is not known if the passed file name was from a symbolic link or not. Flagging the symbolic link doesn't really help. For example a trailing ";0", the traditional VMS specification for the last (=highest) version may be suggested as a flag. Flagging a symbolic link like this is like faking a version. If a version is faked, that is a ";0" is added to indicate the last version, the output of "ls" also changes: # ls -l WORLD.;1 lrwxr-x--- 1 bin bin 10 Oct 8 12:33 WORLD.;1 -> ../hello;0 Did you see that there is no dot? All VMS file names have a type part. The "." is part of the type and always present. There is no VMS file like "hello;0". But the dot is not added because only a version is faked. Did you see that the file size also changed? It has to. If a smart program sees a symbolic link file and uses a buffer of its size to get the link, the reported size must be as long as the faked symbolic link. This leaves us with the oddity of WORLD.;1 pointing to ../hello;0 which can be ../hello.;3 or ../hello.DIR;1. And again, now # ls -l WORLD;0 lrwxr-x--- 1 bin bin 10 Oct 8 12:33 WORLD;0 -> ../hello;0 "works", too and prints as output WORLD;0 Did you see that there is no dot? "ls" prints the filename as it gets it. Another option to flag the symbolic link is to use a character which will never show in an ODS-5 file name: "*" is one. The symbolic link would then show as ../hello*. Then in a lookup, any trailing asterisk can be matched with ../hello.;3 or ../HELLO.DIR;1/ or maybe to ../Hello.;16. This is nice and somehow compatible with an # ls WORLD* which would be matched similar. Although the added asterisk sounds like a good compromise, any flag (";0" or "*") will not work if a symbolic link from ODS-5 points to a Linux file: ../../../hello;0 and ../../../hello* will never be matched with an existing ../../../hello, when the uppermost parent directory is in a Unix file system. Sigh, so stat("../hello") has to work to make the best out of the ODS-5 symbolic links. Implementing this means, that any file without a ;<version> is from a symbolic link and is treated like a ";0". Then there are the obscure cases where there are two files like hello.;1;1 (DCL shows it as hello^.^;1.;1) and hello.;1 in one directory and a symbolic link world.;1 -> hello.;1 Now, on Linux with this file system do an ls hello.;1 -> print info on hello.;1 cat world.;1 -> print contents of hello.;1;1 file world -> stat("hello.;1") -> check status of the wrong file hello.;1 Maybe it isn't worth the effort. Maybe symbolic links should not be supported, here.