stat: adjust the printing of SELinux context
[coreutils/ericb.git] / src / uptime.c
blobbf4323cc1aa7463c2473d1945fe05c556cc6b6bf
1 /* GNU's uptime.
2 Copyright (C) 1992-2002, 2004-2010 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 3 of the License, or
7 (at your option) 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, see <http://www.gnu.org/licenses/>. */
17 /* Created by hacking who.c by Kaveh Ghazi ghazi@caip.rutgers.edu. */
19 #include <config.h>
20 #include <getopt.h>
21 #include <stdio.h>
23 #include <sys/types.h>
24 #include "system.h"
26 #if HAVE_SYSCTL && HAVE_SYS_SYSCTL_H
27 # include <sys/sysctl.h>
28 #endif
30 #if HAVE_OS_H
31 # include <OS.h>
32 #endif
34 #include "c-strtod.h"
35 #include "error.h"
36 #include "long-options.h"
37 #include "quote.h"
38 #include "readutmp.h"
39 #include "fprintftime.h"
41 /* The official name of this program (e.g., no `g' prefix). */
42 #define PROGRAM_NAME "uptime"
44 #define AUTHORS \
45 proper_name ("Joseph Arceneaux"), \
46 proper_name ("David MacKenzie"), \
47 proper_name ("Kaveh Ghazi")
49 static void
50 print_uptime (size_t n, const STRUCT_UTMP *this)
52 size_t entries = 0;
53 time_t boot_time = 0;
54 time_t time_now;
55 time_t uptime = 0;
56 long int updays;
57 int uphours;
58 int upmins;
59 struct tm *tmn;
60 double avg[3];
61 int loads;
62 #ifdef HAVE_PROC_UPTIME
63 FILE *fp;
65 fp = fopen ("/proc/uptime", "r");
66 if (fp != NULL)
68 char buf[BUFSIZ];
69 char *b = fgets (buf, BUFSIZ, fp);
70 if (b == buf)
72 char *end_ptr;
73 double upsecs = c_strtod (buf, &end_ptr);
74 if (buf != end_ptr)
75 uptime = (0 <= upsecs && upsecs < TYPE_MAXIMUM (time_t)
76 ? upsecs : -1);
79 fclose (fp);
81 #endif /* HAVE_PROC_UPTIME */
83 #if HAVE_SYSCTL && defined CTL_KERN && defined KERN_BOOTTIME
85 /* FreeBSD specific: fetch sysctl "kern.boottime". */
86 static int request[2] = { CTL_KERN, KERN_BOOTTIME };
87 struct timeval result;
88 size_t result_len = sizeof result;
90 if (sysctl (request, 2, &result, &result_len, NULL, 0) >= 0)
91 boot_time = result.tv_sec;
93 #endif
95 #if HAVE_OS_H /* BeOS */
97 system_info si;
99 get_system_info (&si);
100 boot_time = si.boot_time / 1000000;
102 #endif
104 #if HAVE_UTMPX_H || HAVE_UTMP_H
105 /* Loop through all the utmp entries we just read and count up the valid
106 ones, also in the process possibly gleaning boottime. */
107 while (n--)
109 entries += IS_USER_PROCESS (this);
110 if (UT_TYPE_BOOT_TIME (this))
111 boot_time = UT_TIME_MEMBER (this);
112 ++this;
114 #else
115 (void) n;
116 (void) this;
117 #endif
119 time_now = time (NULL);
120 #if defined HAVE_PROC_UPTIME
121 if (uptime == 0)
122 #endif
124 if (boot_time == 0)
125 error (EXIT_FAILURE, errno, _("couldn't get boot time"));
126 uptime = time_now - boot_time;
128 updays = uptime / 86400;
129 uphours = (uptime - (updays * 86400)) / 3600;
130 upmins = (uptime - (updays * 86400) - (uphours * 3600)) / 60;
131 tmn = localtime (&time_now);
132 /* procps' version of uptime also prints the seconds field, but
133 previous versions of coreutils don't. */
134 if (tmn)
135 /* TRANSLATORS: This prints the current clock time. */
136 fprintftime (stdout, _(" %H:%M%P "), tmn, 0, 0);
137 else
138 printf (_(" ??:???? "));
139 if (uptime == (time_t) -1)
140 printf (_("up ???? days ??:??, "));
141 else
143 if (0 < updays)
144 printf (ngettext ("up %ld day %2d:%02d, ",
145 "up %ld days %2d:%02d, ",
146 select_plural (updays)),
147 updays, uphours, upmins);
148 else
149 printf ("up %2d:%02d, ", uphours, upmins);
151 printf (ngettext ("%lu user", "%lu users", entries),
152 (unsigned long int) entries);
154 #if defined HAVE_GETLOADAVG || defined C_GETLOADAVG
155 loads = getloadavg (avg, 3);
156 #else
157 loads = -1;
158 #endif
160 if (loads == -1)
161 putchar ('\n');
162 else
164 if (loads > 0)
165 printf (_(", load average: %.2f"), avg[0]);
166 if (loads > 1)
167 printf (", %.2f", avg[1]);
168 if (loads > 2)
169 printf (", %.2f", avg[2]);
170 if (loads > 0)
171 putchar ('\n');
175 /* Display the system uptime and the number of users on the system,
176 according to utmp file FILENAME. Use read_utmp OPTIONS to read the
177 utmp file. */
179 static void
180 uptime (const char *filename, int options)
182 size_t n_users;
183 STRUCT_UTMP *utmp_buf;
185 #if HAVE_UTMPX_H || HAVE_UTMP_H
186 if (read_utmp (filename, &n_users, &utmp_buf, options) != 0)
187 error (EXIT_FAILURE, errno, "%s", filename);
188 #endif
190 print_uptime (n_users, utmp_buf);
193 void
194 usage (int status)
196 if (status != EXIT_SUCCESS)
197 fprintf (stderr, _("Try `%s --help' for more information.\n"),
198 program_name);
199 else
201 printf (_("Usage: %s [OPTION]... [FILE]\n"), program_name);
202 printf (_("\
203 Print the current time, the length of time the system has been up,\n\
204 the number of users on the system, and the average number of jobs\n\
205 in the run queue over the last 1, 5 and 15 minutes."));
206 #ifdef __linux__
207 /* It would be better to introduce a configure test for this,
208 but such a test is hard to write. For the moment then, we
209 have a hack which depends on the preprocessor used at compile
210 time to tell us what the running kernel is. Ugh. */
211 printf (_(" \
212 Processes in\n\
213 an uninterruptible sleep state also contribute to the load average.\n"));
214 #else
215 printf (_("\n"));
216 #endif
217 printf (_("\
218 If FILE is not specified, use %s. %s as FILE is common.\n\
219 \n"),
220 UTMP_FILE, WTMP_FILE);
221 fputs (HELP_OPTION_DESCRIPTION, stdout);
222 fputs (VERSION_OPTION_DESCRIPTION, stdout);
223 emit_ancillary_info ();
225 exit (status);
229 main (int argc, char **argv)
231 initialize_main (&argc, &argv);
232 set_program_name (argv[0]);
233 setlocale (LC_ALL, "");
234 bindtextdomain (PACKAGE, LOCALEDIR);
235 textdomain (PACKAGE);
237 atexit (close_stdout);
239 parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
240 usage, AUTHORS, (char const *) NULL);
241 if (getopt_long (argc, argv, "", NULL, NULL) != -1)
242 usage (EXIT_FAILURE);
244 switch (argc - optind)
246 case 0: /* uptime */
247 uptime (UTMP_FILE, READ_UTMP_CHECK_PIDS);
248 break;
250 case 1: /* uptime <utmp file> */
251 uptime (argv[optind], 0);
252 break;
254 default: /* lose */
255 error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
256 usage (EXIT_FAILURE);
259 exit (EXIT_SUCCESS);