2 Copyright (C) 1992-2002, 2004 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
);
136 printf (_(" %2d:%02d%s up "),
137 ((tmn
->tm_hour
% 12) == 0 ? 12 : tmn
->tm_hour
% 12),
138 /* FIXME: use strftime, not am, pm. Uli reports that
139 the german translation is meaningless. */
140 tmn
->tm_min
, (tmn
->tm_hour
< 12 ? _("am") : _("pm")));
142 printf (_(" ??:???? up "));
144 printf (ngettext("%d day", "%d days", updays
), updays
);
145 printf (" %2d:%02d, ", uphours
, upmins
);
146 printf (ngettext ("%d user", "%d users", entries
), entries
);
148 #if defined (HAVE_GETLOADAVG) || defined (C_GETLOADAVG)
149 loads
= getloadavg (avg
, 3);
159 printf (_(", load average: %.2f"), avg
[0]);
161 printf (", %.2f", avg
[1]);
163 printf (", %.2f", avg
[2]);
169 /* Display the system uptime and the number of users on the system,
170 according to utmp file FILENAME. */
173 uptime (const char *filename
)
176 STRUCT_UTMP
*utmp_buf
;
177 int fail
= read_utmp (filename
, &n_users
, &utmp_buf
);
180 error (EXIT_FAILURE
, errno
, "%s", filename
);
182 print_uptime (n_users
, utmp_buf
);
188 if (status
!= EXIT_SUCCESS
)
189 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
193 printf (_("Usage: %s [OPTION]... [ FILE ]\n"), program_name
);
195 Print the current time, the length of time the system has been up,\n\
196 the number of users on the system, and the average number of jobs\n\
197 in the run queue over the last 1, 5 and 15 minutes.\n\
198 If FILE is not specified, use %s. %s as FILE is common.\n\
201 UTMP_FILE
, WTMP_FILE
);
202 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
203 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
204 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT
);
210 main (int argc
, char **argv
)
213 initialize_main (&argc
, &argv
);
214 program_name
= argv
[0];
215 setlocale (LC_ALL
, "");
216 bindtextdomain (PACKAGE
, LOCALEDIR
);
217 textdomain (PACKAGE
);
219 atexit (close_stdout
);
221 parse_long_options (argc
, argv
, PROGRAM_NAME
, GNU_PACKAGE
, VERSION
,
222 usage
, AUTHORS
, (char const *) NULL
);
224 while ((optc
= getopt_long (argc
, argv
, "", longopts
, &longind
)) != -1)
232 usage (EXIT_FAILURE
);
236 switch (argc
- optind
)
242 case 1: /* uptime <utmp file> */
243 uptime (argv
[optind
]);
247 error (0, 0, _("too many arguments"));
248 usage (EXIT_FAILURE
);