📄 ifstat.c
字号:
/* * ifstat - InterFace STATistics * Copyright (c) 2001, Ga雔 Roualland <gael.roualland@dial.oleane.com> * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: ifstat.c,v 1.47 2003/11/22 01:27:51 gael Exp $ */#ifdef HAVE_CONFIG_H#include <config.h>#endif#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#if STDC_HEADERS#include <string.h>#else# ifndef HAVE_STRCHR# define strchr index# define strrchr rindex# endifchar *strchr (), *strrchr ();# ifndef HAVE_MEMCPY# define memcpy(d, s, n) bcopy ((s), (d), (n))# define memmove(d, s, n) bcopy ((s), (d), (n))# endif#endif#ifdef HAVE_CTYPE_H#include <ctype.h>#endif#if TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# if HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#ifdef HAVE_SYS_TERMIOS_H#include <sys/termios.h>#endif#ifdef HAVE_SYS_IOCTL_H#include <sys/ioctl.h>#endif#ifdef HAVE_SIGNAL_H#include <signal.h>#endif#include <stdio.h>#include <stdlib.h>#include "ifstat.h"#ifdef HAVE_SIGACTIONstatic void _setsig(int sig, RETSIGTYPE (*handler)(int)) { struct sigaction sa; memset(&sa, 0, sizeof(struct sigaction)); sa.sa_handler = handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction(sig, &sa, NULL);}#define SIGNAL(si, handler) _setsig((si), (handler))#define RESIGNAL(si, handler)#else#define SIGNAL(si, handler) signal((si), (handler))#define RESIGNAL(si, handler) signal((si), (handler))#endif#ifndef HAVE_SNPRINTF/* bogus implementation with vsprintf */#ifdef HAVE_STDARG_H#include <stdarg.h>#endif#include <assert.h>int snprintf(char *str, size_t size, const char *format, ...){ int res; va_list ap; va_start(ap, format); res = vsprintf(str, format, ap); va_end(ap); assert(res + 1 <= size); return res;}#endif#ifdef WIN32/* native win32 misses gettimeofday and its select doesn't behave the same way, so replace them by bogus versions that work as expected here */#include <windows.h>#include <sys/timeb.h>static int win_select(int nfds, void *fdr, void *fdw, void *fde, struct timeval *tv) { Sleep(tv->tv_sec * 1000 + tv->tv_usec / 1000); return 0;}#define select win_selectstatic int win_gettimeofday(struct timeval *tv, void *tz) { struct _timeb timeb; _ftime(&timeb); tv->tv_sec = timeb.time; tv->tv_usec = timeb.millitm * 1000; return 0;}#define gettimeofday win_gettimeofday#endif/* parse interface list, using \ as escape character */static int parse_interfaces(char *string, struct ifstat_list *ifs) { char *s, *d, *buf; int len, escaped = 0; if (string == NULL || (len = strlen(string)) <= 0) return 0; if ((buf = malloc(len + 1)) == NULL) { ifstat_perror("malloc"); return 0; } d = buf; for(s = string; *s != '\0'; s++) { if (!escaped) { if (*s == '\\') { escaped = 1; continue; } if (*s == ',') { *d = '\0'; ifstat_add_interface(ifs, buf, 0); d = buf; continue; } } else escaped = 0; *d++ = *s; } *d = '\0'; if (*buf != '\0') ifstat_add_interface(ifs, buf, 0); free(buf); return 1;}static void usage(int result) { fprintf(stderr, "usage: %s [-a] [-l] [-z] [-n] [-v] [-h] [-t] [-i if0,if1,...]\n" " [-d drv[:opt]] [-s [comm@][#]host[/nn]] [-T] [-A] [-w]\n" " [-W] [-S] [-b] [-q] [delay[/delay] [count]]\n", ifstat_progname); exit(result);}static void print_center(char *s, int len, int width) { int ofs, i; ofs = (width - len) / 2; for (i = 0; i < ofs; i++) putc(' ', stdout); for (i = 0; i < len; i++) putc(s[i], stdout); for (i = 0; i < (width - (ofs + len)); i++) putc(' ', stdout);}struct { int cols, lines, datalines;} termsize;int _sigwinch = 0;static RETSIGTYPE update_termsize(int sig) {#ifdef TIOCGWINSZ struct winsize ws; if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_row > 0 && ws.ws_col > 0) { termsize.cols = ws.ws_col; termsize.lines = ws.ws_row; } else { /* defaults if unknown */ termsize.lines = 25; termsize.cols = 80; }#ifdef SIGWINCH if (sig == SIGWINCH) _sigwinch = 1; RESIGNAL(SIGWINCH, &update_termsize);#endif#endif}int _sigcont = 0;#ifdef SIGCONTstatic RETSIGTYPE sigcont(int sig) { _sigcont = 1; RESIGNAL(SIGCONT, &sigcont);}#endif#define OPT_TIMESTAMP 1#define OPT_FIXEDWIDTH 2#define OPT_UNITBITS 4#define OPT_NOINDEX 8#define OPT_NONULL 16#define OPT_NOSCAN 32#define OPT_WRAP 64#define OPT_NOTITLE 128#define OPT_NOSCROLL 256#define SPACE " "#define NUM "12345.12"#define NA " n/a"#define WIDTH (sizeof(NUM) - 1) * 2 + (sizeof(SPACE) - 1)#define LEN(options, namelen) (((options) & OPT_FIXEDWIDTH || (namelen) < WIDTH) ? WIDTH : (namelen))#define FMT(n) (((n) < 1e+5) ? "%8.2f" : (((n) < 1e+6) ? "%.1f" : "%.2e"))/* eth0 lo KB/s in KB/s out KB/s in KB/s out 14562.23 12345.25 0.00 0.00*/static void print_wrap(int options, int line) { putc('\n', stdout); putc((char) (((line - 1) % 26) + 65), stdout); if (options & OPT_TIMESTAMP) fputs(" " SPACE, stdout);}static int pos_next(int pos, int len, int options) { int ofs = (options & OPT_TIMESTAMP) ? 8 + sizeof(SPACE) - 1 : 1; pos += len + sizeof(SPACE) - 1; if (options & OPT_WRAP && pos + ofs + len >= termsize.cols) pos = 0; return pos;}static void print_legend(struct ifstat_data *ptr, int options, int line) { int len, pos; if (line == 0) { putc('\n', stdout); if (options & OPT_TIMESTAMP) fputs("HH:MM:SS" SPACE, stdout); else if (options & OPT_WRAP) putc(' ', stdout); } else print_wrap(options, line); pos = 0; for (; ptr != NULL; ptr = ptr->next) { if (pos > 0) fputs(SPACE, stdout); len = LEN(options, ptr->namelen); print_center((options & OPT_UNITBITS) ? " Kbps in Kbps out" : " KB/s in KB/s out", WIDTH, len); if ((pos = pos_next(pos, len, options)) == 0 && ptr->next != NULL) return; } putc('\n', stdout);} static void print_header(struct ifstat_list *ifs, int options) { struct ifstat_data *ptr, *start; int len, pos, line; if (options & OPT_TIMESTAMP) fputs(" Time " SPACE, stdout); else if (options & OPT_WRAP) putc(' ', stdout); pos = 0; line = 0; start = ifs->first; for (ptr = ifs->first; ptr != NULL; ptr = ptr->next) { if (pos == 0 && ptr != ifs->first) { print_legend(start, options, line); start = ptr; print_wrap(options, ++line); } else if (pos > 0) fputs(SPACE, stdout); len = LEN(options, ptr->namelen); print_center(ptr->name, ptr->namelen < len ? ptr->namelen : len, len); pos = pos_next(pos, len, options); } termsize.datalines = line + 1; print_legend(start, options, line);}static void print_stats(struct ifstat_list *ifs, struct timeval *start, struct timeval *end, int options) { struct ifstat_data *ptr; int hasindex = 1, pos = 0, len, line = 0; char stats[WIDTH + 1]; double delay, kbin, kbout, tkbin, tkbout, scale; struct tm *ltm; if (options & OPT_NOSCROLL) putc('\r', stdout); if (options & OPT_TIMESTAMP) { time_t t = end->tv_sec; if ((ltm = localtime(&t)) != NULL) fprintf(stdout, "%02d:%02d:%02d" SPACE, ltm->tm_hour, ltm->tm_min, ltm->tm_sec); else fputs("--:--:--" SPACE, stdout); } else if (options & OPT_WRAP)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -