Lab 05: Super-Servers and the utmp Database

Goals

Introduction

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 a in-coming request, a system call select (or similar calls on 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 fingure (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.

Setup

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

~/csci363-s13/labs/lab05

Copy all files from ~cs363/Spring13/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 super server works

Your first task is just to compile the programs using the make command. You should get a superServer and two clients timeClient-udp and echoClient. 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.

Read the programs superServer.c and the two clients. Make sure you understand how they work. Pay special attention to the select call, and the FD_SET related macros.

Create an answers.txt and write a paragraph or two describing what the macros FD_ZERO() and FD_SET() do, and what the system call select() does. Consult the relevant manual pages if needed.

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 programmers can write program to 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.

Submission

Submit all your program and answers.txt to your gitlab account. At the least, you'd have the following.

  1. The text file answers.txt.
  2. The revised superServer.c source code which now should include three services, echo, time and getwho.
  3. The revised Makefile.
  4. A trace of executing server and each of the multiple clients using copy-and-paste, or using the script command.
  5. Make sure you submit a complete package so I can compile and run the programs.

Congratulations, you've finished this lab!