Further conditions for usage and distribution apply as
mentioned in the front page.
Some features:
"qvfs06b.zip"
- qvfs_byt - the extension code.
- inet_devices - devices assignment example file.
- inet_dateien - files assignment example file (deutschsprachig kommentiert).
- qvfs_txt - (nicht ganz aktuelle) deutschsprachige Beschreibung.
Currently no english documentation in the archive! Save this text, instead.- qvfs_dat - QVFS internal references.
- qvfs_bas - programming examples.
"e84" editor
- qvfs_byt - the latest version extension code.
- e84_byt - an editor (re below).
- e84_help_txt & e84_hilfe_txt
The program/code and its accompanying texts may
non-commercially and cost free be used and distributed freely.
Any commercial entities that somehow relate to or rely on this file system
require a license agreement (re below).
Publishing (any section of) this text is permitted but requires this copyright
notice included and a proof copy.
This still is merely an experimental program/code. There are many system constellations to test where I simply do not possess the equipment for or, could not afford the time thorough testing would take. Thus alpha testers (who do not insist telling me to implementing a device definition as a "thing", or to writing "C"-code) would be welcome!
It can be linked into QDOS by loading and calling the
code by LRESPR or RESPR/LBYTES/CALL
The code will then install a "simple" device handler, not(!) clobbering the
very few physical QDOS drive definition tables by even more drives, which
maintain the Inet-style filenames and the thus opened QDOS channels I/O and
CLOSE operations - there is no FORMAT and only a substitute
IDELETE.
The displacement figure required for the Qlib $$asmb directive to linking in the *Basic keywords will be shown immediately after initiating the code, enclosed with ":" characters.
Memory and system requirements
Simply, none! You only are recommended to always having the QDOS clock set to the correct DATE, for directory-names purposes (re. below, "Newly created directories"). The QVFS should work within the standard Black QL (tested in QLAY 082+MINERVA 1.93+TK2.12) as well as with MINERVA (1.93 tested) & GoldCard, the QXL (tested with SMSQ 2.76), etc., or any SMSomethings...
Activating the QVFS
Any job can independently activate its own independent instance of the QVFS by the following sequence of *Basic commands or, by its QDOS trap equivalents, after the QVFS was linked into QDOS:
In this special open string the name "VFS" must be written in capital letters, while the assignment symbols (".opn", ".dev", ".nam") must be written in small letters; each of its segments delimited by a blank space.
On success the 1st OPEN_DIR will return D0:=0 from a QDOS call or, the *Basic channel no. Any other consecutive attempt to OPEN_DIR a VFS channel from within the same job will returm that channels ID after a QDOS call in D0 or, as the pseudo error code to *Basic. It does not create a further channel. The above FOP_DIR can be substituted by VFS_FOP(4, ... ).
If the QVFS was set up some session before, with the same system files, this will be all that is required to enable acces to any (enabled) device and file by Inet style names.
The thus carried out setup will be inherited by the following jobs of its tree by searching back for an appropriate VFS channel at the time the actual QVFS operation was invoked. Therefore, if done from the 1st *Basic (job 0) at any time from then on any other jobs can acces the FS by Inet names.
For 1st time installation and for each separate configuration the following should be carried out, further:
<nul> is the code 0 ASCII character, which throughout this text can be taken for any character the code of which is below 32, the blank space, and is not 10, the line feed control code, <lf>.A little (but quite versatile) editor capable of writing any code accompanies the package and thus the mandatory <nul> characters (below code 32) should not raise any difficulties.
Internally, where applicable, any device supplied strings will be terminated by ASCII-<nul> as the single one delimiting character code.
With the above example it will be expected as "win2_inet_devices":
/second networking hard disc/<nul> n2_win2_<nul> /w2/<nul> win2_<nul> # ... ... this is a comment line /net1/floppy1/<nul> n1_flp1_<nul> # another comment /printer<nul> ser1ht<nul> # a "simple" device /incoming/<nul> win2_inet_files_ftp_in_<nul> /ftp/<nul> win2_inet_files_ftp_in_<nul> # doublette - a "link" /InComing/<nul> win2_other_files_bbs_in_<nul> # case sensitive! # /CD ROM/<nul> win2_cdrom_<nul> # re below for r/o redirection
For simplicity (and speed!) he lines layout should be within bounds:
A line, including the <eol> charcters, <lf> or <cr><lf>, may not be longer than 448 bytes.
The significant information may not reach beyond the 382th column of a line.
The Inet name may not begin after the 190th column of a line.
Names delimiter is the <nul> symbol, represented by the ASCII <nul> or any other code below 32, except 10 and 13.
Leading spaces will be discarded.
Everything after a "#" number sign not within a name is a comment.
Names can be made of any characters in the ASCII code range of 32 to 255.
Inet device description (only!) entries begin with a "/" slash.
Inet directory names end with a "/" slash
Inet filenames may not end with a slash.
Assigned QDOS directory names end with an understroke "_".
Assigned QDOS names may not contain a "/" slash at all.
Any filenames are recognized case sensitive (to further simplifying and speeding up the code):i.e. for PC-DOS files access the assignment files name should be initiated in capital letters or, simply, just the inet type name of the directory assignment file the name of which was set with the initial .nam option be editted to the conformant writing mode.
With the above examples the QVFS would expect a file "inetfiles" in each of
the enabled (sub-)directories and/or devices.
Then:
In which lists the QDOS filenames will appear translated to Inet style names
with any "_" understrokes being replaced by a "/" slash, except the very last
one which will be replaced by a dot "." if it is within the last five
characters of a filename (as opposed to a directory name). Any further
conversion can be editted.
As a means of security any QDOS files not listed in the assignment files are not accessible via the QVFS. It can create and register new files, but delete or overwrite only already registered ones.
/next/directories/filename<nul> /dev3_filename<nul> # QDOS path fully specified
A QDOS names entry beginning with a slash will be considered as the full
device+filename description.
- wherein "device" should comply to the (habitual) QDOS conventions of the
device named by a
- (three characters) text string, plus a decimal digit 1..8 and an
understroke, optionally preceded by a
- NETworking symbol, i.e. a letter, a decimal digit, and an understroke.
... and that is it.
The QVFS will now take over the files open calls after the chain of "simple devices" was passed and check the names for their Inet-style properties and process those names that fit.
Inet-style names will be recognized if they begin with a slash "/", or
if the beginning is one of the symbols "./" for the working directory path or
"~/" for the home directory path.
The names will be expected specified as the full path+file names, explicitely,
or after internally expanding the HD or WD path's symbols.
The other Inet names special symbols are
"/../" | discarding the subdirectory level previously specified in a path description. | |
"/.." | as the trailing characters represent the next higher directory level (towards root). | |
"/." | as the trailing characters represent the directory of the given path. | |
"/" |
will be required to be the last character when creating a new QVFS directory (OPEN_NEW, D3=2) or, to reading the corresponding standard QDOS directory (*Basic: DIR inetname$), and will be read as "/.", otherwise. | |
"/" | a single slash denotes the root directory as set up with the .dev option. | |
"/" | if not in QDOS FS preference mode any other names containing a slash will be tried as Inet style names of files residing in the "working directory" path. |
QVFS 05:
Further, any QDOS style filenames wherein a "/" character was found and
which do not begin with one of the above mentioned symbols will be tried
Inet style in the working directory and, responded to with a bad name
error (-12) if no match found - unless the concerning VFS branch was set to
QDOS preference.
No QDOS name designed to be accessible by an Inet-name should contain a
character code of 0 till 31. Those characters can be used as another means to
exclude a QDOS file from QVFS access.
Several additional features will be available to any job that is an owner of a VFS channel or any successor of such a job. Thus, if assigned to the 1st *Basic job any other program in the QL which was executed after has access to the Inet style FS and its long pathnames - if not some error "protection" within those jobs themselves prevent their use!
Working directory: | /hd2/inetfiles/system/data/ | ||
New file: | ./a very long filename with.xtn | ||
Producing: | /hd2/inetfiles/system/data/aame with.xtn |
The underlying QDOS FS is limited to no more than 15 sub-directory levels, by
the filename length limit of 36 (31 if NETworking) characters. This has been
overcome by simulating the Inet-names style directories in a way that no
limits at all apply to nested directory levels. Those appear as they should
when maintained with the QVFS routines, but reside all in the basic QDOS
directory of the device concerned, not nested at all, with an arbitrary unique
filename, derived from the current DATE value.Therefore each call to creating
a directory will be delayed by about one second, to guarantee for unique names
in case of fast consecutive such attempts.
[ :HIER: ändern - z.b. durch hilfs-zähler, lo-byte, anstelle hi-byte von 'date' ]
This naming mode does not apply to names created by VFS_SYNC, etc., thus it will be essential to keeping the assignment files safe, as it would be very difficult to restoring the correct directory structure after such a file was lost. - Which can be done by backtracking the 1st assignment of those files.
QVFS v06, modified:
New Inet type directories - the names of which end with a slash, and
are till unknown to the system - can be created with the open code 18.
Alternatively a standard OPEN-NEW calll can be used (code 2), where the QVFS
will then modify the open code of a conformant name, internally.
Due to the above mentioned QDOS reasons no files of the initial directory
level and its successors can be acessed until the end of this process.
While an empty initial assignment file will also be produced by this call (or
an existing one left untouched) a VFS_SYNC call will be required to enabling
access to any previously unknown conformant files.
A path, ending with a "/" slash, can be passed to a VFS channel via the
QDOS trap fs.heads or by the *Basic function VFS_WD, which additionally
returns the previously set path. The working directory, if set, can then be
abbreviated with the symbolic pathname of "./" followed by any further
directory level, the backstep symbol(s) inclusive, and the filename requested.
Working directory: | owd$ = VFS_WD(#vfs-channel,"/hd2/inetfiles/system/data/") | ||
Filename: | /filename.extn | ||
Opening: | ch = VFS_FOP(open_code,"./filename.extn") |
There is no simple means of distinguishing a directory device name from a name meant to describe a simple device other than by a trial open and directory read which can help to finding out wether a device is capable of files and/or directories simply because the appropriate QDOS traps work, or not in which case a non-directory device might have been found.
Further, the QVFS does provide an sd.extop call, and thus cannot be distinguished from a CON type channel that way, either. But, for those who still feel they cannot trust the QDOS routines a special marker was provided in the handler and in the channels definition tables - re below.
Another warning: Do not falsely interpret the physical data
returned by the fs.xinf call, providing some extra media information,
unlike the logical data of a directory entry supplying a uniform header
structure for each of the several types of QDOS channels.
The QVFS *Basic extensions
Procedures Many of the keywords default to the currently supervising VFS channel. Parameters in [brackets] are optional. The VFS channels can be specified by the full QDOS channel-ID, the QDOS index or, by their *Basic related channel number if preceded by a "#" number sign. |
Functions |
open_mode | access | TK2 equivalent |
0 | r/w | FOPEN, the standard r/w open call |
1 | r/o | FOP_IN, shareable read only |
2 | r/w | FOP_NEW, create and open a file |
3 | r/w | FOP_OVER, overwrite and open a file |
4 | dir | FOP_DIR, open a directory, read only |
8 | w/o | the OR mask modifier to "write only" |
17 | r/o | OPEN Inet style directory file |
18 | r/o | create an Inet and its corresponding QDOS style directory |
QVFS v06, modified:
Names ending with "/" will be used to create a new directory, if
"open_mode"=2 was passed, and not being responded to with an open
channel; the call returning the VFS-ID on success, -12 otherwise.
Creating a new directory will insert any conformant QDOS files to the
corresponding QDOS directory, and, if not already existing, produce an empty
Inet names assignment file. Re-synchronizing will only be required to
enabling any existing (additional) QDOS files - re VFS_SYNC, VFS open
trap.
Yet unsolved...
Modified Inet type channels QDOS-Traps:
Data sizes 32 bit if not stated otherwise.
Registers not mentioned remain unchanged or, if applicable return the standard
QDOS values.
io.open D0=1 D1/A0 parameter passing and D0 error code as usual. D3 OR-Mask 8 "open w/o" modifier: D3 Any OPEN mode can be OR masked to the corresponding r/o mode. Reading operations will be responded to by the err.ef (-10) error code. QDOS-i/o-traps disabled are D0 = 0..3, 8..11, 69, 72 and 78+. The filepointer will initially be set to EOF. D3 OR-Mask 16 "idir" modifier: D3 17 "read idir", directoryfile, r/o; alternatively D3 1 plus the Inet name ending with "/." or "/..". This mode will be set internally if the path+filename supplied ends with "/." or "/..", and passed to QDOS as standard "r/o". D3 18 "create idir", create a new directoryfile; alternatively D3 2 plus the Inet type name ending with "/". An Inet type directory entry will be created in the current level assignment file and a uniqely named QDOS directory and, if not yet present, an empty corresponding QVFS directoryfile newly set up. This mode will be modified, internally, from a call to create a new file if the path+filename supplied ends with a slash "/" and be responded to with D0 = the supervising VFS channels ID on success or, D0 = -12 if the directory was not installed A0 undetermined, this call leaves no open channel. D3 -1 "idelete" Replacing the standard io.delet call (D0=4). D3 -ve "iremove" QVFS v04 D3 any -ve value but -1 can be used to recoverably invalidating the Inet to QDOS assignation, by out-commenting the entry concerned, and not physically deleting any data.
NOTE: For the special operations on Inet-style directory files D3:=-1 is almost mandatory, uncertain (though not unsafe) operation might result, otherwise. The repetitive nature of certain calls occasionnally may lead to unexpectedly long execution times of up to several seconds, depending on the storage media involved. D0=02, 03 io.fstrg, io.fline fetch a string/line of bytes modified handling for directory type channels, only, re below. D0=71 fs.headr read the (file)header IN: D2.L = 512 used to return the Inet type 512 bytes header. D2 any other value used to return the QDOS standard data. A1 buffer address, if D2=512 odd A1 values will be rejected. OUT: D0 = -13, err.te if validating failed or odd address encounterd D1 received length (512, any value other than D2 is an error) A1 points to after the 512 bytes buffer space; for the received data structure re to "fs.headr type QVFS fileheader", below. D0=74 fs.renam rename a file *** yet to be implemented *** D1 specifying the over all length of the string at (A1)+. A1 even address pointing to the new QDOS type name with leading count.w, followed by the <nul> terminated new Inet type name at the next even address. The trap call will 1st modify the Inet assigned name by outcommenting the old and appending the new pair of names, then call the QDOS routine. Thus the Inet name will even appear changed if the QDOS call failed! - Which can be recovered only by editting the assignment file concerned. D0 = -12 (err.bn) will be returned if D1 was out of bounds, D0 = -13, err.te if validating failed or odd address encounterdDirectory type "ccc/." channels special i/o handling (trap#3):
D0=02, 03 io.fstrg, io.fline fetch a string/line of bytes IN: D2 = 512 to fetching the current directory entry, D3 = -1 (almost) mandatory (re above), D3 at any other value can result to incomplete data transfer. A1 buffer address; if D2=512 odd values of A1 will be rejected. OUT: D0 = -13, err.te if validating failed or odd address encounterd D1 received length (should be no other than 512) A1 points to after the 512 bytes buffer space; for the received data structure re to "directory type QVFS fileheader", below. The buffer will initially be set to all -1, which when this value can be read anywhere in the leading 52 bytes or in the Inet name space denotes the data not being read (D3 was not set to -1?), and the filepointer left at its previous state, enabling loss free re-reading. QVFS v05: The root directory headers will be made up from the devices assignment file, only, no QDOS headers being fetched, because of frequent QDOS/PIF related errors. D0=66 fs.posab IN: D1 = number of the entry to be addressed, further data as fs.posre. D0=67 fs.posre IN: D1 = number of entries by which the reqired directory entry is displaced to the current one. OUT: D1 = QDOS style file position at the beginning of the line containing the directory entry requested. If the absolute number results to -2 or -1 the file pointer will be read as zero, while the next consecutive directory reads will start at the the pseudo headers of the current (-2) or the one step back directories, "." and "..", respectively.
"VFS"-Channel QDOS-Traps:
Those calls apply to the QVFS control channels, only.
D0=02 io.open D1 = -1 or owner job ID D3 = any non-directory type code Setting up a very simple NUL-device channel, returning EOF on any reading operations and responding OK to writing, with D1 set to D2 on entry, A1 advanced by D1. D3 = 4 directory type, the general purpose QVFS supervising channel mode: A0 = ptr to a special name as explained above, which must be written exactly as stated (below). The actions concerned apply to the calling jobs VFS channel. "VFS .opn" registering a QVFS instance to the channels owner job "VFS .dev devN_filename" registering the enabled devices list. "VFS .nam devN_filename" registering the 1st files assignment list and determining the lists filename used throughout this QVFS instance. "VFS .nam devN_directory_" producing a complete assignemt list of and in the directory specified, the listfiles name will be as passed with the above .nam registering call. "VFS .fss VFS" Set QVFS mode to Inet names preference. Any names 1st will be tried for Inet style feasibilty, with the WD inserted to lead the name if applicable. "VFS .fss QLF" Set QVFS mode to QDOS names preference. Disabling the Inet names decoding. "VFS .fss STD" Set QVFS mode to standard preference, i.e. if Inet type names check failed passing control to the QDOS devices.
D0=01 io.fbyte Not implemented D0=02, 03 io.fline, io.fstrg pop from WD Pop latest directory segment from working directory path. FLINE can be accessed with the *Basic command INPUT. IN D2 buffer length D2 = 0 flag to clearing the path entry A1 buffer address OUT D1 segment length A1 points to the <nul> byte after the segment string D0=05 io.sbyte Not implemented D0=07 io.sstrg push to WD Append a directory to the working directory path. The string should be terminated with a <nul> byte. SSTRG can be accessed by the *Basic command PRINT. IN D2 string length A1 buffer address OUT D1/A1 as io.fline D0=09 sd.extop user defined Can only be accessed by job 0 or by the VFS-channels owner job. Parameters & execution routine user supplied. QVFS data re below. Odd values of A2 will be rejected, if not in the range of 1 to 9. Registers a0/a3/a4/a5/a6 will safely be restored, internally. IN: D1/D2/A1 user supplied data. A2 user supplied execution address. ENTRY: D0 -15 err.bp D1/D2 parameter D3 set by QDOS (0 or -1) D4 what originally was passed as A2 D5 0 Null D6 47 "/" character D7 undetermined A1 parameter A2 actual call address A3 handler base address A4/A5 undetermined A6 QDOS system variables A7 SSP OUT: D0 -2 after an unauthorized call. D1/A1 as supplied by the user defined routine. Special: A2 = 09 Store a new 'home' path Accessible by job 0 and the VFS-channel owner job only. IN: A1 buffer, string with leading count.w. OUT: D1/A1 as io.fstrg A2 = 07 Read old & store new WD Accessible by any job. IN: A1 address of a buffer at least 256 bytes of size. The buffer size will not be checked internally! OUT: D1/A1 as io.fstrg A2 = 05 Read old & store new HD. Accessible by job 0 and the VFS-channel owner job only. Parameters as A2=07 A2 = 03 Lock/unlock decoding mode. Accessible by job 0 only. D1 =/= 0 locking flag, unlocking otherwise. D0=70 fs.heads set WD Set fully specified working directory Parameters as io.sstrg. The string further delimited by a <nul> character. D0=71 fs.headr read WD Read working directory of the VFS-channel's owner-job(s chain) Parameters as io.fline D2 = 512 can be used to fetching the 'home' path. D0=74 fs.renam set 'home' Set 'home'-Directory. Accessible by job 0 and the VFS-channel owner job only. IN A1 buffer address of string with leading count.w OUT D1/A1 as io.fstrg
QVFS system tables. - Preliminary -
Items size 32-bit if not stated.
There is no free space unless explicitely denoted available to the
user.
Actual label values can be found in "qvfs_dat", included in the QVFS
archive.
name disp size use dflg 24 signature "VFC"<<8 dhnd 28 handler base address of primary channel doco 32 open mode as passed with D3 dcdt 36 primary cdt dchn 40 primary channel ID dvfs 44 ID of supervising VFS channel dvjp 48 6 .b i/o trap redirection entry point (subroutine call destination address can vary!) dhrt 54 primary's i/o return address dhcd 58 2ndary (this) cdt base address dcvfs 62 address of the supervising VFS cdt dfpos 66 current directory entry number ddpos 70 current directory entry filepointer ... (internal workspace & auxiliary data) dnam 594 258 .b count.w + Inet type full path+filename dqnm 852 46 .b count.w + QDOS type full device+filename ...
name disp size use pfgnm -36 "QVFS" signature pfver -32 "VF06" current release no. pxcde -28 base address of the extension code (QVFS v06) pqver -24 .w bcd packed QDOS version number pfqfl -22 .b -1:SMSQ/E, 0:QL, 1:SMSQ pqlfl -21 .b 0:QL hardware present (IPC), -1 otherwise pmifl -18 .w -1:MINERVA, 0 otherwise pfctab -8 base link into VFS channels' posn qclnk(a0) pfccnt -4 .w count of VFS channels currently open pdirt -1 .b actual OS' directory file encoding flag pfxntl 00 10 .l VFS handler reference ... pqnmi 40 ID of initial .nam option channel pqnmc 44 .w usage counter ... (.dir & .lok currently unused) pqdvi 64 ID of initial .dev option channel pqdvc 68 .w usage counter pdtab 72 48 .b 2ndary handler reference pqdir 120 48 .b (another dummy handler, yet unused) ...
name disp size use qoco 24 open mode as passed with D3 on open qnam 28 .nam option channel ID qnmc 32 .nam option cdt address ... qdev 52 .dev option channel ID qdvc 56 .dev option cdt address qdvh 60 4*8 .b .nam ... .dev channel handler address qdvu 62 .w usage counter qdvl 64 .w length of QDOS device description ... qclnk 92 VFS cdt link address qsnam 96 4*64 .b count.w+name of the system files ... qiwdr 412 256 .b working directory path qihom 668 256 .b home directory path ... qiwrk 932 448 .b workspace, volatile, can be used in extop routines ... quser 1762 128 .b user data (free space)
Displacements count from the beginning of the extension code - re. <pxcde>.
Vectors are 16-bit pointers relative to their own addresses.
Registers not mentioned remain unchanged.
0002 vfs_fnd IN: -/- OUT: D0 VFS-channel handler base address, or -ve 0004 vfs_cid IN: -/- OUT: D0 currently valid VFS channel ID, 0 or -ve if no such channel exists. D1 the callers job ID D2 the VFS channels owner job ID A2 the VFS channels base address 0006 vfs_rnm IN: A0 a VFS channel ID OUT: D0 that channels internal QDOS error code. -6 if no such channel exists.
000...063 standard assigned QDOS header wherein 004 .w will be set to -1 if this is an error header 064...081 count.w+QDOS-devicename 082...249 reserved for future use 250 count.w of QVFS path (w/o filename) 252 count.w of QVFS device description 254 count.w of the.. 256...511 Inet filename, <nul> terminated
000...063 standard assigned QDOS header 064 count.w of the... 066...075 QDOS device name. 082 count.w of qdos device+path description, current level 084 count.w of qdos device+path description, previous level 086 flag -1 if no QDOS header produced (con, pipe, etc) 088 this directory entries consecutive number 090 and filepointer.l to the assignement files line 094...249 reserved for future use 250 length of Inet device+path description, 252 length of Inet type device description, 254 length of the... 256...511 Inet path+filename, <nul> terminated.
QVFS License
Anyone may use the QVFS in a particular computer free of charges, no matter what for.
Any commercial entities, those things inclusive which someone may be begging a "donation" for, that somehow make use of, rely on, or may be accompanied by, the QVFS require a license the fee of which is determined by the number of pieces intended to be sold, payed to the author in advance:
- 10: DM 40,- Pounds Sterling 20,- U.S. Dollars 40,- - 50: DM 150,- 60,- 110,- - 200: DM 400,- 160,- 290,- (Or any foreign currency equivalent to the above Pounds Sterling rates.) The above rates are subject to change without public notice and do not include any foreign trade taxes nor customs fees.The licensee will receive a written permission to using the QVFS to whatever commercial purpose intended, according to the rate payed, which validates the license agreement.