Executing Remote Commands in a Program
The library function rexec can be used in a program to execute a system-level command on a remote host. In many ways we can think of the rexec library function as a remote version of the system call system that was discussed earlier, as it allows us to request the execution of a command on a remote system. The syntax for rexec is summarized in Table 9.1.
Table 9.1. Summary of the rexec Library Call.
Include File(s) |
Manual Section |
3 |
|||
Summary |
int rexec( char **ahost, unsigned short inport, char *user, char *passwd, char *cmd, int *fd2p ); |
||||
Return |
Success |
Failure |
Sets errno |
||
A stream socket file descriptor |
-1 |
The rexec library call takes six arguments. The first is a reference to the name of the remote host. This reference is passed by rexec to the gethostbyname network call for authentication (the details of the gethostbyname function are covered in Chapter 10). The second argument, inport , is an integer value that indicates the port to be used for the connection. Most often, the port number used with rexec is 512 (the port associated with the execution of remote commands, using TCP protocol). The port argument is followed by two character-string reference arguments that indicate the user's name and password respectively. If these entries are set to NULL, the system checks the contents of the file . netrc that resides in the user's home directory for machine (host), login (user name), and password information. If the $HOME/.netrc file does not exist or it contains only partial information, the user is prompted for his or her name and/or password. The sixth argument to rexec is a reference to an integer. If this value is not 0, rexec assumes it is a reference to a valid file descriptor and maps a standard error from the execution of the remote command to the indicated file descriptor. If the rexec command is successful, it returns a valid stream socket file descriptor that is mapped to the local host's standard input and output. If the rexec function fails, it returns a -1.
Program 9.1 demonstrates the use of the rexec library call.
Program 9.1 Using rexec in a program.
[View full width]
File : p9.1.cxx Note that on some systems you may need to
In Program 9.1 the first command-line argument is the host on which the remote command will be executed. The second command-line argument is the command that will be passed to the remote host. The invocation of the rexec function (line 22) uses the htons network call on its second argument to ensure the proper network byte ordering when specifying the port number. [3] The prototype for htons resides in the include file . The arguments for the user name and password are set to NULL. This directs rexec to first check the .netrc file in the owner's home directory for user name and password information. If the .netrc file is not present or is incomplete, rexec prompts the user for this information. Note that while this is technically how things should work, on our system (running Red Hat Linux version 7.1) unless the .netrc file is present and its contents complete (includes the host and the user's login and password), the rexec call will fail. In a weak attempt to gain at least a semblance of security, rexec will read .netrc files whose permissions are read only for the file's owner. If the rexec call completes without error, the output from the execution of the command on the remote host is read and displayed to standard output on the local host. Figure 9.4 shows a compilation and run of Program 9.1. Note in some versions of the OS the library -lnsl and/or -lsocket may need to be included as the object code for the network functions may reside in these separate libraries.
[3] On i80x86 platforms the host byte order is LSB (least significant byte first), while on the Internet the byte order is MSB (most significant byte first).
Figure 9.4 Using Program 9.1.
linux$ g++ p9.1.cxx -o p9.1 linux$ p9.1 morpheus df / (/dev/dsk/c0t0d0s0 ): 1066026 blocks 241598 files /usr (/dev/dsk/c0t0d0s4 ): 3538746 blocks 384628 files /proc (/proc ): 0 blocks 3768 files /dev/fd (fd ): 0 blocks 0 files /etc/mnttab (mnttab ): 0 blocks 0 files . . .
The rexec function communicates with rexecd (the remote execution daemon) on the host system. While the rexec function is interesting and does provide a somewhat painless (but generally insecure ) way to execute commands on a remote host, we more frequently will want to write our own client server pairs that will perform specific, directed tasks .
To round out the discussion, a command-line version of rexec can also be found in Linux. Usually, it resides in the /usr/bin directory. Its general syntax is
linux$ rexec [options] -l user_name -p password host the_command
Unlike its library function counterpart , the command-line version of rexec does not seem to choke if the user's .netrc file is not fully qualified, and it will know enough to prompt if a user's login or password are omitted.