JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
ONC+ Developer's Guide     Oracle Solaris 11.1 Information Library
search filter icon
search icon

Document Information

Preface

1.  Introduction to ONC+ Technologies

2.  Introduction to TI-RPC

3.  rpcgen Programming Guide

4.  Programmer's Interface to RPC

5.  Advanced RPC Programming Techniques

6.  Porting From TS-RPC to TI-RPC

Porting an Application

Benefits of Porting

IPv6 Considerations for RPC

Porting Issues

Differences Between TI-RPC and TS-RPC

Function Compatibility Lists

Creating and Destroying Services

Registering and Unregistering Services

Compatibility Calls

Broadcasting

Address Management Functions

Authentication Functions

Other Functions

Comparison Examples

7.  Multithreaded RPC Programming

8.  Extensions to the Oracle Solaris RPC Library

A.  XDR Technical Note

B.  RPC Protocol and Language Specification

C.  XDR Protocol Specification

D.  RPC Code Examples

E.  portmap Utility

Glossary

Index

Comparison Examples

The changes in client creation from TS-RPC to TI-RPC are illustrated in Example 6-1 and Example 6-2. Each example:

Example 6-1 Client Creation in TS-RPC

    struct hostent *h;
    struct sockaddr_in sin;
    int sock = RPC_ANYSOCK;
    u_short port;
    struct timeval wait;

    if ((h = gethostbyname( "host" )) == (struct hostent *) NULL)
{
        syslog(LOG_ERR, "gethostbyname failed");
        exit(1);
    }
    sin.sin_addr.s_addr = *(u_int *) hp->h_addr;
    if ((port = pmap_getport(&sin, PROGRAM, VERSION, "udp")) == 0) {
        syslog (LOG_ERR, "pmap_getport failed");
        exit(1);
    } else
        sin.sin_port = htons(port);
    wait.tv_sec = 25;
    wait.tv_usec = 0;
    clntudp_create(&sin, PROGRAM, VERSION, wait, &sock);

The TI-RPC version of client creation, shown in the following example, assumes that the UDP transport has the netid udp. A netid is not necessarily a well-known name.

Example 6-2 Client Creation in TI-RPC

    struct netconfig *nconf;
    struct netconfig *getnetconfigent();
    struct t_bind *tbind;
    struct timeval wait;

    nconf = getnetconfigent("udp");
    if (nconf == (struct netconfig *) NULL) {
        syslog(LOG_ERR, "getnetconfigent for udp failed");
        exit(1);
    }
    fd = t_open(nconf->nc_device, O_RDWR, (struct t_info *)NULL);
    if (fd == -1) {
        syslog(LOG_ERR, "t_open failed");
        exit(1);
    }
    tbind = (struct t_bind *) t_alloc(fd, T_BIND, T_ADDR);
    if (tbind == (struct t_bind *) NULL) {
        syslog(LOG_ERR, "t_bind failed");
        exit(1);
    }
    if (rpcb_getaddr( PROGRAM, VERSION, nconf, &tbind->addr, "host")
                                == FALSE) {
        syslog(LOG_ERR, "rpcb_getaddr failed");
        exit(1);
    }
    cl = clnt_tli_create(fd, nconf, &tbind->addr, PROGRAM, VERSION,
                          0, 0);
    (void) t_free((char *) tbind, T_BIND);
    if (cl == (CLIENT *) NULL) {
        syslog(LOG_ERR, "clnt_tli_create failed");
        exit(1);
    }
    wait.tv_sec = 25;
    wait.tv_usec = 0;
    clnt_control(cl, CLSET_TIMEOUT, (char *) &wait);

Example 6-3 and Example 6-4 show the differences between broadcast in TS-RPC and TI-RPC. The older clnt_broadcast() is similar to the newer rpc_broadcast(). The primary difference is in the collectnames() function: it deletes duplicate addresses and displays the names of hosts that reply to the broadcast.

Example 6-3 Broadcast in TS-RPC

statstime sw;
extern int collectnames();

clnt_broadcast(RSTATPROG, RSTATVERS_TIME, RSTATPROC_STATS,         
        xdr_void, NULL, xdr_statstime, &sw, collectnames);
    ...
collectnames(resultsp, raddrp)
    char *resultsp;
    struct sockaddr_in *raddrp;
{
    u_int addr;
    struct entry *entryp, *lim;
    struct hostent *hp;
    extern int curentry;

    /* weed out duplicates */
    addr = raddrp->sin_addr.s_addr;
    lim = entry + curentry;
    for (entryp = entry; entryp < lim; entryp++)
        if (addr == entryp->addr)
            return (0);
    ...
    /* print the host's name (if possible) or address */
    hp = gethostbyaddr(&raddrp->sin_addr.s_addr, sizeof(u_int),
        AF_INET);
    if( hp == (struct hostent *) NULL)
        printf("0x%x", addr);
    else
        printf("%s", hp->h_name);
}

The following code example shows broadcast in TI-RPC.

Example 6-4 Broadcast in TI-RPC

statstime sw;
extern int collectnames();

rpc_broadcast(RSTATPROG, RSTATVERS_TIME, RSTATPROC_STATS,
     xdr_void, NULL, xdr_statstime, &sw, collectnames, (char *)
0);
    ...

collectnames(resultsp, taddr, nconf)
    char *resultsp;
    struct t_bind *taddr;
    struct netconfig *nconf;
{
    struct entry *entryp, *lim;
    struct nd_hostservlist *hs;
    extern int curentry;
    extern int netbufeq();

    /* weed out duplicates */
    lim = entry + curentry;
    for (entryp = entry; entryp < lim; entryp++)
        if (netbufeq( &taddr->addr, entryp->addr))
            return (0);
    ...
    /* print the host's name (if possible) or address */
    if (netdir_getbyaddr( nconf, &hs, &taddr->addr ) == ND_OK)
        printf("%s", hs->h_hostservs->h_host);
    else {
        char *uaddr = taddr2uaddr(nconf, &taddr->addr);
        if (uaddr) {
            printf("%s\n", uaddr);
            (void) free(uaddr);
        } else
            printf("unknown");
    }
}
netbufeq(a, b)
    struct netbuf *a, *b;
{
    return(a->len == b->len && !memcmp( a->buf, b->buf, a->len));
}