|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T g
Length: 5092 (0x13e4)
Types: TextFile
Names: »gethost.c«
└─⟦87ddcff64⟧ Bits:30001253 CPHDIST85 Tape, 1985 Autumn Conference Copenhagen
└─⟦this⟧ »cph85dist/rman/client/gethost.c«
/*
* 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);
}