uptime.c
changeset 8 af9ebb57baf6
parent 7 6524d7d3061b
child 9 c1f0277182a3
equal deleted inserted replaced
7:6524d7d3061b 8:af9ebb57baf6
    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