1/* See LICENSE file for copyright and license details. */
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <time.h>
7#include <utmpx.h>
8
9#include "config.h"
10#include "util.h"
11
12int get_uptime(long *);
13int get_loads(double *);
14
15static void
16usage(void)
17{
18 eprintf("usage: %s\n", argv0);
19}
20
21// ?man uptime: show system uptime
22// ?man display how long the system has been running and load averages
23int
24main(int argc, char *argv[])
25{
26 struct utmpx utx;
27 FILE *ufp;
28 long uptime;
29 double loads[3];
30 time_t tmptime;
31 struct tm *now;
32 unsigned int days, hours, minutes;
33 int nusers = 0;
34 size_t n;
35
36 ARGBEGIN
37 {
38 default:
39 usage();
40 }
41 ARGEND;
42
43 if (argc)
44 usage();
45
46 if (get_uptime(&uptime) < 0)
47 eprintf("get_uptime:");
48 if (get_loads(loads) < 0)
49 eprintf("get_loads:");
50
51 time(&tmptime);
52 now = localtime(&tmptime);
53 printf(" %02d:%02d:%02d up ", now->tm_hour, now->tm_min, now->tm_sec);
54
55 uptime /= 60;
56 minutes = uptime % 60;
57 uptime /= 60;
58 hours = uptime % 24;
59 days = uptime / 24;
60 if (days)
61 printf("%d day%s, ", days, days != 1 ? "s" : "");
62 if (hours)
63 printf("%2d:%02d, ", hours, minutes);
64 else
65 printf("%d min, ", minutes);
66
67 if ((ufp = fopen(UTMP_PATH, "r"))) {
68 while ((n = fread(&utx, sizeof(utx), 1, ufp)) > 0) {
69 if (!utx.ut_user[0])
70 continue;
71 if (utx.ut_type != USER_PROCESS)
72 continue;
73 nusers++;
74 }
75 if (ferror(ufp))
76 eprintf("%s: read error:", UTMP_PATH);
77 fclose(ufp);
78 printf(" %d user%s, ", nusers, nusers != 1 ? "s" : "");
79 }
80
81 printf(" load average: %.02f, %.02f, %.02f\n", loads[0], loads[1], loads[2]);
82
83 if (fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>"))
84 return 1;
85
86 return 0;
87}