home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume24 / lb / srvclnt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-05  |  5.7 KB  |  218 lines

  1. /*
  2.  * Copyright (c) 1989, University of Rochester
  3.  * Department of Electrical Engineering
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms are permitted
  7.  * provided that the above copyright notice and this paragraph are
  8.  * duplicated in all such forms and that any documentation,
  9.  * advertising materials, and other materials related to such
  10.  * distribution and use acknowledge that the software was developed
  11.  * at the University of Rochester.
  12.  *
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. /* srvclnt.c version 1.1  3/7/89
  19.  * for the 'lb' load balancer - by Deke Kassabian
  20.  *
  21.  *   -Deke Kassabian, University of Rochester EE Department
  22.  *   ( deke@ee.rochester.edu )  (716) 275-3106
  23.  */
  24.  
  25. #include <sys/param.h>
  26. #include <sys/socket.h>
  27. #include <netinet/in.h>
  28. #include <netdb.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include "stats.h"
  32. #include "config.h"
  33.  
  34. char *pname;
  35. short    server = 0;            /* indicates we aren't server    */
  36. struct    sockaddr_in sin;        /* address of remote host    */
  37.  
  38. main(argc, argv, envp)
  39. int argc;
  40. char **argv;
  41. char **envp;
  42. {
  43.     FILE *fd,*fopen();
  44.  
  45. int start,             /* where in the argv the command begins */
  46.     ppgrp,            /* parent process group            */
  47.     command,            /* whether there is a command         */
  48.     verbose_mode,         /* all possible output            */
  49.     quiet_mode;            /* no output                */
  50.  
  51. char *path=RSH;
  52.  
  53. char *dir;
  54. char *cmd_exec[MAXSHBUF],    /* command to execute (local)        */
  55.      *rcmd_exec[MAXSHBUF],    /* command to execute (remote)        */
  56.      dbuf[MAXSHBUF],        /* working directory placeholder    */
  57.      host[MAXHOST],        /* hostname placeholder            */
  58.      best_host[MAXHOST],    /* hostname placeholder            */
  59.      fentry[MAXLINE];        /* file entry                     */
  60.  
  61. float my_sfactor,
  62.       best_sfactor,
  63.       load,
  64.       factor,limit;        /* file variables            */
  65.  
  66.     int socktype;
  67.     register int s;
  68.     char buf[10240];
  69.     struct hostent *hp;
  70.     struct servent *sp;
  71.     char *servtype;
  72.     struct hostent *gethostbyname();
  73.     struct servent *getservbyname();
  74.  
  75.     pname = *argv;            /* Name of this program  */
  76.  
  77.     verbose_mode=0,quiet_mode=0;    /* Default is neither    */
  78.     best_sfactor=MAXFLOAT;         /* Practically infinity! */
  79.      command=1;            /* There is a command     */
  80.  
  81.  /* Check arguments. 
  82.   *
  83.   * if argc=1 then verbose=Y and command=NULL
  84.   * if argc>=2 check for flags:
  85.   *    -v=verbose (full output),  -q=quiet (don't output machine selection)
  86.   *    with no flags, only machine selection will be output
  87.   *    The above flags are mutually exclusive.  v overrides q
  88.   *
  89.   *    Additional arguments are taken to be a command.  No sanity checking
  90.   *    will be done.  When a machine is selected, the command will be run
  91.   *    on that machine
  92.   *
  93.   */
  94.  
  95.  if (argc == 1) {
  96.     command=0;            /* no command to execute */
  97.     verbose_mode=1;            /* verbose mode         */
  98.     }
  99.  else {
  100.      start=1;
  101.      if(!strcmp(argv[1],"-q")){
  102.       quiet_mode=1;            /* quiet mode - no output */
  103.       start=2;
  104.       if(argc == 2) exit(0);        /* No command, no output! */
  105.      } 
  106.      if(!strcmp(argv[1],"-v")){
  107.       verbose_mode=1;            /* verbose mode         */
  108.       start=2;
  109.       if(argc == 2) command=0;        /* No command - verbose   */
  110.      } 
  111.  }
  112.  
  113.   if(command){
  114.     for( ; start<argc; start++){
  115.         strcat(cmd_exec," "); strcat(cmd_exec,argv[start]);
  116.     }
  117.   }
  118.  
  119.  /* Open the config file */
  120.  if((fd=fopen(CONFIGFILE,"r"))==0){
  121.      fprintf(stderr,"Error opening configuration file ");
  122.      exit(1);
  123.  }
  124.  
  125.  /* Set up to use TCP stream sockets.  */
  126.     servtype = "tcp";
  127.     socktype = SOCK_STREAM;
  128.  
  129.  /* Look up the port the server lives on.  */
  130.  if ((sp = getservbyname(SERVNAME, servtype)) == NULL) {
  131.     fprintf(stderr, "%s: %s/%s: service unknown.\n", 
  132.         pname, SERVNAME, servtype);
  133.     exit(1);
  134.     }
  135.  
  136.  /* Read the config file */
  137.     strcpy(best_host,"localhost");
  138.     while((fgets(fentry,MAXLINE,fd))!=NULL){
  139.        sscanf(fentry,"%s %f %f",host,&factor,&limit);
  140.        if(fentry[0]=='#') continue; /*ignore comments*/
  141.         
  142.        if(verbose_mode)
  143.          printf("\nHOST=%s\tFACTOR=%.2f\tLIMIT=%.2f\n",host,factor,limit);
  144.        
  145.  
  146.        /* Look up the host's address.  */
  147.        if ((hp = gethostbyname(host)) == NULL) {
  148.         fprintf(stderr, "%s: %s: host unknown.\n", pname, host);
  149.         exit(1);
  150.        }
  151.     
  152.        /* Get a socket. */
  153.        if ((s = socket(AF_INET, socktype, 0)) < 0) {
  154.             error("socket");
  155.             exit(1);
  156.        }
  157.  
  158.         /* Build the server's address.  */
  159.         sin.sin_port = sp->s_port;
  160.         sin.sin_family = hp->h_addrtype;
  161.         bcopy(hp->h_addr, &sin.sin_addr, sizeof(sin.sin_addr));
  162.  
  163.         /* connect to the remote host.  */
  164.         if (connect(s, &sin, sizeof(struct sockaddr_in)) < 0) {
  165.             /* if not quiet mode, print connect error */
  166.             error("connect");
  167.             /* can't reach this host, try the next */
  168.             continue;
  169.         }
  170.  
  171.         /* make the request and grab the result */
  172.         st_send(s,"loadav");
  173.         st_recv(s,buf,sizeof(buf),"response");
  174.         sscanf(buf,"%f",&load);
  175.  
  176.             if( load > limit){
  177.                if(verbose_mode)
  178.               printf("Host %s is over defined limit\n",host);
  179.                continue;
  180.             }
  181.  
  182.         my_sfactor=100*( load / factor );
  183.         if(verbose_mode){
  184.           printf("Load avg=%.3f ",load);
  185.           printf("Selection factor=%.2f\n",my_sfactor);
  186.         }
  187.         
  188.         if(best_sfactor>my_sfactor){
  189.             best_sfactor=my_sfactor;
  190.             strcpy(best_host,host);
  191.         }
  192.  
  193.     } /*endwhile */
  194.  
  195. if(verbose_mode)
  196.    printf("Selected host: <%s> factor=<%.3f>\n",best_host,best_sfactor);
  197.  
  198.     if(command){
  199.         sprintf(rcmd_exec,"(cd %s;%s)",getwd(dbuf),cmd_exec);
  200.         if(!quiet_mode){    /* print if not quiet_mode */
  201.            printf("\nrsh %s %s &\n",best_host,rcmd_exec);
  202.         }
  203.         ppgrp = getpgrp(getppid());
  204.         if (fork())
  205.         exit(0);
  206.         if(setpgrp(getpid(), ppgrp)) 
  207.         perror("stepgrp");
  208.         execle(path,path,best_host,rcmd_exec,(char *)0,envp); exit(0);
  209.         perror("");
  210.      }
  211. exit(0);
  212. }
  213.  
  214. error(s)
  215. {
  216.     fprintf(stderr, "%s: ", pname); perror(s);
  217. }
  218.