3 * Revision 1.24 1994/06/22 00:37:13 markc
4 * Fixed code to remove warnings.
6 * Revision 1.23 1994/06/02 23:36:58 markc
7 * Added support for igen error checking.
9 * Revision 1.22 1994/05/17 00:14:45 hollings
10 * added rcs log entry.
12 * Revision 1.21 1994/05/16 04:27:47 hollings
13 * Added inlcude of vfork.h on SUNS to prevent problem with optimizer.
15 * Revision 1.20 1994/05/12 18:47:51 jcargill
16 * Changed make args function to leave room for program name in arg_list[0],
17 * and added code to RPCprocessCreate to poke it in there before execv'ing.
19 * Revision 1.19 1994/04/21 23:23:49 hollings
20 * removed paradynd name from make args function.
22 * Revision 1.18 1994/04/06 22:46:12 markc
23 * Fixed bug in XDRrpc constructor that clobbered the fd value. Added feature
24 * to RPC_readReady to do blocking select.
26 * Revision 1.17 1994/04/01 20:05:27 hollings
27 * Removed kill of rsh process (not needed and it causes a race condition).
29 * Revision 1.16 1994/04/01 04:59:13 markc
30 * Put in support to encode NULL ptrs to strings in xdr_String.
32 * Revision 1.15 1994/03/31 22:59:08 hollings
33 * added well known port as a paramter to xdrRPC constructor.
35 * Revision 1.14 1994/03/31 22:45:04 markc
41 // This file defines a set of utility routines for RPC services.
45 // overcome malloc redefinition due to /usr/include/rpc/types.h declaring
51 /* prevents malloc from being redefined */
53 #define MALLOC_DEFINED_AS_VOID
56 #include "util/h/rpcUtil.h"
65 #include <netinet/in.h>
67 #include <sys/types.h>
73 #include <rpc/types.h>
77 // functions that g++-fixincludes missed
80 void bzero (char*, int);
81 int select (int, fd_set*, fd_set*, fd_set*, struct timeval*);
83 int gethostname(char*, int);
84 int socket(int, int, int);
85 int bind(int s, struct sockaddr *, int);
86 int getsockname(int, struct sockaddr*, int *);
88 int connect(int s, struct sockaddr*, int);
89 int socketpair(int, int, int, int sv[2]);
91 int accept(int, struct sockaddr *addr, int *);
94 #include <sys/socket.h>
97 void bzero (char*, int);
98 int select (int, fd_set*, fd_set*, fd_set*, struct timeval*);
99 int socket(int, int, int);
100 int gethostname(char*, int);
101 int bind(int s, struct sockaddr *, int);
102 int getsockname(int, struct sockaddr*, int *);
103 int listen(int, int);
104 int connect(int s, struct sockaddr*, int);
105 int socketpair(int, int, int, int sv[2]);
106 int accept(int, struct sockaddr *addr, int *);
111 #define RSH_COMMAND "rsh"
113 int RPCdefaultXDRRead(int handle, char *buf, u_int len)
118 ret = read(handle, buf, len);
119 } while (ret < 0 && errno == EINTR);
121 if (ret <= 0) return(-1);
125 int RPCdefaultXDRWrite(int handle, char *buf, u_int len)
130 ret = write(handle, buf, len);
131 } while (ret < 0 && errno == EINTR);
143 fcntl (fd, F_SETFL, FNDELAY);
148 xdr_destroy (__xdrs__);
154 // prepare for RPC's to be done/received on the passed fd.
156 XDRrpc::XDRrpc(int f, xdrIOFunc readRoutine, xdrIOFunc writeRoutine, int nblock)
160 if (!readRoutine) readRoutine = RPCdefaultXDRRead;
161 if (!writeRoutine) writeRoutine = RPCdefaultXDRWrite;
162 (void) xdrrec_create(__xdrs__, 0, 0, (char *) fd, readRoutine,writeRoutine);
164 fcntl (fd, F_SETFL, FNDELAY);
168 // prepare for RPC's to be done/received on the passed fd.
170 XDRrpc::XDRrpc(char *machine,
173 xdrIOFunc readRoutine,
174 xdrIOFunc writeRoutine,
179 fd = RPCprocessCreate(&pid, machine, user, program, arg_list,
183 if (!readRoutine) readRoutine = RPCdefaultXDRRead;
184 if (!writeRoutine) writeRoutine = RPCdefaultXDRWrite;
185 (void) xdrrec_create(__xdrs__, 0, 0, (char *) fd,
186 readRoutine, writeRoutine);
188 fcntl (fd, F_SETFL, FNDELAY);
196 RPC_readReady (int fd, int timeout)
199 struct timeval tvptr, *the_tv;
201 tvptr.tv_sec = timeout; tvptr.tv_usec = 0;
202 if (fd < 0) return -1;
204 FD_SET (fd, &readfds);
206 // -1 timeout = blocking select
212 if (select (fd+1, &readfds, NULL, NULL, the_tv) == -1)
214 // if (errno == EBADF)
217 return (FD_ISSET (fd, &readfds));
221 RPC_undo_arg_list (int argc, char **arg_list, char **machine, int &family,
222 int &type, int &well_known_socket, int &flag)
228 for (loop=0; loop < argc; ++loop)
230 if (!strncmp(arg_list[loop], "-p", 2))
232 well_known_socket = (int) strtol (arg_list[loop] + 2, &ptr, 10);
233 if (ptr == (arg_list[loop] + 2))
237 else if (!strncmp(arg_list[loop], "-f", 2))
239 family = (int) strtol (arg_list[loop] + 2, &ptr, 10);
240 if (ptr == (arg_list[loop] + 2))
244 else if (!strncmp(arg_list[loop], "-t", 2))
246 type = (int) strtol (arg_list[loop] + 2, &ptr, 10);
247 if (ptr == (arg_list[loop] + 2))
251 else if (!strncmp(arg_list[loop], "-m", 2))
253 *machine = strdup (arg_list[loop] + 2);
254 if (!(*machine)) return -1;
257 else if (!strncmp(arg_list[loop], "-l", 2))
259 flag = (int) strtol (arg_list[loop] + 2, &ptr, 10);
260 if (ptr == (arg_list[loop] + 2))
265 if (sum == (16 + 8 + 4 + 2 + 1))
271 char **RPC_make_arg_list (int family, int type, int well_known_socket,
277 char machine_name[50];
279 arg_list = new char*[8];
281 sprintf(arg_str, "%s%d", "-p", well_known_socket);
282 arg_list[arg_count++] = strdup (arg_str);
283 sprintf(arg_str, "%s%d", "-f", family);
284 arg_list[arg_count++] = strdup (arg_str);
285 sprintf(arg_str, "%s%d", "-t", type);
286 arg_list[arg_count++] = strdup (arg_str);
287 gethostname (machine_name, 49);
288 sprintf(arg_str, "%s%s", "-m", machine_name);
289 arg_list[arg_count++] = strdup (arg_str);
290 sprintf(arg_str, "%s%d", "-l", flag);
291 arg_list[arg_count++] = strdup (arg_str);
292 arg_list[arg_count++] = 0;
296 // returns fd of socket that is listened on, or -1
298 RPC_setup_socket (int *sfd, // return file descriptor
299 int family, // AF_INET ...
300 int type) // SOCK_STREAM ...
302 struct sockaddr_in serv_addr;
306 if (gethostname(machine, 49) != 0)
309 if ((*sfd = socket(family, type, 0)) < 0)
312 memset ((char*) &serv_addr, 0, sizeof(serv_addr));
313 /* bzero ((char *) &serv_addr, sizeof(servaddr)); */
314 serv_addr.sin_family = (short) family;
315 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
316 serv_addr.sin_port = htons(0);
318 length = sizeof(serv_addr);
320 if (bind(*sfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
323 if (getsockname (*sfd, (struct sockaddr *) &serv_addr, &length) < 0)
326 if (listen(*sfd, 5) < 0)
329 return (ntohs (serv_addr.sin_port));
333 // connect to well known socket
335 XDRrpc::XDRrpc(int family,
339 xdrIOFunc readRoutine,
340 xdrIOFunc writeRoutine,
342 // socket, connect using machine
344 struct sockaddr_in serv_addr;
345 struct hostent *hostptr = 0;
346 struct in_addr *inadr = 0;
350 if ( (hostptr = gethostbyname(machine)) == 0)
353 inadr = (struct in_addr *) hostptr->h_addr_list[0];
354 memset ((char*) &serv_addr, 0, sizeof(serv_addr));
355 /* bzero ((char *) &serv_addr, sizeof(serv_addr)); */
356 serv_addr.sin_family = family;
357 serv_addr.sin_addr = *inadr;
358 serv_addr.sin_port = htons(req_port);
360 if ( (fd = socket(family, type, 0)) < 0)
363 if (connect(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
367 if (!readRoutine) readRoutine = RPCdefaultXDRRead;
368 if (!writeRoutine) writeRoutine = RPCdefaultXDRWrite;
369 (void) xdrrec_create(__xdrs__, 0, 0, (char *) fd, readRoutine,writeRoutine);
371 fcntl (fd, F_SETFL, FNDELAY);
376 // prepare for RPC's to be done/received on the passed thread id.
378 THREADrpc::THREADrpc(int thread)
384 // This should never be called, it should be replaced by a virtual function
385 // from the derived class created by igen.
387 void RPCUser::verifyProtocolAndVersion()
393 // our version of string encoding that does malloc as needed.
395 bool_t xdr_String(XDR *xdrs, String *str)
398 unsigned char isNull=0;
400 // if XDR_FREE, str's memory is freed
401 switch (xdrs->x_op) {
404 len = strlen(*str)+1;
405 if (!xdr_u_char(xdrs, &isNull))
408 isNull = (unsigned char) 1;
409 if (!xdr_u_char(xdrs, &isNull))
414 return (xdr_string (xdrs, str, 65536));
417 if (!xdr_u_char(xdrs, &isNull))
422 return (xdr_string (xdrs, str, 65536));
424 // xdr_free (xdr_string, str);
433 // this should never occur
437 int RPCprocessCreate(int *pid, char *hostName, char *userName,
438 char *command, char **arg_list, int portFd)
445 if (gethostname(local, 49))
449 !strcmp(hostName, "") ||
450 !strcmp(hostName, "localhost") ||
451 !strcmp(hostName, local)) {
452 ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
453 if (ret) return(ret);
460 execl(command, command);
462 arg_list[0] = command;
463 execv(command, arg_list);
467 } else if (*pid > 0 && !execlERROR) {
482 char *paradyndCommand;
484 total = strlen(command) + 2;
485 for (curr = arg_list+1; *curr; curr++) {
486 total += strlen(*curr) + 2;
488 paradyndCommand = (char *) malloc(total+2);
490 sprintf(paradyndCommand, "%s ", command);
491 for (curr = arg_list+1; *curr; curr++) {
492 strcat(paradyndCommand, *curr);
493 strcat(paradyndCommand, " ");
496 // need to rsh to machine and setup io path.
506 dup2(fd[1], 1); /* copy it onto stdout */
510 execlp(RSH_COMMAND, RSH_COMMAND, hostName, "-l",
511 userName, "-n", paradyndCommand, "-l0", NULL);
513 execlp(RSH_COMMAND, RSH_COMMAND, hostName, "-n",
514 paradyndCommand, "-l0", NULL);
517 } else if (shellPid > 0) {
523 pfp = fdopen(fd[0], "r");
525 ret = fgets(line, sizeof(line)-1, pfp);
526 if (ret && !strncmp(line, "PARADYND", strlen("PARADYND"))) {
527 // got the good stuff
528 sscanf(line, "PARADYND %d", pid);
530 retFd = RPC_getConnect(portFd);
533 // some sort of error message from rsh.
545 // wait for an expected RPC responce, but also handle upcalls while waiting.
546 // Should not be called directly !!!
548 void RPCUser::awaitResponce(int tag)
554 XDRrpc::setNonBlock()
557 fcntl (fd, F_SETFL, FNDELAY);
561 XDRrpc::readReady(int timeout)
563 return RPC_readReady (fd, timeout);
567 RPC_getConnect(int fd)
570 struct in_addr cli_addr;
576 clilen = sizeof(cli_addr);
578 if ((new_fd = accept (fd, (struct sockaddr *) &cli_addr, &clilen)) < 0)
584 RPCUser::RPCUser(int st)
589 RPCServer::RPCServer(int st)