ECS 40 Program #5 - CS-CSIF

ECS 40
Program #5 (50 points + 10 points extra credit) my time 2.5 hours
Winter 2015
Due: Wednesday, February 18th at 11:59pm using handin to p5 directory of cs40a.
New concepts: linked lists, static variables, copy constructors, and overloaded [], +=, <.
Name of executable: funix.out
File names: Makefile, funix.cpp, funix.h, directory.cpp, directory.h, main.cpp, permissions.cpp, permissions.h, Time.cpp,
Time.h, list.cpp, list.h.
For this assignment, you will modify your program #4 code to do the following. As usual, your program should
compile without warnings, and run perfectly after the completion of each major step. You are welcome to use my own
code as a starting point, it will be available in ~ssdavis/40/p4/SeansSrc Thursday morning.
Because of the Presidents’ Day holiday, and the lack of new concepts involved, the implementation of a Funix::user
and a Permission::owner is worth 10 points extra credit. The TAs, I, and, I hope, Alex will not help anyone with the extra
credit part of the assignment. We all will focus on helping students with the new concepts. We are going to alter the
original format of directories.txt in step 1 so that it will be compatible with both versions—with or without owners.
Specifications:
1. (1 minute) Change the Directory insertion and extraction operators so that deal with the subDirectory count BEFORE
the permissions. That way the owner will be the last thing on each line, and will be ignored on non-extra credit
versions. Whether you are doing the extra credit or not, the first two lines of the Directory extraction operator must
become:
is >> rhs.name >> rhs.time >> >> rhs.subDirectoryCount >> rhs.permissions;
is.ignore(10, ‘\n’);
2. (35 minutes) Replace the array of subdirectories with a singly linked list of Directory* sorted by the Directory names.
2.1. The subdirectory linked list will only have the following methods: default constructor, copy constructor,
destructor, [] operators both const and not const that return Directory*, and += operator. Do not try writing the
copy constructor until you write the cp command in step #3.
2.2. Each ListNode will hold a pointer to a dynamically allocated Directory. Though the Directory class and List
assignment operator will be expected to dynamically allocate each new Directory, the ListNode class destructor
will delete them.
2.3. Do NOT #include directory.h in list.h. Do forward declare the class Directory in list.h. This is necessary
because of the cross referencing of the two classes in the header files and the action of the #ifndefs.
2.4. The += operator will take a Directory* as its parameter. It will rely on an overloaded < operator of the Directory
class to sort the list by Directory name.
2.4.1. Since the linked list is sorted by names, you will need to read into a Directory from the directories.txt file
before using += to insert into the linked list.
2.4.2. This replaces the Directory::addDirectory() method
2.5. Once you have created all of the methods, you will experience one of the advantages of Object Oriented
Programming. Since only the Directory class interacts with the subDirectories, the only code you will need to
concern yourself with is in directory.cpp and directory.h. The many other classes don’t care how subDirectories
is implemented.
2.6. Make sure everything compiles and works properly before continuing with any later development.
3. (35 minutes) There should now be a cp command that recreate the entire directory structure of the source directory.
3.1. syntax cp source_directory_name destination_directory_name
3.2. The implementation must rely on a copy constructor of Directory.
3.3. The copy constructor of Directory must rely on the copy constructor of List which relies on the Directory copy
constructor! This is tricky so don’t rush into it. In particular, parents need to be adjusted.
3.4. The modification times of the new directory and its subdirectories are set to their time of creation, and not that of
the original directories. This is automatically achieved!
4. (15 minutes) Remove umask from Funix, and make it a static variable of the Permissions class.
4.1. The Permissions class should now handle the setUmask method.
4.2. It should also handle reading and writing the umask value to the file with two new methods.
4.3. All methods dealing with the umask should be static methods.
4.4. You will now need a chmod() method for Permissions since umask will no longer be passed in the set() method.
5. (10 minutes) All code dealing with any aspect of permissions, including range checking, should be within the
Permissions class. If you are using my code, then Directory::checkOctals() should now be a static method of the
Permissions class.
Owner Implementation (10 points extra credit)
6. (25 minutes) Add an owner char* to the Permissions class and a user char[9] to the Funix class.
6.1. This is a big step. I suggest that you take some time, and make sure that everything works properly up through
step 5. Save a copy of the non-owner version in a separate directory so that you can submit it if you cannot get
the extra credit version working properly! I guarantee you the you won’t be able to change back in the five
minute re-grade time period.
6.2. When there is no directories.txt from which to read, the initial user is “root”.
6.3. Owners and users may not have strings longer than eight characters.
6.4. You need to pass the user to most of the Directory methods, and some of the Permissions methods.
6.5. ls –l will now display properly formatted owners of directories after the permissions.
6.6. Have the permissions of a directory determine whether a given command, except “cd ..”, can be done based on
its owner too. If the user is not the owner, then the “other” permissions apply.
7. (5 minutes) Add a su method that simply changes the Funix::user to another user, and, unlike UNIX, does not require
a password.
7.1. Syntax: su username
7.2. If username is longer than eight characters, su should report an error as if the user was unknown to the system.
7.3. If there is an incorrect number of arguments, then provide the appropriate usage error message.
7.4. Unlike UNIX, which uses exit to return to the original user, we will simply use “su root”.
8. (15 minutes) Add a chown method that changes the owner of a directory to the specified owner.
8.1. Syntax: chown owner_name filename
8.2. It can only be used when the user is “root”. This should be checked by Funix::chown().
8.3. If owner name is longer than eight characters, chown should report an error as if the owner was unknown to the
system like that of su. This should be checked by Funix::chown() since, in theory, it would know the names of
users, and the Directory class would not.
8.4. chown of a directory does not change the owner of the subdirectories of the specified directory.
[ssdavis@lect1 p5]$ funix.out
/ # mkdir first
/ # mkdir second
/ # ls -l
rwxr-xr-x
root Feb 11 10:12 first
rwxr-xr-x
root Feb 11 10:12 second
/ # cd first
/first/ # mkdir third
/first/ # cd ..
/ # chown
chown: missing operand
Try 'chown --help' for more information.
/ # chown davis second
/ # cp first fourth
/ # ls -l
rwxr-xr-x
root Feb 11 10:12 first
rwxr-xr-x
root Feb 11 10:14 fourth
rwxr-xr-x
davis Feb 11 10:12 second
/ # cd fourth
/fourth/ # ls -l
rwxr-xr-x
root Feb 11 10:14 third
/fourth/ # cd ..
/ # chmod 700 second
chmod: Permission denied
/ # su davis
/ # chmod 700 second
/ # chmod 755 first
chmod: Permission denied
/ # su root
/ # cd second
second: Permission denied.
/ # su davis
/ # chown davis second
chown: Permission denied
/ # exit
[ssdavis@lect1 p5]$ cat directories.txt
18
/ 1 11 10 12 3 493 root
first 1 11 10 12 1 493 root
third 1 11 10 12 0 493 root
fourth 1 11 10 14 1 493 root
third 1 11 10 14 0 493 root
second 1 11 10 12 0 448 davis
[ssdavis@lect1 p5]$