The assignment is to simulate access control rule evaluations. The program will read a sequence of commands. These commands will define the environment and then perform a variety of file operations. The program must evaluate whether or not an operation is permitted. To permit easy evaluation of your program, you MUST use exactly the specified input format and output format. You MUST NOT extend or restrict either in any way. The input file -- which must be read from stdin -- consists of two portions, a user definition portion and a file operation portion. The two are separated by a line consisting of a period. User Definition: The user definition section consists of a series of lines containing a user name, a group name, and an optional file name. User names and group names may contain only lower-case letters; the two are separated on the input line by a single period. The file name, if present, is Unix-style, but simplified: a series of components separated by slashes. Component names may contain only letters and periods. The filename must ALWAYS start with a slash. A given user may belong to multiple groups; a group may contain multiple users. If a user name appears more than once, only the first instance may have a file name -- but that one MUST have a file name. The filename is separated from the user.group by a single space. Example: smb.faculty /home/smb smb.columbia sal.faculty /home/sal bollinger.columbia /home/bollinger suphannee.ta /home/suphannee Your program must allow AT LEAST 100 users and 100 groups. File names may be up to 256 bytes long; component names may be up to 16 bytes long. The program must accept arbitrarily many file names; the only acceptable limit is the amout of memory your program can use. In other words, you cannot use a fixed-size array for the files; you must use dynamic memory management. There must not be any limit to the size of a user name or a group name. When a user.group is specified, the associated file is created with an access control list (ACL) of user.group rw *.* r (The format is explained below.) If a user appears more than once, there is an ACL entry for each group. Thus, in the example shown above, the file /home/smb would have an ACL of smb.faculty rw smb.columbia rw A file that does not belong to any user -- /home, in this case -- will have an ACL allowing all reads but no writes: *.* r Your file system must also have a file /tmp that anyone can read and write: *.* rw ACLs: An ACL is a set of lines given a user (or *), a group (or *), a single space or blank, and either "r", "w", "rw", or "-". That last entry indicates "no permission". ACLs are evaluated line by line, exactly as explained in class; the first line that matches produces a decision. Thus, if there's an ACL smb.* - *.faculty rw and I tried to read the file, it would be rejected. Operations: There are five operations: READ, WRITE, CREATE, DELETE, and ACL. All commands have the syntax command user.group filename with a single space that separates the three fields. Thus, legal input would include: READ smb.columbia /home CREATE smb.faculty /home/smb/foo WRITE bollinger.columbia /tmp/low.library The CREATE and ACL commands are followed by a mandatory ACL for the file. The ACL is ended by a line consisting of just a period. The prior example should really be READ smb.columbia /home CREATE smb.faculty /home/smb/foo smb.faculty rw *.faculty r . WRITE bollinger.columbia /tmp/low.library There is an implicit *.* - line at the end of every ACL. Semantics: To get to a file, you need read permission on all components of the file name preceeding the last one. That's why /home is world-readable -- without that, someone else wouldn't be able to get anywhere. For the READ command, the user must (via ACL evaluation) have read permission on the actual file. User bollinger.columbia would not be able to read /home/smb/foo because there is no ACL lie permitting it. User sal.faculty could read it but not write it. WRITE works the same way. Note that you need read permissions on the previous components, but write permission on the last component. To CREATE or DELETE a file, you need write permission on the previous component. Thus, to delete /home/smb/foo the user would need write permission on /home/smb. If you CREATE a file with a null ACL, it inherits the ACL of its parent. An attempt to delete an ACL -- that is, an attempt to use the ACL command with no input lines before the period -- is an error. Why? If there's a null ACL, the file can no longer be acted on by anyone; it cannot be read, written, deleted, or had its access permissions changed. You cannot create a file if the previous component is missing, nor can you delete a component with elements below it. Thus, to create /a/b/c, /a/b must exist; to delete /a/b, there must not be, for example, /a/b/c or /a/b/d. The ACL command changes the ACL for a file. You must have write permission on the file to do that. Output: For each user.group command, print the input line number, a Y (if valid) or an X if invalid, and any text you choose, including an error message. The line number and the Y or X are each followed by a single tab character. For each command, print the command number (NOT the line number, but which command -- in my example, the WRITE of /tmp/low.library is number 3), a Y/N/X for "yes" (i.e., the operation is allowed), "no", or "error". After that, echo the command input but *not* the ACL (if any), followed by an optional free-form error message. Again, the line number, the Y/N/X, and the command are separated by single tabs. Pay a LOT of attention to your test data -- that's a vital part of the assignment. You will probably want to have multiple input files to test different things.