*** empty log message ***
[coreutils.git] / src / uptime.c
blob779dff73b6d11750c19c297971fc5f39bef21529
1 /* GNU's uptime.
2 Copyright (C) 1992-2000 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)
7 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, 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. */
20 #include <config.h>
21 #include <getopt.h>
22 #include <stdio.h>
24 #include <sys/types.h>
25 #include "system.h"
27 #include "error.h"
28 #include "long-options.h"
29 #include "readutmp.h"
30 #include "closeout.h"
32 /* The official name of this program (e.g., no `g' prefix). */
33 #define PROGRAM_NAME "uptime"
35 #define AUTHORS "Joseph Arceneaux, David MacKenzie, and Kaveh Ghazi"
37 int getloadavg ();
39 /* The name this program was run with. */
40 char *program_name;
42 static struct option const longopts[] =
44 {NULL, 0, NULL, 0}
47 static void
48 print_uptime (int n, const STRUCT_UTMP *this)
50 register int entries = 0;
51 time_t boot_time = 0;
52 time_t time_now;
53 time_t uptime = 0;
54 int updays;
55 int uphours;
56 int upmins;
57 struct tm *tmn;
58 double avg[3];
59 int loads;
60 #ifdef HAVE_PROC_UPTIME
61 FILE *fp;
62 double upsecs;
64 fp = fopen ("/proc/uptime", "r");
65 if (fp != NULL)
67 char buf[BUFSIZ];
68 int res;
69 char *b = fgets (buf, BUFSIZ, fp);
70 if (b == buf)
72 /* The following sscanf must use the C locale. */
73 setlocale (LC_NUMERIC, "C");
74 res = sscanf (buf, "%lf", &upsecs);
75 setlocale (LC_NUMERIC, "");
76 if (res == 1)
77 uptime = (time_t) upsecs;
80 fclose (fp);
82 #endif /* HAVE_PROC_UPTIME */
83 /* Loop through all the utmp entries we just read and count up the valid
84 ones, also in the process possibly gleaning boottime. */
85 while (n--)
87 if (UT_USER (this) [0]
88 #ifdef USER_PROCESS
89 && this->ut_type == USER_PROCESS
90 #endif
93 ++entries;
95 /* If BOOT_MSG is defined, we can get boottime from utmp. This avoids
96 possibly needing special privs to read /dev/kmem. */
97 #ifdef BOOT_MSG
98 # if HAVE_PROC_UPTIME
99 if (uptime == 0)
100 # endif /* HAVE_PROC_UPTIME */
101 if (!strcmp (this->ut_line, BOOT_MSG))
102 boot_time = UT_TIME_MEMBER (this);
103 #endif /* BOOT_MSG */
104 ++this;
106 time_now = time (0);
107 #if defined HAVE_PROC_UPTIME
108 if (uptime == 0)
109 #endif
111 if (boot_time == 0)
112 error (1, errno, _("couldn't get boot time"));
113 uptime = time_now - boot_time;
115 updays = uptime / 86400;
116 uphours = (uptime - (updays * 86400)) / 3600;
117 upmins = (uptime - (updays * 86400) - (uphours * 3600)) / 60;
118 tmn = localtime (&time_now);
119 printf (_(" %2d:%02d%s up "), ((tmn->tm_hour % 12) == 0
120 ? 12 : tmn->tm_hour % 12),
121 /* FIXME: use strftime, not am, pm. Uli reports that
122 the german translation is meaningless. */
123 tmn->tm_min, (tmn->tm_hour < 12 ? _("am") : _("pm")));
124 if (updays > 0)
125 printf ("%d %s,", updays, (updays == 1 ? _("day") : _("days")));
126 printf (" %2d:%02d, %d %s", uphours, upmins, entries,
127 (entries == 1) ? _("user") : _("users"));
129 #if defined (HAVE_GETLOADAVG) || defined (C_GETLOADAVG)
130 loads = getloadavg (avg, 3);
131 #else
132 loads = -1;
133 #endif
135 if (loads == -1)
136 putchar ('\n');
137 else
139 if (loads > 0)
140 printf (_(", load average: %.2f"), avg[0]);
141 if (loads > 1)
142 printf (", %.2f", avg[1]);
143 if (loads > 2)
144 printf (", %.2f", avg[2]);
145 if (loads > 0)
146 putchar ('\n');
150 /* Display the system uptime and the number of users on the system,
151 according to utmp file FILENAME. */
153 static void
154 uptime (const char *filename)
156 int n_users;
157 STRUCT_UTMP *utmp_buf;
158 int fail = read_utmp (filename, &n_users, &utmp_buf);
160 if (fail)
161 error (1, errno, "%s", filename);
163 print_uptime (n_users, utmp_buf);
166 void
167 usage (int status)
169 if (status != 0)
170 fprintf (stderr, _("Try `%s --help' for more information.\n"),
171 program_name);
172 else
174 printf (_("Usage: %s [OPTION]... [ FILE ]\n"), program_name);
175 printf (_("\
176 Print the current time, the length of time the system has been up,\n\
177 the number of users on the system, and the average number of jobs\n\
178 in the run queue over the last 1, 5 and 15 minutes.\n\
179 If FILE is not specified, use %s. %s as FILE is common.\n\
181 --help display this help and exit\n\
182 --version output version information and exit\n"),
183 UTMP_FILE, WTMP_FILE);
184 puts (_("\nReport bugs to <bug-sh-utils@gnu.org>."));
186 exit (status);
190 main (int argc, char **argv)
192 int optc, longind;
193 program_name = argv[0];
194 setlocale (LC_ALL, "");
195 bindtextdomain (PACKAGE, LOCALEDIR);
196 textdomain (PACKAGE);
198 atexit (close_stdout);
200 parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
201 AUTHORS, usage);
203 while ((optc = getopt_long (argc, argv, "", longopts, &longind)) != -1)
205 switch (optc)
207 case 0:
208 break;
210 default:
211 usage (1);
215 switch (argc - optind)
217 case 0: /* uptime */
218 uptime (UTMP_FILE);
219 break;
221 case 1: /* uptime <utmp file> */
222 uptime (argv[optind]);
223 break;
225 default: /* lose */
226 error (0, 0, _("too many arguments"));
227 usage (1);
230 exit (0);