10.3 Sending LISTSERV commands directly from your application
The lcmdx program is convenient, as it doesn’t require programming to use, but it does not allow much flexibility in how your application can react to LISTSERV’s responses to the commands sent. For greater flexibility, you can integrate the techniques used in lcmdx for communicating with LISTSERV directly into your application.
The lcmdx source code consists of three C functions:
- receive - used by LSV_send_command to receive a string of a given length from a socket
- LSV_send_command - the function that sends a command from LISTSERV and returns the answer; this function can be used directly by your application with few or no changes.
- main - the main function simply parses the command line for lcmdx into its component parts, passes them to LSV_send_command, and prints LISTSERV’s response; your application would replace main.
The primary change that you may want to make to the LSV_send_command function will be to have it write the LISTSERV response to a string (or an array of strings) rather than to a file, as is the case in lcmdx. What you actually do with LISTSERV’s response will be dictated by the needs of your application.
The only other changes that might be required are changes that relate to how sockets are implemented on your operating system. For example, if you are using Windows sockets (WINSOCK), you would have to add the Windows sockets initialization code at the start of your application, calling and checking the status of the WSAStartup routine; and the cleanup code at the end, calling the routine WSACleanup. With Windows sockets, you would also have to include the header file <winsock.h> instead of <sys/socket.h>, <netdb.h>, and <netinet/in.h>; and replace the call to close(ss) with a call to closesocket(ss).
The LSV_send_command function uses the following calling sequence:
int LSV_send_command(char *hostname, unsigned short port,
char *origin, char *pw, char *command, FILE *writeto)
where the return value is:
- 0 if the command was sent and the answer received without a problem, from a TCP/ IP point of view - this does not indicate that the command itself was successfully executed by LISTSERV: your application needs to look at the answer received from LISTSERV to determine whether the command itself was successful;
- 1000 if a protocol error occurred while communicating with LISTSERV;
- a socket error code if a socket error occurred while communicating with LISTSERV - the socket errors should be described in the documentation for socket functions for your C compiler.
and the parameters are:
- hostname - a pointer to a character array containing the name of the LISTSERV host to which to send the command
- port - the port number to which to connect (use 2306 unless otherwise specified in the site configuration file of the LISTSERV host)
- origin - a pointer to a character array containing the e-mail address of the “originator” of the command
- pw - a pointer to a character array containing the LISTSERV password registered for the originator’s e-mail address (must be UPPER CASE)
- command - a pointer to a character array containing the one-line command to send to LISTSERV
- writeto - a pointer to the file in which to write LISTSERV’s response; as mentioned above, depending on the needs of your application, you may want to change this parameter and the code within LSV_send_command that writes to this file.
Of course, if you use LSV_send_command without modification, you will be opening and closing a connection to LISTSERV for each command you send. You can make your application more efficient by opening up a connection to LISTSERV and sending a series of commands before closing the connection again. The LSV_send_command function will work “out of the box”, but an experienced programmer can use it as a guide for developing customized functions for working with the TCPGUI interface.