Project 3: A Friendly Daemon
Due Monday, December 9, at 10:30 AM (Start of the final exam)
On Unix-like systems, including Linux, long-running processes are called daemons (always spelled with the a). The name is a reference to Maxwell's Demon, which in the Wikipedia article, is spelled without an a. Regardless of spelling, quite a few long-running background processes exist on any operating system.
For this assignment, write a daemon which will notice when you log in, as well as message other users when they log in if you have a message for them. The daemon should periodically check to see if you have logged in, and if you have, send you a greeting. Once per minute is a reasonable frequency here, particularly since the command "last" supports minutes well. Note that "once per minute" is the frequency of checking. Only send one message in response to each new login! Otherwise it will be very annoying. In addition to checking for you, the daemon should look at the contents of a directory in your home directory named ".outgoing", which will contain messages for other users. Each file in .outgoing should be the name of another user, and the contents should be a message for that user. If the user is currently logged in, the daemon will send them the contents of the file, and delete the file so the message is not sent again.
Besides the usual behaviour, your daemon must support a debug flag (--debug). If --debug is specified, the daemon won't daemonize, but remain attached to the terminal (skip calling fork, and leave file descriptors alone).
Specifics you might find useful:
- The command "last" can be used to list users who have logged in during the previous minute. This is a pretty good way to look for recent logins. It's also possible to use who, or w, or finger.
- The daemon should be written in C/C++, but you can run commands, and take advantage of grep, cat, rm, etc. The function "system" will run a command and return the status, which can be useful for checking to see if grep found a result. If you need the text that was produced, the function "getoutput" from the demo use_getoutput.c (or use_getoutput.cpp if you prefer a C++ string) can do this for you. If you need both, run getoutput, and then retrieve the last exit status with wait. All features of C++ are available to you including STL data structures.
- Remember that you can use pipes when running a command with system or getoutput. So for example, to pipe a file into write, you can run a command like "cat thefile | write theuser". This assignment doesn't require using C pipes except as already contained in getoutput.
- Once the process is daemonized (with the "fork" function), you can still kill it by looking up the process ID and using kill, or killall and the process name. But for testing, it might be handy to see debugging output. You can either write the debugging output to a file, or just comment out the call to fork that daemonizes the process while debugging.
- The name .outgoing for the folder makes it a "hidden" folder, as in, ls will not display it by default. ls -a will display hidden files/folders.