.
[coreutils.git] / src / uptime.c
blobed0c2aa3e1d964f83a4a0c02b0c9ecb6d68c37cb
1 /* GNU's uptime.
2 Copyright (C) 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /* Written by jla; revised by djm */
20 #include <config.h>
21 #include <getopt.h>
23 #include "system.h"
24 #include "error.h"
25 #include "readutmp.h"
27 /* The name this program was run with. */
28 char *program_name;
30 /* If nonzero, display usage information and exit. */
31 static int show_help;
33 /* If nonzero, print the version on standard output and exit. */
34 static int show_version;
36 static struct option const longopts[] =
38 {"help", no_argument, &show_help, 1},
39 {"version", no_argument, &show_version, 1},
40 {NULL, 0, NULL, 0}
43 static void
44 print_uptime (int n, const STRUCT_UTMP *this)
46 register int entries = 0;
47 time_t boot_time = 0;
48 time_t time_now;
49 time_t uptime = 0;
50 int updays;
51 int uphours;
52 int upmins;
53 struct tm *tmn;
54 double avg[3];
55 int loads;
56 #ifdef HAVE_PROC_UPTIME
57 FILE *fp;
58 double upsecs;
60 fp = fopen ("/proc/uptime", "r");
61 if (fp != NULL)
63 char buf[BUFSIZ];
64 int res;
65 fgets (buf, BUFSIZ, fp);
66 res = sscanf (buf, "%lf", &upsecs);
67 if (res == 1)
68 uptime = (time_t) upsecs;
69 fclose (fp);
71 #endif /* HAVE_PROC_UPTIME */
72 /* Loop through all the utmp entries we just read and count up the valid
73 ones, also in the process possibly gleaning boottime. */
74 while (n--)
76 if (this->ut_name[0]
77 #ifdef USER_PROCESS
78 && this->ut_type == USER_PROCESS
79 #endif
82 ++entries;
84 /* If BOOT_MSG is defined, we can get boottime from utmp. This avoids
85 possibly needing special privs to read /dev/kmem. */
86 #ifdef BOOT_MSG
87 # if HAVE_PROC_UPTIME
88 if (uptime == 0)
89 # endif /* HAVE_PROC_UPTIME */
90 if (!strcmp (this->ut_line, BOOT_MSG))
91 boot_time = UT_TIME_MEMBER (this);
92 #endif /* BOOT_MSG */
93 ++this;
95 time_now = time (0);
96 #if defined HAVE_PROC_UPTIME
97 if (uptime == 0)
98 #endif
100 if (boot_time == 0)
101 error (1, errno, _("couldn't get boot time"));
102 uptime = time_now - boot_time;
104 updays = uptime / 86400;
105 uphours = (uptime - (updays * 86400)) / 3600;
106 upmins = (uptime - (updays * 86400) - (uphours * 3600)) / 60;
107 tmn = localtime (&time_now);
108 printf (_(" %2d:%02d%s up "), ((tmn->tm_hour % 12) == 0
109 ? 12 : tmn->tm_hour % 12),
110 /* FIXME: use strftime, not am, pm. Uli reports that
111 the german translation is meaningless. */
112 tmn->tm_min, (tmn->tm_hour < 12 ? _("am") : _("pm")));
113 if (updays > 0)
114 printf ("%d %s,", updays, (updays == 1 ? _("day") : _("days")));
115 printf (" %2d:%02d, %d %s", uphours, upmins, entries,
116 (entries == 1) ? _("user") : _("users"));
118 #if defined (HAVE_GETLOADAVG) || defined (C_GETLOADAVG)
119 loads = getloadavg (avg, 3);
120 #else
121 loads = -1;
122 #endif
124 if (loads == -1)
125 putchar ('\n');
126 else
128 if (loads > 0)
129 printf (_(", load average: %.2f"), avg[0]);
130 if (loads > 1)
131 printf (", %.2f", avg[1]);
132 if (loads > 2)
133 printf (", %.2f", avg[2]);
134 if (loads > 0)
135 putchar ('\n');
139 /* Display the system uptime and the number of users on the system,
140 according to utmp file FILENAME. */
142 static void
143 uptime (const char *filename)
145 int n_users;
146 STRUCT_UTMP *utmp_buf;
147 int fail = read_utmp (filename, &n_users, &utmp_buf);
149 if (fail)
150 error (1, errno, "%s", filename);
152 print_uptime (n_users, utmp_buf);
155 static void
156 usage (int status)
158 if (status != 0)
159 fprintf (stderr, _("Try `%s --help' for more information.\n"),
160 program_name);
161 else
163 printf (_("Usage: %s [OPTION]... [ FILE ]\n"), program_name);
164 printf (_("\
165 Output who is currently logged in according to FILE.\n\
166 If FILE is not specified, use %s. %s as FILE is common.\n\
168 --help display this help and exit\n\
169 --version output version information and exit\n"),
170 UTMP_FILE, WTMP_FILE);
171 puts (_("\nReport bugs to <sh-utils-bugs@gnu.org>."));
173 exit (status);
177 main (int argc, char **argv)
179 int optc, longind;
180 program_name = argv[0];
181 setlocale (LC_ALL, "");
182 bindtextdomain (PACKAGE, LOCALEDIR);
183 textdomain (PACKAGE);
185 while ((optc = getopt_long (argc, argv, "", longopts, &longind)) != -1)
187 switch (optc)
189 case 0:
190 break;
192 default:
193 usage (1);
197 if (show_version)
199 printf ("uptime (%s) %s\n", GNU_PACKAGE, VERSION);
200 exit (0);
203 if (show_help)
204 usage (0);
206 switch (argc - optind)
208 case 0: /* uptime */
209 uptime (UTMP_FILE);
210 break;
212 case 1: /* uptime <utmp file> */
213 uptime (argv[optind]);
214 break;
216 default: /* lose */
217 error (0, 0, _("too many arguments"));
218 usage (1);
221 exit (0);