GLib version 1 is very outdated by now and not available in any recent Linux distribution. Keeping this code around without actually being able to test it makes little sense so let's get rid of that.
2371 lines
51 KiB
C
2371 lines
51 KiB
C
/* GKrellM
|
|
| Copyright (C) 1999-2010 Bill Wilson
|
|
|
|
|
| Author: Bill Wilson billw@gkrellm.net
|
|
| Latest versions might be found at: http://gkrellm.net
|
|
|
|
|
|
|
|
| GKrellM 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 3 of the License, or
|
|
| (at your option) any later version.
|
|
|
|
|
| GKrellM 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/
|
|
|
|
|
|
|
|
| Additional permission under GNU GPL version 3 section 7
|
|
|
|
|
| If you modify this program, or any covered work, by linking or
|
|
| combining it with the OpenSSL project's OpenSSL library (or a
|
|
| modified version of that library), containing parts covered by
|
|
| the terms of the OpenSSL or SSLeay licenses, you are granted
|
|
| additional permission to convey the resulting work.
|
|
| Corresponding Source for a non-source form of such a combination
|
|
| shall include the source code for the parts of OpenSSL used as well
|
|
| as that of the covered work.
|
|
*/
|
|
|
|
#include "gkrellmd.h"
|
|
#include "gkrellmd-private.h"
|
|
#include <inttypes.h>
|
|
|
|
GList *gkrellmd_monitor_list;
|
|
|
|
static GList *serveflag_done_list;
|
|
|
|
static struct tm gkrellmd_current_tm;
|
|
|
|
gint
|
|
gkrellm_get_timer_ticks(void)
|
|
{
|
|
return GK.timer_ticks;
|
|
}
|
|
|
|
gboolean
|
|
gkrellmd_check_client_version(GkrellmdMonitor *mon,
|
|
gint major, gint minor, gint rev)
|
|
{
|
|
GkrellmdClient *client = mon->privat->client;
|
|
|
|
if ( client->major_version > major
|
|
|| (client->major_version == major && client->minor_version > minor)
|
|
|| ( client->major_version == major && client->minor_version == minor
|
|
&& client->rev_version >= rev
|
|
)
|
|
)
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
void
|
|
gkrellmd_add_serveflag_done(gboolean *flag)
|
|
{
|
|
serveflag_done_list = g_list_append(serveflag_done_list, flag);
|
|
}
|
|
|
|
|
|
void
|
|
gkrellmd_set_serve_name(GkrellmdMonitor *mon, const gchar *tag)
|
|
{
|
|
GkrellmdMonitorPrivate *mp = mon->privat;
|
|
|
|
mp->serve_name = tag;
|
|
mp->serve_name_sent = FALSE;
|
|
}
|
|
|
|
void
|
|
gkrellmd_serve_data(GkrellmdMonitor *mon, gchar *line)
|
|
{
|
|
GkrellmdMonitorPrivate *mp = mon->privat;
|
|
gchar buf[128];
|
|
|
|
if (!line || !*line)
|
|
return;
|
|
if (!mp->serve_name_sent)
|
|
{
|
|
if (mp->serve_name)
|
|
{
|
|
snprintf(buf, sizeof(buf), "<%s>\n", mp->serve_name);
|
|
gkrellm_debug(DEBUG_SERVER, "%s", buf);
|
|
mp->serve_gstring = g_string_append(mp->serve_gstring, buf);
|
|
mp->serve_name_sent = TRUE;
|
|
}
|
|
else
|
|
{
|
|
g_warning("gkrellmd: %s forgot to gkrellmd_set_serve_name()\n",
|
|
mon->name);
|
|
return;
|
|
}
|
|
}
|
|
gkrellm_debug(DEBUG_SERVER,"%s", line);
|
|
mp->serve_gstring = g_string_append(mp->serve_gstring, line);
|
|
}
|
|
|
|
/* ======================================================= */
|
|
typedef struct
|
|
{
|
|
gint instance;
|
|
gulong user,
|
|
nice,
|
|
sys,
|
|
idle;
|
|
}
|
|
CpuData;
|
|
|
|
static gchar *n_cpus_setup;
|
|
static gboolean nice_time_unsupported;
|
|
|
|
static GList *cpu_list;
|
|
static GList *instance_list;
|
|
|
|
void
|
|
gkrellm_cpu_set_number_of_cpus(gint n)
|
|
{
|
|
CpuData *cpu;
|
|
GList *list;
|
|
gint i;
|
|
|
|
n_cpus_setup = g_strdup_printf("n_cpus %d\n", n);
|
|
for (i = 0; i < n; ++i)
|
|
{
|
|
cpu = g_new0(CpuData, 1);
|
|
cpu_list = g_list_append(cpu_list, cpu);
|
|
|
|
if (instance_list && (list = g_list_nth(instance_list, i)) != NULL)
|
|
cpu->instance = GPOINTER_TO_INT(list->data);
|
|
else
|
|
cpu->instance = i;
|
|
}
|
|
}
|
|
|
|
void
|
|
gkrellm_cpu_add_instance(gint instance)
|
|
{
|
|
instance_list = g_list_append(instance_list, GINT_TO_POINTER(instance));
|
|
}
|
|
|
|
void
|
|
gkrellm_cpu_nice_time_unsupported(void)
|
|
{
|
|
nice_time_unsupported = TRUE;
|
|
}
|
|
|
|
void
|
|
gkrellm_cpu_assign_composite_data(gulong user, gulong nice,
|
|
gulong sys, gulong idle)
|
|
{
|
|
return; /* let client gkrellm compute it */
|
|
}
|
|
|
|
void
|
|
gkrellm_cpu_assign_data(gint n, gulong user, gulong nice,
|
|
gulong sys, gulong idle)
|
|
{
|
|
CpuData *cpu = NULL;
|
|
GList *list;
|
|
|
|
for (list = cpu_list; list; list = list->next)
|
|
{
|
|
cpu = (CpuData *) list->data;
|
|
if (cpu->instance == n)
|
|
break;
|
|
}
|
|
if (list)
|
|
{
|
|
cpu->user = user;
|
|
cpu->nice = nice;
|
|
cpu->sys = sys;
|
|
cpu->idle = idle;
|
|
}
|
|
}
|
|
|
|
static void
|
|
update_cpu(GkrellmdMonitor *mon, gboolean first_update)
|
|
{
|
|
gkrellm_sys_cpu_read_data();
|
|
gkrellmd_need_serve(mon);
|
|
}
|
|
|
|
static void
|
|
serve_cpu_data(GkrellmdMonitor *mon, gboolean first_serve)
|
|
{
|
|
CpuData *cpu;
|
|
GList *list;
|
|
gchar buf[128];
|
|
|
|
gkrellmd_set_serve_name(mon, "cpu");
|
|
for (list = cpu_list; list; list = list->next)
|
|
{
|
|
cpu = (CpuData *) list->data;
|
|
snprintf(buf, sizeof(buf), "%d %lu %lu %lu %lu\n", cpu->instance,
|
|
cpu->user, cpu->nice, cpu->sys, cpu->idle);
|
|
gkrellmd_serve_data(mon, buf);
|
|
}
|
|
}
|
|
|
|
static void
|
|
serve_cpu_setup(GkrellmdMonitor *mon)
|
|
{
|
|
GkrellmdClient *client = mon->privat->client;
|
|
GList *list;
|
|
gchar buf[64];
|
|
|
|
gkrellmd_send_to_client(client, "<cpu_setup>\n");
|
|
for (list = instance_list; list; list = list->next)
|
|
{
|
|
snprintf(buf, sizeof(buf), "cpu_instance %d\n",
|
|
GPOINTER_TO_INT(list->data));
|
|
gkrellmd_send_to_client(client, buf);
|
|
}
|
|
gkrellmd_send_to_client(client, n_cpus_setup);
|
|
if (nice_time_unsupported)
|
|
gkrellmd_send_to_client(client, "nice_time_unsupported\n");
|
|
}
|
|
|
|
static GkrellmdMonitor cpu_monitor =
|
|
{
|
|
"cpu",
|
|
update_cpu,
|
|
serve_cpu_data,
|
|
serve_cpu_setup
|
|
};
|
|
|
|
|
|
static GkrellmdMonitor *
|
|
init_cpu_monitor(void)
|
|
{
|
|
if (gkrellm_sys_cpu_init())
|
|
return &cpu_monitor;
|
|
return NULL;
|
|
}
|
|
|
|
/* ======================================================= */
|
|
struct
|
|
{
|
|
gboolean changed;
|
|
gint n_processes,
|
|
n_running,
|
|
n_users;
|
|
gulong n_forks;
|
|
gfloat fload;
|
|
}
|
|
proc;
|
|
|
|
void
|
|
gkrellm_proc_assign_data(gint n_processes, gint n_running,
|
|
gulong n_forks, gfloat load)
|
|
{
|
|
if ( proc.n_processes != n_processes
|
|
|| proc.n_running != n_running
|
|
|| proc.n_forks != n_forks
|
|
|| proc.fload != load
|
|
)
|
|
{
|
|
proc.n_processes = n_processes;
|
|
proc.n_running = n_running;
|
|
proc.n_forks = n_forks;
|
|
proc.fload = load;
|
|
proc.changed = TRUE;
|
|
}
|
|
}
|
|
|
|
void
|
|
gkrellm_proc_assign_users(gint n_users)
|
|
{
|
|
if (proc.n_users != n_users)
|
|
{
|
|
proc.n_users = n_users;
|
|
proc.changed = TRUE;
|
|
}
|
|
}
|
|
|
|
static void
|
|
update_proc(GkrellmdMonitor *mon, gboolean first_update)
|
|
{
|
|
proc.changed = FALSE;
|
|
gkrellm_sys_proc_read_data();
|
|
if (first_update || GK.five_second_tick)
|
|
gkrellm_sys_proc_read_users();
|
|
|
|
if (proc.changed)
|
|
gkrellmd_need_serve(mon);
|
|
}
|
|
|
|
static void
|
|
serve_proc_data(GkrellmdMonitor *mon, gboolean first_serve)
|
|
{
|
|
gchar buf[128];
|
|
|
|
gkrellmd_set_serve_name(mon, "proc");
|
|
snprintf(buf, sizeof(buf), "%d %d %lu %.2f %d\n",
|
|
proc.n_processes, proc.n_running,
|
|
proc.n_forks, proc.fload, proc.n_users);
|
|
gkrellmd_serve_data(mon, buf);
|
|
}
|
|
|
|
static GkrellmdMonitor proc_monitor =
|
|
{
|
|
"proc",
|
|
update_proc,
|
|
serve_proc_data,
|
|
NULL
|
|
};
|
|
|
|
|
|
static GkrellmdMonitor *
|
|
init_proc_monitor(void)
|
|
{
|
|
if (!gkrellm_sys_proc_init())
|
|
return NULL;
|
|
serveflag_done_list = g_list_append(serveflag_done_list, &proc.changed);
|
|
return &proc_monitor;
|
|
}
|
|
|
|
/* ======================================================= */
|
|
typedef struct
|
|
{
|
|
gchar *name;
|
|
gchar *subdisk_parent;
|
|
gint order,
|
|
subdisk,
|
|
changed;
|
|
gint device_number,
|
|
unit_number;
|
|
gboolean virtual;
|
|
guint64 rb,
|
|
wb;
|
|
}
|
|
DiskData;
|
|
|
|
static GList *disk_list;
|
|
static gint n_disks;
|
|
static gboolean units_are_blocks;
|
|
|
|
|
|
static DiskData *
|
|
add_disk(const gchar *name, gint order, gint device_number, gint unit_number)
|
|
{
|
|
DiskData *disk;
|
|
GList *list;
|
|
gint i;
|
|
|
|
disk = g_new0(DiskData, 1);
|
|
disk->name = g_strdup(name);
|
|
disk->order = order;
|
|
disk->subdisk = -1;
|
|
disk->device_number = device_number;
|
|
disk->unit_number = unit_number;
|
|
if (order >= 0)
|
|
{
|
|
for (i = 0, list = disk_list; list; list = list->next, ++i)
|
|
if (disk->order < ((DiskData *) list->data)->order)
|
|
break;
|
|
disk_list = g_list_insert(disk_list, disk, i);
|
|
}
|
|
else
|
|
disk_list = g_list_append(disk_list, disk);
|
|
++n_disks;
|
|
return disk;
|
|
}
|
|
|
|
static DiskData *
|
|
add_subdisk(gchar *subdisk_name, gchar *disk_name, gint subdisk)
|
|
{
|
|
DiskData *sdisk = NULL;
|
|
DiskData *disk;
|
|
GList *list = NULL;
|
|
|
|
for (list = disk_list; list; list = list->next)
|
|
{
|
|
disk = (DiskData * ) list->data;
|
|
if (!strcmp(disk_name, disk->name))
|
|
break;
|
|
}
|
|
if (!list)
|
|
return NULL;
|
|
sdisk = g_new0(DiskData, 1);
|
|
sdisk->name = g_strdup(subdisk_name);
|
|
sdisk->subdisk_parent = g_strdup(disk_name);
|
|
sdisk->order = disk->order;
|
|
sdisk->subdisk = subdisk;
|
|
|
|
for (list = list->next; list; list = list->next)
|
|
{
|
|
disk = (DiskData * ) list->data;
|
|
if (disk->subdisk == -1 || disk->subdisk > subdisk)
|
|
break;
|
|
}
|
|
disk_list = g_list_insert_before(disk_list, list, sdisk);
|
|
++n_disks;
|
|
return sdisk;
|
|
}
|
|
|
|
static void
|
|
disk_assign_data(DiskData *disk, guint64 rb, guint64 wb, gboolean virtual)
|
|
{
|
|
if (disk)
|
|
{
|
|
if (disk->rb != rb || disk->wb != wb)
|
|
disk->changed = TRUE;
|
|
else
|
|
disk->changed = FALSE;
|
|
disk->rb = rb;
|
|
disk->wb = wb;
|
|
disk->virtual = virtual;
|
|
}
|
|
}
|
|
|
|
void
|
|
gkrellm_disk_reset_composite(void)
|
|
{
|
|
/* Don't handle this. */
|
|
}
|
|
|
|
void
|
|
gkrellm_disk_units_are_blocks(void)
|
|
{
|
|
units_are_blocks = TRUE;
|
|
}
|
|
|
|
void
|
|
gkrellm_disk_add_by_name(const gchar *name, const gchar *label)
|
|
{
|
|
gint order = -1;
|
|
|
|
if (NULL == name) // Cannot add disk without a name
|
|
return;
|
|
order = gkrellm_sys_disk_order_from_name(name);
|
|
/* FIXME: gkrellmd currently has no support for disk labels. Extend
|
|
network-protocol and server to support disks with both name and label. */
|
|
add_disk(name, order, 0, 0);
|
|
}
|
|
|
|
void
|
|
gkrellm_disk_assign_data_by_device(gint device_number, gint unit_number,
|
|
guint64 rb, guint64 wb, gboolean virtual)
|
|
{
|
|
GList *list;
|
|
DiskData *disk = NULL;
|
|
gchar *name;
|
|
gint order = -1;
|
|
|
|
for (list = disk_list; list; list = list->next)
|
|
{
|
|
disk = (DiskData * ) list->data;
|
|
if ( disk->device_number == device_number
|
|
&& disk->unit_number == unit_number
|
|
)
|
|
break;
|
|
disk = NULL;
|
|
}
|
|
if (!disk)
|
|
{
|
|
name = gkrellm_sys_disk_name_from_device(device_number,
|
|
unit_number, &order);
|
|
if (name)
|
|
disk = add_disk(name, order, device_number, unit_number);
|
|
}
|
|
disk_assign_data(disk, rb, wb, virtual);
|
|
}
|
|
|
|
void
|
|
gkrellm_disk_assign_data_nth(gint n, guint64 rb, guint64 wb, gboolean virtual)
|
|
{
|
|
DiskData *disk;
|
|
gchar name[32];
|
|
|
|
if (n < n_disks)
|
|
disk = (DiskData *) g_list_nth_data(disk_list, n);
|
|
else
|
|
{
|
|
snprintf(name, sizeof(name), "%s%c", _("Disk"), 'A' + n);
|
|
disk = add_disk(name, n, 0, 0);
|
|
}
|
|
disk_assign_data(disk, rb, wb, virtual);
|
|
}
|
|
|
|
void
|
|
gkrellm_disk_assign_data_by_name(gchar *name,
|
|
guint64 rb, guint64 wb, gboolean virtual)
|
|
{
|
|
GList *list;
|
|
DiskData *disk = NULL;
|
|
gint order = -1;
|
|
|
|
for (list = disk_list; list; list = list->next)
|
|
{
|
|
disk = (DiskData * ) list->data;
|
|
if (!strcmp(name, disk->name))
|
|
break;
|
|
disk = NULL;
|
|
}
|
|
if (!disk)
|
|
{
|
|
order = gkrellm_sys_disk_order_from_name(name);
|
|
disk = add_disk(name, order, 0, 0);
|
|
}
|
|
disk_assign_data(disk, rb, wb, virtual);
|
|
}
|
|
|
|
void
|
|
gkrellm_disk_subdisk_assign_data_by_name(gchar *subdisk_name, gchar *disk_name,
|
|
guint64 rb, guint64 wb)
|
|
{
|
|
GList *list;
|
|
DiskData *disk = NULL;
|
|
gchar *s, *endptr;
|
|
gint subdisk;
|
|
|
|
if (!subdisk_name || !disk_name)
|
|
return;
|
|
for (list = disk_list; list; list = list->next)
|
|
{
|
|
disk = (DiskData * ) list->data;
|
|
if (!strcmp(subdisk_name, disk->name))
|
|
break;
|
|
disk = NULL;
|
|
}
|
|
if (!disk)
|
|
{
|
|
/* A subdisk name is expected to be the disk_name with a number string
|
|
| appended. Eg. "hda1" is a subdisk_name of disk_name "hda"
|
|
*/
|
|
s = subdisk_name + strlen(disk_name);
|
|
subdisk = strtol(s, &endptr, 0);
|
|
if (!*s || *endptr)
|
|
return;
|
|
disk = add_subdisk(subdisk_name, disk_name, subdisk);
|
|
}
|
|
disk_assign_data(disk, rb, wb, FALSE);
|
|
}
|
|
|
|
static void
|
|
update_disk(GkrellmdMonitor *mon, gboolean first_update)
|
|
{
|
|
GList *list;
|
|
DiskData *disk = NULL;
|
|
|
|
gkrellm_sys_disk_read_data();
|
|
for (list = disk_list; list; list = list->next)
|
|
{
|
|
disk = (DiskData * ) list->data;
|
|
if (disk->changed)
|
|
{
|
|
gkrellmd_need_serve(mon);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
serve_disk_data(GkrellmdMonitor *mon, gboolean first_serve)
|
|
{
|
|
DiskData *disk;
|
|
GList *list;
|
|
gchar *buf = NULL;
|
|
|
|
gkrellmd_set_serve_name(mon, "disk");
|
|
for (list = disk_list; list; list = list->next)
|
|
{
|
|
disk = (DiskData *) list->data;
|
|
if (!disk->changed && !first_serve)
|
|
continue;
|
|
if (!disk->subdisk_parent)
|
|
{
|
|
if (gkrellmd_check_client_version(mon, 2, 2, 7) && disk->virtual)
|
|
buf = g_strdup_printf("%s virtual %" PRIu64 " %" PRIu64 "\n",
|
|
disk->name, disk->rb, disk->wb);
|
|
else
|
|
buf = g_strdup_printf("%s %" PRIu64 " %" PRIu64 "\n",
|
|
disk->name, disk->rb, disk->wb);
|
|
}
|
|
else if (mon->privat->client->feature_subdisk)
|
|
buf = g_strdup_printf("%s %s %" PRIu64 " %" PRIu64 "\n",
|
|
disk->name, disk->subdisk_parent, disk->rb, disk->wb);
|
|
else
|
|
continue;
|
|
gkrellmd_serve_data(mon, buf);
|
|
g_free(buf);
|
|
buf = NULL;
|
|
}
|
|
}
|
|
|
|
static void
|
|
serve_disk_setup(GkrellmdMonitor *mon)
|
|
{
|
|
GkrellmdClient *client = mon->privat->client;
|
|
|
|
if (units_are_blocks)
|
|
gkrellmd_send_to_client(client, "<disk_setup>\nunits_are_blocks\n");
|
|
if (gkrellmd_check_client_version(mon, 2,1,3))
|
|
client->feature_subdisk = TRUE;
|
|
}
|
|
|
|
static GkrellmdMonitor disk_monitor =
|
|
{
|
|
"disk",
|
|
update_disk,
|
|
serve_disk_data,
|
|
serve_disk_setup
|
|
};
|
|
|
|
|
|
static GkrellmdMonitor *
|
|
init_disk_monitor(void)
|
|
{
|
|
if (gkrellm_sys_disk_init())
|
|
return &disk_monitor;
|
|
return NULL;
|
|
}
|
|
|
|
/* ======================================================= */
|
|
#include "../src/inet.h"
|
|
|
|
typedef struct
|
|
{
|
|
ActiveTCP tcp;
|
|
gboolean alive,
|
|
new_connection;
|
|
}
|
|
InetData;
|
|
|
|
static GList *inet_list,
|
|
*inet_dead_list;
|
|
|
|
static gboolean inet_unsupported,
|
|
inet_new;
|
|
|
|
void
|
|
gkrellm_inet_log_tcp_port_data(gpointer data)
|
|
{
|
|
GList *list;
|
|
InetData *in;
|
|
ActiveTCP *tcp, *active_tcp = NULL;
|
|
gchar *ap, *aap;
|
|
gint slen;
|
|
|
|
tcp = (ActiveTCP *) data;
|
|
for (list = inet_list; list; list = list->next)
|
|
{
|
|
in = (InetData *) list->data;
|
|
active_tcp = &in->tcp;
|
|
if (tcp->family == AF_INET)
|
|
{
|
|
ap = (char *)&tcp->remote_addr;
|
|
aap = (char *)&active_tcp->remote_addr;
|
|
slen = sizeof(struct in_addr);
|
|
}
|
|
#if defined(INET6)
|
|
else if (tcp->family == AF_INET6)
|
|
{
|
|
ap = (char *)&tcp->remote_addr6;
|
|
aap = (char *)&active_tcp->remote_addr6;
|
|
slen = sizeof(struct in6_addr);
|
|
}
|
|
#endif
|
|
else
|
|
return;
|
|
if ( memcmp(aap, ap, slen) == 0
|
|
&& active_tcp->remote_port == tcp->remote_port
|
|
&& active_tcp->local_port == tcp->local_port
|
|
)
|
|
{
|
|
in->alive = TRUE; /* Old alive connection still alive */
|
|
return;
|
|
}
|
|
}
|
|
inet_new = TRUE;
|
|
in = g_new0(InetData, 1);
|
|
in->tcp = *tcp;
|
|
in->alive = TRUE;
|
|
in->new_connection = TRUE;
|
|
inet_list = g_list_append(inet_list, in);
|
|
}
|
|
|
|
static void
|
|
update_inet(GkrellmdMonitor *mon, gboolean first_update)
|
|
{
|
|
GList *list;
|
|
InetData *in;
|
|
static gint check_tcp;
|
|
|
|
|
|
if (!first_update && !GK.second_tick)
|
|
return;
|
|
|
|
if (first_update || check_tcp == 0)
|
|
{
|
|
gkrellm_free_glist_and_data(&inet_dead_list);
|
|
inet_new = FALSE;
|
|
for (list = inet_list; list; list = list->next)
|
|
{
|
|
in = (InetData *) list->data;
|
|
in->alive = FALSE;
|
|
in->new_connection = FALSE;
|
|
}
|
|
|
|
gkrellm_sys_inet_read_tcp_data();
|
|
|
|
for (list = inet_list; list; )
|
|
{
|
|
in = (InetData *) list->data;
|
|
if (!in->alive)
|
|
{
|
|
if (list == inet_list)
|
|
inet_list = inet_list->next;
|
|
list = g_list_remove(list, in);
|
|
inet_dead_list = g_list_append(inet_dead_list, in);
|
|
}
|
|
else
|
|
list = list->next;
|
|
}
|
|
if (inet_new || inet_dead_list)
|
|
gkrellmd_need_serve(mon);
|
|
}
|
|
check_tcp = (check_tcp + 1) % _GK.inet_interval;
|
|
}
|
|
|
|
static void
|
|
serve_inet_data(GkrellmdMonitor *mon, gboolean first_serve)
|
|
{
|
|
InetData *in;
|
|
ActiveTCP *tcp;
|
|
GList *list;
|
|
gchar buf[128], *cp;
|
|
#if defined(INET6) && defined(HAVE_GETADDRINFO)
|
|
struct sockaddr_in6 sin6;
|
|
char addrbuf[NI_MAXHOST];
|
|
#endif
|
|
|
|
if (inet_new || first_serve)
|
|
{
|
|
gkrellmd_set_serve_name(mon, "inet");
|
|
for (list = inet_list; list; list = list->next)
|
|
{
|
|
in = (InetData *) list->data;
|
|
tcp = &in->tcp;
|
|
if ( tcp->family == AF_INET
|
|
&& (in->new_connection || first_serve)
|
|
)
|
|
{
|
|
cp = inet_ntoa(tcp->remote_addr);
|
|
snprintf(buf, sizeof(buf), "+0 %x %s:%x\n",
|
|
tcp->local_port, cp, tcp->remote_port);
|
|
}
|
|
#if defined(INET6) && defined(HAVE_GETADDRINFO)
|
|
else if (tcp->family == AF_INET6
|
|
&& (in->new_connection || first_serve))
|
|
{
|
|
memset(&sin6, 0, sizeof(sin6));
|
|
memcpy(&sin6.sin6_addr, &tcp->remote_addr6,
|
|
sizeof(struct in6_addr));
|
|
sin6.sin6_family = AF_INET6;
|
|
#ifdef SIN6_LEN
|
|
sin6.sin6_len = sizeof(struct sockaddr_in6);
|
|
#endif
|
|
if (getnameinfo((struct sockaddr *)&sin6,
|
|
sizeof(struct sockaddr_in6),
|
|
addrbuf, sizeof(addrbuf),
|
|
NULL, 0,
|
|
NI_NUMERICHOST|NI_WITHSCOPEID)
|
|
!= 0)
|
|
continue;
|
|
snprintf(buf, sizeof(buf), "+6 %x [%s]:%x\n",
|
|
tcp->local_port, addrbuf,
|
|
tcp->remote_port);
|
|
}
|
|
#endif
|
|
else
|
|
continue;
|
|
|
|
gkrellmd_serve_data(mon, buf);
|
|
}
|
|
}
|
|
if (!first_serve)
|
|
{
|
|
gkrellmd_set_serve_name(mon, "inet");
|
|
for (list = inet_dead_list; list; list = list->next)
|
|
{
|
|
in = (InetData *) list->data;
|
|
tcp = &in->tcp;
|
|
if (tcp->family == AF_INET)
|
|
{
|
|
cp = inet_ntoa(tcp->remote_addr);
|
|
snprintf(buf, sizeof(buf), "-0 %x %s:%x\n",
|
|
tcp->local_port, cp, tcp->remote_port);
|
|
}
|
|
#if defined(INET6) && defined(HAVE_GETADDRINFO)
|
|
else if (tcp->family == AF_INET6)
|
|
{
|
|
memset(&sin6, 0, sizeof(sin6));
|
|
memcpy(&sin6.sin6_addr, &tcp->remote_addr6,
|
|
sizeof(struct in6_addr));
|
|
sin6.sin6_family = AF_INET6;
|
|
#ifdef SIN6_LEN
|
|
sin6.sin6_len = sizeof(struct sockaddr_in6);
|
|
#endif
|
|
if (getnameinfo((struct sockaddr *)&sin6,
|
|
sizeof(struct sockaddr_in6),
|
|
addrbuf, sizeof(addrbuf),
|
|
NULL, 0,
|
|
NI_NUMERICHOST|NI_WITHSCOPEID)
|
|
!= 0)
|
|
continue;
|
|
snprintf(buf, sizeof(buf), "-6 %x [%s]:%x\n",
|
|
tcp->local_port, addrbuf,
|
|
tcp->remote_port);
|
|
}
|
|
#endif
|
|
else
|
|
continue;
|
|
|
|
gkrellmd_serve_data(mon, buf);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
serve_inet_setup(GkrellmdMonitor *mon)
|
|
{
|
|
GkrellmdClient *client = mon->privat->client;
|
|
|
|
if (inet_unsupported)
|
|
gkrellmd_send_to_client(client, "<inet_setup>\ninet_unsupported\n");
|
|
}
|
|
|
|
static GkrellmdMonitor inet_monitor =
|
|
{
|
|
"inet",
|
|
update_inet,
|
|
serve_inet_data,
|
|
serve_inet_setup
|
|
};
|
|
|
|
|
|
static GkrellmdMonitor *
|
|
init_inet_monitor(void)
|
|
{
|
|
if (_GK.inet_interval > 0 && gkrellm_sys_inet_init())
|
|
return &inet_monitor;
|
|
inet_unsupported = TRUE;
|
|
return NULL;
|
|
}
|
|
|
|
/* ======================================================= */
|
|
|
|
#define TIMER_TYPE_NONE 0
|
|
#define TIMER_TYPE_PPP 1
|
|
#define TIMER_TYPE_IPPP 2
|
|
|
|
typedef struct
|
|
{
|
|
gchar *name;
|
|
gboolean changed,
|
|
up,
|
|
up_prev,
|
|
up_event,
|
|
down_event;
|
|
|
|
gboolean timed_changed;
|
|
time_t up_time;
|
|
|
|
gulong rx,
|
|
tx;
|
|
}
|
|
NetData;
|
|
|
|
static NetData *net_timer;
|
|
|
|
static GList *net_list,
|
|
*net_sys_list;
|
|
|
|
static time_t net_timer0;
|
|
static gint net_timer_type;
|
|
|
|
static gboolean net_use_routed;
|
|
|
|
|
|
gchar *
|
|
gkrellm_net_mon_first(void)
|
|
{
|
|
gchar *name = NULL;
|
|
|
|
net_sys_list = net_list;
|
|
if (net_sys_list)
|
|
{
|
|
name = ((NetData *) (net_sys_list->data))->name;
|
|
net_sys_list = net_sys_list->next;
|
|
}
|
|
return name;
|
|
}
|
|
|
|
gchar *
|
|
gkrellm_net_mon_next(void)
|
|
{
|
|
gchar *name = NULL;
|
|
|
|
if (net_sys_list)
|
|
{
|
|
name = ((NetData *) (net_sys_list->data))->name;
|
|
net_sys_list = net_sys_list->next;
|
|
}
|
|
return name;
|
|
}
|
|
|
|
void
|
|
gkrellm_net_use_routed(gboolean real_routed /* not applicable in server */)
|
|
{
|
|
net_use_routed = TRUE;
|
|
}
|
|
|
|
static NetData *
|
|
net_new(gchar *name)
|
|
{
|
|
NetData *net;
|
|
|
|
net = g_new0(NetData, 1);
|
|
net->name = g_strdup(name);
|
|
net_list = g_list_append(net_list, net);
|
|
|
|
if (net_timer_type != TIMER_TYPE_NONE && !strcmp(_GK.net_timer, net->name))
|
|
net_timer = net;
|
|
|
|
return net;
|
|
}
|
|
|
|
void
|
|
gkrellm_net_assign_data(gchar *name, gulong rx, gulong tx)
|
|
{
|
|
GList *list;
|
|
NetData *net;
|
|
|
|
for (list = net_list; list; list = list->next)
|
|
{
|
|
net = (NetData *) list->data;
|
|
if (!strcmp(net->name, name))
|
|
{
|
|
if (net->rx != rx || net->tx != tx)
|
|
net->changed = TRUE;
|
|
else
|
|
net->changed = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
if (!list)
|
|
net = net_new(name);
|
|
|
|
if (GK.second_tick && !net_use_routed)
|
|
net->up = TRUE;
|
|
net->rx = rx;
|
|
net->tx = tx;
|
|
}
|
|
|
|
void
|
|
gkrellm_net_routed_event(gchar *name, gboolean routed)
|
|
{
|
|
GList *list;
|
|
NetData *net;
|
|
|
|
for (list = net_list; list; list = list->next)
|
|
{
|
|
net = (NetData *) list->data;
|
|
if (!strcmp(net->name, name))
|
|
break;
|
|
}
|
|
if (!list)
|
|
net = net_new(name);
|
|
|
|
if (routed)
|
|
net->up_event = TRUE;
|
|
else
|
|
net->down_event = TRUE;
|
|
net->up = routed;
|
|
}
|
|
|
|
void
|
|
gkrellm_net_add_timer_type_ppp(gchar *name)
|
|
{
|
|
if (!_GK.net_timer || !name)
|
|
return;
|
|
if (name && !strncmp(_GK.net_timer, name, strlen(name) - 1))
|
|
net_timer_type = TIMER_TYPE_PPP;
|
|
}
|
|
|
|
void
|
|
gkrellm_net_add_timer_type_ippp(gchar *name)
|
|
{
|
|
if (!_GK.net_timer || !name)
|
|
return;
|
|
if (name && !strncmp(_GK.net_timer, name, strlen(name) - 1))
|
|
net_timer_type = TIMER_TYPE_IPPP;
|
|
}
|
|
|
|
void
|
|
gkrellm_net_set_lock_directory(gchar *dir)
|
|
{
|
|
/* Not supported remotely */
|
|
}
|
|
|
|
static void
|
|
update_net(GkrellmdMonitor *mon, gboolean first_update)
|
|
{
|
|
GList *list;
|
|
NetData *net;
|
|
gint up_time = 0;
|
|
|
|
if (GK.second_tick)
|
|
{
|
|
if (!net_use_routed)
|
|
{
|
|
for (list = net_list; list; list = list->next)
|
|
{
|
|
net = (NetData *) list->data;
|
|
net->up_prev = net->up;
|
|
net->up = FALSE;
|
|
}
|
|
}
|
|
else
|
|
gkrellm_sys_net_check_routes();
|
|
}
|
|
gkrellm_sys_net_read_data();
|
|
|
|
if (GK.second_tick && !net_use_routed)
|
|
{
|
|
for (list = net_list; list; list = list->next)
|
|
{
|
|
net = (NetData *) list->data;
|
|
if (net->up && !net->up_prev)
|
|
net->up_event = TRUE;
|
|
else if (!net->up && net->up_prev)
|
|
net->down_event = TRUE;
|
|
}
|
|
}
|
|
|
|
if (net_timer && GK.second_tick)
|
|
{
|
|
if (net_timer_type == TIMER_TYPE_PPP)
|
|
{
|
|
struct stat st;
|
|
gchar buf[256];
|
|
|
|
if (net_timer->up_event)
|
|
{
|
|
snprintf(buf, sizeof(buf), "/var/run/%s.pid", net_timer->name);
|
|
if (g_stat(buf, &st) == 0)
|
|
net_timer0 = st.st_mtime;
|
|
else
|
|
time(&net_timer0);
|
|
}
|
|
if (net_timer->up)
|
|
up_time = (int) (time(0) - net_timer0);
|
|
}
|
|
else if (net_timer_type == TIMER_TYPE_IPPP)
|
|
{
|
|
/* get all isdn status from its connect state because the
|
|
| net_timer->up can be UP even with isdn line not connected.
|
|
| Can't get time history if gkrellmd started after connects.
|
|
*/
|
|
static gboolean old_connected;
|
|
gboolean connected;
|
|
|
|
connected = gkrellm_sys_net_isdn_online();
|
|
if (connected && !old_connected)
|
|
time(&net_timer0); /* New session just started */
|
|
old_connected = connected;
|
|
|
|
up_time = (int) (time(0) - net_timer0);
|
|
}
|
|
if (up_time != net_timer->up_time)
|
|
net_timer->timed_changed = TRUE;
|
|
net_timer->up_time = up_time;
|
|
}
|
|
|
|
gkrellmd_need_serve(mon); /* serve func checks for changed */
|
|
}
|
|
|
|
static void
|
|
serve_net_data(GkrellmdMonitor *mon, gboolean first_serve)
|
|
{
|
|
NetData *net;
|
|
GList *list;
|
|
gchar buf[128];
|
|
gboolean fake_up_event;
|
|
|
|
gkrellmd_set_serve_name(mon, "net");
|
|
for (list = net_list; list; list = list->next)
|
|
{
|
|
net = (NetData *) list->data;
|
|
if (net->changed || first_serve)
|
|
{
|
|
snprintf(buf, sizeof(buf), "%s %lu %lu\n", net->name, net->rx, net->tx);
|
|
gkrellmd_serve_data(mon, buf);
|
|
}
|
|
}
|
|
|
|
/* Since the server transmits changes only, use the routed interface
|
|
| to the client regardless if the sysdep code uses routed.
|
|
*/
|
|
if (GK.second_tick || first_serve)
|
|
{
|
|
gkrellmd_set_serve_name(mon, "net_routed");
|
|
for (list = net_list; list; list = list->next)
|
|
{
|
|
net = (NetData *) list->data;
|
|
fake_up_event = (first_serve && net->up);
|
|
if (net->up_event || net->down_event || fake_up_event)
|
|
{
|
|
snprintf(buf, sizeof(buf), "%s %d\n", net->name,
|
|
fake_up_event ? TRUE : net->up_event);
|
|
gkrellmd_serve_data(mon, buf);
|
|
}
|
|
if (mon->privat->client->last_client)
|
|
net->up_event = net->down_event = FALSE;
|
|
}
|
|
}
|
|
|
|
if (net_timer && GK.second_tick)
|
|
{
|
|
if (net_timer->timed_changed || first_serve)
|
|
{
|
|
gkrellmd_set_serve_name(mon, "net_timer");
|
|
snprintf(buf, sizeof(buf), "%s %d\n", net_timer->name, (gint)net_timer->up_time);
|
|
gkrellmd_serve_data(mon, buf);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
serve_net_setup(GkrellmdMonitor *mon)
|
|
{
|
|
GkrellmdClient *client = mon->privat->client;
|
|
gchar buf[128];
|
|
|
|
/* The client <-> server link always uses routed mode, but the client
|
|
| needs to know if server sysdep uses routed for config purposes.
|
|
*/
|
|
if (net_use_routed)
|
|
gkrellmd_send_to_client(client, "<net_setup>\nnet_use_routed\n");
|
|
|
|
if (net_timer_type != TIMER_TYPE_NONE)
|
|
{
|
|
snprintf(buf, sizeof(buf),
|
|
"<net_setup>\nnet_timer %s\n", _GK.net_timer);
|
|
gkrellmd_send_to_client(client, buf);
|
|
}
|
|
}
|
|
|
|
static GkrellmdMonitor net_monitor =
|
|
{
|
|
"net",
|
|
update_net,
|
|
serve_net_data,
|
|
serve_net_setup
|
|
};
|
|
|
|
|
|
static GkrellmdMonitor *
|
|
init_net_monitor(void)
|
|
{
|
|
net_timer_type = TIMER_TYPE_NONE;
|
|
if (gkrellm_sys_net_init())
|
|
return &net_monitor;
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/* ======================================================= */
|
|
struct
|
|
{
|
|
gboolean mem_changed;
|
|
guint64 total,
|
|
used,
|
|
free,
|
|
shared,
|
|
buffers,
|
|
cached;
|
|
|
|
gboolean swap_changed;
|
|
guint64 swap_total,
|
|
swap_used;
|
|
gulong swap_in,
|
|
swap_out;
|
|
}
|
|
mem;
|
|
|
|
void
|
|
gkrellm_mem_assign_data(guint64 total, guint64 used, guint64 free,
|
|
guint64 shared, guint64 buffers, guint64 cached)
|
|
{
|
|
if ( mem.total != total
|
|
|| mem.used != used
|
|
|| mem.free != free
|
|
|| mem.shared != shared
|
|
|| mem.buffers != buffers
|
|
|| mem.cached != cached
|
|
)
|
|
{
|
|
mem.total = total;
|
|
mem.used = used;
|
|
mem.free = free;
|
|
mem.shared = shared;
|
|
mem.buffers = buffers;
|
|
mem.cached = cached;
|
|
mem.mem_changed = TRUE;
|
|
}
|
|
}
|
|
|
|
void
|
|
gkrellm_swap_assign_data(guint64 total, guint64 used,
|
|
gulong swap_in, gulong swap_out)
|
|
{
|
|
if ( mem.swap_total != total
|
|
|| mem.swap_used != used
|
|
|| mem.swap_in != swap_in
|
|
|| mem.swap_out != swap_out
|
|
)
|
|
{
|
|
mem.swap_total = total;
|
|
mem.swap_used = used;
|
|
mem.swap_in = swap_in;
|
|
mem.swap_out = swap_out;
|
|
mem.swap_changed = TRUE;
|
|
}
|
|
}
|
|
|
|
static void
|
|
update_mem(GkrellmdMonitor *mon, gboolean first_update)
|
|
{
|
|
mem.mem_changed = mem.swap_changed = FALSE;
|
|
|
|
gkrellm_sys_swap_read_data();
|
|
if (first_update || GK.five_second_tick)
|
|
gkrellm_sys_mem_read_data();
|
|
|
|
if (mem.mem_changed || mem.swap_changed)
|
|
gkrellmd_need_serve(mon);
|
|
}
|
|
|
|
static void
|
|
serve_mem_data(GkrellmdMonitor *mon, gboolean first_serve)
|
|
{
|
|
gchar buf[128];
|
|
|
|
if (mem.mem_changed || first_serve)
|
|
{
|
|
gkrellmd_set_serve_name(mon, "mem");
|
|
snprintf(buf, sizeof(buf), "%" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
|
|
mem.total, mem.used, mem.free,
|
|
mem.shared, mem.buffers, mem.cached);
|
|
gkrellmd_serve_data(mon, buf);
|
|
}
|
|
|
|
if (mem.swap_changed || first_serve)
|
|
{
|
|
gkrellmd_set_serve_name(mon, "swap");
|
|
snprintf(buf, sizeof(buf), "%" PRIu64 " %" PRIu64 " %lu %lu\n",
|
|
mem.swap_total, mem.swap_used,
|
|
mem.swap_in, mem.swap_out);
|
|
gkrellmd_serve_data(mon, buf);
|
|
}
|
|
}
|
|
|
|
static GkrellmdMonitor mem_monitor =
|
|
{
|
|
"mem",
|
|
update_mem,
|
|
serve_mem_data,
|
|
NULL
|
|
};
|
|
|
|
|
|
static GkrellmdMonitor *
|
|
init_mem_monitor(void)
|
|
{
|
|
if (!gkrellm_sys_mem_init())
|
|
return NULL;
|
|
serveflag_done_list = g_list_append(serveflag_done_list, &mem.mem_changed);
|
|
serveflag_done_list = g_list_append(serveflag_done_list,&mem.swap_changed);
|
|
return &mem_monitor;
|
|
}
|
|
|
|
/* ======================================================= */
|
|
typedef struct
|
|
{
|
|
gboolean busy,
|
|
deleted,
|
|
is_mounted,
|
|
is_nfs,
|
|
changed;
|
|
gchar *directory,
|
|
*device,
|
|
*type,
|
|
*options;
|
|
glong blocks,
|
|
bavail,
|
|
bfree,
|
|
bsize;
|
|
}
|
|
Mount;
|
|
|
|
static GList *mounts_list,
|
|
*fstab_list;
|
|
|
|
static gboolean nfs_check,
|
|
fs_check,
|
|
fs_need_serve,
|
|
fstab_list_modified,
|
|
mounts_list_modified,
|
|
mounting_unsupported;
|
|
|
|
static gchar *remote_fs_types[] =
|
|
{
|
|
"cifs",
|
|
"nfs",
|
|
"smbfs"
|
|
};
|
|
|
|
void
|
|
gkrellm_fs_setup_eject(gchar *eject_tray, gchar *close_tray,
|
|
void (*eject_func)(), void (*close_func)())
|
|
{
|
|
/* Not supported remotely */
|
|
}
|
|
|
|
void
|
|
gkrellm_fs_add_to_mounts_list(gchar *dir, gchar *dev, gchar *type)
|
|
{
|
|
GList *list;
|
|
Mount *m;
|
|
gint i;
|
|
|
|
for (list = mounts_list; list; list = list->next)
|
|
{
|
|
m = (Mount *) list->data;
|
|
if ( !strcmp(m->directory, dir)
|
|
&& !strcmp(m->device, dev)
|
|
&& !strcmp(m->type, type)
|
|
)
|
|
break;
|
|
}
|
|
if (!list)
|
|
{
|
|
m = g_new0(Mount, 1);
|
|
m->directory = g_strdup(dir);
|
|
m->device = g_strdup(dev);
|
|
m->type = g_strdup(type);
|
|
mounts_list = g_list_append(mounts_list, m);
|
|
mounts_list_modified = TRUE;
|
|
serveflag_done_list = g_list_append(serveflag_done_list, &m->changed);
|
|
|
|
for (i = 0; i < (sizeof(remote_fs_types) / sizeof(gchar *)); ++i)
|
|
{
|
|
if (!strcmp(m->type, remote_fs_types[i]))
|
|
{
|
|
m->is_nfs = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
m->is_mounted = TRUE;
|
|
}
|
|
|
|
void
|
|
gkrellm_fs_add_to_fstab_list(gchar *dir, gchar *dev, gchar *type, gchar *opt)
|
|
{
|
|
Mount *m;
|
|
|
|
m = g_new0(Mount, 1);
|
|
m->directory = g_strdup(dir);
|
|
m->device = g_strdup(dev);
|
|
m->type = g_strdup(type);
|
|
fstab_list = g_list_append(fstab_list, m);
|
|
}
|
|
|
|
void
|
|
gkrellm_fs_assign_fsusage_data(gpointer pointer,
|
|
glong blocks, glong bavail, glong bfree, glong bsize)
|
|
{
|
|
Mount *m = (Mount *) pointer;
|
|
|
|
if ( m->blocks != blocks
|
|
|| m->bavail != bavail
|
|
|| m->bfree != bfree
|
|
|| m->bsize != bsize
|
|
)
|
|
{
|
|
m->blocks = blocks;
|
|
m->bavail = bavail;
|
|
m->bfree = bfree;
|
|
m->bsize = bsize;
|
|
|
|
m->changed = TRUE;
|
|
}
|
|
}
|
|
|
|
void
|
|
gkrellm_fs_mounting_unsupported(void)
|
|
{
|
|
mounting_unsupported = TRUE;
|
|
}
|
|
|
|
static void
|
|
refresh_mounts_list(void)
|
|
{
|
|
GList *list;
|
|
Mount *m;
|
|
|
|
for (list = mounts_list; list; list = list->next)
|
|
((Mount *) list->data)->is_mounted = FALSE;
|
|
|
|
gkrellm_sys_fs_get_mounts_list();
|
|
|
|
for (list = mounts_list; list; )
|
|
{
|
|
m = (Mount *) list->data;
|
|
if (!m->is_mounted)
|
|
{
|
|
if (list == mounts_list)
|
|
mounts_list = mounts_list->next;
|
|
list = g_list_remove_link(list, list);
|
|
g_free(m->directory);
|
|
g_free(m->device);
|
|
g_free(m->type);
|
|
serveflag_done_list = g_list_remove(serveflag_done_list,
|
|
&m->changed);
|
|
if (m->busy)
|
|
m->deleted = TRUE;
|
|
else
|
|
g_free(m);
|
|
mounts_list_modified = TRUE;
|
|
}
|
|
else
|
|
list = list->next;
|
|
}
|
|
}
|
|
|
|
static void
|
|
refresh_fstab_list(void)
|
|
{
|
|
Mount *m;
|
|
|
|
while (fstab_list)
|
|
{
|
|
m = (Mount *) fstab_list->data;
|
|
g_free(m->directory);
|
|
g_free(m->device);
|
|
g_free(m->type);
|
|
g_free(m);
|
|
fstab_list = g_list_remove(fstab_list, fstab_list->data);
|
|
}
|
|
gkrellm_sys_fs_get_fstab_list();
|
|
fstab_list_modified = TRUE;
|
|
}
|
|
|
|
static gpointer
|
|
get_fsusage_thread(void *data)
|
|
{
|
|
Mount *m = (Mount *) data;
|
|
|
|
gkrellm_sys_fs_get_fsusage(m, m->directory);
|
|
|
|
if (m->deleted)
|
|
g_free(m);
|
|
else
|
|
{
|
|
if (m->changed)
|
|
fs_need_serve = TRUE;
|
|
m->busy = FALSE;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
update_fs(GkrellmdMonitor *mon, gboolean first_update)
|
|
{
|
|
GList *list;
|
|
Mount *m;
|
|
static gint check_tick;
|
|
|
|
if (fs_need_serve) /* Asynchronous change in fsusage thread? */
|
|
gkrellmd_need_serve(mon);
|
|
fs_need_serve = FALSE;
|
|
|
|
if (GK.second_tick)
|
|
++check_tick;
|
|
fs_check = !(check_tick % _GK.fs_interval);
|
|
|
|
if (_GK.nfs_interval > 0)
|
|
nfs_check = !(check_tick % _GK.nfs_interval);
|
|
else
|
|
nfs_check = 0;
|
|
|
|
if (!first_update && (!GK.second_tick || (!fs_check && !nfs_check)))
|
|
return;
|
|
refresh_mounts_list();
|
|
for (list = mounts_list; list; list = list->next)
|
|
{
|
|
m = (Mount *) list->data;
|
|
if (fs_check && !m->is_nfs)
|
|
gkrellm_sys_fs_get_fsusage(m, m->directory);
|
|
else if (nfs_check && m->is_nfs && !m->busy)
|
|
{
|
|
m->busy = TRUE;
|
|
g_thread_new("get_fsusage", get_fsusage_thread, m);
|
|
}
|
|
}
|
|
if (first_update || gkrellm_sys_fs_fstab_modified())
|
|
refresh_fstab_list();
|
|
|
|
gkrellmd_need_serve(mon);
|
|
}
|
|
|
|
static void
|
|
serve_fs_data(GkrellmdMonitor *mon, gboolean first_serve)
|
|
{
|
|
Mount *m;
|
|
GList *list;
|
|
gchar buf[128];
|
|
|
|
if (mounts_list_modified || first_serve)
|
|
{
|
|
gkrellmd_set_serve_name(mon, "fs_mounts");
|
|
gkrellmd_serve_data(mon, ".clear\n");
|
|
for (list = mounts_list; list; list = list->next)
|
|
{
|
|
m = (Mount *) list->data;
|
|
snprintf(buf, sizeof(buf), "%s %s %s %ld %ld %ld %ld\n",
|
|
m->directory, m->device, m->type,
|
|
m->blocks, m->bavail, m->bfree, m->bsize);
|
|
/*gkrellm_debug(DEBUG_SERVER,
|
|
"Adding mount-line for %s to serve-data\n", m->directory);*/
|
|
gkrellmd_serve_data(mon, buf);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gkrellmd_set_serve_name(mon, "fs");
|
|
for (list = mounts_list; list; list = list->next)
|
|
{
|
|
m = (Mount *) list->data;
|
|
if (!m->changed)
|
|
continue;
|
|
snprintf(buf, sizeof(buf), "%s %s %ld %ld %ld %ld\n",
|
|
m->directory, m->device,
|
|
m->blocks, m->bavail, m->bfree, m->bsize);
|
|
/*gkrellm_debug(DEBUG_SERVER,
|
|
"Updating fs %s in serve-data\n", m->directory);*/
|
|
gkrellmd_serve_data(mon, buf);
|
|
}
|
|
}
|
|
if (fstab_list_modified || first_serve)
|
|
{
|
|
gkrellmd_set_serve_name(mon, "fs_fstab");
|
|
gkrellmd_serve_data(mon, ".clear\n");
|
|
for (list = fstab_list; list; list = list->next)
|
|
{
|
|
m = (Mount *) list->data;
|
|
snprintf(buf, sizeof(buf), "%s %s %s\n",
|
|
m->directory, m->device, m->type);
|
|
/*gkrellm_debug(DEBUG_SERVER,
|
|
"Adding fstab-line for %s to serve-data\n", m->directory);*/
|
|
gkrellmd_serve_data(mon, buf);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
serve_fs_setup(GkrellmdMonitor *mon)
|
|
{
|
|
GkrellmdClient *client = mon->privat->client;
|
|
|
|
if (mounting_unsupported)
|
|
gkrellmd_send_to_client(client, "<fs_setup>\nmounting_unsupported\n");
|
|
}
|
|
|
|
static GkrellmdMonitor fs_monitor =
|
|
{
|
|
"fs",
|
|
update_fs,
|
|
serve_fs_data,
|
|
serve_fs_setup
|
|
};
|
|
|
|
|
|
static GkrellmdMonitor *
|
|
init_fs_monitor(void)
|
|
{
|
|
if (!gkrellm_sys_fs_init())
|
|
return NULL;
|
|
serveflag_done_list =
|
|
g_list_append(serveflag_done_list, &fstab_list_modified);
|
|
serveflag_done_list =
|
|
g_list_append(serveflag_done_list, &mounts_list_modified);
|
|
return &fs_monitor;
|
|
}
|
|
|
|
/* ======================================================= */
|
|
|
|
|
|
typedef struct
|
|
{
|
|
gboolean changed,
|
|
have_data;
|
|
|
|
gint id;
|
|
gboolean present,
|
|
on_line,
|
|
charging;
|
|
gint percent;
|
|
gint time_left;
|
|
}
|
|
Battery;
|
|
|
|
static GList *battery_list;
|
|
|
|
static Battery *composite_battery;
|
|
|
|
|
|
static Battery *
|
|
battery_nth(gint n)
|
|
{
|
|
Battery *bat;
|
|
static gint n_batteries;
|
|
|
|
if (n > 10)
|
|
return NULL;
|
|
if (n < 0)
|
|
{
|
|
if (!composite_battery)
|
|
{
|
|
bat = g_new0(Battery, 1);
|
|
battery_list = g_list_prepend(battery_list, bat);
|
|
bat->id = GKRELLM_BATTERY_COMPOSITE_ID;
|
|
composite_battery = bat;
|
|
serveflag_done_list = g_list_append(serveflag_done_list,
|
|
&composite_battery->changed);
|
|
}
|
|
return composite_battery;
|
|
}
|
|
|
|
if (composite_battery)
|
|
++n;
|
|
|
|
while ((bat = (Battery *)g_list_nth_data(battery_list, n)) == NULL)
|
|
{
|
|
bat = g_new0(Battery, 1);
|
|
battery_list = g_list_append(battery_list, bat);
|
|
bat->id = n_batteries++;
|
|
serveflag_done_list = g_list_append(serveflag_done_list,
|
|
&bat->changed);
|
|
}
|
|
return bat;
|
|
}
|
|
|
|
void
|
|
gkrellm_battery_assign_data(gint id, gboolean present, gboolean on_line,
|
|
gboolean charging, gint percent, gint time_left)
|
|
{
|
|
Battery *bat;
|
|
|
|
bat = battery_nth(id);
|
|
if (!bat)
|
|
return;
|
|
|
|
if ( present != bat->present
|
|
|| on_line != bat->on_line
|
|
|| charging != bat->charging
|
|
|| percent != bat->percent
|
|
|| time_left != bat->time_left
|
|
)
|
|
{
|
|
bat->present = present;
|
|
bat->on_line = on_line;
|
|
bat->charging = charging;
|
|
bat->percent = percent;
|
|
bat->time_left = time_left;
|
|
bat->changed = TRUE;
|
|
}
|
|
|
|
bat->have_data = TRUE;
|
|
}
|
|
|
|
gint
|
|
gkrellm_battery_full_cap_fallback()
|
|
{
|
|
return 5000; /* XXX Linux ACPI bug not handled by server */
|
|
}
|
|
|
|
static void
|
|
update_battery(GkrellmdMonitor *mon, gboolean first_update)
|
|
{
|
|
GList *list;
|
|
Battery *bat;
|
|
|
|
if (!first_update && !GK.five_second_tick)
|
|
return;
|
|
|
|
for (list = battery_list; list; list = list->next)
|
|
{
|
|
bat = (Battery *) list->data;
|
|
bat->have_data = FALSE;
|
|
bat->changed = FALSE;
|
|
}
|
|
gkrellm_sys_battery_read_data();
|
|
|
|
for (list = battery_list; list; list = list->next)
|
|
{
|
|
bat = (Battery *) list->data;
|
|
if (!bat->have_data && bat->present)
|
|
{
|
|
bat->present = FALSE;
|
|
bat->changed = TRUE;
|
|
}
|
|
if (bat->changed)
|
|
gkrellmd_need_serve(mon);
|
|
}
|
|
}
|
|
|
|
static void
|
|
serve_battery_data(GkrellmdMonitor *mon, gboolean first_serve)
|
|
{
|
|
Battery *bat;
|
|
GList *list;
|
|
gchar buf[128];
|
|
|
|
gkrellmd_set_serve_name(mon, "battery");
|
|
for (list = battery_list; list; list = list->next)
|
|
{
|
|
bat = (Battery *) list->data;
|
|
|
|
if ( (!bat->changed && !first_serve)
|
|
|| ( !gkrellmd_check_client_version(mon, 2,1,9)
|
|
&& bat->id > 0
|
|
)
|
|
)
|
|
continue;
|
|
snprintf(buf, sizeof(buf), "%d %d %d %d %d %d\n",
|
|
bat->present, bat->on_line, bat->charging,
|
|
bat->percent, bat->time_left, bat->id);
|
|
gkrellmd_serve_data(mon, buf);
|
|
}
|
|
}
|
|
|
|
static void
|
|
serve_battery_setup(GkrellmdMonitor *mon)
|
|
{
|
|
GkrellmdClient *client = mon->privat->client;
|
|
|
|
gkrellm_sys_battery_read_data();
|
|
if (battery_list)
|
|
gkrellmd_send_to_client(client,
|
|
"<battery_setup>\nbattery_available\n");
|
|
}
|
|
|
|
static GkrellmdMonitor battery_monitor =
|
|
{
|
|
"battery",
|
|
update_battery,
|
|
serve_battery_data,
|
|
serve_battery_setup
|
|
};
|
|
|
|
static GkrellmdMonitor *
|
|
init_battery_monitor(void)
|
|
{
|
|
if (!gkrellm_sys_battery_init())
|
|
return NULL;
|
|
return &battery_monitor;
|
|
}
|
|
|
|
/* ======================================================= */
|
|
|
|
typedef struct
|
|
{
|
|
gboolean changed;
|
|
gint type;
|
|
|
|
gchar *path; /* Pathname to sensor data or device file */
|
|
|
|
gchar *id_name; /* These 4 are unique sensor identification */
|
|
gint id; /* of a particular sensor type */
|
|
gint iodev; /* One or any combination may be used. */
|
|
gint inter;
|
|
|
|
gchar *vref;
|
|
gchar *default_label;
|
|
gint group;
|
|
|
|
gfloat factor;
|
|
gfloat offset;
|
|
gfloat raw_value;
|
|
}
|
|
Sensor;
|
|
|
|
static GList *sensors_list;
|
|
|
|
static gboolean thread_busy,
|
|
sensors_need_serve;
|
|
|
|
static gpointer
|
|
read_sensors(void *data)
|
|
{
|
|
GList *list;
|
|
Sensor *sensor;
|
|
gfloat tmp;
|
|
gboolean need_serve = FALSE;
|
|
|
|
for (list = sensors_list; list; list = list->next)
|
|
{
|
|
sensor = (Sensor *) list->data;
|
|
tmp = sensor->raw_value;
|
|
if (sensor->type == SENSOR_TEMPERATURE)
|
|
gkrellm_sys_sensors_get_temperature(sensor->path, sensor->id,
|
|
sensor->iodev, sensor->inter, &sensor->raw_value);
|
|
else if (sensor->type == SENSOR_FAN)
|
|
gkrellm_sys_sensors_get_fan(sensor->path, sensor->id,
|
|
sensor->iodev, sensor->inter, &sensor->raw_value);
|
|
else if (sensor->type == SENSOR_VOLTAGE)
|
|
gkrellm_sys_sensors_get_voltage(sensor->path, sensor->id,
|
|
sensor->iodev, sensor->inter, &sensor->raw_value);
|
|
if (sensor->raw_value != tmp)
|
|
{
|
|
sensor->changed = TRUE;
|
|
need_serve = TRUE;
|
|
}
|
|
else
|
|
sensor->changed = FALSE;
|
|
}
|
|
thread_busy = FALSE;
|
|
sensors_need_serve = need_serve; /* Thread, so set after data collected */
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
run_sensors_thread(void)
|
|
{
|
|
if (thread_busy)
|
|
return;
|
|
thread_busy = TRUE;
|
|
g_thread_new("read_sensors", read_sensors, NULL);
|
|
}
|
|
|
|
|
|
void
|
|
gkrellm_sensors_config_migrate_connect(gboolean (*func)(), gint sysdep_version)
|
|
{
|
|
}
|
|
|
|
void
|
|
gkrellm_sensors_update_volt_order_base(void)
|
|
{
|
|
}
|
|
|
|
void
|
|
gkrellm_sensors_set_group(gpointer sr, gint group)
|
|
{
|
|
Sensor *sensor = (Sensor *) sr;
|
|
|
|
if (sensor)
|
|
sensor->group = group;
|
|
}
|
|
|
|
void
|
|
gkrellm_sensors_sysdep_option(gchar *keyword, gchar *label, void (*func)())
|
|
{
|
|
}
|
|
|
|
/* A sensor within a type is uniquely identified by its id_name.
|
|
| A sysdep interface may additionally use any of the triple integer
|
|
| set (id, iodev, inter) for internal identification.
|
|
| Monitor code here uses path to read the sensor values, but id_name is only
|
|
| passed to the client since that is all that is needed for identification
|
|
| (the client is no longer interfacing to sysdep code).
|
|
*/
|
|
gpointer
|
|
gkrellm_sensors_add_sensor(gint type, gchar *sensor_path, gchar *id_name,
|
|
gint id, gint iodev, gint inter,
|
|
gfloat factor, gfloat offset, gchar *vref, gchar *default_label)
|
|
{
|
|
Sensor *sensor;
|
|
|
|
if (!id_name || !*id_name || type < 0 || type > 2)
|
|
return NULL;
|
|
|
|
sensor = g_new0(Sensor, 1);
|
|
sensor->id_name = g_strdup(id_name);
|
|
|
|
if (sensor_path)
|
|
sensor->path = g_strdup(sensor_path);
|
|
else
|
|
sensor->path = g_strdup(id_name);
|
|
|
|
sensor->vref = g_strdup(vref ? vref : "NONE");
|
|
sensor->default_label = g_strdup(default_label ? default_label : "NONE");
|
|
|
|
sensor->factor = factor;
|
|
sensor->offset = offset;
|
|
sensor->type = type;
|
|
sensor->id = id;
|
|
sensor->iodev = iodev;
|
|
sensor->inter = inter;
|
|
sensors_list = g_list_append(sensors_list, sensor);
|
|
return sensor;
|
|
}
|
|
|
|
static void
|
|
update_sensors(GkrellmdMonitor *mon, gboolean first_update)
|
|
{
|
|
if (sensors_need_serve) /* Asynchronously set in thread */
|
|
gkrellmd_need_serve(mon);
|
|
sensors_need_serve = FALSE;
|
|
|
|
if (!GK.five_second_tick && !first_update)
|
|
return;
|
|
if (first_update)
|
|
read_sensors(NULL); /* No thread on first read */
|
|
else
|
|
run_sensors_thread();
|
|
}
|
|
|
|
static void
|
|
serve_sensors_data(GkrellmdMonitor *mon, gboolean first_serve)
|
|
{
|
|
Sensor *sr;
|
|
GList *list;
|
|
gchar buf[128];
|
|
gboolean sensor_disk_ok;
|
|
|
|
gkrellmd_set_serve_name(mon, "sensors");
|
|
sensor_disk_ok = gkrellmd_check_client_version(mon, 2,2,0);
|
|
for (list = sensors_list; list; list = list->next)
|
|
{
|
|
sr = (Sensor *) list->data;
|
|
if (sr->group == SENSOR_GROUP_DISK && !sensor_disk_ok)
|
|
continue;
|
|
if (sr->changed || first_serve)
|
|
{
|
|
snprintf(buf, sizeof(buf), "%d \"%s\" %d %d %d %.2f\n",
|
|
sr->type, sr->id_name,
|
|
sr->id, sr->iodev, sr->inter, sr->raw_value);
|
|
gkrellmd_serve_data(mon, buf);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
serve_sensors_setup(GkrellmdMonitor *mon)
|
|
{
|
|
GkrellmdClient *client = mon->privat->client;
|
|
GList *list;
|
|
Sensor *s;
|
|
gchar buf[256];
|
|
gboolean sensor_disk_ok;
|
|
|
|
gkrellmd_send_to_client(client, "<sensors_setup>\n");
|
|
sensor_disk_ok = gkrellmd_check_client_version(mon, 2,2,0);
|
|
for (list = sensors_list; list; list = list->next)
|
|
{
|
|
s = (Sensor *) list->data;
|
|
if (s->group == SENSOR_GROUP_DISK && !sensor_disk_ok)
|
|
continue;
|
|
if (sensor_disk_ok)
|
|
snprintf(buf, sizeof(buf), "%d \"%s\" %d %d %d %.4f %.4f \"%s\" \"%s\" %d\n",
|
|
s->type, s->id_name,
|
|
s->id, s->iodev, s->inter,
|
|
s->factor, s->offset, s->vref, s->default_label, s->group);
|
|
else
|
|
snprintf(buf, sizeof(buf), "%d \"%s\" %d %d %d %.4f %.4f \"%s\" \"%s\"\n",
|
|
s->type, s->id_name,
|
|
s->id, s->iodev, s->inter,
|
|
s->factor, s->offset, s->vref, s->default_label);
|
|
gkrellmd_send_to_client(client, buf);
|
|
}
|
|
}
|
|
|
|
static GkrellmdMonitor sensors_monitor =
|
|
{
|
|
"sensors",
|
|
update_sensors,
|
|
serve_sensors_data,
|
|
serve_sensors_setup
|
|
};
|
|
|
|
static GkrellmdMonitor *
|
|
init_sensors_monitor(void)
|
|
{
|
|
if (!gkrellm_sys_sensors_init())
|
|
return NULL;
|
|
return &sensors_monitor;
|
|
}
|
|
|
|
/* ======================================================= */
|
|
static time_t base_uptime,
|
|
up_seconds;
|
|
static gulong up_minutes = -1;
|
|
|
|
void
|
|
gkrellm_uptime_set_base_uptime(time_t base)
|
|
{
|
|
base_uptime = base;
|
|
}
|
|
|
|
static void
|
|
update_uptime(GkrellmdMonitor *mon, gboolean first_update)
|
|
{
|
|
gint prev_up;
|
|
|
|
if (GK.ten_second_tick || up_minutes < 0 || first_update)
|
|
{
|
|
prev_up = up_minutes;
|
|
up_seconds = gkrellm_sys_uptime_read_uptime();
|
|
if (up_seconds > 0)
|
|
up_minutes = (gint) (up_seconds / 60);
|
|
else
|
|
up_minutes = (gint)(time(0) - _GK.start_time + base_uptime) / 60;
|
|
if (up_minutes != prev_up)
|
|
gkrellmd_need_serve(mon);
|
|
}
|
|
}
|
|
|
|
static void
|
|
serve_uptime_data(GkrellmdMonitor *mon, gboolean first_serve)
|
|
{
|
|
gchar buf[128];
|
|
|
|
gkrellmd_set_serve_name(mon, "uptime");
|
|
snprintf(buf, sizeof(buf), "%lu\n", (gulong) up_minutes);
|
|
gkrellmd_serve_data(mon, buf);
|
|
}
|
|
|
|
static GkrellmdMonitor uptime_monitor =
|
|
{
|
|
"uptime",
|
|
update_uptime,
|
|
serve_uptime_data,
|
|
NULL
|
|
};
|
|
|
|
static GkrellmdMonitor *
|
|
init_uptime_monitor(void)
|
|
{
|
|
if (!gkrellm_sys_uptime_init())
|
|
return NULL;
|
|
return &uptime_monitor;
|
|
}
|
|
|
|
/* ======================================================= */
|
|
static void
|
|
send_time(GkrellmdClient *client)
|
|
{
|
|
struct tm *t;
|
|
gchar buf[128];
|
|
|
|
t = &gkrellmd_current_tm;
|
|
snprintf(buf, sizeof(buf), "<time>\n%d %d %d %d %d %d %d %d %d\n",
|
|
t->tm_sec, t->tm_min, t->tm_hour,
|
|
t->tm_mday, t->tm_mon, t->tm_year,
|
|
t->tm_wday, t->tm_yday, t->tm_isdst);
|
|
gkrellmd_send_to_client(client, buf);
|
|
}
|
|
|
|
/* ======================================================= */
|
|
|
|
void
|
|
gkrellmd_plugin_serve_setup(GkrellmdMonitor *mon, gchar *name, gchar *line)
|
|
{
|
|
GkrellmdClient *client = mon->privat->client;
|
|
gchar buf[256];
|
|
|
|
if (!mon || !name || !line)
|
|
return;
|
|
gkrellmd_send_to_client(client, "<plugin_setup>\n");
|
|
snprintf(buf, sizeof(buf), "%s %s\n", name, line);
|
|
gkrellmd_send_to_client(client, buf);
|
|
}
|
|
|
|
static void
|
|
add_monitor(GkrellmdMonitor *mon)
|
|
{
|
|
if (!mon)
|
|
return;
|
|
mon->privat = g_new0(GkrellmdMonitorPrivate, 1);
|
|
mon->privat->serve_gstring = g_string_new("");
|
|
gkrellmd_monitor_list = g_list_append(gkrellmd_monitor_list, mon);
|
|
}
|
|
|
|
void
|
|
gkrellmd_load_monitors(void)
|
|
{
|
|
GList *list;
|
|
GkrellmdMonitor *mon;
|
|
|
|
add_monitor(init_sensors_monitor());
|
|
add_monitor(init_cpu_monitor());
|
|
add_monitor(init_proc_monitor());
|
|
add_monitor(init_disk_monitor());
|
|
add_monitor(init_net_monitor());
|
|
add_monitor(init_inet_monitor());
|
|
add_monitor(init_mem_monitor());
|
|
add_monitor(init_fs_monitor());
|
|
add_monitor(gkrellmd_init_mail_monitor());
|
|
add_monitor(init_battery_monitor());
|
|
add_monitor(init_uptime_monitor());
|
|
|
|
list = gkrellmd_plugins_load();
|
|
if (_GK.list_plugins)
|
|
exit(0);
|
|
if (_GK.log_plugins)
|
|
g_message("%s\n", plugin_install_log ? plugin_install_log :
|
|
_("No plugins found\n"));
|
|
for ( ; list; list = list->next)
|
|
{
|
|
mon = (GkrellmdMonitor *) list->data;
|
|
mon->privat->serve_gstring = g_string_new("");
|
|
mon->privat->is_plugin = TRUE;
|
|
gkrellmd_monitor_list = g_list_append(gkrellmd_monitor_list, mon);
|
|
}
|
|
}
|
|
|
|
void
|
|
gkrellmd_need_serve(GkrellmdMonitor *mon)
|
|
{
|
|
if (mon)
|
|
mon->privat->need_serve = TRUE;
|
|
}
|
|
|
|
gint
|
|
gkrellmd_update_monitors(void)
|
|
{
|
|
GList *list, *c_list;
|
|
GkrellmdMonitor *mon;
|
|
GkrellmdMonitorPrivate *mp;
|
|
GkrellmdClient *client;
|
|
struct tm *pCur;
|
|
static time_t time_prev;
|
|
gchar buf[64];
|
|
static gboolean first_update = TRUE;
|
|
static GString *serve_gstring;
|
|
|
|
time(&_GK.time_now);
|
|
GK.second_tick = (_GK.time_now == time_prev) ? FALSE : TRUE;
|
|
time_prev = _GK.time_now;
|
|
|
|
if (GK.second_tick)
|
|
{
|
|
pCur = localtime(&_GK.time_now);
|
|
GK.two_second_tick = ((pCur->tm_sec % 2) == 0) ? TRUE : FALSE;
|
|
GK.five_second_tick = ((pCur->tm_sec % 5) == 0) ? TRUE : FALSE;
|
|
GK.ten_second_tick = ((pCur->tm_sec % 10) == 0) ? TRUE : FALSE;
|
|
GK.minute_tick = (pCur->tm_min != gkrellmd_current_tm.tm_min);
|
|
gkrellmd_current_tm = *pCur;
|
|
}
|
|
else
|
|
{
|
|
GK.two_second_tick = FALSE;
|
|
GK.five_second_tick = FALSE;
|
|
GK.ten_second_tick = FALSE;
|
|
GK.minute_tick = FALSE;
|
|
}
|
|
|
|
for (list = gkrellmd_monitor_list; list; list = list->next)
|
|
{
|
|
mon = (GkrellmdMonitor *) list->data;
|
|
if (mon->update_monitor)
|
|
(*(mon->update_monitor))(mon, first_update);
|
|
}
|
|
++GK.timer_ticks;
|
|
if (!serve_gstring)
|
|
serve_gstring = g_string_new("");
|
|
for (c_list = gkrellmd_client_list; c_list; c_list = c_list->next)
|
|
{
|
|
client = (GkrellmdClient *) c_list->data;
|
|
client->last_client = !c_list->next;
|
|
if (!client->served)
|
|
gkrellmd_send_to_client(client, "<initial_update>\n");
|
|
for (list = gkrellmd_monitor_list; list; list = list->next)
|
|
{
|
|
mon = (GkrellmdMonitor *) list->data;
|
|
mp = mon->privat;
|
|
if (!mon->serve_data || (!mp->need_serve && client->served))
|
|
continue;
|
|
mp->client = client;
|
|
mp->serve_name_sent = FALSE;
|
|
(*(mon->serve_data))(mon, client->served ? FALSE : TRUE);
|
|
if (mp->serve_gstring->len > 0)
|
|
{
|
|
serve_gstring =
|
|
g_string_append(serve_gstring, mp->serve_gstring->str);
|
|
mp->serve_gstring = g_string_truncate(mp->serve_gstring, 0);
|
|
}
|
|
}
|
|
gkrellmd_send_to_client(client, serve_gstring->str);
|
|
serve_gstring = g_string_truncate(serve_gstring, 0);
|
|
|
|
if (GK.minute_tick || !client->served)
|
|
send_time(client);
|
|
else if (GK.second_tick)
|
|
{
|
|
snprintf(buf, sizeof(buf), "<.%d>\n", gkrellmd_current_tm.tm_sec);
|
|
gkrellmd_send_to_client(client, buf);
|
|
}
|
|
|
|
if (!client->served)
|
|
gkrellmd_send_to_client(client, "</initial_update>\n");
|
|
client->served = TRUE;
|
|
}
|
|
|
|
for (list = gkrellmd_monitor_list; list; list = list->next)
|
|
{
|
|
mon = (GkrellmdMonitor *) list->data;
|
|
mp = mon->privat;
|
|
mp->need_serve = FALSE;
|
|
}
|
|
|
|
for (list = serveflag_done_list; list; list = list->next)
|
|
*((gboolean *) list->data) = FALSE;
|
|
|
|
first_update = FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
gkrellmd_serve_setup(GkrellmdClient *client)
|
|
{
|
|
GList *list;
|
|
GkrellmdMonitor *mon;
|
|
struct lconv *lc;
|
|
gchar buf[32], *s, *name;
|
|
|
|
gkrellmd_send_to_client(client, "<gkrellmd_setup>\n");
|
|
|
|
s = g_strdup_printf("<version>\ngkrellmd %d.%d.%d%s\n",
|
|
GKRELLMD_VERSION_MAJOR, GKRELLMD_VERSION_MINOR,
|
|
GKRELLMD_VERSION_REV, GKRELLMD_EXTRAVERSION);
|
|
gkrellmd_send_to_client(client, s);
|
|
g_free(s);
|
|
|
|
lc = localeconv();
|
|
snprintf(buf, sizeof(buf), "%c\n", *lc->decimal_point);
|
|
s = g_strconcat("<decimal_point>\n", buf, "\n", NULL);
|
|
gkrellmd_send_to_client(client, s);
|
|
g_free(s);
|
|
|
|
for (list = gkrellmd_monitor_list; list; list = list->next)
|
|
{
|
|
mon = (GkrellmdMonitor *) list->data;
|
|
mon->privat->client = client;
|
|
if (mon->serve_setup)
|
|
(*(mon->serve_setup))(mon);
|
|
}
|
|
name = gkrellm_sys_get_host_name();
|
|
s = g_strconcat("<hostname>\n", name, "\n", NULL);
|
|
gkrellmd_send_to_client(client, s);
|
|
g_free(s);
|
|
|
|
name = gkrellm_sys_get_system_name();
|
|
s = g_strconcat("<sysname>\n", name, "\n", NULL);
|
|
gkrellmd_send_to_client(client, s);
|
|
g_free(s);
|
|
|
|
send_time(client);
|
|
|
|
gkrellmd_send_to_client(client, "<monitors>\n");
|
|
for (list = gkrellmd_monitor_list; list; list = list->next)
|
|
{
|
|
mon = (GkrellmdMonitor *) list->data;
|
|
snprintf(buf, sizeof(buf), "%s\n", mon->name);
|
|
gkrellmd_send_to_client(client, buf);
|
|
}
|
|
|
|
snprintf(buf, sizeof(buf), "%d\n", _GK.io_timeout);
|
|
s = g_strconcat("<io_timeout>\n", buf, "\n", NULL);
|
|
gkrellmd_send_to_client(client, s);
|
|
g_free(s);
|
|
|
|
snprintf(buf, sizeof(buf), "%d\n", _GK.reconnect_timeout);
|
|
s = g_strconcat("<reconnect_timeout>\n", buf, "\n", NULL);
|
|
gkrellmd_send_to_client(client, s);
|
|
g_free(s);
|
|
|
|
gkrellmd_send_to_client(client, "</gkrellmd_setup>\n");
|
|
}
|
|
|
|
void
|
|
gkrellmd_client_input_connect(GkrellmdMonitor *mon,
|
|
void (*func)(GkrellmdClient *, gchar *))
|
|
{
|
|
mon->privat->client_input_func = func;
|
|
}
|
|
|
|
void
|
|
gkrellmd_client_read(gint fd, gint nbytes)
|
|
{
|
|
GList *list;
|
|
GkrellmdClient *client = NULL;
|
|
GkrellmdMonitor *mon;
|
|
GkrellmdMonitorPrivate *mp;
|
|
gchar buf[513], *s, *e;
|
|
gint n, buflen;
|
|
|
|
for (list = gkrellmd_client_list; list; list = list->next)
|
|
{
|
|
client = (GkrellmdClient *) list->data;
|
|
if (client->fd != fd)
|
|
continue;
|
|
|
|
if (!client->input_gstring)
|
|
client->input_gstring = g_string_new("");
|
|
|
|
buflen = sizeof(buf) - 1;
|
|
while (nbytes > 0)
|
|
{
|
|
n = (nbytes > buflen) ? buflen : nbytes;
|
|
n = recv(fd, buf, n, 0);
|
|
if (n <= 0)
|
|
break;
|
|
nbytes -= n;
|
|
buf[n] = '\0';
|
|
client->input_gstring =
|
|
g_string_append(client->input_gstring, buf);
|
|
}
|
|
break;
|
|
}
|
|
if (!list)
|
|
return;
|
|
|
|
while (gkrellmd_getline_from_gstring(&client->input_gstring,
|
|
buf, sizeof(buf) - 1))
|
|
{
|
|
if (*buf == '<')
|
|
{
|
|
client->input_func = NULL;
|
|
s = buf + 1;
|
|
for (list = gkrellmd_monitor_list; list; list = list->next)
|
|
{
|
|
mon = (GkrellmdMonitor *) list->data;
|
|
mp = mon->privat;
|
|
if (!mp->serve_name)
|
|
continue;
|
|
n = strlen(mp->serve_name);
|
|
e = s + n;
|
|
if (*e == '>' && !strncmp(mp->serve_name, s, n))
|
|
{
|
|
client->input_func = mp->client_input_func;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else if (client->input_func)
|
|
(*client->input_func)(client, buf);
|
|
// printf("%s: %s", client->hostname, buf);
|
|
}
|
|
}
|