3 // This file defines a set of utility routines for RPC services.
7 // overcome malloc redefinition due to /usr/include/rpc/types.h declaring
11 #define MALLOC_DEFINED_AS_VOID
14 #include "util/h/rpcUtil.h"
16 int RPCdefaultXDRRead(int handle, char *buf, u_int len)
21 ret = read(handle, buf, len);
22 } while (ret < 0 && errno == EINTR);
24 if (ret <= 0) return(-1);
28 int RPCdefaultXDRWrite(int handle, char *buf, u_int len)
33 ret = write(handle, buf, len);
34 } while (ret < 0 && errno == EINTR);
43 fcntl (fd, F_SETFL, FNDELAY);
48 xdr_destroy (__xdrs__);
54 // prepare for RPC's to be done/received on the passed fd.
56 XDRrpc::XDRrpc(int f, xdrIOFunc readRoutine, xdrIOFunc writeRoutine, int nblock)
60 if (!readRoutine) readRoutine = RPCdefaultXDRRead;
61 if (!writeRoutine) writeRoutine = RPCdefaultXDRWrite;
62 (void) xdrrec_create(__xdrs__, 0, 0, (char *) fd, readRoutine,writeRoutine);
64 fcntl (fd, F_SETFL, FNDELAY);
68 // prepare for RPC's to be done/received on the passed fd.
70 XDRrpc::XDRrpc(char *machine,
73 xdrIOFunc readRoutine,
74 xdrIOFunc writeRoutine,
78 fd = RPCprocessCreate(&pid, machine, user, program, arg_list);
81 if (!readRoutine) readRoutine = RPCdefaultXDRRead;
82 if (!writeRoutine) writeRoutine = RPCdefaultXDRWrite;
83 (void) xdrrec_create(__xdrs__, 0, 0, (char *) fd,
84 readRoutine, writeRoutine);
86 fcntl (fd, F_SETFL, FNDELAY);
94 RPC_readReady (int fd)
99 tvptr.tv_sec = 0; tvptr.tv_usec = 0;
100 if (fd < 0) return -1;
102 FD_SET (fd, &readfds);
103 if (select (fd+1, &readfds, NULL, NULL, &tvptr) == -1)
105 // if (errno == EBADF)
108 return (FD_ISSET (fd, &readfds));
112 RPC_undo_arg_list (int argc, char **arg_list, char **machine, int *family,
113 int *type, int *well_known_socket, int *flag)
117 int ret = 0, sum = 0;
119 for (loop=0; loop < argc; ++loop)
121 if (!strncmp(arg_list[loop], "-p", 2))
123 *well_known_socket = (int) strtol (arg_list[loop] + 2, &ptr, 10);
128 else if (!strncmp(arg_list[loop], "-f", 2))
130 *family = (int) strtol (arg_list[loop] + 2, &ptr, 10);
135 else if (!strncmp(arg_list[loop], "-t", 2))
137 *type = (int) strtol (arg_list[loop] + 2, &ptr, 10);
142 else if (!strncmp(arg_list[loop], "-m", 2))
144 *machine = strdup (arg_list[loop] + 2);
145 if (!(*machine)) return -1;
148 else if (!strncmp(arg_list[loop], "-l", 2))
150 *flag = (int) strtol (arg_list[loop] + 2, &ptr, 10);
156 if (sum == (16 + 8 + 4 + 2 + 1))
163 RPC_make_arg_list (char *program, int family, int type, int well_known_socket,
169 char machine_name[50];
171 arg_list = new char*[7];
172 arg_list[arg_count++] = strdup (program);
173 sprintf(arg_str, "%s%d", "-p", well_known_socket);
174 arg_list[arg_count++] = strdup (arg_str);
175 sprintf(arg_str, "%s%d", "-f", family);
176 arg_list[arg_count++] = strdup (arg_str);
177 sprintf(arg_str, "%s%d", "-t", type);
178 arg_list[arg_count++] = strdup (arg_str);
179 gethostname (machine_name, 49);
180 sprintf(arg_str, "%s%s", "-m", machine_name);
181 arg_list[arg_count++] = strdup (arg_str);
182 sprintf(arg_str, "%s%d", "-l", flag);
183 arg_list[arg_count++] = strdup (arg_str);
184 arg_list[arg_count++] = 0;
188 // returns fd of socket that is listened on, or -1
190 RPC_setup_socket (int *sfd, // return file descriptor
191 int family, // AF_INET ...
192 int type) // SOCK_STREAM ...
194 struct sockaddr_in serv_addr;
198 if (gethostname(machine, 49) != 0)
201 if ((*sfd = socket(family, type, 0)) < 0)
204 bzero ((char *) &serv_addr, sizeof(serv_addr));
205 serv_addr.sin_family = (short) family;
206 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
207 serv_addr.sin_port = htons(0);
209 length = sizeof(serv_addr);
211 if (bind(*sfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
214 if (getsockname (*sfd, (struct sockaddr *) &serv_addr, &length) < 0)
217 if (listen(*sfd, 5) < 0)
220 return (ntohs (serv_addr.sin_port));
224 // connect to well known socket
226 XDRrpc::XDRrpc(int family,
230 xdrIOFunc readRoutine,
231 xdrIOFunc writeRoutine,
233 // socket, connect using machine
237 struct sockaddr_in serv_addr;
238 struct hostent *hostptr = 0;
239 struct in_addr *inadr = 0;
243 if ( (hostptr = gethostbyname(machine)) == 0)
246 inadr = (struct in_addr *) hostptr->h_addr_list[0];
247 bzero ((char *) &serv_addr, sizeof(serv_addr));
248 serv_addr.sin_family = family;
249 serv_addr.sin_addr = *inadr;
250 serv_addr.sin_port = htons(req_port);
252 if ( (fd = socket(family, type, 0)) < 0)
255 if (connect(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
259 if (!readRoutine) readRoutine = RPCdefaultXDRRead;
260 if (!writeRoutine) writeRoutine = RPCdefaultXDRWrite;
261 (void) xdrrec_create(__xdrs__, 0, 0, (char *) fd, readRoutine,writeRoutine);
263 fcntl (fd, F_SETFL, FNDELAY);
268 // prepare for RPC's to be done/received on the passed thread id.
270 THREADrpc::THREADrpc(int thread)
276 // This should never be called, it should be replaced by a virtual function
277 // from the derived class created by igen.
279 void RPCUser::verifyProtocolAndVersion()
285 // our version of string encoding that does malloc as needed.
287 bool_t xdr_String(XDR *xdrs, String *str)
291 // if XDR_FREE, str's memory is freed
292 switch (xdrs->x_op) {
294 len = strlen(*str)+1;
300 // xdr_free (xdr_string, str);
309 // this should never occur
311 // should we have a better max length ???.
312 // xdr_bytes(xdrs, str, &len, 65536*32768);
314 return (xdr_string (xdrs, str, 65536));
317 int RPCprocessCreate(int *pid, char *hostName, char *userName,
318 char *command, char **arg_list)
324 if (!hostName || !strcmp(hostName, "") || !strcmp(hostName, "localhost")) {
325 ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
326 if (ret) return(ret);
333 execl(command, command);
335 execv(command, arg_list);
338 } else if (*pid > 0 && !execlERROR) {
345 // need to rsh to machine and setup io path.
346 printf("remote starts not implemented\n");
352 // wait for an expected RPC responce, but also handle upcalls while waiting.
353 // Should not be called directly !!!
355 void RPCUser::awaitResponce(int tag)
361 XDRrpc::setNonBlock()
364 fcntl (fd, F_SETFL, FNDELAY);
370 return RPC_readReady (fd);
374 RPC_getConnect(int fd)
377 struct in_addr cli_addr;
383 clilen = sizeof(cli_addr);
385 if ((new_fd = accept (fd, (struct sockaddr *) &cli_addr, &clilen)) < 0)