long lookuphost (char **host,struct sockaddr_in *sin) { char *s = *host; /* in case of error */ sin->sin_addr.s_addr = rhost (host); if (sin->sin_addr.s_addr == -1) { *host = s; /* error, restore old host name */ return NIL; } *host = cpystr (*host); /* make permanent copy of name */ return T; /* success */ }
static int get_tcp_socket( char *machine, /* remote host */ char *service, /* nttp/smtp etc. */ unsigned short port) /* tcp port number */ { int s = -1; int save_errno = 0; struct sockaddr_in sock_in; # ifdef TLI /* Transport Level Interface */ char device[20]; char *env_device; extern int t_errno; extern struct hostent *gethostbyname(); struct hostent *hp; struct t_call *callptr; /* * Create a TCP transport endpoint. */ if ((env_device = getenv("DEV_TCP")) != NULL) /* SCO uses DEV_TCP, most other OS use /dev/tcp */ STRCPY(device, env_device); else strcpy(device, "/dev/tcp"); if ((s = t_open(device, O_RDWR, (struct t_info *) 0)) < 0){ t_error(txt_error_topen); return -EPROTO; } if (t_bind(s, (struct t_bind *) 0, (struct t_bind *) 0) < 0) { t_error("t_bind"); t_close(s); return -EPROTO; } memset((char *) &sock_in, '\0', sizeof(sock_in)); sock_in.sin_family = AF_INET; sock_in.sin_port = htons(port); if (!isdigit((unsigned char)*machine) || # ifdef HAVE_INET_ATON !inet_aton(machine, &sock_in) # else # ifdef HAVE_INET_ADDR (long) (sock_in.sin_addr.s_addr = inet_addr(machine)) == INADDR_NONE) # endif /* HAVE_INET_ADDR */ # endif /* HAVE_INET_ATON */ { if ((hp = gethostbyname(machine)) == NULL) { my_fprintf(stderr, _(txt_gethostbyname), "gethostbyname() ", machine); t_close(s); return -EHOSTUNREACH; } memcpy((char *) &sock_in.sin_addr, hp->h_addr, hp->h_length); } /* * Allocate a t_call structure and initialize it. * Let t_alloc() initialize the addr structure of the t_call structure. */ if ((callptr = (struct t_call *) t_alloc(s, T_CALL, T_ADDR)) == NULL){ t_error("t_alloc"); t_close(s); return -EPROTO; } callptr->addr.maxlen = sizeof(sock_in); callptr->addr.len = sizeof(sock_in); callptr->addr.buf = (char *) &sock_in; callptr->opt.len = 0; /* no options */ callptr->udata.len = 0; /* no user data with connect */ /* * Connect to the server. */ if (t_connect(s, callptr, (struct t_call *) 0) < 0) { save_errno = t_errno; if (save_errno == TLOOK) fprintf(stderr, _(txt_error_server_unavailable)); else t_error("t_connect"); t_free((char *) callptr, T_CALL); t_close(s); return -save_errno; } /* * Now replace the timod module with the tirdwr module so that * standard read() and write() system calls can be used on the * descriptor. */ t_free((char *) callptr, T_CALL); if (ioctl(s, I_POP, (char *) 0) < 0) { perror("I_POP(timod)"); t_close(s); return -EPROTO; } if (ioctl(s, I_PUSH, "tirdwr") < 0) { perror("I_PUSH(tirdwr)"); t_close(s); return -EPROTO; } # else # ifndef EXCELAN struct servent *sp; struct hostent *hp; # ifdef h_addr int x = 0; char **cp; static char *alist[2] = {0, 0}; # endif /* h_addr */ static struct hostent def; static struct in_addr defaddr; static char namebuf[256]; # ifdef HAVE_GETSERVBYNAME if ((sp = (struct servent *) getservbyname(service, "tcp")) == NULL) { my_fprintf(stderr, _(txt_error_unknown_service), service); return -EHOSTUNREACH; } # else sp = my_malloc(sizeof(struct servent)); sp->s_port = htons(IPPORT_NNTP); # endif /* HAVE_GETSERVBYNAME */ /* If not a raw ip address, try nameserver */ if (!isdigit((unsigned char) *machine) || # ifdef HAVE_INET_ATON !inet_aton(machine, &defaddr) # else # ifdef HAVE_INET_ADDR (long) (defaddr.s_addr = (long) inet_addr(machine)) == -1 # endif /* HAVE_INET_ADDR */ # endif /* HAVE_INET_ATON */ ) { hp = gethostbyname(machine); } else { /* Raw ip address, fake */ STRCPY(namebuf, machine); def.h_name = (char *) namebuf; # ifdef h_addr def.h_addr_list = alist; # endif /* h_addr */ def.h_addr = (char *) &defaddr; def.h_length = sizeof(struct in_addr); def.h_addrtype = AF_INET; def.h_aliases = 0; hp = &def; } if (hp == NULL) { my_fprintf(stderr, _(txt_gethostbyname), "\n", machine); return -EHOSTUNREACH; } memset((char *) &sock_in, '\0', sizeof(sock_in)); sock_in.sin_family = hp->h_addrtype; sock_in.sin_port = htons(port); /* sock_in.sin_port = sp->s_port; */ # else memset((char *) &sock_in, '\0', sizeof(sock_in)); sock_in.sin_family = AF_INET; # endif /* !EXCELAN */ /* * The following is kinda gross. The name server under 4.3 * returns a list of addresses, each of which should be tried * in turn if the previous one fails. However, 4.2 hostent * structure doesn't have this list of addresses. * Under 4.3, h_addr is a #define to h_addr_list[0]. * We use this to figure out whether to include the NS specific * code... */ # ifdef h_addr /* * Get a socket and initiate connection -- use multiple addresses */ for (cp = hp->h_addr_list; cp && *cp; cp++) { # if defined(__hpux) && defined(SVR4) unsigned long socksize, socksizelen; # endif /* __hpux && SVR4 */ if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) { perror("socket"); return -errno; } memcpy((char *) &sock_in.sin_addr, *cp, hp->h_length); # ifdef HAVE_INET_NTOA if (x < 0) my_fprintf(stderr, _(txt_trying), (char *) inet_ntoa(sock_in.sin_addr)); # endif /* HAVE_INET_NTOA */ # if defined(__hpux) && defined(SVR4) /* recommended by [email protected] */ # define HPSOCKSIZE 0x8000 getsockopt(s, SOL_SOCKET, SO_SNDBUF, /* (caddr_t) */ &socksize, /* (caddr_t) */ &socksizelen); if (socksize < HPSOCKSIZE) { socksize = HPSOCKSIZE; setsockopt(s, SOL_SOCKET, SO_SNDBUF, /* (caddr_t) */ &socksize, sizeof(socksize)); } socksize = 0; socksizelen = sizeof(socksize); getsockopt(s, SOL_SOCKET, SO_RCVBUF, /* (caddr_t) */ &socksize, /* (caddr_t) */ &socksizelen); if (socksize < HPSOCKSIZE) { socksize = HPSOCKSIZE; setsockopt(s, SOL_SOCKET, SO_RCVBUF, /* (caddr_t) */ &socksize, sizeof(socksize)); } # endif /* __hpux && SVR4 */ if ((x = connect(s, (struct sockaddr *) &sock_in, sizeof(sock_in))) == 0) break; save_errno = errno; /* Keep for later */ # ifdef HAVE_INET_NTOA my_fprintf(stderr, _(txt_connection_to), (char *) inet_ntoa(sock_in.sin_addr)); perror(""); # endif /* HAVE_INET_NTOA */ (void) s_close(s); } if (x < 0) { my_fprintf(stderr, _(txt_giving_up)); return -save_errno; /* Return the last errno we got */ } # else # ifdef EXCELAN if ((s = socket(SOCK_STREAM, (struct sockproto *) NULL, &sock_in, SO_KEEPALIVE)) < 0) { perror("socket"); return -errno; } /* set up addr for the connect */ memset((char *) &sock_in, '\0', sizeof(sock_in)); sock_in.sin_family = AF_INET; sock_in.sin_port = htons(IPPORT_NNTP); if ((sock_in.sin_addr.s_addr = rhost(&machine)) == -1) { my_fprintf(stderr, _(txt_gethostbyname), "\n", machine); return -1; } /* And connect */ if (connect(s, (struct sockaddr *) &sock_in) < 0) { save_errno = errno; perror("connect"); (void) s_close(s); return -save_errno; } # else if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); return -errno; } /* And then connect */ memcpy((char *) &sock_in.sin_addr, hp->h_addr, hp->h_length); if (connect(s, (struct sockaddr *) &sock_in, sizeof(sock_in)) < 0) { save_errno = errno; perror("connect"); (void) s_close(s); return -save_errno; } # endif /* !EXCELAN */ # endif /* !h_addr */ # endif /* !TLI */ return s; }