From 4b7a174cdea92f937ab6f9b43310d0512c27e102 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Sat, 6 Apr 2002 00:20:53 +0000 Subject: [PATCH] * sclient.c: Include fake-addrinfo.h. Include stdlib.h unconditionally. (net_read): New function, borrowed from krb5_net_read. (main): Use krb5_c_valid_cksumtype, net_read, getaddrinfo, getnameinfo. Try contacting each address for the host. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@14362 dc483132-0cff-0310-8789-dd5450dbe970 --- src/appl/sample/sclient/ChangeLog | 8 ++ src/appl/sample/sclient/sclient.c | 153 +++++++++++++++++------------- 2 files changed, 93 insertions(+), 68 deletions(-) diff --git a/src/appl/sample/sclient/ChangeLog b/src/appl/sample/sclient/ChangeLog index 50cd26492..4fdcef4ad 100644 --- a/src/appl/sample/sclient/ChangeLog +++ b/src/appl/sample/sclient/ChangeLog @@ -1,3 +1,11 @@ +2002-04-05 Ken Raeburn + + * sclient.c: Include fake-addrinfo.h. Include stdlib.h + unconditionally. + (net_read): New function, borrowed from krb5_net_read. + (main): Use krb5_c_valid_cksumtype, net_read, getaddrinfo, + getnameinfo. Try contacting each address for the host. + 2002-03-28 Ken Raeburn * sclient.c: Include errno.h. diff --git a/src/appl/sample/sclient/sclient.c b/src/appl/sample/sclient/sclient.c index a1fff5125..46877211b 100644 --- a/src/appl/sample/sclient/sclient.c +++ b/src/appl/sample/sclient/sclient.c @@ -41,17 +41,15 @@ #include #include #include +#include "fake-addrinfo.h" /* not everyone implements getaddrinfo yet */ + #include #ifdef HAVE_UNISTD_H #include #endif -#ifdef HAVE_STDLIB_H #include -#else -extern char *malloc(); -#endif #include "../sample.h" @@ -59,16 +57,42 @@ extern char *malloc(); #define GETSOCKNAME_ARG3_TYPE int #endif +static int +net_read(fd, buf, len) + int fd; + char *buf; + int len; +{ + int cc, len2 = 0; + + do { + cc = SOCKET_READ((SOCKET)fd, buf, len); + if (cc < 0) { + if (SOCKET_ERRNO == SOCKET_EINTR) + continue; + + /* XXX this interface sucks! */ + errno = SOCKET_ERRNO; + + return(cc); /* errno is already set */ + } + else if (cc == 0) { + return(len2); + } else { + buf += cc; + len2 += cc; + len -= cc; + } + } while (len > 0); + return(len2); +} + int -main(argc, argv) -int argc; -char *argv[]; +main(int argc, char *argv[]) { - struct servent *sp; - struct hostent *hp; - struct sockaddr_in sockin, lsockin; + struct addrinfo *ap, aihints; + int aierr; int sock; - GETSOCKNAME_ARG3_TYPE namelen; krb5_context context; krb5_data recv_data; krb5_data cksum_data; @@ -79,6 +103,7 @@ char *argv[]; krb5_ap_rep_enc_part *rep_ret; krb5_auth_context auth_context = 0; short xmitlen; + char *portstr; char *service = SAMPLE_SERVICE; if (argc != 2 && argc != 3 && argc != 4) { @@ -93,76 +118,68 @@ char *argv[]; } (void) signal(SIGPIPE, SIG_IGN); - if (!valid_cksumtype(CKSUMTYPE_CRC32)) { - com_err(argv[0], KRB5_PROG_SUMTYPE_NOSUPP, "while using CRC-32"); + + if (argc > 2) + portstr = argv[2]; + else + portstr = SAMPLE_PORT; + + memset(&aihints, 0, sizeof(aihints)); + aihints.ai_socktype = SOCK_STREAM; + aierr = getaddrinfo(argv[1], portstr, &aihints, &ap); + if (aierr) { + fprintf(stderr, "%s: error looking up host '%s' port '%s'/tcp: %s\n", + argv[0], argv[1], portstr, gai_strerror(aierr)); exit(1); } - - /* clear out the structure first */ - (void) memset((char *)&sockin, 0, sizeof(sockin)); - - if (argc > 2) { - sockin.sin_family = AF_INET; - sockin.sin_port = htons(atoi(argv[2])); - } else { - /* find the port number for knetd */ - sp = getservbyname(SAMPLE_PORT, "tcp"); - if (!sp) { - fprintf(stderr, - "unknown service %s/tcp; check /etc/services\n", - SAMPLE_PORT); - exit(1); - } - /* copy the port number */ - sockin.sin_port = sp->s_port; - sockin.sin_family = AF_INET; + if (ap == 0) { + /* Should never happen. */ + fprintf(stderr, "%s: error looking up host '%s' port '%s'/tcp: no addresses returned?\n", + argv[0], argv[1], portstr); + exit(1); } + if (argc > 3) { service = argv[3]; } - /* look up the server host */ - hp = gethostbyname(argv[1]); - if (!hp) { - fprintf(stderr, "unknown host %s\n",argv[1]); - exit(1); - } - retval = krb5_sname_to_principal(context, argv[1], service, KRB5_NT_SRV_HST, &server); if (retval) { - com_err(argv[0], retval, "while creating server name for %s/%s", + com_err(argv[0], retval, "while creating server name for host %s service %s", argv[1], service); exit(1); } /* set up the address of the foreign socket for connect() */ - sockin.sin_family = hp->h_addrtype; - (void) memcpy((char *)&sockin.sin_addr, - (char *)hp->h_addr, - sizeof(hp->h_addr)); - - /* open a TCP socket */ - sock = socket(PF_INET, SOCK_STREAM, 0); - if (sock < 0) { - perror("socket"); - exit(1); - } - - /* connect to the server */ - if (connect(sock, (struct sockaddr *)&sockin, sizeof(sockin)) < 0) { - perror("connect"); - close(sock); - exit(1); + for (sock = -1; ap && sock == -1; ap = ap->ai_next) { + char abuf[NI_MAXHOST], pbuf[NI_MAXSERV]; + char mbuf[NI_MAXHOST + NI_MAXSERV + 64]; + if (getnameinfo(ap->ai_addr, ap->ai_addrlen, abuf, sizeof(abuf), + pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { + memset(abuf, 0, sizeof(abuf)); + strncpy(abuf, "[error, cannot print address?]", + sizeof(abuf)-1); + strcpy(pbuf, "[?]"); + } + sprintf(mbuf, "error contacting %s port %s", abuf, pbuf); + sock = socket(ap->ai_family, SOCK_STREAM, 0); + if (sock < 0) { + fprintf(stderr, "%s: socket: %s\n", mbuf, strerror(errno)); + continue; + } + if (connect(sock, ap->ai_addr, ap->ai_addrlen) < 0) { + fprintf(stderr, "%s: connect: %s\n", mbuf, strerror(errno)); + close(sock); + sock = -1; + continue; + } + /* connected, yay! */ } - - /* find out who I am, now that we are connected and therefore bound */ - namelen = sizeof(lsockin); - if (getsockname(sock, (struct sockaddr *) &lsockin, &namelen) < 0) { - perror("getsockname"); - close(sock); + if (sock == -1) + /* Already printed error message above. */ exit(1); - } + printf("connected\n"); cksum_data.data = argv[1]; cksum_data.length = strlen(argv[1]); @@ -203,8 +220,8 @@ char *argv[]; krb5_free_ap_rep_enc_part(context, rep_ret); printf("sendauth succeeded, reply is:\n"); - if ((retval = krb5_net_read(context, sock, (char *)&xmitlen, - sizeof(xmitlen))) <= 0) { + if ((retval = net_read(sock, (char *)&xmitlen, + sizeof(xmitlen))) <= 0) { if (retval == 0) errno = ECONNABORTED; com_err(argv[0], errno, "while reading data from server"); @@ -216,8 +233,8 @@ char *argv[]; "while allocating buffer to read from server"); exit(1); } - if ((retval = krb5_net_read(context, sock, (char *)recv_data.data, - recv_data.length)) <= 0) { + if ((retval = net_read(sock, (char *)recv_data.data, + recv_data.length)) <= 0) { if (retval == 0) errno = ECONNABORTED; com_err(argv[0], errno, "while reading data from server"); -- 2.26.2