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.
*
*/
|