Comp 272 Programming assignment 2 Dordal October 2, 2002 Due: Monday, October 14 Take the mail system program, and make the following changes. The program, mail.cpp, is available on my web page. It contains my version of getline(), and also contains a few "stub" declarations to get you started. 1. In the original version, when you enter the wrong password, you don't get prompted for a new one. Change this so you do. The user should be allowed MAX_TRIES = 3 attempts in all, including the first attempt. 2. Add an option to the administrative mailbox to change the passcode and greeting of any other mailbox. Press 5 to change the passcode of another mailbox 3. In the existing version, all input is handled by the mailbox, once the user enters the extension. The mailsystem class makes no further use of InputReader; in fact, the mailsystem class doesn't do *anything* further until the user has completed the "call". Change this so that the Mailsystem class handles some of the direct user interaction, as specified below. In order to keep things simple, we will continue to assume that the Mailbox takes over **after the login process has been completed**. Up until the login operation succeeds, however, Mailsystem is to handle all I/O (except Message::play() still outputs messages directly). In particular, Mailsystem will now: Play the greeting Get messages from the user Put them into the Mailbox On receipt of "#" instead of a message, prompt for the passcode and verify that it is correct. The revised Mailbox::login2() function will take over after the passcode has been verified. Here are the Mailbox member functions that engage in I/O before login: receive_message prints greeting, prompts for message/#, reads in message login prompts for password, prints opening login statement You will need to replace these, by receive_message2() and login2(). receive_message2() will be moved into class Mailsystem; Mailbox::login2() will be the second half, more or less, of Mailbox::login(). The following will remain unchanged, as they are invoked *after* login: prompt_command prompts for a command, eg "press 1 to ..." retrieve_messages prompts about progress in reading your messages change_greeting prompts for new greeting, and updates it change_passcode ditto for passcode The main point of this assignment is that this redesign changes the class interfaces involved, because the class responsibilities are different. For example, you will now need a way for MailSystem to print the greeting, to add a new message to the Mailbox, and to verify that the passcode supplied is correct when login is attempted. The first can be handled by an accessor: string Mailbox::greeting() To add new messages, we will use bool Mailbox::addnewmessage(Message m); This returns true if the append succeeds, and false if not (which happens when the mailbox is already full). To check the passcode, either of the following would work: int Mailbox::passcode(); // get original passcode bool Mailbox::checkpasscode(int passcode); // check if supplied passcode is good The second approach is more in keeping with how real passcode systems work (which generally do *not* keep unencrypted or even unencryptable copies of the original passcodes anywhere around), but you may choose either. As for parts 1 and 2, note that #1 (prompting for the passcode) will now be handled within Mailsystem. Item #2, letting admin mailboxes change other mailboxes, is more interesting in that it will require a significant interface tweak. Specifically, from within AdminMailbox, how do we even find another mailbox? The mailboxes are stored within a private vector Mailsystem._mailboxes Any other mailbox is *invisible* to AdminMailbox! Making "_mailboxes" public would be dastardly. The slickest way to fix this is to have an accessor in MailSystem that returns a *reference* to any Mailbox, or, for those so inclined, a pointer. We've covered neither technique so far. We can (and will!) have AdminMailbox call Mailsystem::locate_mailbox(int extn); this gets us the index of the other mailbox in the array "_mailboxes". But we now need a member function in *MailSystem* to take the mailbox index (or the original extension, if you prefer), and the new passcode, and make the appropriate call to Mailbox::setpasscode().