[[Title:File access]]
[[Category:Filing]]
Files have access attributes, returned and set in XY+14 in [[OSFILE]] calls.
Each bit indicates different access rights to the file. However, care needs
to be taken in interpreting these bits, particularly as errors have been
propogated in most documentation on the matter.
==Definition==
Each access bit has the following definition:
b0 - R - file can be read by owner
b1 - W - file can be written to by owner
b2 - E - file can be executed by owner
b3 - L - file cannot be deleted, renamed or overwritten by owner
b4 - R - file can be read by public
b5 - W - file can be written to by public
b6 - E - file can be executed by public
b7 - L - file cannot be deleted, renamed or overwritten by public
Note that lots of documentation (including the Advanced User Guides) list
these as ''cannot'' be read or written. This is wrong. Each bit is set if
the corresponding access right is ''present''.
In access strings, the owner access is on the left of any '/' character, and
the public access is on the right, sometimes in lower case. For example:
WR/R - owner read and write access, public read access only
The normal default access string of WR/WR gives the access byte &33.
===Read Access===
Having read access means that a file can be read with LOAD, BGET, OSGBPB, *RUN and */.
The owner of a file can determine if they are allowed to read or load a file
by examining the 'R' bit with:
readable%=(access% AND 1)<>0
===Write Access===
Having write access means that a file can be written to with BPUT and OSGBB.
Not having write access does ''not'' mean that you cannot ''overwrite'' the
file with SAVE. That is controlled by the Locked access.
The owner of a file can determine if they are allowed to write to a file by
examining the 'W' bit with:
writable%=(access% AND 2)<>0
===Execution Access===
Having execute access means the file can be run with *RUN and */.
Most filing systems do not maintain a seperate execution access setting. If
a file is readable, then it is also executable. Consequently, most filing
systems either never return the 'E' bit, or always return the 'E' bit as a
copy of the relevant 'R' bit.
The owner of a file can determine if they are allowed to run a file by
examining both the 'R' and the 'E' bits with:
runnable%=(access% AND 5)<>0
If the 'E' bit is set and the 'R' bit is not set, then the file cannot be
loaded or read, and can only be accessed with *RUN. The owner of a file can
determine if a file is run-only with:
runonly%=(access% AND 5)=4
HADFS and HDFS maintain a seperate 'E' bit (HDFS calls it the 'X' bit). ADFS
allows you to set 'E' access with the *ACCESS command to create a run-only
file, but it does not reflect this in the returned file access byte. Also,
ADFS does not let you set the 'E' bit with OSFILE, you can only do it with
the *ACCESS command.
===Locked Access===
Being locked means that the file cannot be deleted, cannot be renamed, and
cannot be overwritten with SAVE. Being locked does ''not'' mean the file
cannot be written to with BPUT and OSGBPB. That is controlled by the Write
access.
It may not be obvious, but a non-owner can never be able to delete a file.
To a non-owner, a file is always locked, bit 7 is always implicitly set.
However, most filing systems actually return bit 7 as an exact copy of bit
3, implying that a non-owner may be able to delete the file. You should
never examine bit 7 to decide whether you can delete, rename or overwrite a
file. If you do not own the file, you cannot delete it.
The owner of a file can determine if they are allowed to delete, rename or
overwrite a file with:
deletable%=(access% AND 8)<>0
==Owner vs Public==
The access byte holds the owner's access in the bottom four bits and the
public's access in the top four bits. However, there is no way of knowing
whether you actually own the file you are examining and so which bits you
should look at to determine your own access. [[OSGBPB]] 6 will tell you if
you own the currently selected directory, but that does not have to be the
directory that the file you are examining is in.
==DFS==
DFS must be considered as a special case, as it completely mangles the file
access byte. Also, some DFS extensions or replacements have been written
using the flawed documentation propagated by likes of the Advanced User
Guide.
===Reading the access byte===
DFS only ever returns the 'Locked' bit in bit 3. It never returns anything
for the owner 'R', 'W' or 'E' bits and never returns anything for the public
access bits.
*ACCESS file returns an access byte of &00, ie: ----
*ACCESS file L returns an access byte of &08, ie: L---
Consequently, if reading the file access byte from DFS you must modify it
before using it:
IF dfs% THEN access%=(access% OR 7)EOR(access% DIV 4)
This changes:
---- to -EWR and L--- to LE-R
===Writing the access byte===
Even though DFS only ever ''returns'' the owner's Locked bit, when writing
the access byte both the Locked bit ''and the Write bit'' set the Locked
bit.
Writing &00 (----) results in Unlocked
Writing &01 (--W-) results in Locked
Writing &08 (L---) results in Locked
Consequently, if writing the file access byte in DFS you must translate it
before using it, and avoid writing to the 'W' bit:
IF dfs% THEN access%=access% AND 8
This changes all access bytes to just Locked off or Locked on.
==HDFS==
Hierarchial DFS by Andrew Duggan implements the full Locked, Execute, Write
and Read access bits, but implements them according to the flawed
documentation that says ''cannot'' read/etc instead of read/etc access
''present''. Consequently, if reading or writing access bytes on HDFS, they
must be translated:
IF FNhdfs THEN access%=(access% EOR 7)
HDFS and DFS both report themselves as filing system 4, but they use a
different range of file handles. Calling FSCV with A=7 to request the handle
range can be used to distinguish between them:
DEFFNhdfs
A%=7:A%=USR !&21E
=(A% AND &FF00)=&12
Note that this can only be done from the I/O processor.
==Directories==
Conventionally, the only access that directories can have is Locked or not
Locked. If any other bit is written with OSFILE, they are either ignored
entirely, or they are stored, but have no effect.
ADFS returns the 'R' bits set when reading a directory's access byte. RISC
OS ADFS allows all the owner access bits to be set and read with OSFILE
calls.
Some filing systems and programs[The Level 4 File Server hides
directories from non-owners if the 'R' bit is unset] use the 'R' bit to
indicate that the directory can be read - ie, catalogued - and the 'E' bit
to indicate that the directory can be searched.
==Private Access==
HADFS and the SJ MDFS implement a 'P'rivate bit where an object is invisible
to a non-owner. HADFS returns the 'P' bit in bit 7 of the access byte,
whereas the NFS cannot see the MDFS's 'P' bit. On NFS bit 7 is a copy of the
owner's Locked bit.
Unless copying within the same filing system, bit 7 should be ignored with:
access%=access% AND &7F
On RISC OS, the MDFS 'P' bit is returned in the owner's 'E' bit, and the 'P'
bit is always returned set reflecting the fact that a non-owner can never
delete an object.
==Access permission on other systems==
===DOS===
BBC access permissions are translated to DOS access permissions as follows[From investigation with RISC OS 3.11]:
Owner R ignored
Owner W ignored
Owner E ignored
Owner L -> ReadOnly
Public R ignored
Public W ignored
Public E ignored
Public L ignored
0 -> Hidden
0 -> System
0 -> Archive
this can be done with the following code:
dattr%=(attr% AND 8) DIV 8
DOS access permissions are translated to BBC access permissions as follows:
1 -> Owner R
1 -> Owner W
0 -> Owner E
ReadOnly -> Owner L
0 -> Public R
0 -> Public E
0 -> Public W
0 -> Public L
Hidden -> b8 of attributes, overwriting date
System -> b9 of attributes, overwriting date
Archive -> b10 of attributes, overwriting date
this can be done with the following code:
attr%=(dattr% AND 1)*8+3
Win95FS also sets the public access bits, as follows:
1 -> Owner R
1 -> Owner W
0 -> Owner E
ReadOnly -> Owner L
1 -> Public R
1 -> Public W
0 -> Public E
0 -> Public L
Hidden -> b8 of attributes, overwriting date
System -> b9 of attributes, overwriting date
Archive -> b10 of attributes, overwriting date
this can be done with the following code:
attr%=(dattr% AND 1)*8+&33
LanManFS for the BBC translates BBC access permissions to DOS access permissions with the following scheme[Sprow Ethernet Module http://acorn.chriswhy.co.uk/docs/Sprow/masternet.pdf]:
Owner R ignored
Owner W -> NOT ReadOnly
Owner E ignored
Owner L -> Hidden -> System
Public R ignored
Public W ignored
Public E ignored
Public L ignored
0 -> Archive
this can be done with the following code:
dattr%=((attr% AND 8)*0.75) EOR ((attr% AND 2) DIV 2)
LanManFS translates DOS access permissions to BBC access permissions as follows:
1 -> Owner R
NOT ReadOnly -> Owner W
0 -> Owner E
Hidden OR System -> Owner L
NOT ReadOnly -> Public R
0 -> Public E
Hidden OR System -> Public W
0 -> Public L
this can be done with the following code:
attr%=(((dattr% AND 6)<>0) AND 8) EOR (2*(dattr% AND 1)) OR 1
===UNIX===
BBC access permissions are translated to UNIX access permissions as
follows:[TCP Protocol Suite User Guide]
Owner R -> Owner r
Owner W -> Owner w
(Owner R AND filetype=UnixEx) -> Owner x
Owner L ignored
Public R -> Group r -> World r
Public W -> Group w -> World w
(Public R AND filetype=UnixEx) -> Owner x
Public E -> Group x -> World x
Public L ignored
this can be done with the following code:
uattr%=(attr%AND1)*4+(attr%AND2)+(attr%AND16)*2+(attr%AND32)DIV2+(attr%AND16)*16+(attr%AND32)*4
IF ftype%=&FE6:uattr%=uattr%+(attr%AND1)+(attr%AND16)DIV2+(attr%AND16)*4
UNIX access permissions are translated to BBC access permissions as follows:
Owner r -> Owner R
Owner w -> Owner W
Owner x -> Owner E
0 -> Owner L
Group r OR World r -> Public R
Group w OR World w -> Public W
Group x OR World x -> Public E
0 -> Public L
this can be done with the following code:
attr%=(uattr%AND1)*4+(uattr%AND2)+(uattr%AND4)DIV4+(uattr%AND8)*8+(uattr%AND16)*2+(uattr%AND32)DIV2
attr%=attr% OR ((uattr%AND64)+(uattr%AND128)DIV4+(uattr%AND256)DIV16)
==References==
[[User:Jgharston|Jgharston]] 12:37, 29 July 2009 (UTC)