|
|
1.1 root 1: untested - there are some minor changes in tcpconnect that have not been
2: moved to this routine.
3:
4: #include <stdio.h>
5: #include <sys/types.h>
6: #include <sys/uio.h>
7: #include <sys/socket.h>
8: #include <sys/ioctl.h>
9: #include <sys/time.h>
10: #include <netinet/in.h>
11: #include <arpa/inet.h>
12: #include <netdb.h>
13: #include <sysexits.h>
14: #include <string.h>
15:
16: extern int ipcdebug;
17:
18: extern char syserrstr[];
19:
20: /*
21: * This is an older version of tcp_connect for systems that
22: * use the old Berkeley 4.2 gethostbyname which returned
23: * a single host entry instead of several.
24: *
25: * This code hasn't been tested as hard as the newer stuff.
26: */
27: int
28: tcp_connect(dest, param)
29: char *dest, *param;
30: {
31: struct hostent *hp;
32: struct sockaddr_in sin;
33: char *inet_ntoa();
34: int s, port, i;
35: unsigned long addr;
36: char buf[100];
37: char *host, *service;
38: char *h_addr_list[2];
39: int errtype = 0;
40: char errstr[256];
41:
42: strcpy(buf, dest);
43: host = buf;
44:
45: if ((port = tcp_service(host)) < 0) {
46: ipcseterror(EX_NOHOST, "unknown service", "tcp_connect");
47: return(-1);
48: }
49:
50: if (ipcdebug)
51: fprintf(stderr, "TCP port number is %d\n", ntohs(port));
52:
53: if ((addr = inet_addr(host)) != (unsigned long) -1) {
54: if (ipcdebug)
55: fprintf(stderr, "Numeric address: %s %lx\n",
56: host, addr);
57: s = socket(AF_INET, SOCK_STREAM, 0);
58: if(s < 0){
59: ipcsyserr("can't open socket");
60: return(-1);
61: }
62: bzero((char *)&sin, sizeof(sin));
63: sin.sin_family = AF_INET;
64: sin.sin_port = port;
65: sin.sin_addr.s_addr = addr;
66: if(connect(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0) {
67: setopt(s);
68: return s;
69: }
70: ipcsyserr("can't connect");
71: close(s);
72: return -1;
73: }
74:
75: if((hp = gethostbyname(host)) == (struct hostent *)0){
76: ipcseterror(EX_NOHOST, "unknown host", "tcp_connect");
77: return(-1);
78: }
79: h_addr_list[0] = hp->h_addr;
80: h_addr_list[1] = 0;
81: for(i=0; h_addr_list[i]; i++ ){
82: bzero((char *)&sin, sizeof(sin));
83: bcopy(h_addr_list[i], &sin.sin_addr, hp->h_length);
84: sin.sin_family = hp->h_addrtype;
85: sin.sin_port = port;
86: if (ipcdebug)
87: fprintf(stderr, "Trying address %s\n",
88: inet_ntoa(sin.sin_addr));
89:
90: s = socket(AF_INET, SOCK_STREAM, 0);
91: if(s < 0){
92: ipcsyserr("can't open socket");
93: return(-1);
94: }
95: if(connect(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0) {
96: setopt(s);
97: return s;
98: }
99: ipcgetsyserr();
100: if (errtype == 0 ||
101: (errtype != EX_TEMPFAIL && ipcmaperror()==EX_TEMPFAIL)) {
102: errtype = ipcmaperror();
103: strcpy(errstr, syserrstr);
104: }
105: ipcsyserr("connect");
106: close(s);
107: }
108:
109: ipcseterror(errtype, errstr, "Can't connect to host");
110: return -1;
111: }
112:
113: setopt(s)
114: int s;
115: {
116: /*
117: * for some reason, the following linger does not seem
118: * to have any effect, at least on the Sun `shamash'.
119: * I have placed a sleep before the close in ../pftp/ftp.c
120: * in the routine sendrequest.
121: * suggestions are [email protected]
122: */
123: struct linger linger;
124:
125: linger.l_onoff = 1;
126: linger.l_linger = 3000;
127: if (setsockopt(s, SOL_SOCKET, SO_LINGER, (char *)&linger,
128: sizeof (linger)) < 0)
129: ipcsyserr("error setting socket option");
130: return s;
131: }
132:
133: int
134: tcp_service(path)
135: char *path;
136: {
137: struct servent *sp;
138: char *service;
139:
140: if ((service = strchr(path, '!')) == NULL)
141: service = "";
142: else
143: *service++ = '\0';
144:
145: /*
146: * translate service/port name
147: */
148: if(strncmp(service, "tcp.", 4)==0)
149: service += 4;
150: if(strncmp(service, "/cs/", 4)==0)
151: service += 4;
152: if(strcmp(service, "")==0)
153: return 0;
154: else if(atoi(service)!=0)
155: return atoi(htons(service));
156: else if ((sp = getservbyname (service, "tcp")) != NULL)
157: return sp->s_port;
158: return -1;
159: }
160:
161: int
162: tcp_close(fd)
163: int fd;
164: {
165: write(fd, &fd, 0); /* stub - is this useful or necessary? */
166: if (shutdown(fd, 2) < 0)
167: ipcseterror(EX_SOFTWARE, "shutdown failed", "tcp_close");
168: return close(fd);
169: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.