ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/statgrab/statgrab.c
(Generate patch)

Comparing projects/libstatgrab/src/statgrab/statgrab.c (file contents):
Revision 1.8 by ats, Fri Aug 29 06:56:12 2003 UTC vs.
Revision 1.18 by ats, Fri Feb 13 12:52:40 2004 UTC

# Line 1 | Line 1
1   /*
2   * i-scream central monitoring system
3   * http://www.i-scream.org
4 < * Copyright (C) 2000-2003 i-scream
4 > * Copyright (C) 2000-2004 i-scream
5   *
6   * This program is free software; you can redistribute it and/or
7   * modify it under the terms of the GNU General Public License
# Line 16 | Line 16
16   * You should have received a copy of the GNU General Public License
17   * along with this program; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 + *
20 + * $Id$
21   */
22  
23   #ifdef HAVE_CONFIG_H
# Line 35 | Line 37 | typedef enum {
37          FLOAT,
38          DOUBLE,
39          STRING,
40 <        INT
40 >        INT,
41 >        DUPLEX
42   } stat_type;
43  
44   typedef enum {
# Line 140 | Line 143 | void add_stat(stat_type type, void *stat, ...) {
143          ++num_stats;
144   }
145  
146 < /* Compare two stats by name, for sorting purposes. */
146 > /* Compare two stats by name for qsort and bsearch. */
147   int stats_compare(const void *a, const void *b) {
148          return strcmp(((stat *)a)->name, ((stat *)b)->name);
149   }
150  
151 + /* Compare up to the length of the key for bsearch. */
152 + int stats_compare_prefix(const void *key, const void *item) {
153 +        const char *kn = ((stat *)key)->name;
154 +        const char *in = ((stat *)item)->name;
155 +
156 +        return strncmp(kn, in, strlen(kn));
157 + }
158 +
159   void populate_const() {
160          static int zero = 0;
161  
# Line 260 | Line 271 | void populate_fs() {
271          if (disk != NULL) {
272                  for (i = 0; i < n; i++) {
273                          /* FIXME it'd be nicer if libstatgrab did this */
274 <                        const char *name = disk[i].device_name,
275 <                                   *p = strrchr(name, '/');
276 <                        if (p != NULL)
277 <                                name = p + 1;
278 <                        if (*name == '\0')
279 <                                name = "root";
280 <        
274 >                        char *buf, *name, *p;
275 >                        const char *device = disk[i].device_name;
276 >
277 >                        if (strcmp(device, "/") == 0)
278 >                                device = "root";
279 >
280 >                        buf = strdup(device);
281 >                        if (buf == NULL)
282 >                                die("out of memory");
283 >
284 >                        name = buf;
285 >                        if (strlen(name) == 2 && name[1] == ':')
286 >                                name[1] = '\0';
287 >                        if (strncmp(name, "/dev/", 5) == 0)
288 >                                name += 5;
289 >                        while ((p = strchr(name, '/')) != NULL)
290 >                                *p = '_';
291 >
292                          add_stat(STRING, &disk[i].device_name,
293                                   "fs", name, "device_name", NULL);
294                          add_stat(STRING, &disk[i].fs_type,
# Line 285 | Line 307 | void populate_fs() {
307                                   "fs", name, "used_inodes", NULL);
308                          add_stat(LONG_LONG, &disk[i].free_inodes,
309                                   "fs", name, "free_inodes", NULL);
310 +
311 +                        free(buf);
312                  }
313          }
314   }
# Line 325 | Line 349 | void populate_proc() {
349   void populate_net() {
350          int n, i;
351          network_stat_t *net;
352 +        network_iface_stat_t *iface;
353  
354          net = use_diffs ? get_network_stats_diff(&n) : get_network_stats(&n);
355          if (net != NULL) {
# Line 341 | Line 366 | void populate_net() {
366                                   "net", name, "systime", NULL);
367                  }
368          }
369 +
370 +        iface = get_network_iface_stats(&n);
371 +        if (iface != NULL) {
372 +                for (i = 0; i < n; i++) {
373 +                        const char *name = iface[i].interface_name;
374 +
375 +                        add_stat(INT, &iface[i].speed,
376 +                                 "net", name, "speed", NULL);
377 +                        add_stat(DUPLEX, &iface[i].dup,
378 +                                 "net", name, "duplex", NULL);
379 +                }
380 +        }
381   }
382  
383   void populate_page() {
# Line 350 | Line 387 | void populate_page() {
387          if (page != NULL) {
388                  add_stat(LONG_LONG, &page->pages_pagein, "page", "in", NULL);
389                  add_stat(LONG_LONG, &page->pages_pageout, "page", "out", NULL);
390 <                add_stat(LONG_LONG, &page->systime, "page", "systime", NULL);
390 >                add_stat(TIME_T, &page->systime, "page", "systime", NULL);
391          }
392   }
393  
# Line 437 | Line 474 | void print_stat_value(const stat *s) {
474          case INT:
475                  printf("%d", *(int *)v);
476                  break;
477 +        case DUPLEX:
478 +                switch (*(duplex *) v) {
479 +                case FULL_DUPLEX:
480 +                        printf("full");
481 +                        break;
482 +                case HALF_DUPLEX:
483 +                        printf("half");
484 +                        break;
485 +                default:
486 +                        printf("unknown");
487 +                        break;
488 +                }
489 +                break;
490          }
491   }
492  
# Line 468 | Line 518 | void print_stats(int argc, char **argv) {
518          } else {
519                  /* Print selected stats. */
520                  for (i = optind; i < argc; i++) {
521 +                        char *name = argv[i];
522                          stat key;
523 <                        const stat *s;
523 >                        const stat *s, *end;
524 >                        int (*compare)(const void *, const void *);
525  
526 <                        key.name = argv[i];
526 >                        key.name = name;
527 >                        if (name[strlen(name) - 1] == '.')
528 >                                compare = stats_compare_prefix;
529 >                        else
530 >                                compare = stats_compare;
531 >
532                          s = (const stat *)bsearch(&key, stats, num_stats,
533 <                                                  sizeof *stats,
534 <                                                  stats_compare);
535 <                        if (s != NULL) {
533 >                                                  sizeof *stats, compare);
534 >                        if (s == NULL) {
535 >                                printf("Unknown stat %s\n", name);
536 >                                continue;
537 >                        }
538 >
539 >                        /* Find the range of stats the user wanted. */
540 >                        for (; s >= stats; s--) {
541 >                                if (compare(&key, s) != 0)
542 >                                        break;
543 >                        }
544 >                        s++;
545 >                        for (end = s; end < &stats[num_stats]; end++) {
546 >                                if (compare(&key, end) != 0)
547 >                                        break;
548 >                        }
549 >
550 >                        /* And print them. */
551 >                        for (; s < end; s++) {
552                                  print_stat(s);
553                          }
554                  }
# Line 484 | Line 557 | void print_stats(int argc, char **argv) {
557  
558   void usage() {
559          printf("Usage: statgrab [OPTION]... [STAT]...\n"
560 <               "Display system statistics (all statistics by default).\n"
560 >               "Display system statistics.\n"
561 >               "\n"
562 >               "If no STATs are given, all will be displayed. Specify 'STAT.' to display all\n"
563 >               "statistics starting with that prefix.\n"
564                 "\n");
565          printf("  -l         Linux sysctl-style output (default)\n"
566                 "  -b         BSD sysctl-style output\n"
# Line 557 | Line 633 | int main(int argc, char **argv) {
633                  use_diffs = 1;
634  
635          select_interesting(argc - optind, &argv[optind]);
636 +
637 +        /* We don't care if statgrab_init fails, because we can just display
638 +           the statistics that can be read as non-root. */
639 +        statgrab_init();
640 +        if (statgrab_drop_privileges() != 0)
641 +                die("Failed to drop setuid/setgid privileges");
642  
643          switch (repeat_mode) {
644          case REPEAT_NONE:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines