Jump to content United States-English
HP.com Home Products and Services Support and Drivers Solutions How to Buy
» Contact HP
More options
HP.com home
HP-UX Reference > R


HP-UX 11i Version 3: February 2007

Technical documentation

» Feedback
Content starts here

 » Table of Contents

 » Index


rcmd(), rcmd_af(), rresvport(), rresvport_af(), ruserok() — return a stream to a remote command


int rcmd( char **ahost, int remport, const char *locuser, const char *remuser, const char *cmd, int *fd2p); int rcmd_af( char **ahost, int remport, const char *locuser, const char *remuser, const char *cmd, int *fd2p, int af); int rresvport(int *port); int rresvport_af(int *port,int af); int ruserok( const char *rhost, int superuser, const char *ruser, const char *luser);



The rcmd() function is used by privileged programs to execute a command on a remote host. rcmd() returns a file descriptor for the socket to which the standard input and standard output of the command are attached. A command level interface to rcmd() is provided by remsh (see remsh(1)), which is the same as the BSD rsh command.

ahost is a pointer to the address of the remote host name. The name of the remote host can be either an official host name or an alias as understood by gethostbyname() (see gethostent(3N), named(1M), and hosts(4)).

remport is the Internet port on the remote system, which rcmd() will try to connect to.

locuser and remuser point to the user login name on the local host and on the remote host, respectively. The names are used by the server on the remote host to authenticate the user (see ruserok() below).

cmd points to a string that specifies the command to be executed on the remote host.

fd2p is a pointer to an integer (it can be a NULL pointer).

rcmd() looks up the host *ahost using gethostbyname(), returning -1 if the host does not exist. Otherwise, *ahost is set to the standard name of the host and a connection is established to a server accepting requests at the port remport. If the connection is refused after five tries, or if it was refused for a reason other than the port being in use, rcmd() returns -1.

If the call succeeds, a socket of type SOCK_STREAM is returned to the caller and given to the remote command as stdin and stdout. If fd2p is non-NULL, rcmd() opens a second socket between the calling process (local) and the control process (remote), and places its descriptor in *fd2p. On this connection, the control process sends the diagnostic output (stderr) from cmd to the calling process, and receives UNIX signals from the calling process, to be forwarded to cmd. If the auxiliary port cannot be set up, rcmd() returns -1. If fd2p is NULL, stderr of the remote command is made the same as stdout, and no provision is made for sending arbitrary signals to the remote process.

The protocol is described in detail in remshd(1M).

Any program using rcmd() must be run as superuser.


rcmd_af() function behaves the same as rcmd(), but it can also create an AF_INET6 TCP socket. The type of socket to be created is specified through the af argument. rcmd_af() fails with EAFNOSUPPORT if the address family af is not supported.


The rresvport() function creates a socket and binds it to a reserved port. This socket is suitable for use by rcmd() and several other routines.

The caller is expected to set the initial value of *port to a number between 512 and IPPORT_RESERVED-1. (The value of IPPORT_RESERVED is defined in netinet/in.h and is 1024.) Typically, the initial value of *port is set to IPPORT_RESERVED-1. If the value is outside the valid range, rresvport() resets it silently to IPPORT_RESERVED-1. The function uses the inital value of *port as the first port number that it tries to bind to the created socket. If the operation fails, rresvport() decrements *port and attempts to bind the new port number to the socket. The process is repeated until either the operation succeeds, or the port numbers between 512 and IPPORT_RESERVED-1 are exhausted.

If the call succeeds, the socket descriptor is returned to the caller and the port number is returned in the location pointed to by port. If the call fails, -1 is returned to the caller.

The socket returned by rresvport() has the SO_KEEPALIVE option on.

Only the superuser is permitted to bind a privileged address to a socket. Therefore, any program using rresvport() must be run as superuser.


rresvport_af() function behaves the same as rresvport(), but it can also create an AF_INET6 TCP socket. The type of socket to be created is specified through the af argument. rresvport_af() fails with EAFNOSUPPORT if the address family af is not supported.


The ruserok() function is used by servers to authenticate clients requesting service with rcmd(). ruserok() verifies that ruser on rhost is authorized to act as luser on the local host.

superuser is an integer flag that should be nonzero if the local user name corresponds to a superuser. If the superuser flag is not set, ruserok() first checks the file /etc/hosts.equiv to authenticate the request for service. If this check succeeds, ruserok() returns 0. If the superuser flag is set, or if there is no file /etc/hosts.equiv, or if the check fails, ruserok() then checks the file .rhosts (if there is one) in the local user's home directory. ruserok() returns 0 if this check succeeds. Otherwise, it returns -1.

Typically, the file /etc/hosts.equiv contains a list of host names, and users' .rhosts files contain host-name/user-name pairs. A remote user is authenticated by ruserok() if the remote host name appears in /etc/hosts.equiv and the remote user name and local user name are the same, or if the remote host name and the remote user name appear together in .rhosts in the home directory of the local user.

For a complete explanation of the syntax understood by ruserok(), see hosts.equiv(4).


rcmd() Diagnostic Messages

rcmd() generates the following diagnostic messages.

hostname: Unknown host

gethostbyname was unable to find an entry in the hosts database matching the name of the server (see gethostent(3N) and hosts(4)).

Next step: Have the system administrator of your host check whether the remote host's entry is in the hosts database (see hosts(4)).

connect: hostname: ...

Unable to establish a connection to the reserved port. A message that specifies the reason for the failure is appended to this diagnostic message.

write: Setting up stderr

Error writing to the socket connection set up for error message transmission.

system call: ...

Error executing the system call. Appended to this error is a message specifying the reason for the failure.

socket: Protocol failure in circuit setup

Socket connection not established on a reserved port or socket address not of the Internet family type.

read: hostname: ...

Error in reading information from the standard socket connection. Appended to this error is a message explaining the reason for the error.

Connection timeout

The remote host did not connect within 30 seconds to the secondary socket set up as an error connection.

Lost connection

The program attempted to read from the socket and failed. This means the socket connection with the remote host was lost.


An error message can be transmitted through the socket connection from the daemon. That message will be sent to stderr.

primary connection shutdown

While waiting for the secondary socket to be set up, rcmd() had its primary connection shut down. This may have been caused by an inetd security failure.

recv: ...

While trying to set up the secondary (stderr) socket, rcmd() had an error condition on its primary connection.

accept: Interrupted system call

While trying to set up its secondary socket, rcmd() ran out of some resource that caused the accept to be timed out.

Next step: Repeat the command.

rresvport() Diagnostic Messages

rresvport() generates the following diagnostic messages. These messages can also appear in rcmd() since rcmd() calls rresvport().

system call: ...

Error in executing the system call. The error message returned by the system call is appended to the message.

socket: All ports in use

All reserved ports in use. If a timeout occurs, check whether the Internet Services are installed and inetd is running.


To execute the date command on remote host hpxzgy using the remote account chm, call rcmd() as shown below. This program requires superuser privileges and the remote account must be equivalent (see hosts.equiv(4)) to the local account that runs the program.

#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <pwd.h> struct passwd *getpwuid(); char *host[] = { "hpxzgy" }; char *cmd = "date"; char *ruser = "chm"; main(argc,argv) int argc; char **argv; { struct servent *sp; struct passwd *pwd; FILE *fp; char ch; int rem; sp = getservbyname("shell","tcp"); pwd = getpwuid(getuid()); rem = rcmd(host, sp->s_port, pwd->pw_name, ruser, cmd, 0); if (rem < 0) exit(1); /* rcmd outputs its own error messages */ fp = fdopen(rem, "r"); while ((ch = getc(fp)) != EOF) putchar(ch); }


There is no way to specify options to the socket() call that rcmd() makes. Since rcmd() replaces the pointer to the host name (*ahost) with a pointer to the standard name of the host in a static data area, this value must be copied into the user's data area if it is to be used later. Otherwise, unpredictable results will occur.


rcmd() was developed by the University of California, Berkeley.

Printable version
Privacy statement Using this site means you accept its terms Feedback to webmaster
© 1983-2007 Hewlett-Packard Development Company, L.P.