2 Copyright (C) 1992-2002 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)
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 /* Created by hacking who.c by Kaveh Ghazi ghazi@caip.rutgers.edu. */
24 #include <sys/types.h>
27 #if HAVE_SYSCTL && HAVE_SYS_SYSCTL_H
28 # include <sys/sysctl.h>
32 #include "long-options.h"
35 /* The official name of this program (e.g., no `g' prefix). */
36 #define PROGRAM_NAME "uptime"
38 #define AUTHORS "Joseph Arceneaux", "David MacKenzie", "Kaveh Ghazi"
42 /* The name this program was run with. */
45 static struct option const longopts[] =
51 print_uptime (int n, const STRUCT_UTMP *this)
53 register int entries = 0;
63 #ifdef HAVE_PROC_UPTIME
67 fp = fopen ("/proc/uptime", "r");
72 char *b = fgets (buf, BUFSIZ, fp);
75 /* The following sscanf must use the C locale. */
76 setlocale (LC_NUMERIC, "C");
77 res = sscanf (buf, "%lf", &upsecs);
78 setlocale (LC_NUMERIC, "");
80 uptime = (time_t) upsecs;
85 #endif /* HAVE_PROC_UPTIME */
87 #if HAVE_SYSCTL && defined CTL_KERN && defined KERN_BOOTTIME
89 /* FreeBSD specific: fetch sysctl "kern.boottime". */
90 static int request[2] = { CTL_KERN, KERN_BOOTTIME };
91 struct timeval result;
92 size_t result_len = sizeof result;
94 if (sysctl (request, 2, &result, &result_len, NULL, 0) >= 0)
95 boot_time = result.tv_sec;
99 /* Loop through all the utmp entries we just read and count up the valid
100 ones, also in the process possibly gleaning boottime. */
103 if (UT_USER (this) [0]
105 && this->ut_type == USER_PROCESS
111 /* If BOOT_MSG is defined, we can get boottime from utmp. This avoids
112 possibly needing special privs to read /dev/kmem. */
114 # if HAVE_PROC_UPTIME
116 # endif /* HAVE_PROC_UPTIME */
117 if (STREQ (this->ut_line, BOOT_MSG))
118 boot_time = UT_TIME_MEMBER (this);
119 #endif /* BOOT_MSG */
123 #if defined HAVE_PROC_UPTIME
128 error (EXIT_FAILURE, errno, _("couldn't get boot time"));
129 uptime = time_now - boot_time;
131 updays = uptime / 86400;
132 uphours = (uptime - (updays * 86400)) / 3600;
133 upmins = (uptime - (updays * 86400) - (uphours * 3600)) / 60;
134 tmn = localtime (&time_now);
135 printf (_(" %2d:%02d%s up "), ((tmn->tm_hour % 12) == 0
136 ? 12 : tmn->tm_hour % 12),
137 /* FIXME: use strftime, not am, pm. Uli reports that
138 the german translation is meaningless. */
139 tmn->tm_min, (tmn->tm_hour < 12 ? _("am") : _("pm")));
141 printf (ngettext("%d day", "%d days", updays), updays);
142 printf (" %2d:%02d, ", uphours, upmins);
143 printf (ngettext ("%d user", "%d users", entries), entries);
145 #if defined (HAVE_GETLOADAVG) || defined (C_GETLOADAVG)
146 loads = getloadavg (avg, 3);
156 printf (_(", load average: %.2f"), avg[0]);
158 printf (", %.2f", avg[1]);
160 printf (", %.2f", avg[2]);
166 /* Display the system uptime and the number of users on the system,
167 according to utmp file FILENAME. */
170 uptime (const char *filename)
173 STRUCT_UTMP *utmp_buf;
174 int fail = read_utmp (filename, &n_users, &utmp_buf);
177 error (EXIT_FAILURE, errno, "%s", filename);
179 print_uptime (n_users, utmp_buf);
186 fprintf (stderr, _("Try `%s --help' for more information.\n"),
190 printf (_("Usage: %s [OPTION]... [ FILE ]\n"), program_name);
192 Print the current time, the length of time the system has been up,\n\
193 the number of users on the system, and the average number of jobs\n\
194 in the run queue over the last 1, 5 and 15 minutes.\n\
195 If FILE is not specified, use %s. %s as FILE is common.\n\
198 UTMP_FILE, WTMP_FILE);
199 fputs (HELP_OPTION_DESCRIPTION, stdout);
200 fputs (VERSION_OPTION_DESCRIPTION, stdout);
201 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
207 main (int argc, char **argv)
210 initialize_main (&argc, &argv);
211 program_name = argv[0];
212 setlocale (LC_ALL, "");
213 bindtextdomain (PACKAGE, LOCALEDIR);
214 textdomain (PACKAGE);
216 atexit (close_stdout);
218 parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
219 usage, AUTHORS, NULL);
221 while ((optc = getopt_long (argc, argv, "", longopts, &longind)) != -1)
229 usage (EXIT_FAILURE);
233 switch (argc - optind)
239 case 1: /* uptime <utmp file> */
240 uptime (argv[optind]);
244 error (0, 0, _("too many arguments"));
245 usage (EXIT_FAILURE);