|
|
researchv10 Norman
#include <sys/types.h> /* needed for socket.h */
#include <sys/uio.h> /* needed for socket.h */
#include <sys/socket.h>
#include <sysexits.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>
#include "ipc.h"
int
tcpdial(ip, host, service)
ipcinfo *ip;
{
struct hostent *hp;
struct servent *sp;
struct sockaddr_in sin;
struct sockaddr_in me;
int fd, lport, n;
char field[5];
int melen;
char *dotaddr();
static char nipcname[128];
bzero((char *)&sin, sizeof(sin));
bzero((char *)&me, sizeof(me));
/*
* translate host name
*/
if (strcmp(host, "*")!=0) {
if ((hp = gethostbyname(host)) == (struct hostent *) NULL) {
errstr = "unknown host";
errno = ENOENT;
return(-1);
}
bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
sin.sin_family = hp->h_addrtype;
}
/*
* translate service/port name
*/
if(strcmp(service, "*")==0)
sin.sin_port = 0;
else if(strncmp(service, "tcp.", 4)==0)
sin.sin_port = htons(atoi(service+4));
else if(atoi(service)!=0)
sin.sin_port = htons(atoi(service));
else if ((sp = getservbyname (service, "tcp")) == NULL)
sin.sin_port = sp->s_port;
else {
errstr = "unknown service";
errno = ENOENT;
return(-1);
}
/*
* get a socket
*/
fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd < 0) {
errstr = "can't open socket";
return(-1);
}
/*
* connect or listen
*/
if(ip->params & IPC_CREAT) {
/*
* get a local port number
*/
if (bind(fd, &sin, sizeof(sin))<0) {
errstr = "can't bind to requested address";
close(fd);
return(-1);
}
/*
* specify number of incoming calls
*/
if (listen(s, 10) < 0) {
close(fd);
return(-1);
}
} else {
/*
* look through params for local port number
*/
lport=0;
setfields(" \t");
n = getmfields(ip->param, field, 5);
for(n--; n>=0; n--)
if (strncmp(field[n], "port=", 5)==0)
lport = atoi(field[n]+5);
me.sin_port = htons(lport);
/*
* connect to a local port
*/
if (bind(fd, &me, sizeof(me))<0) {
errstr = "can't bind to requested address";
close(fd);
return(-1);
}
/*
* dial the other end
*/
if (connect(fd, (struct sockaddr *) &sin, sizeof (sin)) < 0) {
errstr = "can't connect";
close(fd);
return(-1);
}
}
/*
* remember my name
*/
melen = sizeof(me);
getsockname(nfd, &me, melen);
ipcname = dotaddr(&me, nipcname);
return(fd);
}
/*
* listen for a connection
*/
ipcinfo *
tcplisten(fd, ip)
int fd;
ipcinfo *ip;
{
int nfd;
static char machine[32];
static char myname[32];
struct sockaddr_in from;
struct sockaddr_in me;
struct hostent *hp;
int fromlen;
int melen;
char *dotaddr();
/*
* accept the connection
*/
fromlen = sizeof(from);
nfd = accept(fd, (struct sockaddr *)&from, &fromlen);
if(nfd<0) {
close(fd);
return(NULL);
}
/*
* figure out the caller's true name
*/
hp = gethostbyaddr((char *)&from, fromlen);
if(hp != NULL)
ip->machine = hp->h_name;
else
ip->machine = dotaddr(&from, machine);
/*
* figure out our true name
*/
melen = sizeof(me);
getsockname(nfd, &me, melen);
ip->myaddr = dotaddr(&me, machine);
ip->cfd = nfd
ipcname = machine;
return(ip);
}
/*
* create dot form of the address (byte by arduous byte)
*/
char *
dotaddr(ap, np)
struct sockaddr_in *ap;
char *np;
{
int port;
unsigned char *cp;
cp = (char *)&ap->sin_addr;
port = ntohs(ap->sin_port);
sprintf(np, "%d.%d.%d.%d!%d", cp[0], cp[1], cp[2], cp[3], port);
return(np);
}
/*
* accept a call
*/
tcpaccept(ip)
ipcinfo *ip;
{
return(ip->cfd);
}
/*
* reject a call
*/
tcpreject(ip, no, str)
ipcinfo *ip;
int no;
char *str;
{
close(ip->cfd);
ip->cfd = -1;
return(0);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.