52 .init = NULL, |
52 .init = NULL, |
53 .uninit = NULL, |
53 .uninit = NULL, |
54 .next = &info_uptime_experimental, |
54 .next = &info_uptime_experimental, |
55 }; |
55 }; |
56 |
56 |
|
57 guint hz = 0; |
|
58 long long unsigned int mstime = 0; |
57 time_t starttime = 0; |
59 time_t starttime = 0; |
|
60 gboolean proc_used = FALSE; |
|
61 |
|
62 static int sys_uptime (void) |
|
63 { |
|
64 GString *line = g_string_new (NULL); |
|
65 GError *error = NULL; |
|
66 GIOStatus ret; |
|
67 int sec, ssec; |
|
68 GIOChannel *channel = g_io_channel_new_file ("/proc/uptime", "r", &error); |
|
69 if (!channel) { |
|
70 g_string_free (line, TRUE); |
|
71 scr_log_print (LPRINT_LOGNORM, |
|
72 "Cannot open system uptime for reading."); |
|
73 return 0; |
|
74 } |
|
75 g_io_channel_set_close_on_unref (channel, TRUE); |
|
76 |
|
77 ret = g_io_channel_read_line_string (channel, line, NULL, &error); |
|
78 if (ret != G_IO_STATUS_NORMAL) { |
|
79 if (error) { |
|
80 scr_log_print (LPRINT_LOGNORM, |
|
81 "uptime: System uptime reading error: %s.", |
|
82 error -> message); |
|
83 g_error_free (error); |
|
84 } |
|
85 g_io_channel_unref (channel); |
|
86 g_string_free (line, TRUE); |
|
87 return 0; |
|
88 } |
|
89 g_io_channel_unref (channel); |
|
90 if (sscanf (line -> str, "%d.%ds", &sec, &ssec) != 2) { |
|
91 scr_log_print (LPRINT_LOGNORM, |
|
92 "Unable to parse system uptime."); |
|
93 g_string_free (line, TRUE); |
|
94 return 0; |
|
95 } |
|
96 return (sec * hz) + (ssec * hz)/100; |
|
97 } |
58 |
98 |
59 void do_uptime (char *arg) |
99 void do_uptime (char *arg) |
60 { |
100 { |
61 GString *line = g_string_new (NULL); |
101 GString *line = g_string_new (NULL); |
62 guint seconds = time (NULL) - starttime; |
102 guint seconds; |
63 guint minutes = seconds / 60; |
103 guint minutes; |
64 guint hours = minutes / 60; |
104 guint hours; |
65 guint days = hours / 24; |
105 guint days; |
|
106 time_t now = time (NULL); |
|
107 |
|
108 if (proc_used && settings_opt_get_int ("uptime_use_proc")) { |
|
109 int sysup = sys_uptime(); |
|
110 if (!sysup) { |
|
111 g_string_free (line, TRUE); |
|
112 scr_log_print (LPRINT_NORMAL, "Uptime not available :-("); |
|
113 return; |
|
114 } |
|
115 seconds = (sysup - mstime) / hz; |
|
116 } else { |
|
117 seconds = now - starttime; |
|
118 } |
|
119 |
|
120 minutes = seconds / 60; |
|
121 hours = minutes / 60; |
|
122 days = hours / 24; |
66 seconds %= 60; |
123 seconds %= 60; |
67 minutes %= 60; |
124 minutes %= 60; |
68 hours %= 24; |
125 hours %= 24; |
69 |
126 |
70 if (days) |
127 if (days) |
81 g_string_free (line, TRUE); |
138 g_string_free (line, TRUE); |
82 } |
139 } |
83 |
140 |
84 gchar *g_module_check_init (GModule *module) |
141 gchar *g_module_check_init (GModule *module) |
85 { |
142 { |
|
143 starttime = time (NULL); |
|
144 |
86 if (settings_opt_get_int ("uptime_use_proc")) { |
145 if (settings_opt_get_int ("uptime_use_proc")) { |
87 long long unsigned int mstime = 0; |
146 //long long unsigned int kbtime = 0; |
88 long long unsigned int kbtime = 0; |
|
89 GError *error = NULL; |
147 GError *error = NULL; |
90 GString *line; |
148 GString *line; |
91 GIOChannel *channel = g_io_channel_new_file ("/proc/self/stat", "r", &error); |
149 GIOChannel *channel = g_io_channel_new_file ("/proc/self/stat", "r", &error); |
92 |
150 |
93 if (!channel) |
151 if (!channel) |
95 g_io_channel_set_close_on_unref (channel, TRUE); |
153 g_io_channel_set_close_on_unref (channel, TRUE); |
96 |
154 |
97 line = g_string_new (NULL); |
155 line = g_string_new (NULL); |
98 if (g_io_channel_read_line_string (channel, line, NULL, &error) != G_IO_STATUS_NORMAL) { |
156 if (g_io_channel_read_line_string (channel, line, NULL, &error) != G_IO_STATUS_NORMAL) { |
99 if (error) { |
157 if (error) { |
100 scr_log_print (LPRINT_DEBUG, "uptime: Own stats reading error: %s.", error -> message); |
158 scr_log_print (LPRINT_LOGNORM, "uptime: Own stats reading error: %s.", error -> message); |
101 g_error_free (error); |
159 g_error_free (error); |
102 } |
160 } |
103 g_io_channel_unref (channel); |
161 g_io_channel_unref (channel); |
104 g_string_free (line, TRUE); |
162 g_string_free (line, TRUE); |
105 return "Error reading own stats"; |
163 return "Error reading own stats"; |
108 gchar *p = strrchr (line -> str, ')'); // end of command |
166 gchar *p = strrchr (line -> str, ')'); // end of command |
109 if (!p) { |
167 if (!p) { |
110 g_string_free (line, TRUE); |
168 g_string_free (line, TRUE); |
111 return "Missing ) in own stats"; |
169 return "Missing ) in own stats"; |
112 } |
170 } |
|
171 p++; |
113 while (*p && isspace (*p)) p++; |
172 while (*p && isspace (*p)) p++; |
114 while (*p && isalpha (*p)) p++; // state (%c) |
173 while (*p && isalpha (*p)) p++; // state (%c) |
115 while (*p && isspace (*p)) p++; |
174 while (*p && isspace (*p)) p++; |
116 while (*p && isdigit (*p)) p++; // ppid (this and next are %d) |
175 while (*p && isdigit (*p)) p++; // ppid (this and next are %d) |
117 while (*p && isspace (*p)) p++; |
176 while (*p && isspace (*p)) p++; |
158 "remaining string: %s.", |
217 "remaining string: %s.", |
159 p - line -> str, line -> len, p); |
218 p - line -> str, line -> len, p); |
160 g_string_free (line, TRUE); |
219 g_string_free (line, TRUE); |
161 return "Malformed own start time."; |
220 return "Malformed own start time."; |
162 } |
221 } |
163 |
222 g_string_free (line, TRUE); |
164 channel = g_io_channel_new_file ("/proc/stat", "r", &error); |
223 |
165 if (!channel) { |
224 hz = sysconf(_SC_CLK_TCK); |
166 g_string_free (line, TRUE); |
225 if (hz && mstime) |
167 return "Cannot open system stats for reading"; |
226 proc_used = TRUE; |
168 } |
227 } |
169 g_io_channel_set_close_on_unref (channel, TRUE); |
|
170 |
|
171 while (TRUE) { |
|
172 GIOStatus ret = g_io_channel_read_line_string (channel, line, NULL, &error); |
|
173 if (ret != G_IO_STATUS_NORMAL) { |
|
174 if (error) { |
|
175 scr_log_print (LPRINT_DEBUG, "uptime: System stats reading error: %s.", error -> message); |
|
176 g_error_free (error); |
|
177 } |
|
178 g_io_channel_unref (channel); |
|
179 g_string_free (line, TRUE); |
|
180 return "Error reading system stats."; |
|
181 } |
|
182 if (sscanf (line -> str, "btime %llu", &kbtime)) |
|
183 break; |
|
184 } |
|
185 g_io_channel_unref (channel); |
|
186 |
|
187 g_string_free (line, TRUE); |
|
188 |
|
189 guint hz = sysconf(_SC_CLK_TCK); |
|
190 starttime = kbtime + (mstime / hz); |
|
191 } else |
|
192 starttime = time (NULL); |
|
193 |
228 |
194 cmd_add ("uptime", "", 0, 0, do_uptime, NULL); |
229 cmd_add ("uptime", "", 0, 0, do_uptime, NULL); |
195 return NULL; |
230 return NULL; |
196 } |
231 } |
197 |
232 |