/* getloadavg.c -- routine to get loadavgd-values
** this version is used with loadavgd-server in aix3
*/

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

#include "getloadavg.h"

#define MIN(a,b) ((a)<(b)?(a):(b))

int signal_handler(sig, code, scp)
int sig;
int code;
struct sigcontext *scp;
{
    /* set this signal-handler again */
    signal(sig,signal_handler);
}

getloadavg(loadv,nelem)
double loadv[];
int nelem;
{
    static int initted=0;
    static int sock;
    static struct sockaddr_in server;
    static struct hostent *hp;
    static long alarm_sig;
    char buf[80];
    int status;
    int server_len = sizeof(struct sockaddr_in);
    int errno2;
    int i;

    if (! initted) {
	initted=1;
        sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock < 0) { perror("opening datagram socket"); exit(1); }
	server.sin_family = AF_INET;
	hp = gethostbyname("localhost");
	if (hp == 0) { fprintf(stderr,"localhost unknown\n"); exit(1); }
	bcopy(hp->h_addr, &server.sin_addr, hp->h_length);
	server.sin_port = htons(LOADAVGD_PORT);
    }
    
    /* send something to loadavgd-server to get reply back */
    status = sendto(sock,"\n\000",2,0, &server,sizeof(server));
    if (status == -1) {perror("getloadavg: sendto loadavgd");exit(1);}

    alarm_sig = signal(SIGALRM,signal_handler);
    alarm(2); /* lets wait for 2 second to get respond from server */
    status = recvfrom(sock, buf, 80,0, &server, &server_len);
    errno2 = errno;
    alarm(0);
    signal(SIGALRM,alarm_sig);

    if (status==-1) {
	if (errno2 == EINTR) { /* if recvfrom was interrupter by alarm */
	    fprintf(stderr,"\n***getloadavg: starting loadavgd-daemon ***\n");
	    launch_loadavgd();
	    fflush(stderr);
	    sleep(1);
	    status = sendto(sock,"\n\000",2,0, &server,sizeof(server));
	    if (status == -1) {perror("getloadavg: sendto loadavgd");exit(1);}
	    status = recvfrom(sock, buf, 80,0, &server, &server_len);
	}
	if (status == -1) {
	    perror("getloadavg: recvfrom from loadavgd daemon");
	    exit(1);
	}
    }
    if (nelem == 3) sscanf(buf,"%lf %lf %lf",&loadv[0],&loadv[1],&loadv[2]);
    if (nelem == 2) sscanf(buf,"%lf %lf",&loadv[0],&loadv[1]);
    if (nelem == 1) sscanf(buf,"%lf",&loadv[0]);
}
