File: uptime.c

package info (click to toggle)
mrtgutils 0.8.3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, stretch
  • size: 124 kB
  • ctags: 42
  • sloc: ansic: 497; makefile: 32
file content (130 lines) | stat: -rw-r--r-- 3,330 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <utmp.h>
#include <sys/ioctl.h>
#include "uptime.h"

static char buf[128];
static double av[3];
static char *sprint_uptime(void);

int uptime(double *uptime_secs, double *idle_secs) {
    static int got_uptime = 0;
    static double up = 0, idle = 0;

    if (!got_uptime) {
      FILE *f;
      f = fopen("/proc/uptime", "r");
      if (!f) return -1;
      if (fscanf(f, "%lf %lf", &up, &idle) < 2) {
        fprintf(stderr, "bad data in /proc/uptime\n");
        return 0;
      }
      fclose(f);
      got_uptime = 1;
    }
    if (uptime_secs) *uptime_secs = up;
    if (idle_secs) *idle_secs = idle;
    return up;  /* assume never be zero seconds in practice */
}

void loadavg(double *av1, double *av5, double *av15) {
    static int got_load = 0;
    static double avg_1 = 0, avg_5 = 0, avg_15 = 0;

    if (!got_load) {
      FILE *f;
      f = fopen("/proc/loadavg", "r");
      if (!f) return;
      if (fscanf(f, "%lf %lf %lf", &avg_1, &avg_5, &avg_15) < 3) {
        fprintf(stderr, "bad data in /proc/loadavg\n");
        exit(1);
      }
      got_load = 1;
    }
    if (av1) *av1 = avg_1;
    if (av5) *av5 = avg_5;
    if (av15) *av15 = avg_15;
}

char *sprint_uptime(void) {
  struct utmp *utmpstruct;
  int upminutes, uphours, updays;
  int pos;
  struct tm *realtime;
  time_t realseconds;
  int numuser;
  double uptime_secs, idle_secs;

/* first get the current time */

  time(&realseconds);
  realtime = localtime(&realseconds);
  pos = sprintf(buf, " %2d:%02d%s  ",
		realtime->tm_hour%12 ? realtime->tm_hour%12 : 12,
		realtime->tm_min, realtime->tm_hour > 11 ? "pm" : "am");

/* read and calculate the amount of uptime */

  uptime(&uptime_secs, &idle_secs);

  updays = (int) uptime_secs / (60*60*24);
  strcat (buf, "up ");
  pos += 3;
  if (updays)
    pos += sprintf(buf + pos, "%d day%s, ", updays, (updays != 1) ? "s" : "");
  upminutes = (int) uptime_secs / 60;
  uphours = upminutes / 60;
  uphours = uphours % 24;
  upminutes = upminutes % 60;
  if(uphours)
    pos += sprintf(buf + pos, "%2d:%02d, ", uphours, upminutes);
  else
    pos += sprintf(buf + pos, "%d min, ", upminutes);

/* count the number of users */

  numuser = 0;
  setutent();
  while ((utmpstruct = getutent())) {
    if ((utmpstruct->ut_type == USER_PROCESS) &&
       (utmpstruct->ut_name[0] != '\0'))
      numuser++;
  }
  endutent();

  pos += sprintf(buf + pos, "%2d user%s, ", numuser, numuser == 1 ? "" : "s");

  loadavg(&av[0], &av[1], &av[2]);

  pos += sprintf(buf + pos, " load average: %.2f, %.2f, %.2f",
		 av[0], av[1], av[2]);

  return buf;
}

void print_uptime(void)
{
  printf("%s\n", sprint_uptime());
}

/* This is a trivial uptime program.  I hereby release this program
 * into the public domain.  I disclaim any responsibility for this
 * program --- use it at your own risk.  (as if there were any.. ;-)
 * -michaelkjohnson (johnsonm@sunsite.unc.edu)
 *
 * Modified by Larry Greenfield to give a more traditional output,
 * count users, etc.  (greenfie@gauss.rutgers.edu)
 *
 * Modified by mkj again to fix a few tiny buglies.
 *
 * Modified by J. Cowley to add printing the uptime message to a
 * string (for top) and to optimize file handling.  19 Mar 1993.
 *
 */