|
|
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.