MTB-671 MULTICS TECHNICAL BULLETIN
To: Distribution
From: Michael A. Pandolf
Date: 84.09.21
Subject: A Method to Extend the Multics File System
Abstract
This document describes a method whereby the presentation of the
Multics file system can be altered to include entries not directly
supported by the Supervisor. It starts with the current
implementation of file processing found at the user ring command
level and describes some of the limitations of this method. Next,
an alternate mechanism is presented, starting with its
architecture and ending with a discussion of its implications.
Finally, information is provided for those wishing to take
advantage of this facility. This document also superceeds Multics
Technical Bulletin 615 (named "A Mechanism for Managing Extended
Objects"), which is now to be considered obsolete.
Revision 1 includes changes to the original document brought about |
by its review. Change bars are used to indicate differences |
between the two. |
Send comments on this MTB by one of the following means:
By Multics Mail, on System-M to:
Pandolf.Multics
By Multics forum, on System-M in:
>site>forum>Extended_Objects.forum
By Telephone at:
(HVN) 492-9391 or (617) 492-9391
------------------------------------------------------------------
Multics Project internal working documentation. Not to be
distributed outside the Multics Project.
MULTICS TECHNICAL BULLETIN MTB-671
1 Background
1.1 Low Level Presentation of the File System
Consider, if you will, the Multics hierarchy as it is defined by
the ring zero environment. It is constructed from three
fundamental building blocks: the directory, the segment and the
link. As shall be shown, this may contrast with the perception of
the hierarchy when one is executing in the user rings, rings four
and five. Up to this point in time, additional types of entries
have been individually implemented, due to the lack of a
programming facility to allow tailoring of the file system for
specific applications. As the number of entry types that are
defined in the user ring increases, the software support for file
system entries becomes more difficult, and almost begs for a
solution.
1.2 Inner Ring Entries
Several file system objects that are fabricated outside of ring
zero have existed for some time now. We shall use them as
examples of how extra entry types have been implemented in the
past, and how continuing to follow such a precedent can be a
burden to both the user and the developer of these new components.
Let us firstly consider mailboxes. These components reside within
ring one for a variety of reasons. What is interesting to us is
that ring zero is not very helpful with mailboxes when interacting
with the user ring. The ring one mailbox/message segment software
becomes our way of manipulating these structures. For example, a
call to the supervisor interface hcs_$delentry_file will delete a
segment from the hierarchy for us, whereas a call to
mailbox_$delete is required to delete a mailbox even though it is
a segment to ring zero software. Conceptually, what has happened
in this situation is that one command is used as an interface to
hcs_ to delete segments (delete) and another command is used to
interface to mailbox_ (mbx_delete). Yet another command exists to
delete message segments, appropriately enough named ms_delete.
MTB-671 MULTICS TECHNICAL BULLETIN
Clearly, if other inner ring resident components are to be added
to the user ring complement, one pattern to follow is to generate
another set of commands to interface with some gate into the inner
ring. Perhaps with two inner ring components the need to be aware
of other sets of commands is no great inconvenience, but when
given four (as is currently proposed) it may very quickly become
tiring, and if given five or ten (not unreasonable for some future
time as Multics continues to respond to new requirements) then it
may become downright ugly. The desired goal here is that Multics
be made to worry about the identity of a file system component
being referenced, as opposed to the user being concerned about
such. In fact, this convention has been used to support another
type of file system component, the multisegment file.
1.3 User Ring Entries
Limited by a maximum size of roughly a quarter million words,
segments proved to be too small a storage unit for many
applications. To answer this problem, the multisegment file was
developed. It is referenced as a single component in the
hierarchy, and (for the purposes of this discussion) can grow
arbitrarily large. Ring zero does not recognize this component as
a single object, as it is manufactured out of a directory and
segments from the user ring. Because it is a user ring construct,
the multisegment file suffers from a severe limitation that
mailboxes and message segments don't: it can be manipulated from
the user ring in an arbitrary manner. In this way, the
multisegment file is not a complete implementation of a large
capacity atomic file system component. Nevertheless, it does
behave in another manner which is very desirable from the user's
point of view: it can be manipulated using standard file system
commands. For instance, the delete command is intelligent enough
to ascertain the identity of what it is to delete and handle the
deletion of a multisegment file differently than that for a
segment. This is not without cost, however, as the developer must
maintain a separate execution path in the delete command for
multisegment files.
MULTICS TECHNICAL BULLETIN MTB-671
2 Command Level Integration
2.1 Integrating Current Entry Types
Some file system commands have been modified to allow them to
manipulate mailboxes and message segments. Without a focal point
for managing attributes of entries that require access through a
gate other than hcs_, these changed commands have had to include
the code to determine the identity the entry. Upon the addition
of a new file system entry type, this code would have to be added
to every command that knows about different entry types, resulting
in a significant amount of code duplication.
2.2 Projected Entry Types
Looking one step past the theoretical, there is a current need to
expand the scope of the file system. Several new components are
to be added, and the question becomes, "What path is to be
followed, that of the multisegment file, or that of the mailbox?"
At this point, a brief look at the additions to the file system
ought to be helpful. One new component is the Forum meeting, an
inner ring data base which bears some sort of outward similarity
to mailboxes in that it houses relatively small items as textual
information, and requires general read/write permission for all
users, at least while they are in the inner ring. As such,
standard file system commands will be unable to manipulate these
meetings due to validation level restrictions. Another component
to be added is the Data Management file. This is also inner ring
resident, but is not used for a specific purpose as are Forum
meetings. Its proper classification is that of a "file", implying
that there is no single internal structure that defines its
contents. For its first application, it is being used to replace
the multisegment file in many Multics relational database
applications. As a file, it may be thought of as being grouped
with the (single segment) file, and the multisegment file.
Finally, there is a component used within Data Management called
the before journal used for before-modification storage of images
of Data Management files.
2.3 Integrating New Entries
MTB-671 MULTICS TECHNICAL BULLETIN
One may be tempted to say that the implementation of command level
interfaces to these components has already been decided, that
there are only two avenues to take: that of the mailbox and that
of the multisegment file. If so, then one would expect that there
be a new set of commands for Forum meetings and before journals
and that Data Management files be special cased in the "file"
commands. The philosophy of this discussion says that while there
have been two separate methods of dealing with hierarchy
components in the past, the double standard is tolerable only to a
point: the scope of the inconsistency has been relatively small
because so few components were involved, and the number of
components has not changed for several years. Now the number of
components is on the increase and the inconvenience becomes
greater for the developer as well as for the user. The proposal
presented in this discussion says that all file system terminal
nodes be accessed through the same set of commands.
MULTICS TECHNICAL BULLETIN MTB-671
3 A New Mechanism
3.1 General Description
What is now proposed is a utility that allows the user to access
file system components with little forethought about what sort of
component it is being accessed. Multics commands will no longer
interface directly with several subsystems in order to access
files, but will call upon a centralized procedure that is
responsible for determining the nature of a component and
forwarding the call to an appropriate handler. This File System
Utility, as it is called, serves to standardize references to file
system primitives by accepting all file system related calls
through a well defined interface. The Utility itself can handle
calls for five types of hierarchy components: directories,
segments, links, multisegment files, and Data Management files.
The inclusion of the latter two file types (though neither is
currently a fundamental, ring zero component) is due to a design
consideration of the File System Utility, and will become clear
shortly.
The Utility is normally presented with the pathname of an entry
and some pertinent arguments passed to one of its entrypoints.
Upon receiving the entryname of the object (which is a separate
parameter) it extracts the suffix and uses it to determine entry
type. The suffix is used to construct a virtual entry value that
identifies a support routine by prefixing the string with
"suffix_" and adding a "_$validate" to the end. For example, the
entryname "McDonald.mbx" will generate the virtual entry
"suffix_mbx_$validate." The Utility then calls through the
virtual entry to receive confirmation on the entry type. Notice
that if it receives confirmation, the type is considered to be
"extended, " that is, not supported by the supervisor. There are
two ways in which confirmation will not be given: either if the
search for the suffix support routine produces no match or if the
validation program rejects the entry.
If an entry cannot be validated it is considered to be standard,
and the Utility processes the file system request internally,
eventually calling hcs_. If the entry was accepted, the Utility
does no processing; rather, it calls the corresponding entrypoint
in the support routine. It is in fact the presence of this
external support routine that defines the new type of entry: for
a given user, the hierarchy will take on the appearance of a file
system as defined by all the support routines that have been
referenced in the currently active process. Considering that this
support routine is found using the standard search rules and is
relatively easy to write, the presentation of the hierarchy can be
tailored more closely to the needs of the individual user.
MTB-671 MULTICS TECHNICAL BULLETIN
4 Support for the Mechanism
4.1 Hardcore
There is very little support that the user ring can expect from
the hardcore when creating this extended file system. As stated
at the start of this discussion, a components type is specified
from ring zero by two bits, and three components are defined
through this: the directory, the segment, and the link. At
present, there is no ring zero interface to pass arbitrary
information about a file system component, and there is no place
in the supervisor to store such information, anyway. That is,
unless one considers the name of a file such arbitrary
information. The utility indeed uses entry names as a repository
of "arbitrary" information, the information being the particular
type of component a segment or directory is. This usage is not
without precedent: consider the use of suffixes to indicate the
identity of a language source segment. There is mild typing of
the text segment in this case, although the ultimate test of type
is a successful compile.
4.2 The Suffix Convention
The File System Utility's use of suffixes proceeds from this
point. For a file system component to be considered extended, it
must first have a suffix of its type just as source segments have
a suffix of the name of the compiler against which they are to be
run. Whereas the source segment does not need to be compiled
before it is referenced, the potential extended entry must be
validated by the support routine before it can be considered
"worthy of wearing its suffix" and have a name added or be deleted
or what have you. This requirement that there must be a suffix on
the name of an entry for it to be considered extended implies that
any entry type that does not require a suffix on its object must
be regarded as a standard object. Because multisegment files have
no suffix requirements and because they have been in existence for
so long with special case code in various commands, they have been
designated as being standard. The argument for Data Management
files to be considered standard is somewhat different: although
they are not now completely implemented, they are planned to be an
entry known in the supervisor and thus will be similar to
directories and segments to that extent. They also have no suffix
requirements.
MULTICS TECHNICAL BULLETIN MTB-671
5 Software Architecture
5.1 Direct Utility Support
The Utility is embodied in a single program known by the name of
fs_util_. It contains all the logic necessary to determine
whether or not a component is potentially extended, to find and
forward references to a suffix support routine, and to handle the
processing of standard objects itself. There are twenty-six
entrypoints available: ten for ACL and ring bracket manipualtion,
five for typing a component, four for switch manipulation, four
for length manipulation and three for miscellaneous functions.
For the most part, these entrypoints are to replace calls to hcs_
by user ring programs.
5.2 Subsystem Support
When fs_util_ determines that it is dealing with a potential
extended component, it makes as few assumptions as possible:
control is passed directly to the suffix support routine for
validation of its type and, if successful, to complete the
requested operation. In a way, the support program can be
considered a caretaker of the file. It is expected that the
developer of the subsystem that uses the file wrote the support
program. Design of the suffix program is fairly straightforward:
nineteen of its twenty-two entrypoints are mapped directly from
fs_util_, and the operation of its "validate" entrypoint is well
defined.
5.3 Degree of Support
The extent to which fs_util_ is used can be as little as in the
ACL commands alone, or as great as in all commands that reference
an object in the hierarchy. Implications of the latter are far
reaching, for such an implementation would require a whole new way
of conceptualizing the hierarchy. For the time being, fs_util_
will be called by a small set of commands; it is hoped that this
may expand in the future so that a more consistent view of the
file system is presented to its users.
MTB-671 MULTICS TECHNICAL BULLETIN
6 Implementation
6.1 Areas Affected
The implementation that follows describes a three phase conversion
of the Multics command level to bring it under the influence of
the Utility and extended entry typing. Each phase is designed to
require the installation of the previous phase, and implementation
can stop after any of the phases. Implementing all three phases
will probably produce a very different command level behavior
towards the hierarchy.
A list of the commands that will be obviously affected by
implementation of one or more phases follows:
add_name dump_segment print
adjust_bit_count edm qedx
canonicalize emacs rename
change_default_wdir enter_output_request save_dir_info
change_wdir exists segments
compare_ascii hunt set_acl
contents hunt_dec set_bit_count
convert_characters list set_max_length
copy list_accessible set_ring_brackets
copy_acl list_acl status
copy_dir list_not_accessible switch_off
copy_names merge_ascii switch_on
delete move teco
delete_acl move_dir unlink
delete_dir move_names walk_subtree
do_subtree nonzero_segments zero_segments
dprint overlay
6.2 Phase One
Phase one of command level conversion will effect several
commands. The changes necessary to allow these programs to use
the Utility will not require a user visible change to the command
interfaces.
MULTICS TECHNICAL BULLETIN MTB-671
Two fundamental operations are the first to be considered for
conversion: file creation and deletion. Within the context of
Multics, these two operations are not especially symmetric. As a
general rule of thumb, a file is not created through an explicit
request of the user. Text files are implicitly created by text
editors, mailboxes by the mail facility on an as needed basis
(although the user is queried to whether a new mailbox ought to be
created), multisegment files by vfile_ when appropriate. Some
file system components are explicitly created: directories and
links are the prime examples. On the other hand, deletion of a
file is nearly always explicitly requested. In addition, creation
usually concerns itself with the incarnation of one component at a
time; deletion can cause a mass extinction (note the use of the
star convention for the delete command). For these reasons, the
File System Utility will not concern itself with creating objects,
but will have an interface for deleting objects.
There will be a noticeable difference in the behavior of the
delete command: up to now, the delete command would fail when
trying to delete inner ring objects such as was once done with
mailboxes. In one sense this was pleasant behavior: use of the
star convention when deleting would not accidentally include
mailboxes in the action of the delete command. However, this
luxury no longer exists: any inner ring component whose name
matches a starname is destined for hierarchy heaven. It may be
appropriate for the delete command to protest a little when it is
going to perform any starname processing. At the same time that
the delete command is converted to use the Utility, the delete_dir
command should also be converted so that it might not delete an
extended entry that has a directory as its underlying structure.
As a matter of consistancy, unlink ought to be made aware of
extended typing, so that when it reports that the object of its
invocation was not a link, it can use the extended type of the
object in its message.
Considering rename next, its main concern with file system
extensions is that the naming convention be preserved, that the
suffix is not left off any new name added to a directory entry.
In this way, any new or additional name for a file system
component will include the suffix of the original name. The
copy_names, move_names, and add_name commands operate in an
analogous manner when adding names to the target file.
Copying and moving files are considered together. As with rename,
suffix preservation is necessary. In addition, because the thing
to be copied may reside in an inner ring, it will have to be
copied by a call to the inner ring subystem. Past these two
items, copying and moving are the same as they always have been.
Effected are copy, copy_dir, move, and move_dir.
MTB-671 MULTICS TECHNICAL BULLETIN
Bit count manipulation (adjust_bit_count, set_bit_count) and
length manipulation (set_max_length) are also performed by calls
to fs_util_, and there is no difference in user interface. The
suffix support routine may decide that the bit count attribute is
not meaningful for the object being referenced, but this will
merely result in an error message being printed.
Switch manipulation is also handled the way it has always been
from the command level, with the call forwarded to fs_util_. The
utility will determine which switches are appropriate to set.
This effects switch_on and switch_off. Additionally, the older
interfaces (safety_switch_on, copy_switch_on, etc.) ought to be
updated.
Finally, the status command can be made to use fs_util_ without
requiring a new user interface. Status will query fs_util_
several times to obtain information about what to report for a
file, but will keep its report format unchanged.
6.3 Phase Two
In the second phase of converting the command level to use the
Utility, user interface changes are required, but the presentation
of the file system as compared to its traditional form is little
changed. For the most part, these changes will involve access
control commands.
The ACL commands provide a good example of the need and
implications of maintaining an arbitrary set of hierarchy objects.
Two of them, list_acl and set_acl, will serve as a basis for this
example. These commands are to be modified to be able to
manipulate access for a variety of hierarchy components,
regardless of the type of access supported or of the ring in which
the component resides. Of the two, it is set_acl that will be
influenced more and thus will be considered last. As opposed to
set_acl, list_acl does not require a mode string when referencing
the ACL of an entry, which is why changing it is straightforward:
for the most part, the user interface is unchanged. We add the |
"-select_entry_type" argument which will have a specific meaning |
when used in relation to file system extensions. It is used to |
select only those entries of a specified type, being particularly
useful to filter out unwanted entries selected by the star
convention (e.g. "**").
MULTICS TECHNICAL BULLETIN MTB-671
When setting ACL, a problem arises: the same mode specification
may have different meaning for different entries. Consider the
command line "set_acl ** sa". Traditionally, the mode string "sa"
would be mapped to directories; however, it is also a valid,
although not very useful, mode string for mailboxes and message
segments. We must prevent set_acl from applying this string to
the latter two entries. For this reason, set_acl must process
| star names carefully. The restriction it follows is that access
| is set on entries whose type is extended only when the suffix or
| the -select_entry_type control argument is explicitly used to
| specify the given extended type, and that access is set on entries
| whose type is standard whenever the starname matches and
| -select_entry_type has not been used. These actions will be
quiet; that is, if an extended type file matches the supplied
starname (such as "**"), then we will not report that we excluded
the file from the set_acl operation.
The two remaining ACL commands, copy_acl and delete_acl, are
similar to list_acl in that they do not require a mode string as
| part of their command line. The only change in their command
| level interface is the addition of "-select_entry_type" as a
| control argument. Analogously, list_accessible and
list_not_accessible will use the Utility to compute accessibility,
but will otherwise remain unchanged.
One may wonder why IACL commands are not listed in section 6.1.
The primary reason for this is that in their current
implementation, they do not easily lend themselves to outer ring
manipulation as ACLs do. In ring zero, IACLs are associated with
branch creation. As previously mentioned, the supervisor
recognizes links, directories, and segments as the only storage
system entries, and provides an interface to manage IACLs for the
branches. Without a mechanism that allows the supervisor to
recognize more than three types, IACLs will be a feature absent
from the Utility. Until such a time, the supervisor will continue
to honor IACL setting when creating a branch. It is up to the
suffix support routine to determine how apporpriate the ACL
setting on a newly created entry is.
A minor change is made to the command level interface of the
set_ring_brackets command. The subsystem that manages an extended
entry may find it necessary to reference only one or two ring
numbers for the entry. At the command level, the correct number
of ring numbers must be supplied. If not, the command complains
and returns.
MTB-671 MULTICS TECHNICAL BULLETIN
Considering the change in ACL modes effected by the Utility, a |
command level interface ought to be supplied so that the user can |
determine exactly with what sort of beast he or she is dealing. |
Two commands are to be added to Multics to do just this. The one |
named list_entry_types peruses the caller's search rules looking |
for suffix support routines. For each valid one found, it prints |
the name of the entry type and the suffix used by an entry of that |
type. The other, describe_entry_type, returns information about |
the characteristics of an extended entry type. It is by using |
this command that a user would find out the modes that are valid |
for a given type. |
It has proven to be a labor of agony in the choosing of a set of |
consistent short names for these two new commands. Although there |
is an historical tendency to form short names from the leading |
letter of each word in the command name, a more recent agreement |
specifies that the first letter and next consonant be used to form |
the first two letters of the short name, followed by the first |
letter of each additional name. It is also strongly desired that |
the two commands form their name in the same manner. In a |
definitive stroke of arbitrariness, the following names are |
defined for describe_entry_type and list_entry_type: "dset" and |
"lset" respectively. |
One last command to be included in phase two implementation of the
extended file system is the list command. While changing list
will present a different picture of the file system to the user,
it is very convenient to have available, since it does all the
work of deciding which entries are really of an extended type and
which have some arbitrary suffix. The list command currently
types directories with a non zero bit count as multisegment files,
but this is the extent of its special casing. When changed, there
will be no special cases; rather, all entries will be typed and
grouped according to type. The report for each group will be
tailored for the attributes of the group. As with the ACL |
commands, we will add "-select_entry_type" as a control argument |
so that we can select particular entries for display. By default, |
list will print only those entries that are typed as "files" - |
(single) segment (file), multisegment file, and Data Management |
file types. |
6.4 Phase Three
MULTICS TECHNICAL BULLETIN MTB-671
In the third phase of implementation, Multics commands will call
upon the Utility to determine the validity of using a particular
type of entry for their operations. One such check is made when
preparing to send a file to the high speed printer: object
segments are excluded. Although there are no plans for the
Utility to support an entry type known as "Program", there may be
entry types which are not suitable for direct printing (mailboxes
are an obvious, though not entirely appropriate, example). Yet
another check might be made to prevent change_wdir from placing a
user into the middle fo a multi segment file. As a last example,
editors may use information from the Utility to decide upon the
suitability of an entry for editing.
The list of commands that lend themselves to the above convention
is grouped according to what the command is looking for. Those
commands that may want to use only entries that contain ASCII data
are: canonicalize, compare_ascii, contents, convert_characters,
dprint, edm, emacs, enter_output_request, merge_ascii, overlay,
print, qedx, and teco. Those commands that expect to reference an
entry that is known as a directory to the Utility are:
change_default_wdir, change_wdir, do_subtree, hunt, hunt_dec,
save_dir_info, and walk_subtree. Finally, those commands that
expec to reference an entry that is known as a segment to the
Utility are: segments, nonzero_segments, and zero_segments.
| A change is to be made to the "exists" command to allow it to
| selectively determine the existence of an entry based upon its
| type. Here, the control argument "-select_entry_type" is accepted
| by the "entry" keyword, filtering out those entry types not
| desired. It is expected that its most common use is in the
| determination of the existence of some entries of an extended type
| in a given directory.
What may be the major part of phase three implementation is
embodied in providing a method of dumping file system objects.
Currently, there is a great difficulty in obtaining a consistent
dump of a MRDS data base. With the implementation of Data
Management files the pieces exist to build a mechanism to obtain a
consistent saved image of a relation. It is desired that this
dumping be as automatic (i.e., system directed) as possible. If
the first thought is to "make the dumper know about Data
Management files" then we have not divorced ourselves enough from
the idea of special case code. Here is an area that can use a
File System Utility interface. If an entry exists that has a
special dumping requirement, be it that the object needs to be
synchronized in some way, or that the dump format needs to be
different than the file system format, this requirement should be
embodied in a suffix support routine. It is intended that this
facility be available to the system at the level of the user
visible hierarchy, which means that the hierarchy dump tools need
be changed.
MTB-671 MULTICS TECHNICAL BULLETIN
7 Other Issues
7.1 Control Arguments
The Utility provides new ways of referencing entries in a |
directory. In order to specify these new options, control |
arguments are added to the command environment. A couple of these |
were informally introduced in previous sections of this report; |
now, they are formally defined. |
The need to manipulate an extended entry as if it were of a |
standard type is an important facility to system developers, if |
not simply a convenience to standard users, and may be more |
important as the masking of standard types becomes increasingly |
comprehensive. It ought to be possible to tell a command that |
extended typing for an entry ought to be bypassed. To this end |
two control arguments are proposed: |
"-interpret_as_standard_entry" ("-inase") and |
"-interpret_as_extended_entry" ("-inaee"), with the latter usually |
being the default. The first control argument instructs a command |
that as it manipulates attribute information of an entry, it is to |
treat the entry as if it were one of the five standard entry |
types. This essentially instructs the program to behave as it did |
before extended entry typing was implemented. |
Up to this time, file system commands that allow the user to |
select one or more entry types for manipulation use a standard set |
of control arguments to differentiate between the entry types. |
There are currently four control arguments in the set: |
"-segment", "-directory", "-multisegment_file", and "-link" (Data |
Management files are new and of this writing don't have a control |
argument assigned them). With the Utility supporting an arbitrary |
number of different entry types it is not practical to create a |
specific control argument for each entry type. A more general |
mechanism for selecting entries by type is employed by commands |
using the Utility: to select a particular type of entry (or |
entries), one uses "-select_entry_type" ("-slet") followed by a |
string of suffixes delimited by commas. In the case where a |
standard type is desired (since there is no reserved suffix), the |
name of the type is printed out; in fact, the name is formed from |
the now obsolete standard control argument without the hyphen. |
For the standard types a short name is permitted, also formed by |
dropping the hyphen from the short control argument. |
MULTICS TECHNICAL BULLETIN MTB-671
| One last control argument change is for the control argument
| currently used to obtain the type an entry is. The "status"
| command interprets "-type" to mean that it return the entry type
| of its object. When extended entries are implemented, the "-type"
| control argument will be removed from documentation (although
| still recognized by commands) and replaced by "-entry_type"
| ("-ettp").
7.2 The Star Convention
Starname processing will acquire an added twist with the addition
of extended types to the file system. The first issue was
addressed in the discussion of ACLs. Here, it was noticed that a
given mode string had an ambiguous meaning when being applied to
all the entries that matched a given star name. It was decided
that the mode string would be applied to an entry when a suffix
was explicitly provided or when an entry type was explicitly
specified. Another issue surfaces with the naming operations.
When performing wholesale naming operations, names constructed
from the equals convention may break the suffix rules and be
rejected by the suffix support routine. Although this will not
caause as much trouble as setting a meaningless mode on a file
system object, it will give rise to a lot of complaining from the
file system. If the print command ever validates its files for
suitability of printing, it may complain that many of the entries
that matched its given starnames are not printable.
The rule for starname selection (of which, no doubt, there will be
exceptions) is as follows:
| OBTAIN_STARNAME_LIST
| if -select_entry_type_ARG_GIVEN
| then PRUNE_ALL_UNSPECIFIED_ENTRY_TYPES
| else if NO_SUFFIX_SELECTS_EXTENDED_TYPE or
| -interpret_as_standard_entry_ARG_GIVEN
| then PRUNE_EXTENDED_TYPES.
For a suffix to select an extended type, it must have no special
| starname characters in it (asterisks or question marks). This
| algorithm will differentiate between entries that have a suffix of
| an extended type but are not themselves of that type (e.g., a
| directory named "mine.mbx") when the "-select_entry_type" control
| argument is supplied, but will select all entries having a given
| suffix when the suffix is at the end of a starname. An exception
to this rule that immediately comes to mind is in the command line
"delete **" where everything is to evaporate, regardless of type.
Such exceptions ought to be as rare as possible.
MTB-671 MULTICS TECHNICAL BULLETIN
7.3 Switch Name Processing |
The File System Utility allows a subsystem to define any number of |
switches for an extended entry. There is not yet a set of rules |
governing the naming convention of switches, something which to |
this point has not created much confusion because there are not |
all that many switches defined by the standard entry types. |
Within the context of the Utility, a set of rules shall be created |
to prevent switch naming from getting out of hand. |
Each switch supported by an entry type shall be identified by its |
"primary name", which shall describe that attribute the switch |
enables. The primary name shall also be considered the switch's |
"long name". In addition to its primary name, a switch must have |
one or more "secondary" or "short" names. The short names should |
be formed using the same rules that command or control argument |
short names use. The string "switch" should not appear in the |
name of the switch if its only purpose it to identify the |
attribute as a switch (e.g., the long name of the safety switch is |
"safety" and its short name is "sf"). For those instances when a |
secondary name is to be the same as the primary name, the |
secondary name must be separately listed, even though it is the |
same as the primary name. There is no implicit or default |
secondary name for the primary name of a switch. |
When a command wants to use the switch name string, it has the |
responsibility of appending an "_switch" at the end of the long |
name. In the cases where it is desired that there are more than |
one long-type names, the following convention shall be used: if a |
command encounters a secondary name containing an underscore, it |
shall append "_switch" to the end of the name; otherwise, it shall |
append "s". Essentially, the primary name rule as stated above |
provides a mechanism whereby a (rather short) switch name that |
contains no underscores can be referenced as "XXX_switch". |
Current command level convention handles switches with short |
primary names differently than switches with long names: the |
copy, damaged, and safety switches form their short names by |
appending "sw" to the first letter of the switch name, giving |
"csw", "dsw", and "ssw", respectively. Although these names will |
have to be recognized so as to prevent existing exec_coms from |
breaking, the correct switch name abbreviations will be "cps", |
"dms", and "sfs". |
7.4 ACL Mode Processing |
MULTICS TECHNICAL BULLETIN MTB-671
| In the course of providing a simpler ACL interface for the user,
| we have moved the complications of the process to the suffix
| support routine. This routine must deal with directory ACLs,
| segment ACLs, extended segment ACLs, extended directory ACLs, and
| a couple other related structures. To consider a simple example,
| when a user wishes to set ACL on the mythical chessgame entry type
| as defined in the programming example at the end of this report,
| set_acl creates a general ACL structure and passes this in to
| fs_util_. The chessgame stores its "regular" ACL as the extended
| ACL of its base segment, and must therefore convert the general
| ACL structure to an extended ACL structure. Most ACL interfaces
| to fs_util_ involve a similar conversion. The set of all such
| conversions is not exceedingly large and may be able to receive
| support from fs_util_ itself. In this way, these conversions
| which are common to all suffix support routines won't be found
| duplicated many times over.
| Due to time limitations, a generalized ACL conversion mechanism as
| suggested above will not be in the first release of the Utility;
| however, it is hoped that the support will be soon in coming so
| that as few suffix support routines as possible will be required
| to write ACL internal conversion subroutines.
7.5 Performance
Adding these extensions to the file system requires the layer of
fs_util_ accessing to be executed, and this represents some degree
of overhead. There are two paths within fs_util_ that are easily
identifiable as needing some sort of optimization in the future.
First, there is the search for a suffix support routine. This
uses the dynamic searching mechanism, so that past the first
search for a support routine the search will be short. Our
concern is when we search for the suffix support routine of an
entry carrying an unmatched suffix. The potential for
inefficiency may be greatest here due to the following behavior.
Given a suffix that is not explicitly supported, the Utility will
search for it via the search rules. If not found, the Utility
will simply go on its way, figuring that the entry is standard.
Upon encountering the suffix at any subsequent time (on the same
or a different entry) the Utility will (again) search for a suffix
support routine and again not find it. Searching for something
and not finding it is expensive; it should be tolerated only once
| per process. To bypass this problem, the Utility implicitly
| relies on a property of the dynamic search facility to create a
MTB-671 MULTICS TECHNICAL BULLETIN
list of unmatched suffixes: upon failing to find a support |
routine, the Utility will add the entryname portion of the |
fabricated virtual entry as a reference name to a procedure named |
"undefined_suffix_." This routine has only one entrypoint, |
"validate," which always returns the status code |
"error_table_$not_seg_type." Future encounters with an entry |
ending in the unsupported suffix will be given to |
undefined_suffix_ and the entry will be declared standard. |
The second identifiable overhead is in the validation of a typed
entry. The existence of a suffix is not enough to consider a
segment typed: it must be accepted by the support routine. After
a suffix support routine is found, its validate entrypoint is
invoked to accept or reject the entry. The overhead here is
dependent upon the validation routine. For illustration, consider
this rather absurd scenario: there is to be a typed entry called
"pl1 source" with its required support routine, suffix_pl1_.
Whenever someone wishes to reference a pl1 source segment (even
when simply listing it) suffix_pl1_$validate is invoked and, to
properly validate the file as being pl1 source, compiles it with
the "-check" argument. Listing the contents of a directory when
it contains even ten pl1 source files may take a very long time.
Experiments with access commands have generated virtual cpu times
two to four times longer when using fs_util_ than when interfacing
directly with hcs_. The use of an experimental list command
provides a greater variation: depending on the options requested
of list, execution can be as brief as the (very well optimized)
standard list command or as much as ten times longer. The only
conclusion that can be drawn from the second experiment is that
use of fs_util_ can add considerable processing time to a command
under some circumstances. Overall system degradation has been
measured on a test system using a standard performance benchmark
script. The results of this test have shown almost no difference
in response times. While it is agreed by nearly all that
individual uses of the Utility will produce longer response times
in those programs that use it, it seems that when used as part of
a larger scenario, the delays become acceptable.
MULTICS TECHNICAL BULLETIN MTB-671
8 Subroutine Interface
Name: fs_util_
The fs_util_ subroutine provides for uniform handling of file
system entries. The operations it performs are validate, copy,
delete, chname, get_switch, set_switch, get_max_length,
set_max_length, set_bit_count, and ACL manipulation. The
subroutine first checks to see if the entry name provided is that
of an extended entry and if it is, calls the corresponding
entrypoint of the appropriate suffix_XXX_ subroutine. If the name
is not that of an extended entry, then fs_util_ calls the
appropriate standard entry entrypoint handler for the entry.
Entry: fs_util_$chname_file
This entry changes the name of an entry.
USAGE
declare fs_util_$chname_file entry (char(*), char(*),
char(*), char(*), fixed bin (35));
call fs_util_$chname_file (dir_name, entryname, old_name,
new_name, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
old_name
is the entryname that is to be changed. (Input)
new_name
is the new name to be given to the entry. (Input)
code
is a standard system status code. (Output)
MTB-671 MULTICS TECHNICAL BULLETIN
Entry: fs_util_$delentry_file
This entry deletes the name of an entry.
USAGE
declare fs_util_$delentry_file entry (char(*), char(*), fixed
bin (35));
call fs_util_$delentry_file (dir_name, entryname, code)
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
code
is a standard system status code. (Output)
MULTICS TECHNICAL BULLETIN MTB-671
Entry: fs_util_$copy
This entrypoint is used to copy an entry.
USAGE
declare fs_util_$copy entry (ptr, fixed bin (35));
call fs_util_$copy (copy_options_ptr, code);
ARGUMENTS
copy_options_ptr
is a pointer to the copy_options structure. (Input)
code
is a standard system status code. (Output)
NOTES
The copy_options structure and the named constant
COPY_OPTIONS_VERSION_1 are defined in the include file
copy_options.incl.pl1.
The copy_options structure is defined as follows:
1 copy_options aligned based (copy_options_ptr),
2 version char (8),
2 caller_name char (32) unal,
2 source_dir char (168) unal,
2 source_name char (32) unal,
2 target_dir char (168) unal,
2 target_name char (32) unal,
2 flags,
3 no_name_dup bit (1) unaligned,
3 raw bit (1) unaligned,
3 force bit (1) unaligned,
3 delete bit (1) unaligned,
3 target_err_switch bit (1) unaligned,
3 mbz bit (31) unaligned,
2 copy_items like copy_flags;
STRUCTURE ELEMENTS
version
is the current version of this structure and has the
value of the named constant COPY_OPTIONS_VERSION_1.
caller_name
MTB-671 MULTICS TECHNICAL BULLETIN
is the name of the program calling fs_util_, required
when querying the user about duplicate names. See
no_name_dup below.
source_dir
is the absolute pathname of the directory containing the
entry to be copied.
source_name
is the name of the entry to be copied.
target_dir
is the absolute pathname of the directory into which a
copy of the entry is to be placed.
target_name
is the name of the entry created to hold the copy of the
original entry.
no_name_dup
is set to "0"b if the user is to be queried in case of a
duplication of the target_name and "1"b if there is to
be no query, in which case an error code will be
returned.
raw
is set to "0"b if fs_util_ is to honor the extended type
of the entry, and "1"b if it is to bypass this by
calling hcs_.
force
is set to "1"b if access to the target is to be forced.
delete
is set to "1"b if the original is to be deleted after it
is copied.
target_err_switch
is set if an error occurred referencing the target.
mbz
is reserved for future use and must be set to zero.
MULTICS TECHNICAL BULLETIN MTB-671
copy_items
is structured like the copy_flags structure, which is
defined in the include file copy_flags.incl.pl1. The
structure is defined as follows:
1 copy_flags aligned based,
2 names bit (1) unaligned,
2 acl bit (1) unaligned,
2 ring_brackets bit (1) unaligned,
2 max_length bit (1) unaligned,
2 copy_switch bit (1) unaligned,
2 safety_switch bit (1) unaligned,
2 dumper_switches bit (1) unaligned,
2 entry_bound bit (1) unaligned,
2 extend bit (1) unaligned,
2 update bit (1) unaligned,
2 mbz bit (26) unaligned;
When variables in the copy_flags structure have a value
of "1"b, the designated attribute are copied to the new
entry. In the case of extend, the contents of the
original entry may be appended to the end of the target
entry. In the case of update, the contents of the
original entry may replace the contents of the target
entry.
| Before the copy is performed, the copy_items members are
| ANDed with copy_flags members as defined by the
| suffix_info entrypoint. Only those options specified by
| both structures are considered.
MTB-671 MULTICS TECHNICAL BULLETIN
Entry: fs_util_$get_max_length
This entry returns the maximum length setting for an
entry.
USAGE
declare fs_util_$get_max_length entry (char(*), char(*), |
fixed bin (35), fixed bin (35)); |
call fs_util_$get_max_length (dir_name, entryname,
max_length, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
max_length
is the maximum length of the entry in machine words. |
(Output) |
code
is a standard system status code. (Output)
MULTICS TECHNICAL BULLETIN MTB-671
Entry: fs_util_$set_max_length
This entry sets the maximum length that a particular
entry can be.
USAGE
declare fs_util_$set_max_length entry (dir_name, entryname,
max_length, code);
| call fs_util_$set_max_length (char(*), char(*), fixed
| bin(35), fixed bin(35));
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
max_length
| is the maximum length in machine words to which the
| entry is to be set. (Input)
code
is a standard system status code. (Output)
MTB-671 MULTICS TECHNICAL BULLETIN
Entry: fs_util_$get_bit_count
This entry returns the number of useful bits in an
entry.
USAGE
declare fs_util_$get_bit_count entry (char(*), char(*), fixed |
bin(41), fixed bin (35)); |
call fs_util_$get_bit_count (dir_name, entryname, bit_count,
code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
bit_count
is the number of bits considered useful in the entry.
(Output)
code
is a standard system status code. (Output)
MULTICS TECHNICAL BULLETIN MTB-671
Entry: fs_util_$set_bit_count
This entry sets the number of bits considered useful for
the entry.
USAGE
| declare fs_util_$set_bit_count entry (char (*), char (*),
| fixed bin (41), fixed bin (35);
call fs_util_$set_bit_count (dir_name, entryname, bit_count,
code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
bit_count
is the number of bits to be considered useful in the
entry. (Input)
code
is a standard system status code. (Output)
MTB-671 MULTICS TECHNICAL BULLETIN
Entry: fs_util_$get_user_access_modes
USAGE
declare fs_util_$get_user_access_modes entry (char(*),
char(*), char(*), fixed bin, bit(36) aligned, bit(36)
aligned, fixed bin(35));
call fs_util_$get_user_access_modes (dir_name, entryname,
user_name, ring, modes, exmodes, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
user_name
is the name of the user in the form
User_id.Project_id.instance_tag. (Input)
ring
is the ring number in which the program is running.
(Input)
modes
are the standard ACL modes of an entry. (Output)
xmodes
are the extended ACL modes of an entry. (Output)
code
is a standard system status code. (Output)
MULTICS TECHNICAL BULLETIN MTB-671
Entry: fs_util_$get_ring_brackets
This entry returns the ring brackets of an entry.
USAGE
declare fs_util_$get_ring_brackets entry (char(*), char(*),
(*)fixed bin(3), fixed bin(35));
call fs_util_$get_ring_brackets (dir_name, entryname,
ring_brackets, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
ring_brackets
are the upper and lower bounds of the ring structure
from which an entry is accessible. (Output)
code
is a standard system status code. (Output)
MTB-671 MULTICS TECHNICAL BULLETIN
Entry: fs_util_$set_ring_brackets
This entry sets the ring brackets for an entry.
USAGE
declare fs_util_$set_ring_brackets entry (char(*), char(*),
(*)fixed bin(3), fixed bin(35));
call fs_util_$set_ring_brackets (dir_name, entryname,
ring_brackets, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
ring_brackets
are the upper and lower bounds of the ring structure
from which an entry is accessible. (Input)
code
is a standard system status code. (Output)
MULTICS TECHNICAL BULLETIN MTB-671
Entry: fs_util_$get_switch
This entry returns the value of a storage system switch
for an entry.
USAGE
declare fs_util_$get_switch entry (char(*), char(*), char(*),
bit(1) aligned, fixed bin(35));
call fs_util_$get_switch (dir_name, entryname, switch_name,
value, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
switch_name
is the name of the switch whose value is sought. This
may be either "copy," "complete_volume_dump," "damaged,"
"incremental_volume_dump," "safety," "synchronized," or
any switch on an entry. (Input)
value
is the value of the requested switch. (Output)
code
is a standard system status code. It should be set to
error_table_$argerr if switch_name is invalid. (Output)
MTB-671 MULTICS TECHNICAL BULLETIN
Entry: fs_util_$set_switch
This entry sets the value of a storage system switch for
an entry.
USAGE
declare fs_util_$set_switch entry (char(*), char(*), char(*),
bit(1) aligned, fixed bin(35));
call fs_util_$set_switch (dir_name, entryname, switch_name,
value, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
switch_name
is the name of the switch whose value is to be set.
This may be either "copy," "complete_volume_dump,"
"damaged," "incremental_volume_dump," "safety,"
"synchronized," or any switch on an entry. (Input)
value
is the value to which the switch is to be set. (Input)
code
is a standard system status code. It should be set to
error_table_$argerr if switch_name is invalid. (Output)
MULTICS TECHNICAL BULLETIN MTB-671
Entry: fs_util_$add_acl_entries
| This entrypoint is used to add to the Access Control
| List of an entry.
USAGE
declare fs_util_$add_acl_entries entry (char(*), char(*),
ptr, fixed bin(35));
call fs_util_$add_acl_entries (dir_name, entryname, acl_ptr,
code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
acl_ptr
is a pointer to the general_acl structure. (Input)
code
is a standard system status code. (Output)
NOTES
The general_acl structure and the named constant
GENERAL_ACL_VERSION_1 are defined in the include file
acl_structures.incl.pl1.
The general_acl structure is defined as follows:
1 general_acl aligned based (acl_ptr),
2 version char (8) aligned,
2 count fixed bin,
2 entries (acl_count refer (general_acl.count))
aligned like general_acl_entry;
1 general_acl_entry based,
2 access_name character (32) unaligned,
2 mode bit (36) aligned,
2 status_code fixed bin (35);
STRUCTURE ELEMENTS
MTB-671 MULTICS TECHNICAL BULLETIN
version
is the current version of this structure and has the
value of the named constant GENERAL_ACL_VERSION_1.
count
is the size of the entries array in general_acl.
access_name
is the name of a user in the form of
Person_id.Project_id.instance_tag.
mode
is a bit string where each bit represents a possible
access mode which, when true, indicates an allowed
access for the file.
status_code
is a standard system status code indicating success or
the reason for failure to set the ACL entry.
MULTICS TECHNICAL BULLETIN MTB-671
Entry: fs_util_$add_extended_acl_entries
| This entrypoint is used to add to the Extended Access
| Control List of a standard entry.
USAGE
declare fs_util_$add_extended_acl_entries entry (char(*),
char(*), ptr, fixed bin(35));
call fs_util_$add_extended_acl_entries (dir_name, entryname,
acl_ptr, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
acl_ptr
is a pointer to the structure general_extended_acl.
(Input)
code
is a standard system status code. (Output)
NOTES
| This interface is intended to be used only by extended
| entry type support routines which map an ACL mode
| provided to fs_util_ into a standard mode/extended mode
| pair to be placed on the underlying standard entry or
| entries which are being used to implement the extended
| entry type.
The general_extended_acl structure and the named
constant GENERAL_EXTENDED_ACL_VERSION_1 are defined in
the include file acl_structures.incl.pl1.
The general_extended_acl structure is defined as
follows:
MTB-671 MULTICS TECHNICAL BULLETIN
1 general_extended_acl aligned based (acl_ptr),
2 version char (8) aligned,
2 count fixed bin,
2 entries (acl_count refer
(general_extended_acl.count))
aligned like general_extended_acl_entry;
1 general_extended_acl_entry aligned based,
2 access_name character (32) unaligned,
2 mode bit (36) aligned,
2 extended_mode bit (36) aligned,
2 status_code fixed bin (35);
STRUCTURE ELEMENTS
version
is the current version of this structure and has the
value of the named constant
GENERAL_EXTENDED_ACL_VERSION_1.
count
is the size of the entries array in
general_extended_acl.
access_name
is the name of a user in the form of
Person_id.Project_id.instance_tag.
mode
is a bit string where each bit represents a possible
access mode which, when true, indicates an allowed
access for the file.
extended_mode
is a bit string where each bit represents a possible
extended access mode which, when true, indicates an
allowed access for the file.
status
is a standard system status code indicating success or
the reason for failure to set the extended ACL entry.
MULTICS TECHNICAL BULLETIN MTB-671
Entry: fs_util_$delete_acl_entries
| This entrypoint deletes a member of an entry's Access
| Control List.
USAGE
declare fs_util_$delete_acl_entries entry (char(*), char(*),
ptr, fixed bin(35));
call fs_util_$delete_acl_entries (dir_name, entryname,
acl_ptr, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
acl_ptr
is a pointer to the structure general_delete_acl.
(Input)
code
is a standard system status code. (Output)
NOTES
The general_delete_acl structure and the named constant
GENERAL_DELETE_ACL_VERSION_1 are defined in the include
file acl_structures.incl.pl1.
The general_delete_acl structure is defined as follows:
1 general_delete_acl aligned based (acl_ptr),
2 version char (8) aligned,
2 count fixed bin,
2 entries (acl_count refer
(general_delete_acl.count))
aligned like delete_acl_entry;
declare 1 general_delete_acl_entry aligned based,
2 access_name character (32) unaligned,
2 status_code fixed bin (35);
MTB-671 MULTICS TECHNICAL BULLETIN
STRUCTURE ELEMENTS
version
is the current version of this structure and has the
value of the named constant
GENERAL_DELETE_ACL_VERSION_1.
count
is the size of the entries array in general_delete_acl.
access_name
is the name of a user in the form of
Person_id.Project_id.instance_tag
status_code
is a standard system status code indicating success or
the reason for failure to set the extended ACL entry.
MULTICS TECHNICAL BULLETIN MTB-671
Entry: fs_util_$list_acl
| This entry lists the components of an entry's Access
| Control List.
USAGE
declare fs_util_$list_acl entry (char(*), char(*), char(*),
ptr, ptr, fixed bin(35));
call fs_util_$list_acl (dir_name, entryname, version,
area_ptr, acl_ptr, fixed bin(35));
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
version
is the version of the acl structure. (Input)
area_ptr
| is a pointer to an area where fs_util_ can allocate the
| general_acl structure. If area_ptr is null, then the
| user wants access modes for certain ACL entries; these
| will be specified by the structure pointed to by
| acl_ptr. (Input)
acl_ptr
| is a pointer to the general_acl structure. (Input or
| Output)
| Input: if area_ptr is null, then acl_ptr points to a
| general_acl structure filled with access names and into
| which modes will be placed.
| Output: if area_ptr is non null, then acl_ptr will
| point to the start of a newly allocated general_acl
| structure.
code
is a standard system status code. (Output)
NOTES
MTB-671 MULTICS TECHNICAL BULLETIN
If acl_ptr is used to obtain modes for specified access |
names (rather than for all access names on an entry), |
then each ACL entry in the general_acl structure either |
has status_code set to 0 and contains the entry's mode |
or has status_code set to error_table_$user_not_found |
and contains a mode of 0. |
The general_acl structure and the named constant |
GENERAL_ACL_VERSION_1 are defined in the include file |
acl_structures.incl.pl1. For a description of the |
general_acl structure, see the add_acl_entries |
entrypoint above. |
MULTICS TECHNICAL BULLETIN MTB-671
Entry: fs_util_$list_extended_acl
| This entrypoint returns the contents of the Extended
| Access Control List of a standard entry.
USAGE
declare fs_util_$list_extended_acl entry (char(*), char(*),
char(*), ptr, ptr, fixed bin(35));
call fs_util_$list_extended_acl (dir_name, entryname,
version, area_ptr, acl_ptr, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
version
is the version of the acl structure. (Output)
area_ptr
| is a pointer to an area where fs_util_ can allocate the
| general_extended_acl structure. If area_ptr is null,
| then the user wants access modes for certain extended
| ACL entries; these will be specified by the structure
| pointed to acl_ptr. (Input)
acl_ptr
| is a pointer to the general_acl structure. (Input or
| Output)
| Input: if area_ptr is null, then acl_ptr points to a
| general_extended_acl structure filled with access names
| and into which modes will be placed.
| Output: if area_ptr is non null, then acl_ptr will
| point to the start of a newly allocated
| general_extended_acl structure.
code
is a standard system status code. (Output)
NOTES
MTB-671 MULTICS TECHNICAL BULLETIN
This interface is intended to be used only by extended |
entry type support routines which map an ACL mode |
provided to fs_util_ into a standard mode/extended mode |
pair to be placed on the underlying standard entry or |
entries which are being used to implement the extended |
entry type. |
If acl_ptr is used to obtain modes for specified access |
names (rather than for all access names on an entry), |
then each ACL entry in the general_extended_acl |
structure either has status_code set to 0 and contains |
the entry's mode or has status_code set to |
error_table_$user_not_found and contains a mode of 0. |
The general_extended_acl structure and the named |
constant GENERAL_EXTENDED_ACL_VERSION_1 are defined in |
the include file acl_structures.incl.pl1. The |
general_extended_acl structure is described in the |
add_extended_acl_entries entrypoint described above. |
MULTICS TECHNICAL BULLETIN MTB-671
Entry: fs_util_$replace_acl
| This entrypoint is used to replace Access Control List
| components for an entry.
USAGE
declare fs_util_$replace_acl entry (char(*), char(*), ptr,
bit(1), fixed bin(35));
call fs_util_$replace_acl (dir_name, entryname, acl_ptr,
no_sysdaemon, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
acl_ptr
is a pointer to the structure general_extended_acl.
(Input)
no_sysdaemon
is a switch that indicates whether an rw *.SysDaemon.*
entry is to be put on the ACL of the segment after the
existing ACL has been deleted and before the
user-supplied general_acl entries are added. (Input)
"0"b adds rw *.SysDaemon.* entry
"1"b replaces the existing ACL with only the
user-supplied general_acl
code
is a standard system status code. (Output)
NOTES
The general_acl structure and the named constant
GENERAL_ACL_VERSION_1 are defined in the include file
acl_structure.incl.pl1. The general_acl structure is
described above in the entrypoint add_acl_entries.
MTB-671 MULTICS TECHNICAL BULLETIN
Entry: fs_util_$replace_extended_acl
This entry is used to replace Extended Access Control |
List components for a standard entry. |
USAGE
declare fs_util_$replace_extended_acl entry (char(*),
char(*), ptr, bit(1), fixed bin(35));
call fs_util_$replace_extended_acl (dir_name, entryname,
acl_ptr, no_sysdaemon, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
acl_ptr
is a pointer to the structure general_extended_acl.
(Input)
no_sysdaemon
is a switch that indicates whether an rw *.SysDaemon.*
entry is to be put on the ACL of the segment after the
existing ACL has been deleted and before the
user-supplied general_acl entries are added. (Input)
"0"b adds rw *.SysDaemon.* entry
"1"b replaces the existing ACL with only the
user-supplied general_acl
code
is a standard system status code. (Output)
NOTES
This interface is intended to be used only by extended |
entry type support routines which map an ACL mode |
provided to fs_util_ into a standard mode/extended mode |
pair to be placed on the underlying standard entry or |
entries which are being used to implement the extended |
entry type. |
MULTICS TECHNICAL BULLETIN MTB-671
The structure general_extended_acl and the named
constant GENERAL_EXTENDED_ACL_VERSION_1 are defined in
the include file acl_structures.incl.pl1. The structure
general_extended_acl is described in the
add_extended_acl_entries entrypoint above.
MTB-671 MULTICS TECHNICAL BULLETIN
Entry: fs_util_$suffix_info
This entry returns information about an entry's type.
USAGE
declare fs_util_$suffix_info entry (char(*), char(*), ptr,
fixed bin(35));
call fs_util_$suffix_info (dir_name, entryname,
suffix_info_ptr, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
suffix_info_ptr
is a pointer to the suffix_info structure. (Input)
code
is a standard system status code. (Output)
NOTES
The suffix_info structure and the named constant
SUFFIX_INFO_VERSION_1 are defined in the include file
suffix_info.incl.pl1.
The suffix_info structure is defined as follows:
MULTICS TECHNICAL BULLETIN MTB-671
1 suffix_info aligned based (suffix_info_ptr),
2 version char (8),
2 type char (32) unaligned,
2 type_name char (32) unaligned,
2 plural_name char (32) unaligned,
2 flags unaligned,
3 standard_object bit (1) unaligned,
3 extended_acl bit (1) unaligned,
3 has_switches bit (1) unaligned,
3 mbz1 bit (33) unaligned,
2 modes char (36),
2 max_mode_len fixed bin,
2 num_ring_brackets fixed bin,
2 copy_flags like copy_flags,
2 info_pathname char (168) unaligned;
STRUCTURE ELEMENTS
version
is the current version of this structure and has the
value of the named constant SUFFIX_INFO_VERSION_1.
type
is the suffix found on entry names of entries if this
type (e.g., "mbx").
type_name
is the singular name of the entry type (e.g.,
"mailbox").
plural_type
is the plural name of the entry type (e.g.,
"mailboxes").
standard_object
is set to indicate that the entry is to be handled by
fs_util_ itself.
extended_acl
is a switch indicating whether or not the entry type
supports an extended Access Control List. The switch
should be on if the type sufforts extended ACLs, and off
otherwise.
has_switches
MTB-671 MULTICS TECHNICAL BULLETIN
is on if the entry type supports the get_switch and
set_switch entries.
mbz1
is reserved for future use and must be zero.
modes
is a string containing the access modes for the entry
type. This string contains one character for each mode
bit. The position of the character in the string
indicates which bit in the ACL represents that mode.
max_mode_len
is the maximum number of modes on a single entry of this
type. This is used by the list_acl command for
formatting.
num_ring_brackets
is the number of ring brackets on an entry.
copy_flags
for its format, see the copy_flags structure described
above.
The flags configuration provided by suffix_info define |
what copy operations are valid for the extended entry |
type. During the copy operation, these flags are ANDed |
with the copy flags provided with the call to fs_util_. |
Only the operations allowed by suffix_info and requested |
by the copy call are performed. fs_util_ does not |
notify its caller that certain flags were ignored; |
however, the identity of these flags is computable via a |
call to suffix_info. |
info_pathname
is the pathname of an info segment containing more
information.
MULTICS TECHNICAL BULLETIN MTB-671
Entry: fs_util_$suffix_info_for_type
This entrypoint returns information about the
characteristics of an entry that is of a given type. It
behaves exactly as the suffix_info entrypoint except
that a directory and entry name are not used to
determine the type for which suffix info is to be
returned.
USAGE
declare fs_util_$suffix_info_for_type entry (char(*), ptr,
fixed bin(35));
call fs_util_$suffix_info_for_type (type, suffix_info_ptr,
code);
ARGUMENTS
type
is the suffix for the type for which information is to
be returned. (Input)
suffix_info_ptr
is a pointer to the suffix_info structure. (Input)
code
is a standard system status code. (Output)
NOTES
The suffix_info structure and the named constant
SUFFIX_INFO_VERSION_1 are defined in the include file
suffix_info.incl.pl1. The suffix_info structure is
described in the suffix_info entrypoint above.
MTB-671 MULTICS TECHNICAL BULLETIN
Entry: fs_util_$list_switches
This entry returns a list of switches supported by the
entry type.
USAGE
declare fs_util_$list_switches entry (char(*), char(*),
char(*), ptr, ptr, fixed bin(35)));
call fs_util_$list_switches (dir_name, entryname, version,
area_ptr, switch_list_ptr, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
version
is the version of the switch list structure. (Input)
area_ptr
is a pointer to an area where fs_util_ can allocate the
structure switch_list. (Input)
switch_list_ptr
is a pointer to the switch_list structure. (Input)
code
is a standard system status code. (Input)
NOTES
The list_switches structure and the named constant
SWITCH_LIST_VERSION_1 are defined in the include file
suffix_info.incl.pl1.
The list_switches structure is defined as follows:
MULTICS TECHNICAL BULLETIN MTB-671
1 switch_list aligned based (switch_list_ptr),
2 version char (8),
2 switch_count fixed bin,
2 switch_name_count fixed bin,
2 switches (alloc_switch_count
refer (switch_list.switch_count)),
3 name_index fixed bin,
3 name_count fixed bin,
3 default_value bit (1) aligned,
3 mbz1 bit (36) aligned,
2 names (alloc_switch_name_count refer
(switch_list.switch_name_count)) char (32);
STRUCTURE ELEMENTS
version
is the current version of this structure and has the
value of the named constant SWITCH_LIST_VERSION_1.
switch_count
is the number of switches defined for this entry type.
switch_name_count
is the total number of names of the switches; a switch
can have multiple names.
name_index
is the index into suffix_list.names aray of the first
name for this switch.
name_count
is the number of names for this switch. The names for
this switch are located in switch_list.names(name_index)
through switch_list.names(name_index + name_count - 1).
default_value
is the default setting for this switch when the entry is
created.
names
is the array of switch names.
MTB-671 MULTICS TECHNICAL BULLETIN
Entry: fs_util_$list_switches_for_type
This entry returns a list of switches for a particular
type of entry.
USAGE
declare fs_util_$list_switches_for_type entry (char(*),
char(*), ptr, ptr, fixed bin(35));
call fs_util_$list_switches_for_type (type, version,
area_ptr, switch_list_ptr, code);
ARGUMENTS
type
is the type of entry for which a list of switches is
desired. (Input)
version
is the version of the switch_list structure. (Input)
area_ptr
is a pointer to an area where fs_util_ can allocate the
structure switch_list. (Input)
switch_list_ptr
is a pointer to the switch_list structure. (Input)
code
is a standard system status code. (Input)
NOTES
The list_switches structure and the named constant
SWITCH_LIST_VERSION_1 are defined in the include file
suffix_info.incl.pl1. The list_switches structure is
described in the list_switches entrypoint above.
MULTICS TECHNICAL BULLETIN MTB-671
Entry: fs_util_$make_entry
This entry constructs an entry variable to a specified
suffix support subroutine entry for a specified extended
entry.
USAGE
declare fs_util_$make_entry entry (char(*), char(*), char(*),
entry, fixed bin(35));
call fs_util_$make_entry (dir_name, entryname, entrypoint,
entry_to_call, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
entrypoint
is the name of the entrypoint that is is to be
constructed. (Input)
entry_to_call
is the entry variable constructed. (Output)
code
is a standard system status code. (Output)
MTB-671 MULTICS TECHNICAL BULLETIN
Entry: fs_util_$make_entry_for_type
This entry constructs an entry variable to a specified
suffix support subroutine entry for a specified type of
extended entry.
USAGE
declare fs_util_$make_entry_for_type entry (char(*), char(*),
entry, fixed bin(35));
call fs_util_$make_entry_for_type (type, entrypoint,
entry_to_call, code);
ARGUMENTS
type
is the type of entry for which a list of switches is
desired. (Input)
entrypoint
is the name of the entrypoint that is is to be
constructed. (Input)
entry_to_call
is the entry variable constructed. (Output)
code
is a standard system status code. (Output)
MULTICS TECHNICAL BULLETIN MTB-671
Entry: fs_util_$get_type
This entry returns the type of a specified entry.
USAGE
declare fs_util_$get_type entry (char(*), char(*), char(*),
fixed_bin(35));
call fs_util_$get_type (dir_name, entryname, type, code);
ARGUMENTS
dir_name
is the absolute pathname of the directory containing the
entry. (Input)
entryname
is the name of the entry. (Input)
type
is the type of entry for which a list of switches is
desired. (Input)
code
is a standard system status code. (Output)
MTB-671 MULTICS TECHNICAL BULLETIN
9 Command Level Interfaces
describe_entry_type, dset
Syntax: dset suffix {-control_args}
Syntax as an active function: [dset suffix -control_arg]
Function: prints or returns information about an extended entry
type.
Argument:
suffix
is the suffix that identifies the entry type to be described.
Control arguments:
-all, -a
prints all information about the entry type. This includes
name, plural name, access modes, supported attributes, and
the default values and all names for switches. This control
argument may not be used if invoked as an active function.
-attributes, -attr
prints or returns the names of the storage system attributes
that this entry type supports. These are the attributes that
may be copied or moved by the copy and move commands.
-default NAME
prints or returns the default value of the specified switch
for this entry type. Only one -default argument may be
given. This control argument is incompatible with -all and
-switches.
-extended_acl, -xacl
returns "true" if the entry type supports extended ACLs, and
"false" if it does not. This may not be used if invoked as a
command.
-info_pathname, -ipn
prints or returns the pathname of an info segment containing
more information about the entry type, if such an info
segment is available
MULTICS TECHNICAL BULLETIN MTB-671
-modes
prints or returns the acceptable access modes for this entry
type.
-name, -nm
prints or returns the name of an entry of this type.
-plural_name, -plnm
prints or returns the name of a group of entry of this type.
-switches
prints the names and default values of all switches supported
by this entry type.
Notes: When invoked with no arguments, the command prints the
name, plural name, modes, attributes, info seg pathname, switch
names and default values.
This interface is intended to be used only by extended entry type
support routines which map an ACL mode provided to fs_util_ into a
standard mode/extended mode pair to be placed on the underlying
standard entry or entries which are being used to implement the
extended entry type.
MTB-671 MULTICS TECHNICAL BULLETIN
list_entry_types, lset
Syntax: lset
Function: Prints or returns a list of all of the extended entry
types that can be found using the caller's search rules.
Syntax as an active function: [lset]
MULTICS TECHNICAL BULLETIN MTB-671
10 Writing a Suffix Support Routine
What follows is a very elementary example of using the Utility to
support an extended entry type. A hypothetical object for
representing the progression of a chessgame between two Multics
users is stored in a segment and is defined by the following
structure:
dcl chessgame_ptr pointer;
dcl CHESSGAME_VERSION_1 char (8) internal static
options (constant) init ("CHESS1.0");
dcl 1 chessgame based (chessgame_ptr) aligned,
2 version char (8),
2 board dim (1:8, 1:8) char (2) unaligned,
2 white aligned like participant,
2 black aligned like participant;
dcl participant_ptr pointer;
dcl 1 participant based (participant_ptr) aligned,
2 name char (32),
2 clock fixed bin (35),
2 move dim (1:150) aligned,
3 from char (2) unaligned,
3 to char (2) unaligned;
The chessgame segment has a suffix of "chess". A chessgame has
two ACL modes, participant (p) and spectator (s), which map into
read/write and read privilege, respectively. Note how the suffix
support routine performs the conversion.
The support routine is not written with any sort of optimization
in mind, but with the goal of demonstrating general issues of
supporting extended entries. For instance, most of the calls to
fs_util_$make_entry_for_type and handler could be replaced by an
appropriate hcs_ call (remember that the suffix support routine is
allowed to be cognizant of the underlying structure of its
object).
MTB-671 MULTICS TECHNICAL BULLETIN
/* ***********************************************************
* *
* Copyright, (C) Honeywell Information Systems Inc., 1984 *
* *
*********************************************************** */
suffix_chess_$validate:
procedure (p_dir_name, p_entry_name, p_code);
/*
suffix_chess_ - sample typed file support routine.
written 1984.09.20 by M. Pandolf
*/
/*
validate:
procedure (p_dir_name, p_entry_name, p_code);
this entrypoint called by fs_util_ to certify the identity of
a suffixed entry. To be considered a valid chess game, the
entry must be readable by the user, and the version must be
current.
*/
call validate_chessgame (p_dir_name, p_entry_name, p_code);
return;
suffix_info:
entry (p_suffix_info_ptr);
/*
this entrypoint called to obtain information about
an entry type.
a more efficient way to fill in suffix info is to copy
it from a previously compiled data segment, such as:
p_suffix_info_ptr -> suffix_info = chess_info_$suffix_info;
*/
suffix_info_ptr = p_suffix_info_ptr;
suffix_info.type = "chess";
suffix_info.type_name = "Chess game";
suffix_info.plural_name = "Chess games";
suffix_info.flags = ""b;
suffix_info.flags.has_switches = "1"b;
suffix_info.modes = "ps";
MULTICS TECHNICAL BULLETIN MTB-671
suffix_info.max_mode_len = 2;
suffix_info.num_ring_brackets = 1;
suffix_info.copy_flags = ""b;
suffix_info.copy_flags.names = "1"b;
suffix_info.copy_flags.acl = "1"b;
suffix_info.copy_flags.safety_switch = "1"b;
suffix_info.copy_flags.dumper_switches = "1"b;
suffix_info.copy_flags.update = "1"b;
suffix_info.info_pathname = "";
return;
list_switches:
entry (p_desired_version, p_area_ptr, p_switch_list_ptr,
p_code);
/*
this entrypoint called to obtain a list
of switches supported for an entry type.
unlike segments, we don't support the copy switch
or synchronized switch.
*/
if p_area_ptr = null ()
then user_area_ptr = get_user_free_area_ ();
else user_area_ptr = p_area_ptr;
if p_desired_version ^= SWITCH_LIST_VERSION_1
then do;
p_code = error_table_$unimplemented_version;
return;
end;
alloc_switch_count = 4;
alloc_switch_name_count = 6;
allocate switch_list
in (user_area);
switch_list.version = SWITCH_LIST_VERSION_1;
switch_list.switches (1).name_index = 1;
switch_list.switches (1).name_count = 2;
switch_list.switches (1).default_value = "0"b;
switch_list.names (1) = "damaged";
switch_list.names (2) = "dm";
switch_list.switches (2).name_index = 3;
switch_list.switches (2).name_count = 2;
MTB-671 MULTICS TECHNICAL BULLETIN
switch_list.switches (2).default_value = "0"b;
switch_list.names (3) = "safety";
switch_list.names (4) = "sf";
switch_list.switches (3).name_index = 5;
switch_list.switches (3).name_count = 2;
switch_list.switches (3).default_value = "0"b;
switch_list.names (5) = "complete_volume_dump";
switch_list.names (6) = "cvd";
switch_list.switches (4).name_index = 7;
switch_list.switches (4).name_count = 2;
switch_list.switches (4).default_value = "1"b;
switch_list.names (7) = "incremental_volume_dump";
switch_list.names (8) = "ivd";
p_switch_list_ptr = switch_list_ptr;
return;
chname_file:
entry (p_dir_name, p_entry_name,
p_old_name, p_new_name, p_code);
/*
entrypoint to change/add/delete a name of a file.
after checking the new name, we forward the call
to the handler for segments.
*/
call validate_chessgame (p_dir_name, p_entry_name, p_code);
if p_code ^= 0
then return;
call fs_util_$make_entry_for_type (FS_OBJECT_TYPE_SEGMENT,
FS_CHNAME_FILE, handler, p_code);
if p_code = 0
then if valid_chessgame_name (p_new_name) | p_new_name = ""
then call handler (p_dir_name, p_entry_name,
p_old_name, p_new_name, p_code);
else p_code = error_table_$badstar;
else;
return;
copy:
entry (p_copy_options_ptr, p_code);
/*
entrypoint to copy a chess game.
MULTICS TECHNICAL BULLETIN MTB-671
forward the call to the handler for segments.
*/
/* make a copy of copy_options so that we can validate it */
if p_copy_options_ptr = null ()
then do;
p_code = error_table_$argerr;
return;
end;
my_copy_options = p_copy_options_ptr -> copy_options;
unspec (my_copy_options.copy_items) =
COPY_FLAGS_MASK &
unspec (p_copy_options_ptr -> copy_options.copy_items);
call validate_chessgame (my_copy_options.source_dir,
my_copy_options.source_name, p_code);
if p_code ^= 0
then return;
if ^valid_chessgame_name (my_copy_options.target_name)
then do;
p_code = error_table_$badstar;
return;
end;
/* forward the copy operation to fs_util_ */
call fs_util_$make_entry_for_type (FS_OBJECT_TYPE_SEGMENT,
FS_COPY, handler, p_code);
if p_code = 0
then call handler (addr (my_copy_options), p_code);
return;
delentry_file:
entry (p_dir_name, p_entry_name, p_code);
/*
entrypoint to delete a chess game.
delete the chess game as a segment.
*/
call validate_chessgame (p_dir_name, p_entry_name, p_code);
if p_code ^= 0
then return;
call fs_util_$make_entry_for_type (FS_OBJECT_TYPE_SEGMENT,
MTB-671 MULTICS TECHNICAL BULLETIN
FS_DELENTRY_FILE, handler, p_code);
if p_code = 0
then call handler (p_dir_name, p_entry_name, p_code);
return;
/*
then next listed entrypoints have no meaning for
chess games, and should not appear in the object.
get_max_length:
entry (p_dir_name, p_entry_name, p_max_length, p_code);
set_max_length:
entry (p_dir_name, p_entry_name, p_max_length, p_code);
get_bit_count:
entry (p_dir_name, p_entry_name, p_bit_count, p_code);
set_bit_count:
entry (p_dir_name, p_entry_name, p_bit_count, p_code);
*/
get_ring_brackets:
entry (p_dir_name, p_entry_name,
p_ring_brackets, p_code);
/*
entrypoint to return the ring bracket for the chess game.
get them directly from the segment entry type manager.
*/
call validate_chessgame (p_dir_name, p_entry_name, p_code);
if p_code ^= 0
then return;
call fs_util_$make_entry_for_type (FS_OBJECT_TYPE_SEGMENT,
FS_GET_RING_BRACKETS, handler, p_code);
if p_code = 0
then do;
call handler (p_dir_name, p_entry_name,
ring_brackets, p_code);
based_ring_bracket (1) = ring_brackets (1);
end;
return;
set_ring_brackets:
MULTICS TECHNICAL BULLETIN MTB-671
entry (p_dir_name, p_entry_name,
p_ring_brackets, p_code);
/*
entrypoint to set the ring bracket of a chess game.
there is only one ring bracket for chess games,
so we massage the parameter a bit.
*/
call validate_chessgame (p_dir_name, p_entry_name, p_code);
if p_code ^= 0
then return;
ring_brackets (*) = based_ring_bracket (1);
call fs_util_$make_entry_for_type (FS_OBJECT_TYPE_SEGMENT,
FS_SET_RING_BRACKETS, handler, p_code);
if p_code = 0
then call handler (p_dir_name, p_entry_name,
ring_brackets, p_code);
return;
get_switch:
entry (p_dir_name, p_entry_name,
p_switch_name, p_switch_value, p_code);
/*
entrypoint to return the value of a chess game switch.
we pass only those switches we recognize to the
segment entry type manager.
*/
call validate_chessgame (p_dir_name, p_entry_name, p_code);
if p_code ^= 0
then return;
if p_switch_name = "damaged" |
p_switch_name = "dm" |
p_switch_name = "safety" |
p_switch_name = "sf" |
p_switch_name = "complete_volume_dump" |
p_switch_name = "cvd" |
p_switch_name = "incremental_volume_dump" |
p_switch_name = "ivd"
then do;
call fs_util_$make_entry_for_type (
FS_OBJECT_TYPE_SEGMENT, FS_GET_SWITCH,
handler, p_code);
MTB-671 MULTICS TECHNICAL BULLETIN
if p_code = 0
then call handler (p_dir_name, p_entry_name,
p_switch_name, p_switch_value, p_code);
end;
else p_code = error_table_$argerr;
return;
set_switch:
entry (p_dir_name, p_entry_name,
p_switch_name, p_switch_value, p_code);
/*
entrypoint to set one of the chess game switches.
we pass only those switches which we recognize to the
segment entry type manager.
*/
call validate_chessgame (p_dir_name, p_entry_name, p_code);
if p_code ^= 0
then return;
if p_switch_name = "damaged" |
p_switch_name = "dm" |
p_switch_name = "safety" |
p_switch_name = "sf" |
p_switch_name = "complete_volume_dump" |
p_switch_name = "cvd" |
p_switch_name = "incremental_volume_dump" |
p_switch_name = "ivd"
then do;
call fs_util_$make_entry_for_type (
FS_OBJECT_TYPE_SEGMENT, FS_SET_SWITCH,
handler, p_code);
if p_code = 0
then call handler (p_dir_name, p_entry_name,
p_switch_name, p_switch_value, p_code);
end;
else p_code = error_table_$argerr;
return;
/*
there is not extended ACL defined for chess games;
therefore, the entrypoints should not be available.
add_extended_acl_entries:
entry (p_dir_name, p_entry_name, p_acl_ptr, p_code);
MULTICS TECHNICAL BULLETIN MTB-671
list_extended_acl:
entry (p_dir_name, p_entry_name, p_desired_version,
p_area_ptr, p_acl_ptr, p_code);
replace_extended_acl:
entry (p_dir_name, p_entry_name,
p_acl_ptr, p_no_sysdaemon, p_code);
*/
add_acl_entries:
entry (p_dir_name, p_entry_name, p_acl_ptr, p_code);
/*
entrypoint to add ACL entries for a chess game.
the chess game ACL is mapped onto the extended
ACL of a standard segment, which means we
forward the call to segment support. we receive
a non-extended ACL array, and convert it to an
extended ACL array for the call.
*/
/* perform initial validation of the ACL structure */
call validate_chessgame (p_dir_name, p_entry_name, p_code);
if p_code ^= 0
then return;
if p_acl_ptr = null ()
then do;
p_code = error_table_$null_info_ptr;
return;
end;
acl_ptr = p_acl_ptr;
if general_acl.version ^= GENERAL_ACL_VERSION_1
then do;
p_code = error_table_$unimplemented_version;
return;
end;
/* validate mode bits */
acl_count = acl_ptr -> general_acl.count;
if acl_count = 0
then return;
do mode_no = 1 to acl_count;
if (acl_ptr -> general_acl.mode (mode_no) & MODE_MASK) ^= ""b
then do;
p_code = error_table_$bad_acl_mode;
MTB-671 MULTICS TECHNICAL BULLETIN
return;
end;
end;
/* get an entry value for the ACL function */
call fs_util_$make_entry_for_type (FS_OBJECT_TYPE_SEGMENT,
FS_ADD_EXTENDED_ACL_ENTRIES, handler, p_code);
if p_code ^= 0
then return;
/* prepare for the allocation of the XACL structure */
xacl_ptr = null ();
on cleanup
begin;
if xacl_ptr ^= null ()
then free xacl_ptr -> general_extended_acl
in (get_system_free_area_ () -> system_area);
xacl_ptr = null ();
end;
/* allocate and fill in the XACL structure */
allocate general_extended_acl
set (xacl_ptr) in (get_system_free_area_ () -> system_area);
xacl_ptr -> general_extended_acl.version =
GENERAL_EXTENDED_ACL_VERSION_1;
do mode_no = 1 to acl_count;
xacl_ptr -> general_extended_acl.access_name (mode_no) =
acl_ptr -> general_acl.access_name (mode_no);
xacl_ptr -> general_extended_acl.mode (mode_no) =
translate (acl_ptr -> general_acl.mode (mode_no));
xacl_ptr -> general_extended_acl.extended_mode (mode_no) =
acl_ptr -> general_acl.mode (mode_no);
xacl_ptr -> general_extended_acl.status_code (mode_no) = 0;
end;
/* forward the call to the handler with the XACL structure */
call handler (p_dir_name, p_entry_name, xacl_ptr, p_code);
/* pass on the status codes */
acl_ptr -> general_acl.status_code (*) =
xacl_ptr -> general_extended_acl.status_code (*);
return;
delete_acl_entries:
entry (p_dir_name, p_entry_name, p_acl_ptr, p_code);
MULTICS TECHNICAL BULLETIN MTB-671
/*
entrypoint to delete ACL entries from a chess game.
forward directly to segment support.
*/
call validate_chessgame (p_dir_name, p_entry_name, p_code);
if p_code ^= 0
then return;
call fs_util_$make_entry_for_type (FS_OBJECT_TYPE_SEGMENT,
FS_DELETE_ACL_ENTRIES, handler, p_code);
if p_code = 0
then call handler (p_dir_name, p_entry_name, p_acl_ptr, p_code);
return;
list_acl:
entry (p_dir_name, p_entry_name, p_desired_version, p_area_ptr,
p_acl_ptr, p_code);
/*
entrypoint to list some or all ACL entries for a chess game.
we must convert from general ACL to extended ACL so
that we can pass this to segment support using
extended ACLs.
*/
/* perform initial validation of the ACL structure */
call validate_chessgame (p_dir_name, p_entry_name, p_code);
if p_code ^= 0
then return;
if p_acl_ptr = null ()
then if p_desired_version ^= GENERAL_ACL_VERSION_1
then do;
p_code = error_table_$unimplemented_version;
return;
end;
else;
else if p_acl_ptr -> general_acl.version ^=
GENERAL_ACL_VERSION_1
then do;
p_code = error_table_$unimplemented_version;
return;
end;
else;
MTB-671 MULTICS TECHNICAL BULLETIN
/* get an entry value for he ACL function */
call fs_util_$make_entry_for_type (FS_OBJECT_TYPE_SEGMENT,
FS_LIST_EXTENDED_ACL, handler, p_code);
if p_code ^=0
then return;
/* prepare for the allocation of the XACL structure */
xacl_ptr = null ();
on cleanup
begin;
if xacl_ptr ^= null ()
then free xacl_ptr -> general_extended_acl
in (get_system_free_area_ () -> system_area);
xacl_ptr = null ();
end;
/* if caller did not provide acl_ptr, the list everything */
if p_acl_ptr = null ()
then do;
call handler (p_dir_name, p_entry_name,
GENERAL_EXTENDED_ACL_VERSION_1,
get_system_free_area_ (), xacl_ptr, p_code);
if p_area_ptr = null ()
then user_area_ptr = get_user_free_area_ ();
else user_area_ptr = p_area_ptr;
/* allocate and fill in the ACL structure we will return */
acl_count = xacl_ptr -> general_extended_acl.count;
allocate general_acl
set (acl_ptr) in (user_area);
acl_ptr -> general_acl.version =
GENERAL_ACL_VERSION_1;
if acl_count = 0
then do;
free xacl_ptr -> general_extended_acl;
return;
end;
acl_ptr -> general_acl.access_name (*) =
xacl_ptr -> general_extended_acl.access_name (*);
acl_ptr -> general_acl.mode (*) =
xacl_ptr -> general_extended_acl.extended_mode (*);
acl_ptr -> general_acl.status_code (*) =
xacl_ptr -> general_extended_acl.status_code (*);
free xacl_ptr -> general_extended_acl
MULTICS TECHNICAL BULLETIN MTB-671
in (get_system_free_area_ () -> system_area);
p_acl_ptr = acl_ptr;
end;
/* caller wants only some of the ACL entries */
else do;
/* transfer ACL info to XACL structure */
acl_count = p_acl_ptr -> general_acl.count;
allocate general_extended_acl
set (xacl_ptr) in (get_system_free_area_ () -> system_area);
xacl_ptr -> general_extended_acl.version =
GENERAL_EXTENDED_ACL_VERSION_1;
xacl_ptr -> general_extended_acl.count = acl_count;
xacl_ptr -> general_extended_acl.access_name (*) =
p_acl_ptr -> general_acl.access_name (*);
xacl_ptr -> general_extended_acl.status_code (*) = 0;
/* get the info */
call handler (p_dir_name, p_entry_name,
GENERAL_EXTENDED_ACL_VERSION_1,
null (), xacl_ptr, p_code);
/* convert back to ACL form */
p_acl_ptr -> general_acl.mode (*) =
xacl_ptr -> general_extended_acl.extended_mode (*);
p_acl_ptr -> general_acl.status_code (*) =
xacl_ptr -> general_extended_acl.status_code (*);
free xacl_ptr -> general_extended_acl
in (get_system_free_area_ () -> system_area);
end;
return;
replace_acl:
entry (p_dir_name, p_entry_name, p_acl_ptr, p_no_sysdaemon,
p_code);
/*
entrypoint to replace (change) the ACL of a chess game.
after accepting a general ACL structure, fabricate an
extended ACL structure and pass it on to segment
support for extended ACLs.
*/
/* get an entry value for the ACL function */
MTB-671 MULTICS TECHNICAL BULLETIN
call validate_chessgame (p_dir_name, p_entry_name, p_code);
if p_code ^= 0
then return;
call fs_util_$make_entry_for_type (FS_OBJECT_TYPE_SEGMENT,
FS_REPLACE_EXTENDED_ACL, handler, p_code);
if p_code ^= 0
then return;
/* the job is easy if acl_ptr is null */
if p_acl_ptr = null ()
then do;
call handler (p_dir_name, p_entry_name,
p_acl_ptr, p_code);
return;
end;
/* validate ACL structure */
acl_ptr = p_acl_ptr;
if acl_ptr -> general_acl.version ^= GENERAL_ACL_VERSION_1
then do;
p_code = error_table_$unimplemented_version;
return;
end;
/* prepare for the allocation of the XACL structure */
acl_count = acl_ptr -> general_acl.count;
if acl_count = 0
then return;
xacl_ptr = null ();
on cleanup
begin;
if xacl_ptr ^= null ()
then free xacl_ptr -> general_extended_acl
in (get_system_free_area_ () -> system_area);
end;
/* allcoate and fill in the XACL structure */
allocate general_extended_acl
set (xacl_ptr) in (get_system_free_area_ () -> system_area);
xacl_ptr -> general_extended_acl.version =
GENERAL_EXTENDED_ACL_VERSION_1;
MULTICS TECHNICAL BULLETIN MTB-671
do mode_no = 1 to acl_count;
xacl_ptr -> general_extended_acl.access_name (mode_no) =
acl_ptr -> general_acl.access_name (mode_no);
xacl_ptr -> general_extended_acl.mode (mode_no) =
translate (acl_ptr -> general_acl.mode (mode_no));
xacl_ptr -> general_extended_acl.extended_mode (mode_no) =
acl_ptr -> general_acl.mode (mode_no);
xacl_ptr -> general_extended_acl.status_code (*) = 0;
end;
/* forward call to the handler and copy back results */
call handler (p_dir_name, p_entry_name,
xacl_ptr, p_no_sysdaemon, p_code);
acl_ptr -> general_acl.status_code (*) =
xacl_ptr -> general_extended_acl.status_code (*);
free xacl_ptr -> general_extended_acl
in (get_system_free_area_ () -> system_area);
return;
get_user_access_modes:
entry (p_dir_name, p_entry_name, p_user_name, p_ring,
p_modes, p_exmodes, p_code);
/*
entrypoint to return the effective access to a
chessgame given a user name and ring number.
the effective mode for a chessgame is the same as
its effective extended mode when viewed as a segment,
so we get segment support to do most of the work.
*/
p_modes, p_exmodes = ""b;
call validate_chessgame (p_dir_name, p_entry_name, p_code);
if p_code ^= 0
then return;
call fs_util_$make_entry_for_type (FS_OBJECT_TYPE_SEGMENT,
FS_GET_USER_ACCESS_MODES, handler, p_code);
if p_code = 0
then call handler (p_dir_name, p_entry_name, p_user_name, p_ring,
modes, p_modes, p_code);
return;
MTB-671 MULTICS TECHNICAL BULLETIN
/* INTERNAL PROCEDURES */
validate_chessgame:
procedure (dir_name, file_name, status);
/*
this procedure validates the format of a potential chess game.
*/
dcl dir_name char (*) parameter;
dcl file_name char (*) parameter;
dcl status fixed bin (35) parameter;
chessgame_ptr = null ();
on cleanup
begin;
if chessgame_ptr ^= null ()
then call terminate_file_ (chessgame_ptr, 0, ""b, code);
end;
call initiate_file_ (dir_name, file_name, R_ACCESS,
chessgame_ptr, bit_count, status);
if chessgame_ptr = null ()
then return;
if chessgame_ptr -> chessgame.version ^= CHESSGAME_VERSION_1
then p_code = error_table_$not_seg_type;
else p_code = 0;
call terminate_file_ (chessgame_ptr, 0, ""b, code);
return;
end validate_chessgame;
valid_chessgame_name:
procedure (file_name)
returns (bit (1) aligned);
/*
the suffix on a chessgame must exactly be "chess".
check length, then contents of entryname suffix.
*/
dcl file_name char (*) parameter;
if (length (rtrim (file_name)) > 32) |
(length (rtrim (file_name)) < 7)
then return ("0"b);
if substr (reverse (rtrim (file_name)), 1, 6) ^= "ssehc."
MULTICS TECHNICAL BULLETIN MTB-671
then return ("0"b);
else return ("1"b);
end valid_chessgame_name;
translate:
procedure (ps_mode)
returns (bit (36) aligned);
dcl ps_mode bit (36) aligned parameter;
dcl rw_mode (0:3) bit (36) aligned internal static
options (constant) init ("000"b, "100"b, "101"b, "101"b);
/*
translation from chessgame modes to segment modes:
^s^p -> null
s^p -> r
^sp -> rw
sp -> rw
*/
return (rw_mode (binary (substr (ps_mode, 1, 2))));
end translate;
/* DECLARATIONS */
/* Parameter */
dcl (
p_dir_name char (*),
p_entry_name char (*),
p_old_name char (*),
p_new_name char (*),
p_code fixed bin (35),
p_copy_options_ptr pointer,
/* p_max_length fixed bin (19), not used in this procedure */
/* p_bit_count fixed bin (24), not used in this procedure */
p_user_name char (*),
p_ring fixed bin,
p_modes bit (36) aligned,
p_exmodes bit (36) aligned,
p_ring_brackets (*) fixed bin (3),
p_switch_name char (*),
p_switch_value bit (1) aligned,
p_acl_ptr pointer,
p_area_ptr pointer,
p_desired_version char (*),
p_no_sysdaemon bit (1),
p_suffix_info_ptr pointer,
p_switch_list_ptr pointer) parameter;
MTB-671 MULTICS TECHNICAL BULLETIN
/* Automatic */
dcl (
1 my_copy_options aligned like copy_options,
bit_count fixed bin (24),
modes bit (36) aligned,
user_area_ptr pointer,
ring_brackets (1:3) fixed bin (3),
xacl_ptr pointer,
code fixed bin (35),
mode_no fixed bin) automatic;
/* Based */
dcl based_ring_bracket (1) fixed bin (3)
based (addr (p_ring_brackets));
dcl user_area area based (user_area_ptr);
dcl system_area area based;
/* Static, External */
dcl (
error_table_$not_seg_type fixed bin (35),
error_table_$unimplemented_version fixed bin (35),
error_table_$badstar fixed bin (35),
error_table_$argerr fixed bin (35),
error_table_$bad_acl_mode fixed bin (35),
error_table_$null_info_ptr fixed bin (35)) external static;
/* Constant */
dcl (COPY_FLAGS_MASK init ("110001100100000000000000000000000000"b),
MODE_MASK init ("110000000000000000000000000000000000"b))
bit (36) aligned internal static options (constant);
/* Entry (in order of appearance, well almost) */
dcl handler entry variable options (variable);
dcl initiate_file_ entry (char(*), char(*), bit(*), ptr,
fixed bin(24), fixed bin(35));
dcl terminate_file_ entry (ptr, fixed bin(24), bit(*),
fixed bin(35));
dcl fs_util_$make_entry_for_type entry (char(*), char(*), entry,
fixed bin(35));
dcl get_user_free_area_ entry () returns (ptr);
dcl get_system_free_area_ entry () returns (ptr);
/* Condition */
dcl cleanup condition;
MULTICS TECHNICAL BULLETIN MTB-671
/* Builtin */
dcl (
null,
length,
rtrim,
binary,
substr) builtin;
/* Include Files */
%page;%include chessgame;
%page;%include copy_options;
%page;%include copy_flags;
%page;%include file_system_operations;
%page;%include suffix_info;
%page;%include acl_structures;
%page;%include access_mode_values;
end suffix_chess_$validate;