ECS 40 Program #5 - CS-CSIF
Transcription
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]$