Change to using <module>/h/*.h
[dyninst.git] / common / src / rpcUtil.C
1
2 //
3 // This file defines a set of utility routines for RPC services.
4 //
5 //
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <errno.h>
9 #include <assert.h>
10 #include <sys/types.h>
11 #include <sys/socket.h>
12
13 extern "C" {
14 #include <rpc/types.h>
15 #include <rpc/xdr.h>
16 }
17 #include "util/h/rpcUtil.h"
18
19 int RPCdefaultXDRRead(int handle, char *buf, u_int len)
20 {
21     int ret;
22
23     do {
24         ret = read(handle, buf, len);
25     } while (ret < 0 && errno == EINTR);
26
27     if (ret <= 0) return(-1);
28     return (ret);
29 }
30
31 int RPCdefaultXDRWrite(int handle, char *buf, u_int len)
32 {
33     int ret;
34
35     do {
36         ret = write(handle, buf, len);
37     } while (ret < 0 && errno == EINTR);
38     assert(ret == len);
39     return (ret);
40 }
41
42 //
43 // prepare for RPC's to be done/received on the passed fd.
44 //
45 XDRrpc::XDRrpc(int f, xdrIOFunc readRoutine, xdrIOFunc writeRoutine)
46 {
47     fd = f;
48     __xdrs__ = (XDR *) malloc(sizeof(XDR));
49     if (!readRoutine) readRoutine = RPCdefaultXDRRead;
50     if (!writeRoutine) writeRoutine = RPCdefaultXDRWrite;
51     (void) xdrrec_create(__xdrs__, 0, 0, (char *) fd, readRoutine,writeRoutine);
52 }
53
54
55 //
56 // prepare for RPC's to be done/received on the passed fd.
57 //
58 XDRrpc::XDRrpc(char *machine,
59                char *user,
60                char *program,
61                xdrIOFunc readRoutine, 
62                xdrIOFunc writeRoutine)
63 {
64     fd = RPCprocessCreate(machine, user, program);
65     if (fd >= 0) {
66         __xdrs__ = (XDR *) malloc(sizeof(XDR));
67         if (!readRoutine) readRoutine = RPCdefaultXDRRead;
68         if (!writeRoutine) writeRoutine = RPCdefaultXDRWrite;
69         (void) xdrrec_create(__xdrs__, 0, 0, (char *) fd, 
70                 readRoutine, writeRoutine);
71     } else {
72         __xdrs__ = NULL;
73         fd = -1;
74     }
75 }
76
77 //
78 // prepare for RPC's to be done/received on the passed thread id.
79 //
80 THREADrpc::THREADrpc(int thread)
81 {
82     tid = thread;
83 }
84
85 //
86 // This should never be called, it should be replaced by a virtual function
87 //    from the derived class created by igen.
88 //
89 void RPCUser::verifyProtocolAndVersion()
90 {
91     abort();
92 }
93
94 //
95 // our version of string encoding that does malloc as needed.
96 //
97 bool_t xdr_String(XDR *xdrs, String *str)
98 {
99     int len;
100
101     if (xdrs->x_op == XDR_ENCODE) {
102         len = strlen(*str);
103     } else {
104         *str = NULL;
105     }
106     // should we have a better max length ???. 
107     xdr_bytes(xdrs, str, &len, 65536*32768);
108     return(TRUE);
109 }
110
111 int RPCprocessCreate(char *hostName, char *userName, char *command)
112 {
113     int ret;
114     int pid;
115     int sv[2];
116     int execlERROR;
117
118     if (!hostName || !strcmp(hostName, "") || !strcmp(hostName, "localhost")) {
119         ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
120         if (ret) return(ret);
121         execlERROR = 0;
122         pid = vfork();
123         if (pid == 0) {
124             close(sv[0]);
125             dup2(sv[1], 0);
126             execl(command, command);
127             execlERROR = errno;
128             _exit(-1);
129         } else if (pid > 0 && !execlERROR) {
130             close(sv[1]);
131             return(sv[0]);
132         } else {
133             return(-1);
134         }
135     } else {
136         // need to rsh to machine and setup io path.
137         printf("remote starts not implemented\n");
138         exit(-1);
139     }
140 }
141
142 //
143 // wait for an expected RPC responce, but also handle upcalls while waiting.
144 //    Should not be called directly !!!
145 //
146 void RPCUser::awaitResponce(int tag)
147 {
148     abort();
149 }