3 // This file defines a set of utility routines for RPC services.
7 // overcome malloc redefinition due to /usr/include/rpc/types.h declaring
10 #include "util/h/rpcUtil.h"
12 int RPCdefaultXDRRead(int handle, char *buf, u_int len)
17 ret = read(handle, buf, len);
18 } while (ret < 0 && errno == EINTR);
20 if (ret <= 0) return(-1);
24 int RPCdefaultXDRWrite(int handle, char *buf, u_int len)
29 ret = write(handle, buf, len);
30 } while (ret < 0 && errno == EINTR);
39 fcntl (fd, F_SETFL, FNDELAY);
44 xdr_destroy (__xdrs__);
50 // prepare for RPC's to be done/received on the passed fd.
52 XDRrpc::XDRrpc(int f, xdrIOFunc readRoutine, xdrIOFunc writeRoutine, int nblock)
56 if (!readRoutine) readRoutine = RPCdefaultXDRRead;
57 if (!writeRoutine) writeRoutine = RPCdefaultXDRWrite;
58 (void) xdrrec_create(__xdrs__, 0, 0, (char *) fd, readRoutine,writeRoutine);
60 fcntl (fd, F_SETFL, FNDELAY);
64 // prepare for RPC's to be done/received on the passed fd.
66 XDRrpc::XDRrpc(char *machine,
69 xdrIOFunc readRoutine,
70 xdrIOFunc writeRoutine,
74 fd = RPCprocessCreate(&pid, machine, user, program, arg_list);
77 if (!readRoutine) readRoutine = RPCdefaultXDRRead;
78 if (!writeRoutine) writeRoutine = RPCdefaultXDRWrite;
79 (void) xdrrec_create(__xdrs__, 0, 0, (char *) fd,
80 readRoutine, writeRoutine);
82 fcntl (fd, F_SETFL, FNDELAY);
90 RPC_readReady (int fd)
95 tvptr.tv_sec = 0; tvptr.tv_usec = 0;
96 if (fd < 0) return -1;
98 FD_SET (fd, &readfds);
99 if (select (fd+1, &readfds, NULL, NULL, &tvptr) == -1)
101 // if (errno == EBADF)
104 return (FD_ISSET (fd, &readfds));
108 RPC_undo_arg_list (int argc, char **arg_list, char **machine, int &family,
109 int &type, int &well_known_socket, int &flag)
115 for (loop=0; loop < argc; ++loop)
117 if (!strncmp(arg_list[loop], "-p", 2))
119 well_known_socket = (int) strtol (arg_list[loop] + 2, &ptr, 10);
124 else if (!strncmp(arg_list[loop], "-f", 2))
126 family = (int) strtol (arg_list[loop] + 2, &ptr, 10);
131 else if (!strncmp(arg_list[loop], "-t", 2))
133 type = (int) strtol (arg_list[loop] + 2, &ptr, 10);
138 else if (!strncmp(arg_list[loop], "-m", 2))
140 *machine = strdup (arg_list[loop] + 2);
141 if (!(*machine)) return -1;
144 else if (!strncmp(arg_list[loop], "-l", 2))
146 flag = (int) strtol (arg_list[loop] + 2, &ptr, 10);
152 if (sum == (16 + 8 + 4 + 2 + 1))
159 RPC_make_arg_list (char *program, int family, int type, int well_known_socket,
165 char machine_name[50];
167 arg_list = new char*[7];
168 arg_list[arg_count++] = strdup (program);
169 sprintf(arg_str, "%s%d", "-p", well_known_socket);
170 arg_list[arg_count++] = strdup (arg_str);
171 sprintf(arg_str, "%s%d", "-f", family);
172 arg_list[arg_count++] = strdup (arg_str);
173 sprintf(arg_str, "%s%d", "-t", type);
174 arg_list[arg_count++] = strdup (arg_str);
175 gethostname (machine_name, 49);
176 sprintf(arg_str, "%s%s", "-m", machine_name);
177 arg_list[arg_count++] = strdup (arg_str);
178 sprintf(arg_str, "%s%d", "-l", flag);
179 arg_list[arg_count++] = strdup (arg_str);
180 arg_list[arg_count++] = 0;
184 // returns fd of socket that is listened on, or -1
186 RPC_setup_socket (int *sfd, // return file descriptor
187 int family, // AF_INET ...
188 int type) // SOCK_STREAM ...
190 struct sockaddr_in serv_addr;
194 if (gethostname(machine, 49) != 0)
197 if ((*sfd = socket(family, type, 0)) < 0)
200 bzero ((char *) &serv_addr, sizeof(serv_addr));
201 serv_addr.sin_family = (short) family;
202 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
203 serv_addr.sin_port = htons(0);
205 length = sizeof(serv_addr);
207 if (bind(*sfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
210 if (getsockname (*sfd, (struct sockaddr *) &serv_addr, &length) < 0)
213 if (listen(*sfd, 5) < 0)
216 return (ntohs (serv_addr.sin_port));
220 // connect to well known socket
222 XDRrpc::XDRrpc(int family,
226 xdrIOFunc readRoutine,
227 xdrIOFunc writeRoutine,
229 // socket, connect using machine
233 struct sockaddr_in serv_addr;
234 struct hostent *hostptr = 0;
235 struct in_addr *inadr = 0;
239 if ( (hostptr = gethostbyname(machine)) == 0)
242 inadr = (struct in_addr *) hostptr->h_addr_list[0];
243 bzero ((char *) &serv_addr, sizeof(serv_addr));
244 serv_addr.sin_family = family;
245 serv_addr.sin_addr = *inadr;
246 serv_addr.sin_port = htons(req_port);
248 if ( (fd = socket(family, type, 0)) < 0)
251 if (connect(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
255 if (!readRoutine) readRoutine = RPCdefaultXDRRead;
256 if (!writeRoutine) writeRoutine = RPCdefaultXDRWrite;
257 (void) xdrrec_create(__xdrs__, 0, 0, (char *) fd, readRoutine,writeRoutine);
259 fcntl (fd, F_SETFL, FNDELAY);
264 // prepare for RPC's to be done/received on the passed thread id.
266 THREADrpc::THREADrpc(int thread)
272 // This should never be called, it should be replaced by a virtual function
273 // from the derived class created by igen.
275 void RPCUser::verifyProtocolAndVersion()
281 // our version of string encoding that does malloc as needed.
283 bool_t xdr_String(XDR *xdrs, String *str)
287 // if XDR_FREE, str's memory is freed
288 switch (xdrs->x_op) {
290 len = strlen(*str)+1;
296 // xdr_free (xdr_string, str);
305 // this should never occur
307 // should we have a better max length ???.
308 // xdr_bytes(xdrs, str, &len, 65536*32768);
310 return (xdr_string (xdrs, str, 65536));
313 int RPCprocessCreate(int *pid, char *hostName, char *userName,
314 char *command, char **arg_list)
320 if (!hostName || !strcmp(hostName, "") || !strcmp(hostName, "localhost")) {
321 ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
322 if (ret) return(ret);
329 execl(command, command);
331 execv(command, arg_list);
334 } else if (*pid > 0 && !execlERROR) {
341 // need to rsh to machine and setup io path.
342 printf("remote starts not implemented\n");
348 // wait for an expected RPC responce, but also handle upcalls while waiting.
349 // Should not be called directly !!!
351 void RPCUser::awaitResponce(int tag)
357 XDRrpc::setNonBlock()
360 fcntl (fd, F_SETFL, FNDELAY);
366 return RPC_readReady (fd);
370 RPC_getConnect(int fd)
373 struct in_addr cli_addr;
379 clilen = sizeof(cli_addr);
381 if ((new_fd = accept (fd, (struct sockaddr *) &cli_addr, &clilen)) < 0)