home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / ruptime / ruptime.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-18  |  6.8 KB  |  268 lines

  1. /*
  2.  * Copyright (c) 1983 The Regents of the University of California.
  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. char copyright[] =
  36. "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
  37.  All rights reserved.\n";
  38. #endif /* not lint */
  39.  
  40. #ifndef lint
  41. static char sccsid[] = "@(#)ruptime.c    5.8 (Berkeley) 7/21/90";
  42. #endif /* not lint */
  43.  
  44. #include <sys/param.h>
  45. #include <sys/dir.h>
  46. #include <sys/file.h>
  47. #include <sys/errno.h>
  48. #include <protocols/rwhod.h>
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #include <string.h>
  52.  
  53. size_t    nhosts, hspace = 20;
  54. struct hs {
  55.     struct    whod *hs_wd;
  56.     int    hs_nusers;
  57. } *hs;
  58. struct    whod awhod;
  59.  
  60. #define    ISDOWN(h)        (now - (h)->hs_wd->wd_recvtime > 11 * 60)
  61. #define    WHDRSIZE    (sizeof (awhod) - sizeof (awhod.wd_we))
  62.  
  63. time_t now;
  64. int rflg = 1;
  65. int hscmp(), ucmp(), lcmp(), tcmp();
  66.  
  67. main(argc, argv)
  68.     int argc;
  69.     char **argv;
  70. {
  71.     extern char *optarg;
  72.     extern int optind;
  73.     register struct hs *hsp;
  74.     register struct whod *wd;
  75.     register struct whoent *we;
  76.     register DIR *dirp;
  77.     struct direct *dp;
  78.     int aflg, cc, ch, f, i, maxloadav;
  79.     char buf[sizeof(struct whod)];
  80.     int (*cmp)() = hscmp;
  81.     time_t time();
  82.     char *interval();
  83.  
  84.     aflg = 0;
  85.     while ((ch = getopt(argc, argv, "alrut")) != EOF)
  86.         switch((char)ch) {
  87.         case 'a':
  88.             aflg = 1;
  89.             break;
  90.         case 'l':
  91.             cmp = lcmp;
  92.             break;
  93.         case 'r':
  94.             rflg = -1;
  95.             break;
  96.         case 't':
  97.             cmp = tcmp;
  98.             break;
  99.         case 'u':
  100.             cmp = ucmp;
  101.             break;
  102.         default: 
  103.             (void)fprintf(stderr, "usage: ruptime [-alrut]\n");
  104.             exit(1);
  105.         }
  106.  
  107.     if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL) {
  108.         (void)fprintf(stderr, "ruptime: %s: %s.\n",
  109.             _PATH_RWHODIR, strerror(errno));
  110.         exit(1);
  111.     }
  112.     morehosts();
  113.     hsp = hs;
  114.     maxloadav = -1;
  115.     while (dp = readdir(dirp)) {
  116.         if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5))
  117.             continue;
  118.         if ((f = open(dp->d_name, O_RDONLY, 0)) < 0) {
  119.             (void)fprintf(stderr, "ruptime: %s: %s\n",
  120.                 dp->d_name, strerror(errno));
  121.             continue;
  122.         }
  123.         cc = read(f, buf, sizeof(struct whod));
  124.         (void)close(f);
  125.         if (cc < WHDRSIZE)
  126.             continue;
  127.         if (nhosts == hspace) {
  128.             morehosts();
  129.             hsp = hs + nhosts;
  130.         }
  131.         /* NOSTRICT */
  132.         hsp->hs_wd = malloc((size_t)WHDRSIZE);
  133.         wd = (struct whod *)buf;
  134.         bcopy((char *)wd, (char *)hsp->hs_wd, (size_t)WHDRSIZE);
  135.         hsp->hs_nusers = 0;
  136.         for (i = 0; i < 2; i++)
  137.             if (wd->wd_loadav[i] > maxloadav)
  138.                 maxloadav = wd->wd_loadav[i];
  139.         we = (struct whoent *)(buf+cc);
  140.         while (--we >= wd->wd_we)
  141.             if (aflg || we->we_idle < 3600)
  142.                 hsp->hs_nusers++;
  143.         nhosts++;
  144.         hsp++;
  145.     }
  146.     if (!nhosts) {
  147.         (void)printf("ruptime: no hosts in %s.\n", _PATH_RWHODIR);
  148.         exit(1);
  149.     }
  150.     qsort((char *)hs, nhosts, sizeof (hs[0]), cmp);
  151.     (void)time(&now);
  152.     for (i = 0; i < nhosts; i++) {
  153.         hsp = &hs[i];
  154.         if (ISDOWN(hsp)) {
  155.             (void)printf("%-12.12s%s\n", hsp->hs_wd->wd_hostname,
  156.                 interval(now - hsp->hs_wd->wd_recvtime, "down"));
  157.             continue;
  158.         }
  159.         (void)printf(
  160.             "%-12.12s%s,  %4d user%s  load %*.2f, %*.2f, %*.2f\n",
  161.             hsp->hs_wd->wd_hostname,
  162.             interval((time_t)hsp->hs_wd->wd_sendtime -
  163.             (time_t)hsp->hs_wd->wd_boottime, "  up"),
  164.             hsp->hs_nusers,
  165.             hsp->hs_nusers == 1 ? ", " : "s,",
  166.             maxloadav >= 1000 ? 5 : 4,
  167.             hsp->hs_wd->wd_loadav[0] / 100.0,
  168.             maxloadav >= 1000 ? 5 : 4,
  169.                 hsp->hs_wd->wd_loadav[1] / 100.0,
  170.             maxloadav >= 1000 ? 5 : 4,
  171.                 hsp->hs_wd->wd_loadav[2] / 100.0);
  172.         free((void *)hsp->hs_wd);
  173.     }
  174.     exit(0);
  175. }
  176.  
  177. char *
  178. interval(tval, updown)
  179.     time_t tval;
  180.     char *updown;
  181. {
  182.     static char resbuf[32];
  183.     int days, hours, minutes;
  184.  
  185.     if (tval < 0 || tval > 365*24*60*60) {
  186.         (void)sprintf(resbuf, "   %s ??:??", updown);
  187.         return(resbuf);
  188.     }
  189.     minutes = (tval + 59) / 60;        /* round to minutes */
  190.     hours = minutes / 60; minutes %= 60;
  191.     days = hours / 24; hours %= 24;
  192.     if (days)
  193.         (void)sprintf(resbuf, "%s %2d+%02d:%02d",
  194.             updown, days, hours, minutes);
  195.     else
  196.         (void)sprintf(resbuf, "%s    %2d:%02d",
  197.             updown, hours, minutes);
  198.     return(resbuf);
  199. }
  200.  
  201. /* alphabetical comparison */
  202. hscmp(a1, a2)
  203.     void *a1, *a2;
  204. {
  205.     struct hs *h1 = a1, *h2 = a2;
  206.  
  207.     return(rflg * strcmp(h1->hs_wd->wd_hostname, h2->hs_wd->wd_hostname));
  208. }
  209.  
  210. /* load average comparison */
  211. lcmp(a1, a2)
  212.     void *a1, *a2;
  213. {
  214.     register struct hs *h1 = a1, *h2 = a2;
  215.  
  216.     if (ISDOWN(h1))
  217.         if (ISDOWN(h2))
  218.             return(tcmp(a1, a2));
  219.         else
  220.             return(rflg);
  221.     else if (ISDOWN(h2))
  222.         return(-rflg);
  223.     else
  224.         return(rflg *
  225.             (h2->hs_wd->wd_loadav[0] - h1->hs_wd->wd_loadav[0]));
  226. }
  227.  
  228. /* number of users comparison */
  229. ucmp(a1, a2)
  230.     void *a1, *a2;
  231. {
  232.     register struct hs *h1 = a1, *h2 = a2;
  233.  
  234.     if (ISDOWN(h1))
  235.         if (ISDOWN(h2))
  236.             return(tcmp(a1, a2));
  237.         else
  238.             return(rflg);
  239.     else if (ISDOWN(h2))
  240.         return(-rflg);
  241.     else
  242.         return(rflg * (h2->hs_nusers - h1->hs_nusers));
  243. }
  244.  
  245. /* uptime comparison */
  246. tcmp(a1, a2)
  247.     void *a1, *a2;
  248. {
  249.     register struct hs *h1 = a1, *h2 = a2;
  250.  
  251.     return(rflg * (
  252.         (ISDOWN(h2) ? h2->hs_wd->wd_recvtime - now
  253.               : h2->hs_wd->wd_sendtime - h2->hs_wd->wd_boottime)
  254.         -
  255.         (ISDOWN(h1) ? h1->hs_wd->wd_recvtime - now
  256.               : h1->hs_wd->wd_sendtime - h1->hs_wd->wd_boottime)
  257.     ));
  258. }
  259.  
  260. morehosts()
  261. {
  262.     hs = realloc((char *)hs, (hspace *= 2) * sizeof(*hs));
  263.     if (hs == NULL) {
  264.         (void)fprintf(stderr, "ruptime: %s.\n", strerror(ENOMEM));
  265.         exit(1);
  266.     }
  267. }
  268.