|
|
1.1 root 1: #include <stdio.h>
2: #include <sys/types.h>
3: #include <sys/uio.h>
4: #include <sys/socket.h>
5: #include <sys/ioctl.h>
6: #include <sys/time.h>
7: #include <netinet/in.h>
8: #include <arpa/inet.h>
9: #include <netdb.h>
10: #include <sysexits.h>
11: #include <string.h>
12:
13: extern int ipcdebug;
14: extern char syserrstr[];
15:
16: void do_gethosterror();
17:
18: int
19: tcp_connect(dest, param)
20: char *dest, *param;
21: {
22: struct hostent *hp;
23: struct sockaddr_in sin;
24: char *inet_ntoa();
25: int s, port, i;
26: unsigned long addr;
27: char buf[100];
28: char *host, *service;
29: int errtype = 0;
30: char errstr[256];
31:
32: strcpy(buf, dest);
33: host = buf;
34:
35: if ((port = tcp_service(host)) < 0) {
36: ipcseterror(EX_NOHOST, "unknown service", "tcp_connect");
37: return(-1);
38: }
39:
40: if (ipcdebug)
41: fprintf(stderr, "TCP port number is %d\n", ntohs(port));
42:
43: if ((addr = inet_addr(host)) != (unsigned long) -1) {
44: if (ipcdebug)
45: fprintf(stderr, "Numeric address: %s %lx\n",
46: host, addr);
47: s = socket(AF_INET, SOCK_STREAM, 0);
48: if(s < 0){
49: ipcsyserr("can't open socket");
50: return(-1);
51: }
52: bzero((char *)&sin, sizeof(sin));
53: sin.sin_family = AF_INET;
54: sin.sin_port = port;
55: sin.sin_addr.s_addr = addr;
56: if(connect(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0) {
57: setopt(s);
58: return s;
59: }
60: ipcsyserr("can't connect");
61: close(s);
62: return -1;
63: }
64:
65: if((hp = gethostbyname(host)) == (struct hostent *)0){
66: do_gethosterror();
67: return -1;
68: }
69:
70: for(i=0; hp->h_addr_list[i]; i++){
71: bzero((char *)&sin, sizeof(sin));
72: bcopy(hp->h_addr_list[i], &sin.sin_addr, hp->h_length);
73: sin.sin_family = hp->h_addrtype;
74: sin.sin_port = port;
75: if (ipcdebug)
76: fprintf(stderr, "Trying address %s\n",
77: inet_ntoa(sin.sin_addr));
78:
79: s = socket(AF_INET, SOCK_STREAM, 0);
80: if(s < 0){
81: ipcsyserr("can't open socket");
82: return(-1);
83: }
84:
85: if(connect(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0) {
86: setopt(s);
87: return s;
88: }
89: ipcgetsyserr();
90: if (errtype == 0 ||
91: (errtype != EX_TEMPFAIL && ipcmaperror()==EX_TEMPFAIL)) {
92: errtype = ipcmaperror();
93: strcpy(errstr, syserrstr);
94: }
95: ipcsyserr("connect");
96: close(s);
97: }
98: ipcseterror(errtype, errstr, "Can't connect to host");
99: return -1;
100: }
101:
102: setopt(s)
103: int s;
104: {
105: return 0;
106: }
107:
108: #ifdef HOST_NOT_FOUND
109: /*
110: * This processes the new gethostbyname error returns.
111: */
112: void
113: do_gethosterror() {
114: extern int h_errno;
115:
116: if (ipcdebug)
117: fprintf(stderr, "gethostbyname returns h_errno = %d\n",
118: h_errno);
119: switch (h_errno) {
120: case HOST_NOT_FOUND:
121: ipcseterror(EX_NOHOST, "unknown host", "tcp_connect");
122: break;
123: case TRY_AGAIN:
124: ipcseterror(EX_TEMPFAIL, "name server timeout", "tcp_connect"); break;
125: /* On inet, the following was returned for the address `pente..msd' */
126: case NO_RECOVERY:
127: ipcseterror(EX_USAGE, "unrecoverable error", "tcp_connect"); break;
128: case NO_ADDRESS:
129: ipcseterror(EX_TEMPFAIL, "IP address unavailable",
130: "tcp_connect");
131: break;
132: default:
133: ipcseterror(EX_SOFTWARE, "Unknown h_errno",
134: "tcp_connect");
135: break;
136: }
137: }
138: #else /*HOST_NOT_FOUND*/
139:
140: /*
141: * This processes the old dumb gethostbyname error returns.
142: */
143: void
144: do_gethosterror() {
145: ipcseterror(EX_NOHOST, "unknown host", "tcp_connect");
146: return;
147: }
148: #endif
149:
150: int
151: tcp_service(path)
152: char *path;
153: {
154: struct servent *sp;
155: char *service;
156:
157: if ((service = strchr(path, '!')) == NULL)
158: service = "";
159: else
160: *service++ = '\0';
161:
162: /*
163: * translate service/port name
164: */
165: if(strncmp(service, "tcp.", 4)==0)
166: service += 4;
167: if(strncmp(service, "/cs/", 4)==0)
168: service += 4;
169: if(strcmp(service, "")==0)
170: return 0;
171: else if(atoi(service)!=0)
172: return htons(atoi(service));
173: else if ((sp = getservbyname (service, "tcp")) != NULL)
174: return sp->s_port;
175: return -1;
176: }
177:
178: int
179: tcp_close(fd)
180: int fd;
181: {
182: struct linger l;
183: int lingersize=sizeof(l), n;
184:
185: l.l_onoff = SO_LINGER; l.l_linger = 4000;
186: setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
187: return close(fd);
188: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.