--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uptime.c Sun Apr 04 15:45:42 2010 +0300
@@ -0,0 +1,201 @@
+
+/* Copyright 2010 Myhailo Danylenko
+ *
+ * This file is part of mcabber-uptime
+ *
+ * mcabber-uptime is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <glib.h>
+#include <gmodule.h>
+#include <time.h>
+#include <stdio.h>
+
+#include <mcabber/modules.h>
+#include <mcabber/logprint.h>
+#include <mcabber/commands.h>
+#include <mcabber/settings.h>
+
+#include "config.h"
+
+#define DESCRIPTION ( "Shows mcabber uptime\nRecognizes option uptime_hz (at load time)." )
+
+module_info_t info_uptime_experimental = {
+ .branch = "experimental",
+ .api = 12,
+ .version = PROJECT_VERSION,
+ .description = DESCRIPTION,
+ .requires = NULL,
+ .init = NULL,
+ .uninit = NULL,
+ .next = NULL,
+};
+
+module_info_t info_uptime = {
+ .branch = "dev",
+ .api = 11,
+ .version = PROJECT_VERSION,
+ .description = DESCRIPTION,
+ .requires = NULL,
+ .init = NULL,
+ .uninit = NULL,
+ .next = &info_uptime_experimental,
+};
+
+time_t starttime = 0;
+
+void do_uptime (char *arg)
+{
+ GString *line = g_string_new (NULL);
+ guint seconds = time (NULL) - starttime;
+ guint minutes = seconds / 60;
+ guint hours = minutes / 60;
+ guint days = hours / 24;
+ seconds %= 60;
+ minutes %= 60;
+ hours %= 24;
+
+ g_string_truncate (line, 0);
+ if (days)
+ g_string_append_printf (line, " %u days", days);
+ if (hours)
+ g_string_append_printf (line, " %u hours", hours);
+ if (minutes)
+ g_string_append_printf (line, " %u minutes", minutes);
+ if (seconds)
+ g_string_append_printf (line, " %u seconds", seconds);
+
+ scr_log_print (LPRINT_NORMAL, "Uptime: %s.", line -> len ? line -> str : " 0 seconds");
+
+ g_string_free (line, TRUE);
+}
+
+gchar *g_module_check_init (GModule *module)
+{
+ if (settings_opt_get_int ("uptime_use_proc")) {
+ long long unsigned int mstime = 0;
+ long long unsigned int kbtime = 0;
+ GError *error = NULL;
+ GString *line;
+ GIOChannel *channel = g_io_channel_new_file ("/proc/self/stat", "r", &error);
+
+ if (!channel)
+ return "Cannot open own stats for reading";
+ g_io_channel_set_close_on_unref (channel, TRUE);
+
+ line = g_string_new (NULL);
+ if (g_io_channel_read_line_string (channel, line, NULL, &error) != G_IO_STATUS_NORMAL) {
+ if (error) {
+ scr_log_print (LPRINT_DEBUG, "uptime: Own stats reading error: %s.", error -> message);
+ g_error_free (error);
+ }
+ g_io_channel_unref (channel);
+ g_string_free (line, TRUE);
+ return "Error reading own stats";
+ }
+ g_io_channel_unref (channel);
+ gchar *p = strrchr (line -> str, ')'); // end of command
+ if (!p) {
+ g_string_free (line, TRUE);
+ return "Missing ) in own stats"
+ }
+ while (*p && isspace (*p)) p++;
+ while (*p && isalpha (*p)) p++; // state (%c)
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // ppid (this and next are %d)
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // pgrp
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // session
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // tty_nr
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // tpgid
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // flags (this and all next - %u)
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // minflt
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // cminflt
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // majflt
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // cmajflt
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // utime
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // stime
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // cutime (this and next next are %d)
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // cstime
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // priority
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // nice
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // num_threads
+ while (*p && isspace (*p)) p++;
+ while (*p && isdigit (*p)) p++; // itrealvalue
+ while (*p && isspace (*p)) p++;
+ char *u = p;
+ while (*u && isdigit (*u)) u++;
+ *u = '\0';
+ if (!sscanf (p, "%llu", &mstime)) {
+ scr_log_print (LPRINT_LOGNORM, "uptime: now at %u/%u, remaining string: %s.", p - line -> str, line -> len, p);
+ g_string_free (line, TRUE);
+ return "Malformed own start time.";
+ }
+
+ channel = g_io_channel_new_file ("/proc/stat", "r", &error);
+ if (!channel) {
+ g_string_free (line, TRUE);
+ return "Cannot open system stats for reading";
+ }
+ g_io_channel_set_close_on_unref (channel, TRUE);
+
+ while (TRUE) {
+ GIOStatus ret = g_io_channel_read_line_string (channel, line, NULL, &error);
+ if (ret != G_IO_STATUS_NORMAL) {
+ if (error) {
+ scr_log_print (LPRINT_DEBUG, "uptime: System stats reading error: %s.", error -> message);
+ g_error_free (error);
+ }
+ g_io_channel_unref (channel);
+ g_string_free (line, TRUE);
+ return "Error reading system stats.";
+ }
+ if (sscanf (line -> str, "btime %llu", &kbtime))
+ break;
+ }
+ g_io_channel_unref (channel);
+
+ g_string_free (line, TRUE);
+
+ guint hz = settings_opt_get_int ("uptime_hz");
+ if (!hz)
+ hz = 250;
+ starttime = kbtime + (mstime / hz);
+ } else {
+ starttime = time (NULL);
+
+ cmd_add ("uptime", "", 0, 0, do_uptime, NULL);
+ return NULL;
+}
+
+void g_module_unload (GModule *module)
+{
+ cmd_del ("uptime");
+}
+
+/* The End */