Lab 05: Super-Servers and the utmp Database



Often a process has to deal with multiple input streams. For example, a server may have to listen on multiple ports, each of which corresponds to a different type of clients. In the case of Linux, a super server called xinetd is running to service all types of requests such as ssh, finger and others. (Read man xinetd for more information.) A server can create and listen on multiple sockets, each of which is for one type of service. When there is an in-coming request, a system call select (or similar calls in other systems) can help determine which of the multiple sockets has data ready for read. Based on this condition, the server can take (read) information from that particular socket and work from there.

How Does select Work: The system call select works with a piece of data structure called fd_set which is essentially a collection of bits. If one of the input streams is ready (has data), the corresponding bit will be set by the operating system. The select call will return the number of streams that are ready as result. When the call is returned, the calling program can select the input stream that is ready and continue the process with that stream. When multiple inputs are ready, the calling program can deal with them one at a time.

The utmp database: Like many modern computing systems, Linux keeps track of information about its users, in particular, who are currently using the system. By keeping these information, the Linux operating system can respond to commands such as who, w, and finger (if you have never used these commands, read these manual pages, and give these commands a try.) Linux keeps a database of these information in a file called utmp (for user temporary files.) Your second task today is to learn to work with this file and extract user information from this file. Once becoming familiar with the utmp, you are asked to integrate this service as a part of a super server.


Create a directory in your git repository called lab05, as in


Also create on your local file system the directory of lab05 under your CSCI 363 course work directory. Copy all files from ~cs363/Spring16/student/labs/lab05/ to your own lab directory. You should see a collection of seven files, echoClient.c, getwho.c, Makefile, superServer.c, tcplib.c, tcplib.h, and timeClient-udp.c, from which you are to create your solution.

Problem 1: Understand how a FD_SET and related macros work

Your first task is to read the code superServer.c and understand the general flow of this server program. Then you need to fill in the details where the macro FD_SET and its related calls, and the system call select to complete the program. The places you need to add code are highlighted by the TODO comments.

Create an answers.txt and write a paragraph or two describing what the macros FD_ZERO() and FD_SET() do, what the system call select() does, and how it works. Consult the relevant manual pages if needed. Note that there is a complete program example towards the end of the manual page.

Once the superServer program works, it should be able to serve two types of clients, a time service that returns the system time, and an echo service that echo the client input.

Compile and run this set of clients and server to see how they work. Note: before you compile the program, change the port numbers in the programs to your assigned port numbers. You should run the server first, then run the echoClient without actually typing a line of input to the client program so the client program doesn't quit before you run the time client. The point here is to demonstrate that the server is actually able to handle multiple clients simultaneously. While the echoClient is running (that is, you started the echo client without typing a line to it), try also the timeClient-udp which is supposed to get a time reading from the server and displays on the client's screen. In this example, the time client actually is a UDP client. This means that a super server can deal with multiple UDP and TCP clients, simultaneously. After running the time client, type a line of text as input to the echo client program. Both clients should be completed and exit now.

Problem 2: Working with the Linux utmp database

As described in the Introduction section of the lab, the Linux operating systems keeps information about current users in a database called utmp from which programs can access current user information. The utmp database essentially is a collection of records of the type struct utmp (read the manual page on utmp to find out the details.) The program getwho.c goes through the entire list of current users and counts how many records are in the database. Your task is to print out the user name (ut_user) based on the user type (ut_type.) You are asked to print only the normal user process (USER_PROCESS.) You are asked to revise the getwho.c program so that not only does the program print the counts (which it already does), but also print out the user name who are currently on the system.

Before actually coding, you probably should read the manual pages for the three library calls used in the program, that is, setutent(), getutent() and endutent().

Once your program can correctly print who is currently on your local computer, try the program on a server such as linuxremote to see who are on those computers.

Problem 3: Make the getwho as a part of the super server

Now that your program getwho.c works correctly, revise the superServer.c so that getwho will be a part of the service. Here are a few notes about the integration.


Submit all your program files and the answers.txt to your gitlab repository. The files should be complete so that I can compile and run your programs without copying other extra files. You should have the following in your submission.

  1. The text file answers.txt.
  2. The revised Makefile.
  3. A trace of executing server and each of the multiple clients using copy-and-paste, or using the script command.
  4. All the program files.

Congratulations, you've finished this lab!