This is the utility from Paul Nankervis as I found it at http://www.goatley.com/hunter/w2k.html
and which I updated for Linux.
The (original) source uses gets() to read a command (prompted by "$>"). Building the tool with the gcc tool chain
gives you warnings like:
ods2.c: In function ‘main’:
ods2.c:1165:17: warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]
if (gets(str) == NULL) break;
^
...
ods2.c:(.text.startup+0x368): warning: the gets' function is dangerous and should not be used.
On other systems you may get other (even run-time) warnings or you may not be able to build the tool.
This
patch was sent to me to replace the call to gets with one to fgets.
The current ods2 util, as provided in the zip file and built in a 32-bit
environment, is not able to mount
disks bigger than 2GB. This is caused by using lseek() to position to disk
blocks. With bigger disks the usual error is:
$ ./ods2 mount sdc
ODS2 V1.3hb
lseek : Invalid argument
lseek failed -1
Accessfile status 500
Mount failed with 500
$
To remove this restriction in a 32-bit environment, one can
patch
phyunix.c to use lseek() with a 64-bit offset.
Also, the current ods2 util is not able to mount ods2 disks initialized
without a primary home block, which is the default on I64 unless /NOGPT is
specified and can be requested on Alpha with /GPT.
Changes for Linux:
BIG_ENDIAN conflicts with another already defined macro. Something from
BSD, I don't know. So I changed it to
USE_BIG_ENDIAN.
The compiler complained about some string routines therefore in some
sources I changed strings.h to string.h.
I got it to work. But copying files to Linux directories didn't work.
Yes, because of the '/' being an introducer for a qualifier. So I
changed cmdsplit
/*
* New feature for Unix:
'//' stops qualifier parsing (similar to '--'
* for some Unix tools). This enables us to copy to Unix
directories.
* copy /bin // *.com /tmp/*
* is split into argv[0] -> "*.com" argv[1] ->
"/tmp/*" qualv[0] -> "/bin"
*/
Next I thought it would be nice to have a /PAGE for the directory
command and for the type command and for search. But then I thought that
this is Linux and usually there is a good pipe implementation which can
do that for me. The only thing I missed was a one-liner to start the
ods2 reader with some commands. OK, there is the undocumented '@' and
there is input redirection. But both require editing a file. For simple
command sequences it seems too much overhead. Having a one-liner in the
recall buffer and changing that is much easier. So I added command
arguments which are interpreted as chained commands to the ods2 reader.
There are no command line options, yet. So everything is accepted as a
command string(s). As an internal delimiter I chose '$'.
/*
* Parse the command line to read and execute commands:
* ./ods2 mount scd1 $ set def
[hartmut] $ copy *.com $ exit
* '$' is used as command delimiter because it is a familiar
character
* in the VMS world. However, it should be used surrounded by
white spaces;
* otherwise, a token '$copy' is interpreted by the Unix
shell as a shell
* variable. Quoting the whole command string might help:
* ./ods2 'mount scd1 $set def
[hartmut] $copy *.com $exit'
* If the ods2 reader should use any switches '-c' should be
used for
* the command strings, then quoting will be required:
* ./ods2 -c 'mount scd1 $ set
def [hartmut] $ copy *.com $ exit'
*
* The same command concatenation can be implemented for the
prompted input.
* As for indirect command files (@), it isn't checked if
one of the chained
* commands fails. The user has to be careful, all the
subsequent commands
* are executed!
*/
Now I can use the ods2 reader like
./ods2 mount sda $ dir
[...]/file/date $ exit |more
./ods2 mount sda $ dir [...]/file/date $ exit |grep '-2003' |more
./ods2 'mount sda: $set def [hartmut] $copy/bin *.com // /tmp/*
$exit'
The single quotes are useful if I want to prevent the Linux shell from
expanding it's meta characters: '*' etc. The '/bin' is not useful for
text files like command procedure. Here it is used just to show the
effect of '//'. So the last example gives:
ODS2 V1.3hb
%MOUNT-I-MOUNTED, Volume
SYS073 mounted on sda:
%COPY-S-COPIED, sda:[HARTMUT]CRECRC.COM;38 copied to
/tmp/x/CRECRC.COM (59 records)
%COPY-S-COPIED, sda:[HARTMUT]JSTART.COM;4 copied to
/tmp/x/JSTART.COM (4 records)
%COPY-S-COPIED, sda:[HARTMUT]LOGIN.COM;2 copied to
/tmp/x/LOGIN.COM (71 records)
%COPY-S-COPIED, sda:[HARTMUT]NB.COM;5 copied to /tmp/x/NB.COM (15
records)
%COPY-S-COPIED, sda:[HARTMUT]NBR.COM;1 copied to /tmp/x/NBR.COM
(3 records)
%COPY-S-COPIED, sda:[HARTMUT]OLD-NB.COM;1 copied to
/tmp/x/OLD-NB.COM (15 records)
%COPY-S-COPIED, sda:[HARTMUT]PCDISK.COM;3 copied to
/tmp/x/PCDISK.COM (4 records)
%COPY-S-COPIED, sda:[HARTMUT]START.COM;2 copied to
/tmp/x/START.COM (3 records)
%COPY-S-COPIED, sda:[HARTMUT]U2V.COM;41 copied to /tmp/x/U2V.COM
(236 records)
%COPY-S-COPIED, sda:[HARTMUT]V2U-OLD.COM;1 copied to
/tmp/x/V2U-OLD.COM (36 records)
%COPY-S-COPIED, sda:[HARTMUT]V2U.COM;35 copied to /tmp/x/V2U.COM
(59 records)
%COPY-S-COPIED, sda:[HARTMUT]X.COM;1 copied to /tmp/x/X.COM (91
records)
%COPY-S-COPIED, sda:[HARTMUT]XLOGIN.COM;1 copied to
/tmp/x/XLOGIN.COM (89 records)
%COPY-S-NEWFILES, 13 files created
These examples always have an exit command at the end. But that's not
necessary. If there is none, the ods2 reader continues reading commands
from
stdin:
./ods2 mount sda $ set def
[hartmut]
ODS2 V1.3hb
%MOUNT-I-MOUNTED, Volume
SYS073 mounted on sda:
$> dir *.com
Directory sda:[HARTMUT]
CRECRC.COM;38
JSTART.COM;4
LOGIN.COM;2 NB.COM;5
NBR.COM;1
OLD-NB.COM;1
PCDISK.COM;3 START.COM;2
U2V.COM;41
V2U-OLD.COM;1
V2U.COM;35 X.COM;1
XLOGIN.COM;1
Total of 13 files.
$> exit
So on a Linux box an alias can be set up such that I end up on the VMS
disk in my directory.
I'm not happy with the (error) messages being written to stdout, they
should go to stderr, so I can redirect only the wanted output to a file.
Maybe I'll change that, later.
One note on copy/binary. It is not what one might expect. The ods2
reader checks if the VMS file has the attributes FAB$M_CR | FAB$M_PRN |
FAB$M_FTN. If present, the read data is assumed to be text and a "\n" is
appended to each record when writing the copy. "/binary" suppresses
that. If the VMS file has none of the attributes set, the data is copied
as is. Executables with fixed length records will be copied as 512 byte
records and will not differ if copied with or without "/binary". Files
with variable record length will always be copied without the record
length, regardless of "/binary". But if "/binary" is used on a file,
which has one of the above attributes set, the file may not be copied:
the ods2 reader can't handle empty records in "binary" mode. Anyway, I
was not able to copy a Java class file and run it on Linux.
On VMS there can be virtual disks (VDAnnn, LDAnnn), which make a disk
out of a file. These files, disk images, can be copied to Linux disks.
To let ods2 read these virtual disks a simple symbolic link from
/dev/diskfile to the file is set up. Then the usual 'mount diskfile'
can be used. Sorry, the user needs the right to create the symbolic link
in /dev or root has to do that. Or losetup can be used to create a loop
device for the disk image, so a 'mount loop0' will work. Again, the
needs the right to do that.