DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T g

⟦114917375⟧ TextFile

    Length: 5092 (0x13e4)
    Types: TextFile
    Names: »gethost.c«

Derivation

└─⟦87ddcff64⟧ Bits:30001253 CPHDIST85 Tape, 1985 Autumn Conference Copenhagen
    └─ ⟦this⟧ »cph85dist/rman/client/gethost.c« 

TextFile

/*
 *  Copyright (c) 1985  Jonathan C. Broome and The Regents of the 
 *  University of California.
 *
 *  This software may be freely redistributed without licensing
 *  provided that this copyright notice remains intact and no profit
 *  is gained through any redistribution.
 *
 *  Please report any bug fixes or modifications to the author at:
 *
 *        broome@ucb-vax.berkeley.edu
 *   or:
 *        ...!ucbvax!broome
 *
 *  The author and the Regents assume no liability for any damages 
 *  or loss of revenue caused directly or indirectly by the use of 
 *  this software.
 */

#ifndef lint
static char RCSid[] = "$Header: gethost.c,v 1.7 85/08/27 15:19:41 broome Exp $";
#endif

/*
 * $Log:    gethost.c,v $
 * Revision 1.7  85/08/27  15:19:41  broome
 * Added copyright/distribution comment.
 * 
 * Revision 1.6  85/08/27  15:04:37  broome
 * Final cleanup before sending out.
 * 
 * Revision 1.5  85/08/04  18:41:06  broome
 * 
 * Revision 1.4  85/07/31  22:18:22  broome
 * Changed all tracing routines ("verbose") to print to stderr, not stdout....
 * 
 * Revision 1.3  85/07/24  10:38:49  broome
 * 
 * Revision 1.2  85/07/13  15:29:06  broome
 * Changed to ignore errors on sendto - don't want users to see "sendto: 
 * network is unreachable" all over the place...
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdio.h>

/*  Return the ascii form of this address  */
#define asc(sin)  inet_ntoa(sin.sin_addr.s_addr)
#define vprintf   if (verbose) fprintf

#ifndef HOSTS
#define HOSTS "/c/support/broome/mandy/client/man.hosts"
#endif

/*
 *  Try to find an available server host, 
 *  Returns a stream socket descriptor.
 */

get_host (port)
int port;        /* in network order */
{
    struct sockaddr_in sin, low;
    static struct timeval timeout = { 0, 100 };   /* 1/10th sec timeout */
    float  curr_low = 200.0;           /* higher than your system goes! */
    float  la;
    int    got_one = 0;
    int    sock;
    int    hosts;
    int    eof = 0;
    extern int errno;
    extern int verbose;
    char   buf[20];
    char   line[128];
    char   *inet_ntoa();
    char   *index();
    char   *i;
    FILE   *fp;

    if ((fp = fopen (HOSTS, "r")) == NULL)
        return (-1);

    bzero ((char *)&sin, sizeof (sin));
    sin.sin_family = AF_INET;
    sin.sin_port   = port;
    if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror ("get_host: datagram socket");
        return (1);
    }

    while (!got_one && !eof) {
        /*  Read one set of hosts, ping each one  */
        hosts = 0;
        for ( ;; ) {
            if (!fgets (line, 128, fp)) {   /* end of file - drop out */
                eof = 1;
                break;
            }
            i = line;
            /* blank line - end of host group */
            if (*i == '\n' || *i == ' ' || *i == '\t')   
                break;
            if (*i == '#')  /* comment */
                continue;

            if (i = index (line, ' '))     /* grab the first word */
                *i = '\0';
            if (i = index (line, '\t'))
                *i = '\0';

            /* ping each host */
            sin.sin_addr.s_addr = inet_addr (line);
            vprintf (stderr, "Pinging address %s (%s)\n", asc (sin), i+1);
            (void) sendto (sock, "man", 4, 0, &sin, sizeof (sin));
            hosts++;                      /* increment ping count */
        }

        if (!hosts)    /* didn't ping any hosts */
            continue;

        for ( ; hosts; hosts--) {    /* now listen for responses */
            int x, mask = 1 << sock;
            if ((x = select (20, &mask, 0, 0, &timeout)) <= 0) { /* timed out */
                vprintf (stderr, "Select returns %d.\n", x);
                if (got_one)             /* do we already have a viable host? */
                    break;
                continue;
            }
            if ((x = recvfrom (sock, buf, 20, 0, &sin, sizeof (sin))) <= 0)
                continue;
            buf[x] = '\0';
            (void) sscanf (buf, "%f", &la);
            vprintf (stderr, "Recv: address is %s, la is %.2f\n", asc(sin), la);
            if (la < curr_low) {     /* this load lower than previous */
                curr_low = la;       /* save this load */
                bcopy ((char *)&sin, (char *)&low, sizeof (sin));  /*save addr*/
            }
            got_one++;
        }
    }
    (void) fclose (fp);
    (void) close (sock);     /* shutdown datagram socket */
    if (!got_one)            /* timed out after pinging all hosts */
        return (-1);

    vprintf (stderr, "Selected host: address is %s, load is %.2f\n", 
                asc (low), curr_low);

    /* open a stream socket to the selected host */

    if ((sock = socket (AF_INET, SOCK_STREAM, 0)) < 0) { 
        perror ("get_host: socket");
        return (-1);
    }

    if (connect (sock, &low, sizeof (low)) < 0) {
        if (errno != ECONNREFUSED)
            perror ("get_host: connect");
        return (-1);
    }
    return (sock);
}