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"
36 /* The official name of this program (e.g., no `g' prefix). */
37 #define PROGRAM_NAME "uptime"
39 #define AUTHORS N_ ("Joseph Arceneaux, David MacKenzie, and Kaveh Ghazi")
43 /* The name this program was run with. */
46 static struct option
const longopts
[] =
52 print_uptime (int n
, const STRUCT_UTMP
*this)
54 register int entries
= 0;
64 #ifdef HAVE_PROC_UPTIME
68 fp
= fopen ("/proc/uptime", "r");
73 char *b
= fgets (buf
, BUFSIZ
, fp
);
76 /* The following sscanf must use the C locale. */
77 setlocale (LC_NUMERIC
, "C");
78 res
= sscanf (buf
, "%lf", &upsecs
);
79 setlocale (LC_NUMERIC
, "");
81 uptime
= (time_t) upsecs
;
86 #endif /* HAVE_PROC_UPTIME */
88 #if HAVE_SYSCTL && defined CTL_KERN && defined KERN_BOOTTIME
90 /* FreeBSD specific: fetch sysctl "kern.boottime". */
91 static int request
[2] = { CTL_KERN
, KERN_BOOTTIME
};
92 struct timeval result
;
93 size_t result_len
= sizeof result
;
95 if (sysctl (request
, 2, &result
, &result_len
, NULL
, 0) >= 0)
96 boot_time
= result
.tv_sec
;
100 /* Loop through all the utmp entries we just read and count up the valid
101 ones, also in the process possibly gleaning boottime. */
104 if (UT_USER (this) [0]
106 && this->ut_type
== USER_PROCESS
112 /* If BOOT_MSG is defined, we can get boottime from utmp. This avoids
113 possibly needing special privs to read /dev/kmem. */
115 # if HAVE_PROC_UPTIME
117 # endif /* HAVE_PROC_UPTIME */
118 if (STREQ (this->ut_line
, BOOT_MSG
))
119 boot_time
= UT_TIME_MEMBER (this);
120 #endif /* BOOT_MSG */
124 #if defined HAVE_PROC_UPTIME
129 error (1, errno
, _("couldn't get boot time"));
130 uptime
= time_now
- boot_time
;
132 updays
= uptime
/ 86400;
133 uphours
= (uptime
- (updays
* 86400)) / 3600;
134 upmins
= (uptime
- (updays
* 86400) - (uphours
* 3600)) / 60;
135 tmn
= localtime (&time_now
);
136 printf (_(" %2d:%02d%s up "), ((tmn
->tm_hour
% 12) == 0
137 ? 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 (ngettext("%d day", "%d days", updays
), updays
);
143 printf (" %2d:%02d, ", uphours
, upmins
);
144 printf (ngettext ("%d user", "%d users", entries
), entries
);
146 #if defined (HAVE_GETLOADAVG) || defined (C_GETLOADAVG)
147 loads
= getloadavg (avg
, 3);
157 printf (_(", load average: %.2f"), avg
[0]);
159 printf (", %.2f", avg
[1]);
161 printf (", %.2f", avg
[2]);
167 /* Display the system uptime and the number of users on the system,
168 according to utmp file FILENAME. */
171 uptime (const char *filename
)
174 STRUCT_UTMP
*utmp_buf
;
175 int fail
= read_utmp (filename
, &n_users
, &utmp_buf
);
178 error (1, errno
, "%s", filename
);
180 print_uptime (n_users
, utmp_buf
);
187 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
191 printf (_("Usage: %s [OPTION]... [ FILE ]\n"), program_name
);
193 Print the current time, the length of time the system has been up,\n\
194 the number of users on the system, and the average number of jobs\n\
195 in the run queue over the last 1, 5 and 15 minutes.\n\
196 If FILE is not specified, use %s. %s as FILE is common.\n\
199 UTMP_FILE
, WTMP_FILE
);
200 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
201 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
202 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT
);
208 main (int argc
, char **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
,
221 while ((optc
= getopt_long (argc
, argv
, "", longopts
, &longind
)) != -1)
233 switch (argc
- optind
)
239 case 1: /* uptime <utmp file> */
240 uptime (argv
[optind
]);
244 error (0, 0, _("too many arguments"));