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