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;