V10/ipc/libin/tcp_lib.c
#include <sys/inet/tcp_user.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include "config.h"
extern errno;
extern char *errstr;
tcp_sock()
{
int fd, n;
char name[32];
for(n = 01; n < 100; n += 2){
sprintf(name, "/dev/tcp%02d", n);
fd = open(name, 2);
if(fd >= 0){
flabclr(fd); /* for security unix */
return(fd);
}
if(errno != ENXIO)
break;
}
perror(name);
return(-1);
}
static
tcp_rv(fd, tp)
int fd;
struct tcpuser *tp;
{
int n;
n = read(fd, (char *)tp, sizeof(struct tcpuser));
if (n != sizeof(struct tcpuser)){
if(errno==EINTR){
errstr = "timeout";
} else {
errstr = "connection rejected";
errno = EACCES;
}
return -1;
}
switch(tp->code){
case TCPC_OK:
return 0;
case TCPC_BADDEV:
errstr = "tcp dev broken";
errno = EIO;
break;
case TCPC_NOROUTE:
errstr = "no route";
errno = ENOENT;
break;
case TCPC_BADLOCAL:
errstr = "invalid local address";
errno = EINVAL;
break;
case TCPC_BOUND:
errstr = "address(es) already in use";
errno = ENOENT;
break;
default:
errstr = "unknown error";
errno = EIO;
break;
}
return -1;
}
tcp_connect(fd, tp)
int fd;
struct tcpuser *tp;
{
tp->code = TCPC_CONNECT;
if (write(fd, (char *)tp, sizeof(struct tcpuser))!=sizeof(struct tcpuser)){
errstr = "can't write tcp dev";
return -1;
}
return tcp_rv(fd, tp);
}
tcp_listen(fd, tp)
int fd;
struct tcpuser *tp;
{
tp->code = TCPC_LISTEN;
if (write(fd, (char *)tp, sizeof(struct tcpuser))!=sizeof(struct tcpuser)){
errstr = "can't write tcp dev";
return -1;
}
return tcp_rv(fd, tp);
}
tcp_accept(fd, tp)
int fd;
struct tcpuser *tp;
{
char name[128];
int nfd;
if (read(fd, (char *)tp, sizeof(struct tcpuser))!=sizeof(struct tcpuser))
return -1;
if (tp->code != TCPC_OK)
return -1;
sprintf(name, "/dev/tcp%02d", tp->param);
nfd = open(name, 2);
if(nfd>=0)
flabclr(nfd); /* for security unix */
return nfd;
}
tcp_rcmd(host, port, locuser, remuser, cmd, fd2p)
char *host, *port, *locuser, *remuser, *cmd;
int *fd2p;
{
char buf[1];
int fd;
struct in_service *sp;
struct tcpuser tu;
in_addr in_address();
tu.faddr = in_address(host);
if(tu.faddr == 0){
fprintf(stderr, "%s: unknown host\n", host);
return(-1);
}
sp = in_service(port, "tcp", 0L);
if(sp == 0){
fprintf(stderr, "%s: unknown service\n", port);
return(-1);
}
tu.fport = sp->port;
fd = tcp_sock();
if(fd < 0){
perror(host);
return(-1);
}
tu.laddr = INADDR_ANY;
tu.lport = 0;
tu.param = 0;
if(tcp_connect(fd, &tu) < 0){
fprintf(stderr, "%s: connection failed\n", host);
goto bad;
}
if(fd2p == 0)
write(fd, "", 1);
else
goto bad; /* later */
write(fd, locuser, strlen(locuser)+1);
write(fd, remuser, strlen(remuser)+1);
write(fd, cmd, strlen(cmd)+1);
if(read(fd, buf, 1) != 1){
perror(host);
goto bad;
}
if(buf[0] != 0){
while(read(fd, buf, 1) == 1){
write(2, buf, 1);
if(buf[0] == '\n')
break;
}
goto bad;
}
return(fd);
bad:
close(fd);
return(-1);
}