2 * Copyright (c) 1983 Regents of the University of California.
5 * Redistribution and use in source and binary forms are permitted
6 * provided that: (1) source distributions retain this entire copyright
7 * notice and comment, and (2) distributions including binaries display
8 * the following acknowledgement: ``This product includes software
9 * developed by the University of California, Berkeley and its contributors''
10 * in the documentation or other materials provided with the distribution
11 * and in all advertising materials mentioning features or use of this
12 * software. Neither the name of the University nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 #if defined(LIBC_SCCS) && !defined(lint)
21 static char sccsid
[] = "@(#)rcmd.c 5.22 (Berkeley) 6/1/90";
22 #endif /* LIBC_SCCS and not lint */
24 #include <sys/types.h>
26 #include <sys/ioctl.h>
37 #include <net/gen/netdb.h>
38 #include <net/gen/in.h>
39 #include <net/gen/tcp.h>
40 #include <net/gen/tcp_io.h>
42 #include <net/netlib.h>
44 #define MAXHOSTNAMELEN 256
45 #define MAXPATHLEN PATH_MAX
55 int rcmd(ahost
, rport
, locuser
, remuser
, cmd
, fd2p
)
58 CONST
char *locuser
, *remuser
, *cmd
;
64 static tcpport_t lport
;
65 nwio_tcpconf_t tcpconf
;
66 nwio_tcpcl_t tcpconnopt
;
79 lport
= (lport
<< 1) | (pid
& 1);
82 } while (lport
< TCPPORT_RESERVED
/2);
85 tcp_device
= getenv("TCP_DEVICE");
86 if (tcp_device
== NULL
)
87 tcp_device
= TCP_DEVICE
;
88 hp
= gethostbyname(*ahost
);
91 fprintf(stderr
, "%s: unknown host\n", *ahost
);
95 n
= TCPPORT_RESERVED
/2;
98 if (--lport
< TCPPORT_RESERVED
/2)
99 lport
= TCPPORT_RESERVED
-1;
100 fd
= open (tcp_device
, O_RDWR
);
103 fprintf(stderr
, "unable to open %s: %s\n",
104 tcp_device
, strerror(errno
));
107 tcpconf
.nwtc_flags
= NWTC_LP_SET
| NWTC_SET_RA
| NWTC_SET_RP
|
109 tcpconf
.nwtc_locport
= htons(lport
);
110 tcpconf
.nwtc_remport
= rport
;
111 tcpconf
.nwtc_remaddr
= *(ipaddr_t
*)hp
->h_addr
;
113 result
= ioctl(fd
, NWIOSTCPCONF
, &tcpconf
);
116 if (errno
== EADDRINUSE
)
121 fprintf(stderr
, "unable to ioctl(NWIOSTCPCONF): %s\n",
125 tcpconf
.nwtc_flags
= NWTC_SHARED
;
126 result
= ioctl(fd
, NWIOSTCPCONF
, &tcpconf
);
129 fprintf(stderr
, "unable to ioctl(NWIOSTCPCONF): %s\n",
133 tcpconnopt
.nwtcl_flags
= 0;
137 result
= ioctl (fd
, NWIOTCPCONN
, &tcpconnopt
);
138 if (result
<0 && errno
== EAGAIN
)
142 } while (result
<0 && errno
== EAGAIN
);
143 if (result
<0 && errno
!= EADDRINUSE
)
146 "unable to ioctl(NWIOTCPCONN): %s\n",
155 fprintf(stderr
, "can't get port\n");
160 if (write(fd
, "", 1) != 1)
162 fprintf(stderr
, "unable to write: %s", strerror(errno
));
168 fd2
= open (tcp_device
, O_RDWR
);
171 fprintf(stderr
, "unable to open %s: %s\n",
172 tcp_device
, strerror(errno
));
175 tcpconf
.nwtc_flags
= NWTC_LP_SET
| NWTC_UNSET_RA
|
176 NWTC_UNSET_RP
| NWTC_SHARED
;
177 tcpconf
.nwtc_locport
= htons(lport
);
179 result
= ioctl(fd2
, NWIOSTCPCONF
, &tcpconf
);
183 "unable to ioctl(NWIOSTCPCONF): %s\n",
190 fprintf(stderr
, "unable to fork: %s\n",
197 signal(SIGALRM
, SIG_DFL
);
198 alarm(30); /* give up after half a minute */
199 tcpconnopt
.nwtcl_flags
= 0;
203 result
= ioctl (fd2
, NWIOTCPLISTEN
,
205 if (result
<0 && errno
== EAGAIN
)
209 } while (result
<0 && errno
== EAGAIN
);
210 if (result
<0 && errno
!= EADDRINUSE
)
213 "unable to ioctl(NWIOTCPLISTEN): %s\n",
223 * This sleep is a HACK. The command that we are starting
224 * will try to connect to the fd2 port. It seems that for
225 * this to succeed the child process must have already made
226 * the call to ioctl above (the NWIOTCPLISTEN) call.
227 * The sleep gives the child a chance to make the call
228 * before the parent sends the port number to the
229 * command being started.
233 sprintf(num
, "%d", lport
);
234 if (write(fd
, num
, strlen(num
)+1) != strlen(num
)+1)
236 fprintf(stderr
, "unable to write: %s\n",
242 write (fd
, locuser
, strlen(locuser
)+1);
243 write (fd
, remuser
, strlen(remuser
)+1);
244 write (fd
, cmd
, strlen(cmd
)+1);
245 if (read(fd
, &c
, 1) != 1)
247 fprintf(stderr
, "unable to read: %s\n", strerror(errno
) );
252 while (read(fd
, &c
, 1) == 1)
263 result
= ioctl(fd2
, NWIOGTCPCONF
, &tcpconf
);
266 fprintf(stderr
, "unable to ioctl(NWIOGTCPCONF): %s\n",
270 if (ntohs(tcpconf
.nwtc_remport
) >= TCPPORT_RESERVED
)
272 fprintf(stderr
, "unable to setup 2nd channel\n");