2 Copyright (C) 1992-2002, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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>
37 #include "long-options.h"
41 /* The official name of this program (e.g., no `g' prefix). */
42 #define PROGRAM_NAME "uptime"
44 #define AUTHORS "Joseph Arceneaux", "David MacKenzie", "Kaveh Ghazi"
48 /* The name this program was run with. */
52 print_uptime (size_t n, const STRUCT_UTMP *this)
64 #ifdef HAVE_PROC_UPTIME
67 fp = fopen ("/proc/uptime", "r");
71 char *b = fgets (buf, BUFSIZ, fp);
75 double upsecs = c_strtod (buf, &end_ptr);
77 uptime = (0 <= upsecs && upsecs < TYPE_MAXIMUM (time_t)
83 #endif /* HAVE_PROC_UPTIME */
85 #if HAVE_SYSCTL && defined CTL_KERN && defined KERN_BOOTTIME
87 /* FreeBSD specific: fetch sysctl "kern.boottime". */
88 static int request[2] = { CTL_KERN, KERN_BOOTTIME };
89 struct timeval result;
90 size_t result_len = sizeof result;
92 if (sysctl (request, 2, &result, &result_len, NULL, 0) >= 0)
93 boot_time = result.tv_sec;
97 #if HAVE_OS_H /* BeOS */
101 get_system_info (&si);
102 boot_time = si.boot_time / 1000000;
106 #if HAVE_UTMPX_H || HAVE_UTMP_H
107 /* Loop through all the utmp entries we just read and count up the valid
108 ones, also in the process possibly gleaning boottime. */
111 entries += IS_USER_PROCESS (this);
112 if (UT_TYPE_BOOT_TIME (this))
113 boot_time = UT_TIME_MEMBER (this);
117 time_now = time (NULL);
118 #if defined HAVE_PROC_UPTIME
123 error (EXIT_FAILURE, errno, _("couldn't get boot time"));
124 uptime = time_now - boot_time;
126 updays = uptime / 86400;
127 uphours = (uptime - (updays * 86400)) / 3600;
128 upmins = (uptime - (updays * 86400) - (uphours * 3600)) / 60;
129 tmn = localtime (&time_now);
131 printf (_(" %2d:%02d%s up "),
132 ((tmn->tm_hour % 12) == 0 ? 12 : tmn->tm_hour % 12),
133 /* FIXME: use strftime, not am, pm. Uli reports that
134 the german translation is meaningless. */
135 tmn->tm_min, (tmn->tm_hour < 12 ? _("am") : _("pm")));
137 printf (_(" ??:???? up "));
138 if (uptime == (time_t) -1)
139 printf (_("???? days ??:??, "));
143 printf (ngettext ("%ld day", "%ld days", select_plural (updays)),
145 printf (" %2d:%02d, ", uphours, upmins);
147 printf (ngettext ("%lu user", "%lu users", entries),
148 (unsigned long int) entries);
150 #if defined HAVE_GETLOADAVG || defined C_GETLOADAVG
151 loads = getloadavg (avg, 3);
161 printf (_(", load average: %.2f"), avg[0]);
163 printf (", %.2f", avg[1]);
165 printf (", %.2f", avg[2]);
171 /* Display the system uptime and the number of users on the system,
172 according to utmp file FILENAME. Use read_utmp OPTIONS to read the
176 uptime (const char *filename, int options)
179 STRUCT_UTMP *utmp_buf;
181 #if HAVE_UTMPX_H || HAVE_UTMP_H
182 if (read_utmp (filename, &n_users, &utmp_buf, options) != 0)
183 error (EXIT_FAILURE, errno, "%s", filename);
186 print_uptime (n_users, utmp_buf);
192 if (status != EXIT_SUCCESS)
193 fprintf (stderr, _("Try `%s --help' for more information.\n"),
197 printf (_("Usage: %s [OPTION]... [ FILE ]\n"), program_name);
199 Print the current time, the length of time the system has been up,\n\
200 the number of users on the system, and the average number of jobs\n\
201 in the run queue over the last 1, 5 and 15 minutes.\n\
202 If FILE is not specified, use %s. %s as FILE is common.\n\
205 UTMP_FILE, WTMP_FILE);
206 fputs (HELP_OPTION_DESCRIPTION, stdout);
207 fputs (VERSION_OPTION_DESCRIPTION, stdout);
208 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
214 main (int argc, char **argv)
216 initialize_main (&argc, &argv);
217 program_name = argv[0];
218 setlocale (LC_ALL, "");
219 bindtextdomain (PACKAGE, LOCALEDIR);
220 textdomain (PACKAGE);
222 atexit (close_stdout);
224 parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
225 usage, AUTHORS, (char const *) NULL);
226 if (getopt_long (argc, argv, "", NULL, NULL) != -1)
227 usage (EXIT_FAILURE);
229 switch (argc - optind)
232 uptime (UTMP_FILE, READ_UTMP_CHECK_PIDS);
235 case 1: /* uptime <utmp file> */
236 uptime (argv[optind], 0);
240 error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
241 usage (EXIT_FAILURE);