--- projects/libstatgrab/src/statgrab/statgrab.c 2003/08/31 13:23:19 1.9 +++ projects/libstatgrab/src/statgrab/statgrab.c 2004/04/04 21:59:16 1.23 @@ -1,7 +1,7 @@ /* * i-scream central monitoring system * http://www.i-scream.org - * Copyright (C) 2000-2003 i-scream + * Copyright (C) 2000-2004 i-scream * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -16,6 +16,8 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id: statgrab.c,v 1.23 2004/04/04 21:59:16 ats Exp $ */ #ifdef HAVE_CONFIG_H @@ -35,7 +37,9 @@ typedef enum { FLOAT, DOUBLE, STRING, - INT + INT, + BOOL, + DUPLEX } stat_type; typedef enum { @@ -268,13 +272,24 @@ void populate_fs() { if (disk != NULL) { for (i = 0; i < n; i++) { /* FIXME it'd be nicer if libstatgrab did this */ - const char *name = disk[i].device_name, - *p = strrchr(name, '/'); - if (p != NULL) - name = p + 1; - if (*name == '\0') - name = "root"; - + char *buf, *name, *p; + const char *device = disk[i].device_name; + + if (strcmp(device, "/") == 0) + device = "root"; + + buf = strdup(device); + if (buf == NULL) + die("out of memory"); + + name = buf; + if (strlen(name) == 2 && name[1] == ':') + name[1] = '\0'; + if (strncmp(name, "/dev/", 5) == 0) + name += 5; + while ((p = strchr(name, '/')) != NULL) + *p = '_'; + add_stat(STRING, &disk[i].device_name, "fs", name, "device_name", NULL); add_stat(STRING, &disk[i].fs_type, @@ -293,6 +308,8 @@ void populate_fs() { "fs", name, "used_inodes", NULL); add_stat(LONG_LONG, &disk[i].free_inodes, "fs", name, "free_inodes", NULL); + + free(buf); } } } @@ -333,6 +350,7 @@ void populate_proc() { void populate_net() { int n, i; network_stat_t *net; + network_iface_stat_t *iface; net = use_diffs ? get_network_stats_diff(&n) : get_network_stats(&n); if (net != NULL) { @@ -345,10 +363,34 @@ void populate_net() { "net", name, "tx", NULL); add_stat(LONG_LONG, &net[i].rx, "net", name, "rx", NULL); + add_stat(LONG_LONG, &net[i].ipackets, + "net", name, "ipackets", NULL); + add_stat(LONG_LONG, &net[i].opackets, + "net", name, "opackets", NULL); + add_stat(LONG_LONG, &net[i].ierrors, + "net", name, "ierrors", NULL); + add_stat(LONG_LONG, &net[i].oerrors, + "net", name, "oerrors", NULL); + add_stat(LONG_LONG, &net[i].collisions, + "net", name, "collisions", NULL); add_stat(TIME_T, &net[i].systime, "net", name, "systime", NULL); } } + + iface = get_network_iface_stats(&n); + if (iface != NULL) { + for (i = 0; i < n; i++) { + const char *name = iface[i].interface_name; + + add_stat(INT, &iface[i].speed, + "net", name, "speed", NULL); + add_stat(BOOL, &iface[i].up, + "net", name, "up", NULL); + add_stat(DUPLEX, &iface[i].dup, + "net", name, "duplex", NULL); + } + } } void populate_page() { @@ -358,7 +400,7 @@ void populate_page() { if (page != NULL) { add_stat(LONG_LONG, &page->pages_pagein, "page", "in", NULL); add_stat(LONG_LONG, &page->pages_pageout, "page", "out", NULL); - add_stat(LONG_LONG, &page->systime, "page", "systime", NULL); + add_stat(TIME_T, &page->systime, "page", "systime", NULL); } } @@ -417,12 +459,14 @@ void get_stats() { t->populate(); } - qsort(stats, num_stats, sizeof *stats, stats_compare); + if (stats != NULL) + qsort(stats, num_stats, sizeof *stats, stats_compare); } /* Print the value of a stat. */ void print_stat_value(const stat *s) { void *v = s->stat; + long l; switch (s->type) { case LONG_LONG: @@ -430,7 +474,8 @@ void print_stat_value(const stat *s) { break; case TIME_T: /* FIXME option for formatted time? */ - printf("%ld", *(time_t *)v); + l = *(time_t *)v; + printf("%ld", l); break; case FLOAT: printf("%f", *(float *)v); @@ -445,6 +490,22 @@ void print_stat_value(const stat *s) { case INT: printf("%d", *(int *)v); break; + case BOOL: + printf("%s", *(int *)v ? "true" : "false"); + break; + case DUPLEX: + switch (*(statgrab_duplex *) v) { + case FULL_DUPLEX: + printf("full"); + break; + case HALF_DUPLEX: + printf("half"); + break; + default: + printf("unknown"); + break; + } + break; } } @@ -487,8 +548,15 @@ void print_stats(int argc, char **argv) { else compare = stats_compare; - s = (const stat *)bsearch(&key, stats, num_stats, - sizeof *stats, compare); + if (stats == NULL) { + s = NULL; + } else { + s = (const stat *)bsearch(&key, stats, + num_stats, + sizeof *stats, + compare); + } + if (s == NULL) { printf("Unknown stat %s\n", name); continue; @@ -591,6 +659,12 @@ int main(int argc, char **argv) { use_diffs = 1; select_interesting(argc - optind, &argv[optind]); + + /* We don't care if statgrab_init fails, because we can just display + the statistics that can be read as non-root. */ + statgrab_init(); + if (statgrab_drop_privileges() != 0) + die("Failed to drop setuid/setgid privileges"); switch (repeat_mode) { case REPEAT_NONE: