|
|
1.1 root 1: #include <sys/types.h> /* needed for socket.h */
2: #include <sys/uio.h> /* needed for socket.h */
3: #include <sys/socket.h>
4: #include <sysexits.h>
5: #include <netinet/in.h>
6: #include <netdb.h>
7: #include <stdio.h>
8: #include <errno.h>
9: #include "ipc.h"
10:
11: int
12: tcpdial(ip, host, service)
13: ipcinfo *ip;
14: {
15: struct hostent *hp;
16: struct servent *sp;
17: struct sockaddr_in sin;
18: struct sockaddr_in me;
19: int fd, lport, n;
20: char field[5];
21: int melen;
22: char *dotaddr();
23: static char nipcname[128];
24:
25: bzero((char *)&sin, sizeof(sin));
26: bzero((char *)&me, sizeof(me));
27:
28: /*
29: * translate host name
30: */
31: if (strcmp(host, "*")!=0) {
32: if ((hp = gethostbyname(host)) == (struct hostent *) NULL) {
33: errstr = "unknown host";
34: errno = ENOENT;
35: return(-1);
36: }
37: bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
38: sin.sin_family = hp->h_addrtype;
39: }
40:
41: /*
42: * translate service/port name
43: */
44: if(strcmp(service, "*")==0)
45: sin.sin_port = 0;
46: else if(strncmp(service, "tcp.", 4)==0)
47: sin.sin_port = htons(atoi(service+4));
48: else if(atoi(service)!=0)
49: sin.sin_port = htons(atoi(service));
50: else if ((sp = getservbyname (service, "tcp")) == NULL)
51: sin.sin_port = sp->s_port;
52: else {
53: errstr = "unknown service";
54: errno = ENOENT;
55: return(-1);
56: }
57:
58: /*
59: * get a socket
60: */
61: fd = socket(AF_INET, SOCK_STREAM, 0);
62: if(fd < 0) {
63: errstr = "can't open socket";
64: return(-1);
65: }
66:
67: /*
68: * connect or listen
69: */
70: if(ip->params & IPC_CREAT) {
71: /*
72: * get a local port number
73: */
74: if (bind(fd, &sin, sizeof(sin))<0) {
75: errstr = "can't bind to requested address";
76: close(fd);
77: return(-1);
78: }
79: /*
80: * specify number of incoming calls
81: */
82: if (listen(s, 10) < 0) {
83: close(fd);
84: return(-1);
85: }
86: } else {
87: /*
88: * look through params for local port number
89: */
90: lport=0;
91: setfields(" \t");
92: n = getmfields(ip->param, field, 5);
93: for(n--; n>=0; n--)
94: if (strncmp(field[n], "port=", 5)==0)
95: lport = atoi(field[n]+5);
96: me.sin_port = htons(lport);
97: /*
98: * connect to a local port
99: */
100: if (bind(fd, &me, sizeof(me))<0) {
101: errstr = "can't bind to requested address";
102: close(fd);
103: return(-1);
104: }
105: /*
106: * dial the other end
107: */
108: if (connect(fd, (struct sockaddr *) &sin, sizeof (sin)) < 0) {
109: errstr = "can't connect";
110: close(fd);
111: return(-1);
112: }
113: }
114:
115: /*
116: * remember my name
117: */
118: melen = sizeof(me);
119: getsockname(nfd, &me, melen);
120: ipcname = dotaddr(&me, nipcname);
121: return(fd);
122: }
123:
124: /*
125: * listen for a connection
126: */
127: ipcinfo *
128: tcplisten(fd, ip)
129: int fd;
130: ipcinfo *ip;
131: {
132: int nfd;
133: static char machine[32];
134: static char myname[32];
135: struct sockaddr_in from;
136: struct sockaddr_in me;
137: struct hostent *hp;
138: int fromlen;
139: int melen;
140: char *dotaddr();
141:
142: /*
143: * accept the connection
144: */
145: fromlen = sizeof(from);
146: nfd = accept(fd, (struct sockaddr *)&from, &fromlen);
147: if(nfd<0) {
148: close(fd);
149: return(NULL);
150: }
151:
152: /*
153: * figure out the caller's true name
154: */
155: hp = gethostbyaddr((char *)&from, fromlen);
156: if(hp != NULL)
157: ip->machine = hp->h_name;
158: else
159: ip->machine = dotaddr(&from, machine);
160:
161: /*
162: * figure out our true name
163: */
164: melen = sizeof(me);
165: getsockname(nfd, &me, melen);
166: ip->myaddr = dotaddr(&me, machine);
167: ip->cfd = nfd
168: ipcname = machine;
169: return(ip);
170: }
171:
172: /*
173: * create dot form of the address (byte by arduous byte)
174: */
175: char *
176: dotaddr(ap, np)
177: struct sockaddr_in *ap;
178: char *np;
179: {
180: int port;
181: unsigned char *cp;
182:
183: cp = (char *)&ap->sin_addr;
184: port = ntohs(ap->sin_port);
185: sprintf(np, "%d.%d.%d.%d!%d", cp[0], cp[1], cp[2], cp[3], port);
186: return(np);
187: }
188:
189: /*
190: * accept a call
191: */
192: tcpaccept(ip)
193: ipcinfo *ip;
194: {
195: return(ip->cfd);
196: }
197:
198: /*
199: * reject a call
200: */
201: tcpreject(ip, no, str)
202: ipcinfo *ip;
203: int no;
204: char *str;
205: {
206: close(ip->cfd);
207: ip->cfd = -1;
208: return(0);
209: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.