Return to BSD News archive
Xref: sserve comp.infosystems.www.browsers.misc:190 comp.unix.questions:64297 comp.unix.bsd.freebsd.misc:1109 comp.unix.bsd:16585 comp.lang.c:100314 Path: sserve!newshost.anu.edu.au!harbinger.cc.monash.edu.au!yarrina.connect.com.au!classic.iinet.com.au!news.uoknor.edu!news.ecn.uoknor.edu!constellation!convex!news.netins.net!newshost.marcam.com!news.mathworks.com!gatech!swrinde!elroy.jpl.nasa.gov!decwrl!vixie!nnrp!vixie From: vixie@gw.home.vix.com (Paul A Vixie) Newsgroups: comp.infosystems.www.browsers.misc,comp.unix.questions,comp.unix.bsd.freebsd.misc,comp.unix.bsd,comp.lang.c Subject: Re: Simple socket/telnet library? Date: 13 May 1995 00:33:10 GMT Organization: Vixie Enterprises Lines: 164 Message-ID: <VIXIE.95May12173310@gw.home.vix.com> References: <3osqe0$5ei@gate.sinica.edu.tw> NNTP-Posting-Host: gw.home.vix.com In-reply-to: taob@gate.sinica.edu.tw's message of 11 May 1995 10:54:56 GMT > If there is a ready-made library with functions akin to tcpopen(), > tcpwrite(), tcpread() and tcpclose() that works with a 4.4BSD system > (FreeBSD 2.0, in my case), that would be fantastic. Source code fragments, > tutorial files, primers, etc. also gratefully accepted. Thanks. Everybody's got one or more of these. Here's (one of) mine. Note that your tcpopen() is hard (i call it rconnect() below) but after you get your file descriptor you just use read(), write(), fdopen()/fprintf()/fscanf(), and close(). /* rconnect - connect to a service on a remote host * vix 13sep91 [written - again, dammit] */ #ifndef LINT static char RCSid[] = "$Id: connutil.c,v 1.5 1994/05/16 06:36:09 vixie Exp vixie $"; #endif #ifdef WANT_TCPIP #include <stdio.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <setjmp.h> #include <signal.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include "rtty.h" extern int h_errno; extern char *ProgName; /* assume ip/tcp for now */ static jmp_buf jmpalrm; static void sigalrm __P((int)); static int doconnect(n, ns, to) struct sockaddr_in *n; int ns, 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(host, service, verbose, errors, timeout) char *host; 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(x) { longjmp(jmpalrm, 1); /*NOTREACHED*/ } #endif /*WANT_TCPIP*/ -- Paul Vixie La Honda, CA "Illegitimi non carborundum." <paul@vix.com> pacbell!vixie!paul (dont let the bastards grind you down)