/* rconnect - connect to a service on a remote host * vix 13sep91 [written - again, dammit] */ #ifndef LINT static char RCSid[] = "$Id: connutil.c,v 1.9 2001/03/24 21:14:25 vixie Exp $"; #endif /* Copyright (c) 1996 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #ifdef WANT_TCPIP #include #include #include #include #include #include #include #include #include #include "rtty.h" #include "misc.h" extern int h_errno; extern char *ProgName; /* assume ip/tcp for now */ static jmp_buf jmpalrm; static void sigalrm(int); static int doconnect(struct sockaddr_in *n, int ns, int to) { int sock, ok, save; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { return -1; } if (to) { if (!setjmp(jmpalrm)) { signal(SIGALRM, sigalrm); alarm(to); } else { errno = ETIMEDOUT; goto finito; } } ok = (connect(sock, (struct sockaddr *)n, ns) >= 0); save = errno; finito: if (to) { alarm(0); signal(SIGALRM, SIG_DFL); } if (!ok) { close(sock); errno = save; return -1; } errno = save; return sock; } int rconnect(const char *host, const char *service, FILE *verbose, FILE *errors, int timeout) { u_int32_t **hp; struct hostent *h; struct sockaddr_in n; int port, sock, done; if (!(port = htons(atoi(service)))) { struct servent *s = getservbyname(service, "tcp"); if (!s) { if (errors) { fprintf(errors, "%s: unknown service\n", service); } errno = ENOPROTOOPT; return -1; } port = s->s_port; } n.sin_family = AF_INET; #ifndef NO_SOCKADDR_LEN n.sin_len = sizeof(struct sockaddr_in); #endif n.sin_port = port; if (inet_aton(host, &n.sin_addr)) { if (verbose) { fprintf(verbose, "trying [%s]\n", inet_ntoa(n.sin_addr.s_addr)); } done = ((sock = doconnect(&n, sizeof n, timeout)) >= 0); } else { h = gethostbyname(host); if (!h) { if (errors) { #ifndef NO_HSTRERROR fprintf(errors, "%s: %s\n", host, hstrerror(h_errno)); #else fprintf(errors, "%s: cannot resolve hostname\n", host); #endif } return -1; } for (hp = (u_int32_t**)h->h_addr_list; *hp; hp++) { bcopy(*hp, (caddr_t)&n.sin_addr.s_addr, h->h_length); if (verbose) { fprintf(verbose, "trying [%s]\n", inet_ntoa(**hp)); } if ((sock = doconnect(&n, sizeof n, timeout)) >= 0) { break; } } done = (*hp != NULL); } if (!done) { if (errors) { fprintf(errors, "%s: %s\n", host, strerror(errno)); } close(sock); return -1; } return sock; } static void sigalrm(int x) { longjmp(jmpalrm, 1); /*NOTREACHED*/ } #endif /*WANT_TCPIP*/