Earlier this term there was a discussion on the cdf.general newsgroup about the usefulness of a system that you could use to discover which lab workstations were idle, so that you did not need to walk through each lab looking for an open machine.
Your task in this assignment is to implement a program that will tell you which of a set of machines is available. You might imagine that this program displays its output on a screen that is visible in some central location. You could check this screen to help you find a machine you can log into.
The output of the lab monitor program will have two components: Somehow, you must display to the user which machines are available. Also, your program will list the machines and the user names where a user is logged into the console of more than one machine (so you can go accuse them of hogging machines).
The purpose of this assignment is to give you practice writing client server code using sockets and select. It is not to design and implement the perfect system for solving this particular problem. Don't go overboard in designing the user interface.
Each machine that is monitored will run a server that can check if a user is logged into the console of the machine. A single client program will connect to these servers to ask for the status of the machines being monitored.
There are a few restrictions for this assignment:
You will need to determine the protocol that is used between the client and the servers. How will messages get passed? What information should each server provide to the client? How does the client tell the servers that it wants data? What is the format of the output? (You do not need to write a GUI!)
Be a good citizen of the lab!
It is non-trivial to determine whether someone is logged into the console of a machine. Remember that you can be logged into a machine remotely. For this program we depend on the fact that all of the workstations are running X Windows. A function getUser is provided that will return the name of the user logged into the console of a machine, or NULL if nobody is currently logged in. This function is not perfect, so there may be rare occasions where it fails to detect that someone is logged into the console. (It depends on X to make the appropriate login entry in a log file. Some implementations don't do this.)
The function getUser will work both on Solaris and on Linux if it is compiled correctly. When compiled normally, the function will work on the Linux machines. When compiled with an additional flag, "-DSUNOS" it will work on Solaris machines.
You must supply a Makefile that will compile both the server and the client. This topic will be covered in tutorial, and you can refer to the make tutorial or another heavily commented sample Makefile (which has more 209 specific comments) for further assistance.
Use the provided Readline, Readn, and Writen functions provided to read and write on sockets. They have error handling built in.
You can find a list of all of the CDF machines in a file called
/etc/hosts. The server and the client program only needs to
work on Linux. You can find out if a machine is Linux or Sun by typing
echo $OSTYPE
You may want to write a Bourne shell script to start up and kill all of the
processes, so you don't have to do it manually. You can start a process on
a remote machine using the rsh command. For example,
rsh b375-23 who
runs the who program on the machine b375-23.
Hint: you can get the list of machines from the same file that your monitor
program gets it from.
You can also use rsh b375-23 killall usermon to try to
kill a program called usermon on machine b375-23.
Note that killall will print out an error message if there are other people
who have processes with the same name running on the machine, but it will
still kill your process.
Your servers will all be listening on the same port number for connections from the client. You need some way of choosing this port number.
You will use a #define variable in your program to define the port
number. To be safe, choose a number between 10000 and 32767. In the C file
containing main, or in a header file included by all files needing the port
number you will have the following 3 lines of code (replace <some
number> with a port number):
#ifndef PORT #define PORT <some number> #endif
Then, in your Makefile:
PORT= <some number> CFLAGS= -DPORT=$(PORT) -g -Wall
Now, if you type make PORT=15000 the program will be
compiled with the macro PORT defined as 15000. If you type
make it will use the value defined for PORT in
the Makefile. Finally, if PORT is not defined on the compile
line, it will still have the value from your source code file. This method
of setting a port value will make it possible for us to test your code by
choosing a port value to compile your program with.
You will also submit a document that contains two parts: a user's guide, and a section that describes your design decisions. The total document should be less than 750 words, and should be written in plain text format with no more than 80 characters per line. Do not submit an MSWord document or other word processor format. (Marks will be deducted if these instructions are not followed.) Documents must be written in proper English.
The markers will attempt to run your program, so the user's guide must give a clear explanation of how the program works. There will be marks allocated for usability, so it is important that the marker find it easy to figure out how to use your program. It is recommended that you ask a friend to try to use your program based only on your instructions. Remember to tell the marker how to run the server and the client.
The second part of the document outlines your design decisions. It should explain the protocol that is used for the clients and server to exchange information. In other words, how do the client and server interpret the data sent between them? It should explain the major decisions you made in designing your program.
Do not get carried away. There is a lot of leeway in this assignment, but that does not mean that you need to make it too fancy. Do not over-design the assignment. This is not the kind of program that needs a whole bunch of features. Keep it simple, but make it useful, and easy to use. Marks will be awarded for good designs.
readn.c, writen.c,
readline.c, and getUser.c. The
server executable must be called usermon. The client
executable must be called labmon. It must compile and run on
penguin. You must include a Makefile. We should be able to type
"make" to compile both usermon and labmon.