|
|
|
C BSD RunCopyright © 1998 Matthew AltonWelcome back to C BSD Run. In last month's installment we briefly examined the ctags utility and began an examination of the source code for the ftp client program. Newcomers to the column should have a look at the material from last month before continuing here. We continue our study of the main.c file at line 86. Invoking the vi editor in this manner:
we reorient ourselves thusly:
Last month we left off just before being initiated into the wonderful world of network programming - the paradigm at the heart of internet technology. Our first network-oriented construct is declared above as
This structure is defined in the header file /usr/include/netdb.h as
ftp 21/tcp #File Transfer [Control] ftp 21/udp #File Transfer [Control] The character array element s_name will contain the name "ftp". The 2-dimensional array s_aliases will contain optional aliases to this service name. The "port" is defined to be a two-byte integer stored, or at any rate transmitted, in a "network order" format. We'll delve deeper into byte-order later when we encounter the htons() and related functions. Finally, the s_proto array will store the network protocol for use in communication with remote hosts. The /etc/services lines above inform the system software that ftp control transactions will be conducted on port number 21 and that both TCP (Transport Control Protocol) and UDP (User Datagram Protocol) connections will be accepted. The choice of port number is not arbitrary. Services which are to be in general use on the network use so-called "well-known ports". These are registered with and assigned by the governing bodies of the internet. Our application may therefore safely assume that a network ftp listener will be waiting for ftp connections on port 21. Also listed in the /etc/services file are the following lines
ftp-data 20/tcp #File Transfer [Default Data] ftp-data 20/udp #File Transfer [Default Data] These lines assign data ports for the ftp service. Port number 20 is, by default, the port through which the actual file data will be transmitted. The first network-oriented function called by the ftp client program is
The getservbyname() function is a system networking call which returns a pointer to a servent structure. We pass it the arguments to request an ftp service using the tcp protocol. The function will return NULL upon failure. Notice how this BSD application checks the value of sp immediately after the function call returns. Checking the return values of system calls is critical to the soundness of UNIX applications. If we were merely to assume that sp held a valid pointer in all cases, the application might attempt to dereference out-of-bounds memory and fail ungracefully. This seeming unreliability of the system calls is actually evidence of a very sound and flexible underlying strategy. Because our application is expected to run reliably and consistently in all means of adverse systemic conditions ranging from memory starvation to network connectivity failure, we the programmers are given the freedom to proceed in the event of failure as we see fit. This simple scheme accounts for much of the great power and stability of UNIX. With freedom, however, comes responsibility. Always check function return values and plan for failure.
Here, if we are unable to determine the ftp port from the getservbyname() function directly, we make an educated guess. The next few lines perform the same action for the http (HyperText Transport Protocol), the protocol fundamental to the World Wide Web. Lines 96 through 112 attempt to find a useful value for the gateport integer. Notice the line
97 cp = getenv("FTPSERVERPORT");
which attempts to obtain information relevant to the ftp service from the user environment. This is typical and good UNIX program behavior, providing the user with with a convenient means of altering the default or otherwise determined values of important variables. Notice also
109 gateport = htons(GATE_PORT); We arrive at the htons() function mentioned above. Network protocols are designed to be portable between radically differing hardware architectures. One of the chief considerations in system architectures is the manner in which numbers will be stored in memory. While the various storage methods employed are not typically directly relevant to the applications programmer writing code for use on a single system, they are mutually incomaptible and all data must consequently be brought into accord before being transferred between systems of arbitrary construction. The htons() (host to network short) and related functions are system-dependent mechanisms used to standardize numeric data for network transmission. Food for thought: What is "Endianness"? Why? We will continue our discussion of the ftp application next month in C FreeBSD Run. Happy Hacking!
Matthew Alton, alton@plantnet.com
|
||