📄 ifstat.c
字号:
putc(' ', stdout); delay = end->tv_sec - start->tv_sec + ((double) (end->tv_usec - start->tv_usec)) / (double) 1000000; scale = delay * (options & OPT_UNITBITS ? 128 : 1024); tkbin = tkbout = 0; for (ptr = ifs->first; ptr != NULL; ptr = ptr->next) { if (ptr->flags & IFSTAT_HASSTATS) { kbin = (double) (ptr->bin - ptr->obin) / (double) scale; tkbin += kbin; kbout = (double) (ptr->bout - ptr->obout) / (double) scale; tkbout += kbout; ptr->flags &= ~IFSTAT_HASSTATS; } else if (ptr->flags & IFSTAT_TOTAL) { kbin = tkbin; kbout = tkbout; } else { kbin = -1; kbout = -1; } if (ptr->flags & IFSTAT_HASINDEX) ptr->flags &= ~IFSTAT_HASINDEX; else hasindex = 0; if (kbin >= 0) snprintf(stats, sizeof(NUM), FMT(kbin), kbin); else strcpy(stats, NA); strcpy(stats + sizeof(NUM) - 1, SPACE); if (kbout >= 0) snprintf(stats + sizeof(NUM) + sizeof(SPACE) - 2, sizeof(NUM), FMT(kbout), kbout); else strcpy(stats + sizeof(NUM) + sizeof(SPACE) - 2, NA); if (pos == 0 && ptr != ifs->first) print_wrap(options, ++line); else if (pos > 0) fputs(SPACE, stdout); len = LEN(options, ptr->namelen); print_center(stats, WIDTH, len); pos = pos_next(pos, len, options); } termsize.datalines = line + 1; if (!(options & OPT_NOSCROLL)) putc('\n', stdout); if (hasindex && !(options & OPT_NOINDEX)) ifs->flags |= IFSTAT_HASINDEX; else ifs->flags &= ~IFSTAT_HASINDEX;}static void filter_interfaces(struct ifstat_list *ifs, int options) { struct ifstat_data *cur, *next, *parent; cur = ifs->first; parent = NULL; while (cur != NULL) { if (!(cur->flags & IFSTAT_HASSTATS) || ((options & OPT_NONULL) && cur->bin == 0 && cur->bout == 0)) { next = cur->next; if (parent != NULL) parent->next = next; else ifs->first = next; ifstat_free_interface(cur); cur = next; } else { parent = cur; cur = cur->next; } }}static void needarg(char opt, int arg, int argc) { if (arg + 1 >= argc) { fprintf(stderr, "%s: option '%c' requires an argument!\n", ifstat_progname, opt); usage(EXIT_FAILURE); }}static double getdelay(char *string) { double delay; if ((delay = atof(string)) < 0.1) { fprintf(stderr, "%s: bad or too short delay '%s'!\n", ifstat_progname, string); exit(EXIT_FAILURE); } return delay;}/* computes time remaining before start + delay */static int notdone(struct timeval *start, struct timeval *tv_delay, struct timeval *remains) { struct timeval now; struct timeval end; gettimeofday(&now, NULL); end.tv_sec = start->tv_sec + tv_delay->tv_sec; end.tv_usec = start->tv_usec + tv_delay->tv_usec; if (end.tv_usec >= 1000000) { end.tv_sec += (end.tv_usec / 1000000); end.tv_usec %= 1000000; } remains->tv_sec = end.tv_sec - now.tv_sec; remains->tv_usec = end.tv_usec - now.tv_usec; if (remains->tv_usec < 0) { remains->tv_sec--; remains->tv_usec += 1000000; } return (remains->tv_sec >= 0);}int main(int argc, char **argv) { struct ifstat_list ifs; struct ifstat_driver driver; int arg, iter, lasthdr; char *opt; char *dname = NULL; char *dopts = NULL; double delay = 1, first_delay = 1; int count = 0; int options = 0; struct timeval start, tv_delay, tv; if ((ifstat_progname = strrchr(argv[0], '/')) != NULL) ifstat_progname++; else ifstat_progname = argv[0]; ifs.flags = 0; ifs.first = NULL; /* parse options */ for (arg = 1; arg < argc; arg++) { if (argv[arg][0] != '-' || argv[arg][1] == '\0') break; opt = argv[arg]+1; while (*opt) { switch(*opt) { case 'a': ifs.flags |= IFSTAT_LOOPBACK|IFSTAT_DOWN; break; case 'l': ifs.flags |= IFSTAT_LOOPBACK; break; case 'v': printf("ifstat version %s.\n" "Copyright (C) 2001-2003, Ga雔 Roualland <gael.roualland@dial.oleane.com>\n", ifstat_version); opt = ifstat_list_drivers(); printf("Compiled-in drivers: %s.\n", (opt != NULL) ? opt : ""); free(opt); exit(EXIT_SUCCESS); case 'A': options |= OPT_NOINDEX; break; case 'n': options |= OPT_NOTITLE; break; case 't': options |= OPT_TIMESTAMP; break; case 'w': options |= OPT_FIXEDWIDTH; break; case 'b': options |= OPT_UNITBITS; break; case 'z': options |= OPT_NONULL; break; case 'W': options |= OPT_WRAP|OPT_FIXEDWIDTH; break; case 'T': ifs.flags |= IFSTAT_TOTAL; break; case 'S': options |= OPT_NOSCROLL|OPT_NOTITLE; break; case 'd': needarg(*opt, arg, argc); dname = argv[++arg]; if ((dopts = strchr(dname, ':')) != NULL) *dopts++ = '\0'; break; case 'i': needarg(*opt, arg, argc); if (!parse_interfaces(argv[++arg], &ifs)) { fprintf(stderr, "%s: error parsing interface list.\n", ifstat_progname); exit(EXIT_FAILURE); } options |= OPT_NOSCAN; break; case 's': needarg(*opt, arg, argc); dname = "snmp"; dopts = argv[++arg]; break; case 'q': ifstat_quiet = 1; break; case 'h': usage(EXIT_SUCCESS); default: fprintf(stderr, "%s: invalid option '-%c'.\n", ifstat_progname, *opt); usage(EXIT_FAILURE); } opt++; } } if (options & OPT_NOSCROLL) options &= ~OPT_WRAP; /* has delay ? */ if (arg < argc) { if ((opt = strchr(argv[arg], '/')) != NULL) *opt++ = '\0'; first_delay = getdelay(argv[arg]); delay = (opt != NULL) ? getdelay(opt) : first_delay; arg++; } /* has count ? */ if (arg < argc) { if ((count = atoi(argv[arg])) <= 0) { fprintf(stderr, "%s: bad count '%s'!\n", ifstat_progname, argv[arg]); return EXIT_FAILURE; } arg++; } /* extra arguments */ if (arg < argc) { fprintf(stderr, "%s: too many arguments!\n", ifstat_progname); return EXIT_FAILURE; } /* look for driver */ if (!ifstat_get_driver(dname, &driver)) { fprintf(stderr, "%s: driver %s not available in this binary!\n", ifstat_progname, dname); return EXIT_FAILURE; } /* init driver */ if (driver.open_driver != NULL && !driver.open_driver(&driver, dopts)) return EXIT_FAILURE; if (ifs.first == NULL) driver.scan_interfaces(&driver, &ifs); /* poll interfaces for the first time */ if (ifs.first != NULL) { if (driver.get_stats != NULL && !driver.get_stats(&driver, &ifs)) return EXIT_FAILURE; gettimeofday(&start, NULL); if (!(options & OPT_NOSCAN)) filter_interfaces(&ifs, options); ifstat_reset_interfaces(&ifs); } if (ifs.first == NULL) { fprintf(stderr, "%s: no interfaces to monitor!\n", ifstat_progname); if (driver.close_driver != NULL) driver.close_driver(&driver); return EXIT_FAILURE; } if (ifs.flags & IFSTAT_TOTAL) ifstat_add_interface(&ifs, "Total", IFSTAT_TOTAL); /* update size of terminal if needed/possible */ if (!(options & OPT_NOTITLE) || (options & OPT_WRAP)) { update_termsize(0);#ifdef SIGWINCH SIGNAL(SIGWINCH, &update_termsize);#endif }#ifdef SIGCONT /* register SIGCONT for redisplay of header */ if (!(options & OPT_NOTITLE) || (options & OPT_NOSCROLL)) SIGNAL(SIGCONT, &sigcont);#endif print_header(&ifs, options); lasthdr = 1; tv_delay.tv_sec = (int) first_delay; tv_delay.tv_usec = (int) ((first_delay - tv_delay.tv_sec) * 1000000); for (iter = 1; count == 0 || iter <= count; iter++) { if (iter == 2 && first_delay != delay) { tv_delay.tv_sec = (int) delay; tv_delay.tv_usec = (int) ((delay - tv_delay.tv_sec) * 1000000); } tv = tv_delay; while (select(0, NULL, NULL, NULL, &tv) != 0 && _sigwinch && notdone(&start, &tv_delay, &tv)) /* restart select if interrupted by sigwinch */ _sigwinch = 0; if (_sigcont || (!(options & OPT_NOTITLE) && termsize.lines > (3 * termsize.datalines) && (iter - lasthdr) * termsize.datalines >= (termsize.lines - (3 * termsize.datalines)))) { print_header(&ifs, options); lasthdr = iter; _sigcont = 0; } if (driver.get_stats != NULL && !driver.get_stats(&driver, &ifs)) return EXIT_FAILURE; gettimeofday(&tv, NULL); print_stats(&ifs, &start, &tv, options); start = tv; fflush(stdout); } if (driver.close_driver != NULL) driver.close_driver(&driver); return EXIT_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -