NOTE: This assignment is due at 11:59 PM on the due date. If you are even a minute late, you lose 20%. If you are worried about potentially being late, turn in your project ahead of time. Do this by submitting it electronically, then giving the hard copy to me or the TA during office hours or by sliding it under my office door within twenty-four hours after the time it is due. Do not send assignments to me through email or leave them in my departmental mail box.
One type of program that many people have become interested in recently
is the "chat" or "instant message" type of program - one where users can
type messages back and forth to one another and have them appear on each
others' screens right away. UNIX systems have had these types of programs
for decades. See, for example, the talk
program. Your job
will be to write a simple two-person chat program that we will call,
appropriately enough, chat
.
For this assignment, you will implement chat
as follows.
IPC
For our IPC, we will use FIFOs (also called "named pipes"). Each user will have his or her own FIFO for receiving messages and will send messages to other users on the FIFOs belonging to those other users.
INVOKING CHAT
A user may invoke chat
in one of two ways: passive and
active.
Passive Mode.
To invoke chat
in passive mode the user will simply enter
chat
and hit return. When he or she does this, chat
should create,
in the current working directory, a FIFO called
<username>chatfifo
where <username>
is the user name of the user invoking chat
. This FIFO should
be "world writeable" and only readable by the owner. (Note that the user
will need to make sure that the permissions of the directory in which he or
she invokes chat
allow for appropriate reading and
writing.)
Once invoked in passive mode, chat
should simply attempt to
read from the FIFO until a message is received or until the user hits
<Ctrl-C>
.
If a message is received, chat
should process it according
to the following rules:
If the first four bytes of the message, when interpreted as
characters, are ASCII "CCCC
" (capital letter c four times),
the message should be interpreted as a request for a chat from another
user. The fifth byte of the message, when interpreted as an integer,
should be the length (in bytes) of the name of the other user's chat FIFO.
The remaining bytes of the message, when interpreted as characters, will
the that name. This will be an absolute path name.
When a chat request is received, chat
will check to see
whether it is engaged in a prior chat session. If not, it will prompt the
user with the message:
chat request from <username>: (a)ccept, (r)eject, or (i)gnore?where
<username>
is parsed from the name of the FIFO in
the chat request message.
a
" for accept, chat
should attempt to open the FIFO specified in the chat request and send an
accept message to that FIFO. The accept message will be
"AAAA
" (capital letter a four times), the length in bytes of
the user's username, and the user's username. If it successfully sends an
accept message to the FIFO, chat
should record that FIFO name
in order to send messages to it and make a note to itself that it is now
engaged in a chat session.r
" for reject, chat
should send a reject message to the FIFO specified in the chat request
message. The reject message will be an "RRRR
" (capital
letter r four times), the length in bytes of the user's username, and the
user's username.i
" for ignore, chat
should simply discard the chat request message and continue on as if no
message was ever received.If chat
is already engaged in a chat session when a chat
request message is received, it will send a reject message to the FIFO
specified in the chat request message.
If the first four bytes of the message, when interpreted as
characters, are ASCII "MMMM
" (capital letter m four times),
the message should be interpreted as a chat message from another user.
The fifth byte of the message, when interpreted as an integer, will be the
length (in bytes) of the name of the other user. The sixth byte of the
message will be the length of the text of the other user's message. The
other user's name will start at the seventh byte in the message. The text
of the message will start immediately after the name.
When a chat message is received, chat
will print to
standard out
<username>: <text>where
<username>
is the name of the user given in the message and
<text>
is the text of the message received.
If the first four bytes of the message, when interpreted as
characters, are ASCII "BBBB
" (capital letter b four times),
the message should be interpreted as a goodbye message from another user.
The fifth byte of the message, when interpreted as an integer, will be the
length (in bytes) of the name of the other user's chat FIFO. The remaining
bytes of the message will be that name. This will be an absolute path
name.
When a goodbye message is received, chat
will print to
standard out
<username> is done chatting.where
<username>
is the name of the user extracted from
the chat FIFO path name given. Then chat
will remove this
user's chat FIFO name from its memory and make a note to itself that it is
no longer in a chat session.
chat
to print
INVALID MESSAGE: <message>to standard error, where
<message>
is the entire
contents of the message.Once a chat session is started with another user, chat
should read from its standard input and send that input to the other user's
FIFO as chat messages (i.e., type "MMMM
" messages, see above).
A new chat message should be sent each time the user enters
<return>
or 128 characters, whichever comes first.
If the user hits <Ctrl-C>
, chat
should
send a goodbye message (type "BBBB
" message, see above) to the
user currently chatting with it, remove its FIFO, and exit normally.
Active Mode.
To invoke chat
in active mode the user will simply enter
chat <fifoname>
where <fifoname>
is the full path name of a FIFO and hit
return. When he or she does this, chat should create, in the current
working directory, a FIFO called <username>chatfifo
where <username>
is the user name of the user invoking
chat
. This FIFO should be "world writeable" and only readable
by the owner. (Note that the user will need to make sure that the
permissions of the directory in which he or she invokes chat
allow for appropriate reading and writing.)
After creating its own FIFO, chat
should send a chat
request message to the FIFO given by <fifoname>
. If
chat
receives an accept message (type "AAAA
"
message, see above), it should read from its standard input and send that
input to the other user's FIFO as chat messages (i.e., type
"MMMM
" messages, see above). A new chat message should be
sent each time the user enters <return>
or 128
characters, whichever comes first.
If chat
receives a reject message (i.e., type
"RRRR
" message, see above), it should print the message
chat request rejected ... exitingthen remove its FIFO and exit normally.
After a session is started in active mode, chat
will behave
as just as it does in passive mode after a session is started.
You will turn in both a hard copy and an electronic copy of your assignment. Please follow the instructions on how to send electronic copies. Do not send them to my email address.
Both the hard copy and the electronic copy will contain a write-up and
all source code you used in this project. The electronic copy will also
contain the executable version of your code. The electronic copy of your
write-up should not be in a proprietary format (such as MS Word); it should
be either in plain ASCII text or in a portable format (such as Postscript
or PDF). Your source code should either be in a single file called
chat.c
(or chat.cxx
) or in several files that
can be compiled and linked using make
. In the latter case,
chat.c
(or chat.cxx
) will contain the
function main()
and you will include your makefile and it will
be named makefile
. Your executable code should be called
chat
.
Your source code should be well structured and well commented. It should conform to good coding standards (e.g., no memory leaks).
Your write-up will include 1/2 to 1 page (roughly 80 characters per line, 50 lines per page) explaining the data structures and algorithms used in your code. This page limitation does not include figures used in your explanation, which are encouraged and may take up any amount of space. (This explanation does not remove the requirement that your code be well commented.)
You may write your program from scratch or may start from programs for which the source code is freely available on the web or through other sources (such as friends or student organizations). If you do not start from scratch, you must give a complete and accurate accounting of where all of your code came from and indicate which parts are original or changed, and which you got from which other source. Failure to give credit where credit is due is academic fraud and will be dealt with accordingly.
As noted in the syllabus, you are required to work on this programming assignment in a group of at least two people. It is your responsibility to find other group members and work with them. The group should turn in only one (1) hard copy and one (1) electronic copy of the assignment. Both the electronic and hard copies should contain the names and student ID numbers of all group members. If your group composition changes during the course of working on this assignment (for example, a group of five splits into a group of two and a separate group of three), this must be clearly indicated in your write-up, including the names and student ID numbers of everyone involved.
Each group member is required to contribute equally to each project, as far as is possible. You must thoroughly document which group members were involved in each part of the project. For example, if you have three functions in your program and one function was written by group member one, the second was written by group member two, and the third was written jointly and equally by group members three and four, both your write-up and the comments in your code must clearly indicate this division of labor.