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