home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-B.05 / NETKIT-B / NetKit-B-0.05 / rup / rup.c < prev   
Encoding:
C/C++ Source or Header  |  1993-12-17  |  7.3 KB  |  332 lines

  1. /*-
  2.  * Copyright (c) 1993, John Brezak
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char rcsid[] = "$Id: rup.c,v 1.9 1993/12/09 23:58:04 jtc Exp $";
  36. #endif /* not lint */
  37.  
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <time.h>
  42. #include <sys/param.h>
  43. #include <sys/socket.h>
  44. #include <netdb.h>
  45. #include <rpc/rpc.h>
  46. #include <arpa/inet.h>
  47. #include <err.h>
  48.  
  49. #undef FSHIFT            /* Use protocol's shift and scale values */
  50. #undef FSCALE
  51. #include <rpcsvc/rstat.h>
  52.  
  53. #define HOST_WIDTH 24
  54.  
  55. int printtime;            /* print the remote host(s)'s time */
  56.  
  57. struct host_list {
  58.     struct host_list *next;
  59.     struct in_addr addr;
  60. } *hosts;
  61.  
  62. int
  63. search_host(addr)
  64.     struct in_addr addr;
  65. {
  66.     struct host_list *hp;
  67.     
  68.     if (!hosts)
  69.         return(0);
  70.  
  71.     for (hp = hosts; hp != NULL; hp = hp->next) {
  72.         if (hp->addr.s_addr == addr.s_addr)
  73.             return(1);
  74.     }
  75.     return(0);
  76. }
  77.  
  78. void
  79. remember_host(addr)
  80.     struct in_addr addr;
  81. {
  82.     struct host_list *hp;
  83.  
  84.     if (!(hp = (struct host_list *)malloc(sizeof(struct host_list)))) {
  85.         err(1, NULL);
  86.         /* NOTREACHED */
  87.     }
  88.     hp->addr.s_addr = addr.s_addr;
  89.     hp->next = hosts;
  90.     hosts = hp;
  91. }
  92.  
  93.  
  94.  
  95. struct rup_data {
  96.     char *host;
  97.     struct statstime statstime;
  98. };
  99. struct rup_data *rup_data;
  100. int rup_data_idx = 0;
  101. int rup_data_max = 0;
  102.  
  103. enum sort_type { 
  104.     SORT_NONE,
  105.     SORT_HOST,
  106.     SORT_LDAV,
  107.     SORT_UPTIME
  108. };
  109. enum sort_type sort_type;
  110.  
  111. compare(d1, d2)
  112.     struct rup_data *d1;
  113.     struct rup_data *d2;
  114. {
  115.     switch(sort_type) {
  116.     case SORT_HOST:
  117.         return strcmp(d1->host, d2->host);
  118.     case SORT_LDAV:
  119.         return d1->statstime.avenrun[0] 
  120.             - d2->statstime.avenrun[0];
  121.     case SORT_UPTIME:
  122.         return d1->statstime.boottime.tv_sec 
  123.             - d2->statstime.boottime.tv_sec;
  124.     default:
  125.         /* something's really wrong here */
  126.         abort();
  127.     }
  128. }
  129.  
  130. void
  131. remember_rup_data(host, st)
  132.     char *host;
  133.     struct statstime *st;
  134. {
  135.         if (rup_data_idx >= rup_data_max) {
  136.                 rup_data_max += 16;
  137.                 rup_data = realloc (rup_data, 
  138.                 rup_data_max * sizeof(struct rup_data));
  139.                 if (rup_data == NULL) {
  140.                         err (1, NULL);
  141.             /* NOTREACHED */
  142.                 }
  143.         }
  144.     
  145.     rup_data[rup_data_idx].host = strdup(host);
  146.     rup_data[rup_data_idx].statstime = *st;
  147.     rup_data_idx++;
  148. }
  149.  
  150.  
  151. int
  152. rstat_reply(replyp, raddrp)
  153.     char *replyp;
  154.     struct sockaddr_in *raddrp;
  155. {
  156.     struct hostent *hp;
  157.     char *host;
  158.     statstime *host_stat = (statstime *)replyp;
  159.  
  160.     if (!search_host(raddrp->sin_addr)) {
  161.         hp = gethostbyaddr((char *)&raddrp->sin_addr.s_addr,
  162.             sizeof(struct in_addr), AF_INET);
  163.  
  164.         if (hp)
  165.             host = hp->h_name;
  166.         else
  167.             host = inet_ntoa(raddrp->sin_addr);
  168.  
  169.         remember_host(raddrp->sin_addr);
  170.  
  171.         if (sort_type != SORT_NONE) {
  172.             remember_rup_data(host, host_stat);
  173.         } else {
  174.             print_rup_data(host, host_stat);
  175.         }
  176.     }
  177.  
  178.     return (0);
  179. }
  180.  
  181.  
  182. int
  183. print_rup_data(host, host_stat)
  184.     char *host;
  185.     statstime *host_stat;
  186. {
  187.     struct tm *tmp_time;
  188.     struct tm host_time;
  189.     struct tm host_uptime;
  190.     char days_buf[16];
  191.     char hours_buf[16];
  192.  
  193.     printf("%-*.*s", HOST_WIDTH, HOST_WIDTH, host);
  194.  
  195.     tmp_time = localtime((time_t *)&host_stat->curtime.tv_sec);
  196.     host_time = *tmp_time;
  197.  
  198.     host_stat->curtime.tv_sec -= host_stat->boottime.tv_sec;
  199.  
  200.     tmp_time = gmtime((time_t *)&host_stat->curtime.tv_sec);
  201.     host_uptime = *tmp_time;
  202.  
  203.     if (host_uptime.tm_yday != 0)
  204.         sprintf(days_buf, "%3d day%s, ", host_uptime.tm_yday,
  205.             (host_uptime.tm_yday > 1) ? "s" : "");
  206.     else
  207.         days_buf[0] = '\0';
  208.  
  209.     if (host_uptime.tm_hour != 0)
  210.         sprintf(hours_buf, "%2d:%02d, ",
  211.             host_uptime.tm_hour, host_uptime.tm_min);
  212.     else
  213.         if (host_uptime.tm_min != 0)
  214.             sprintf(hours_buf, "%2d mins, ", host_uptime.tm_min);
  215.         else
  216.             hours_buf[0] = '\0';
  217.  
  218.     if (printtime)
  219.         printf(" %2d:%02d%cm", host_time.tm_hour % 12,
  220.             host_time.tm_min,
  221.             (host_time.tm_hour >= 12) ? 'p' : 'a');
  222.  
  223.     printf(" up %9.9s%9.9s load average: %.2f %.2f %.2f\n",
  224.         days_buf, hours_buf,
  225.         (double)host_stat->avenrun[0]/FSCALE,
  226.         (double)host_stat->avenrun[1]/FSCALE,
  227.         (double)host_stat->avenrun[2]/FSCALE);
  228.  
  229.     return(0);
  230. }
  231.  
  232.  
  233. void
  234. onehost(host)
  235.     char *host;
  236. {
  237.     CLIENT *rstat_clnt;
  238.     statstime host_stat;
  239.     
  240.     rstat_clnt = clnt_create(host, RSTATPROG, RSTATVERS_TIME, "udp");
  241.     if (rstat_clnt == NULL) {
  242.         warnx("%s", clnt_spcreateerror(host));
  243.         return;
  244.     }
  245.  
  246.     bzero((char *)&host_stat, sizeof(host_stat));
  247.     if (clnt_call(rstat_clnt, RSTATPROC_STATS, xdr_void, NULL, xdr_statstime, &host_stat, NULL) != RPC_SUCCESS) {
  248.         warnx("%s",  clnt_sperror(rstat_clnt, host));
  249.         return;
  250.     }
  251.  
  252.     print_rup_data(host, &host_stat);
  253.     clnt_destroy(rstat_clnt);
  254. }
  255.  
  256. void
  257. allhosts()
  258. {
  259.     statstime host_stat;
  260.     enum clnt_stat clnt_stat;
  261.     size_t i;
  262.  
  263.     if (sort_type != SORT_NONE) {
  264.         printf("collecting responses...");
  265.         fflush(stdout);
  266.     }
  267.  
  268.     clnt_stat = clnt_broadcast(RSTATPROG, RSTATVERS_TIME, RSTATPROC_STATS,
  269.                    xdr_void, NULL,
  270.                    xdr_statstime, &host_stat, rstat_reply);
  271.     if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) {
  272.         warnx("%s", clnt_sperrno(clnt_stat));
  273.         exit(1);
  274.     }
  275.  
  276.     if (sort_type != SORT_NONE) {
  277.         putchar('\n');
  278.         qsort(rup_data, rup_data_idx, sizeof(struct rup_data), compare);
  279.  
  280.         for (i = 0; i < rup_data_idx; i++) {
  281.             print_rup_data(rup_data[i].host, &rup_data[i].statstime);
  282.         }
  283.     }
  284. }
  285.  
  286.  
  287. main(argc, argv)
  288.     int argc;
  289.     char *argv[];
  290. {
  291.     int ch;
  292.     extern int optind;
  293.  
  294.     sort_type = SORT_NONE;
  295.     while ((ch = getopt(argc, argv, "dhlt")) != -1)
  296.         switch (ch) {
  297.         case 'd':
  298.             printtime = 1;
  299.             break;
  300.         case 'h':
  301.             sort_type = SORT_HOST;
  302.             break;
  303.         case 'l':
  304.             sort_type = SORT_LDAV;
  305.             break;
  306.         case 't':
  307.             sort_type = SORT_UPTIME;
  308.             break;
  309.         default:
  310.             usage();
  311.             /*NOTREACHED*/
  312.         }
  313.     
  314.     setlinebuf(stdout);
  315.  
  316.     if (argc == optind)
  317.         allhosts();
  318.     else {
  319.         for (; optind < argc; optind++)
  320.             onehost(argv[optind]);
  321.     }
  322.  
  323.     exit(0);
  324. }
  325.  
  326.  
  327. usage()
  328. {
  329.     fprintf(stderr, "Usage: rup [-dhlt] [hosts ...]\n");
  330.     exit(1);
  331. }
  332.