Annotation of embedaddon/iftop/tui.c, revision 1.1
1.1 ! misho 1: /*
! 2: * tui.c:
! 3: *
! 4: * Based on ui.c from the original iftop sources.
! 5: *
! 6: * This user interface does not make use of curses. Instead, it prints its
! 7: * output to STDOUT. This output is activated by providing the '-t' flag.
! 8: *
! 9: */
! 10:
! 11: #include "config.h"
! 12:
! 13: #include <string.h>
! 14: #include <stdio.h>
! 15: #include <signal.h>
! 16: #include <stdlib.h>
! 17: #include <unistd.h>
! 18:
! 19: #if defined(HAVE_TERMIOS_H)
! 20: #include <termios.h>
! 21: #elif defined(HAVE_SGTTY_H) && defined(TIOCSETP)
! 22: #include <sys/ioctl.h>
! 23: #include <sgtty.h>
! 24: #elif defined(HAVE_TERMIO_H)
! 25: #include <sys/ioctl.h>
! 26: #include <termio.h>
! 27: #else
! 28: #include <stdlib.h>
! 29: #endif
! 30:
! 31: #include "sorted_list.h"
! 32: #include "options.h"
! 33: #include "ui_common.h"
! 34:
! 35: /* Width of the host column in the output */
! 36: #define PRINT_WIDTH 40
! 37:
! 38:
! 39: /*
! 40: * UI print function
! 41: */
! 42: void tui_print() {
! 43: sorted_list_node* nn = NULL;
! 44: char host1[HOSTNAME_LENGTH], host2[HOSTNAME_LENGTH];
! 45: char buf0_10[10], buf1_10[10], buf2_10[10];
! 46: int j;
! 47: static char *label;
! 48: static char *labellong;
! 49: int l = 0;
! 50:
! 51: if (!label) {
! 52: xfree(label);
! 53: label = (char *)calloc(PRINT_WIDTH + 1, 1);
! 54: }
! 55:
! 56: if (!labellong) {
! 57: xfree(labellong);
! 58: labellong = (char *)calloc(PRINT_WIDTH + 1 + 9, 1);
! 59: }
! 60:
! 61: if (options.paused ) {
! 62: return;
! 63: }
! 64:
! 65: /* Headings */
! 66: snprintf(label, PRINT_WIDTH, "%-*s", PRINT_WIDTH, "Host name (port/service if enabled)");
! 67: printf("%s %s %10s %10s %10s %10s\n", " #", label, "last 2s", "last 10s", "last 40s", "cumulative");
! 68:
! 69: /* Divider line */
! 70: for (j = 0; j < PRINT_WIDTH + 52; j++) {
! 71: printf("-");
! 72: }
! 73: printf("\n");
! 74:
! 75: /* Traverse the list of all connections */
! 76: while((nn = sorted_list_next_item(&screen_list, nn)) != NULL && l < options.num_lines) {
! 77: /* Increment the line counter */
! 78: l++;
! 79:
! 80: /* Get the connection information */
! 81: host_pair_line* screen_line = (host_pair_line*)nn->data;
! 82:
! 83: /* Assemble host information */
! 84: sprint_host(host1, screen_line->ap.af, &(screen_line->ap.src6), screen_line->ap.src_port, screen_line->ap.protocol, PRINT_WIDTH, options.aggregate_src);
! 85: sprint_host(host2, screen_line->ap.af, &(screen_line->ap.dst6), screen_line->ap.dst_port, screen_line->ap.protocol, PRINT_WIDTH, options.aggregate_dest);
! 86:
! 87: /* Send rate per connection */
! 88: printf("%4d %s%s", l, host1, " =>");
! 89: for(j = 0; j < HISTORY_DIVISIONS; j++) {
! 90: readable_size(screen_line->sent[j], buf0_10, 10, 1024, options.bandwidth_in_bytes);
! 91: printf(" %10s", buf0_10);
! 92: }
! 93: /* Cumulative sent data per connection */
! 94: readable_size(screen_line->total_sent, buf0_10, 10, 1024, 1);
! 95: printf(" %10s\n", buf0_10);
! 96:
! 97: /* Receive rate per connection */
! 98: printf(" %s%s", host2, " <=");
! 99: for(j = 0; j < HISTORY_DIVISIONS; j++) {
! 100: readable_size(screen_line->recv[j], buf0_10, 10, 1024, options.bandwidth_in_bytes);
! 101: printf(" %10s", buf0_10);
! 102: }
! 103: /* Cumulative received data per connection */
! 104: readable_size(screen_line->total_recv, buf0_10, 10, 1024, 1);
! 105: printf(" %10s\n", buf0_10);
! 106: }
! 107:
! 108: /* Divider line */
! 109: for (j = 0; j < PRINT_WIDTH + 52; j++) {
! 110: printf("-");
! 111: }
! 112: printf("\n");
! 113:
! 114: /* Rate totals */
! 115: snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Total send rate:");
! 116: printf("%s ", labellong);
! 117: for(j = 0; j < HISTORY_DIVISIONS; j++) {
! 118: readable_size((((host_pair_line *)&totals)->sent[j]) , buf0_10, 10, 1024, options.bandwidth_in_bytes);
! 119: printf("%10s%c", buf0_10, j == HISTORY_DIVISIONS - 1 ? '\n' : ' ');
! 120: }
! 121:
! 122: snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Total receive rate:");
! 123: printf("%s ", labellong);
! 124: for(j = 0; j < HISTORY_DIVISIONS; j++) {
! 125: readable_size((((host_pair_line *)&totals)->recv[j]) , buf0_10, 10, 1024, options.bandwidth_in_bytes);
! 126: printf("%10s%c", buf0_10, j == HISTORY_DIVISIONS - 1 ? '\n' : ' ');
! 127: }
! 128:
! 129: snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Total send and receive rate:");
! 130: printf("%s ", labellong);
! 131: for(j = 0; j < HISTORY_DIVISIONS; j++) {
! 132: readable_size((((host_pair_line *)&totals)->sent[j] + ((host_pair_line *)&totals)->recv[j]) , buf0_10, 10, 1024, options.bandwidth_in_bytes);
! 133: printf("%10s%c", buf0_10, j == HISTORY_DIVISIONS - 1 ? '\n' : ' ');
! 134: }
! 135:
! 136: /* Divider line */
! 137: for (j = 0; j < PRINT_WIDTH + 52; j++) {
! 138: printf("-");
! 139: }
! 140: printf("\n");
! 141:
! 142: /* Peak traffic */
! 143: snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Peak rate (sent/received/total):");
! 144: readable_size(peaksent / RESOLUTION, buf0_10, 10, 1024, options.bandwidth_in_bytes);
! 145: readable_size(peakrecv / RESOLUTION, buf1_10, 10, 1024, options.bandwidth_in_bytes);
! 146: readable_size(peaktotal / RESOLUTION, buf2_10, 10, 1024, options.bandwidth_in_bytes);
! 147: printf("%s %10s %10s %10s\n", labellong, buf0_10, buf1_10, buf2_10);
! 148:
! 149: /* Cumulative totals */
! 150: snprintf(labellong, PRINT_WIDTH + 9, "%-*s", PRINT_WIDTH + 9, "Cumulative (sent/received/total):");
! 151: readable_size(history_totals.total_sent, buf0_10, 10, 1024, 1);
! 152: readable_size(history_totals.total_recv, buf1_10, 10, 1024, 1);
! 153: readable_size(history_totals.total_recv + history_totals.total_sent, buf2_10, 10, 1024, 1);
! 154: printf("%s %10s %10s %10s\n", labellong, buf0_10, buf1_10, buf2_10);
! 155:
! 156: /* Double divider line */
! 157: for (j = 0; j < PRINT_WIDTH + 52; j++) {
! 158: printf("=");
! 159: }
! 160: printf("\n\n");
! 161: }
! 162:
! 163:
! 164: /*
! 165: * Text interface data structure initializations.
! 166: */
! 167: void tui_init() {
! 168: screen_list_init();
! 169: screen_hash = addr_hash_create();
! 170: service_hash = serv_hash_create();
! 171: serv_hash_initialise(service_hash);
! 172:
! 173: printf("Listening on %s\n", options.interface);
! 174: }
! 175:
! 176:
! 177: /*
! 178: * Tick function indicating screen refresh
! 179: */
! 180: void tui_tick(int print) {
! 181: if (print) {
! 182: tui_print();
! 183: }
! 184: }
! 185:
! 186:
! 187: /*
! 188: * Main UI loop. Code any interactive character inputs here.
! 189: */
! 190: void tui_loop() {
! 191: int i;
! 192: extern sig_atomic_t foad;
! 193:
! 194: #if defined(HAVE_TERMIOS_H)
! 195: struct termios new_termios, old_termios;
! 196:
! 197: tcgetattr(STDIN_FILENO, &old_termios);
! 198: new_termios = old_termios;
! 199: new_termios.c_lflag &= ~(ICANON|ECHO);
! 200: new_termios.c_cc[VMIN] = 1;
! 201: new_termios.c_cc[VTIME] = 0;
! 202: tcsetattr(STDIN_FILENO, TCSANOW, &new_termios);
! 203: #elif defined(HAVE_SGTTY_H) && defined(TIOCSETP)
! 204: struct sgttyb new_tty, old_tty;
! 205:
! 206: ioctl(STDIN_FILENO, TIOCGETP, &old_tty);
! 207: new_tty = old_tty;
! 208: new_tty.sg_flags &= ~(ICANON|ECHO);
! 209: ioctl(STDIN_FILENO, TIOCSETP, &new_tty);
! 210: #elif defined(HAVE_TERMIO_H)
! 211: struct termio new_termio, old_termio;
! 212:
! 213: ioctl(0, TCGETA, &old_termio);
! 214: new_termio = old_termio;
! 215: new_termio.c_lflag &= ~(ICANON|ECHO);
! 216: new_termio.c_cc[VMIN] = 1;
! 217: new_termio.c_cc[VTIME] = 0;
! 218: ioctl(0, TCSETA, &new_termio);
! 219: #else
! 220: system("/bin/stty cbreak -echo >/dev/null 2>&1");
! 221: #endif
! 222:
! 223: while ((i = getchar()) != 'q' && foad == 0) {
! 224: switch (i) {
! 225: case 'u':
! 226: tick(1);
! 227: break;
! 228: case 'n':
! 229: options.dnsresolution ^= 1;
! 230: printf("DNS resolution is %s.\n\n", options.dnsresolution ? "ON" : "OFF");
! 231: tick(1);
! 232: break;
! 233: case 'N':
! 234: options.portresolution ^= 1;
! 235: printf("Port resolution is %s.\n\n", options.portresolution ? "ON" : "OFF");
! 236: tick(1);
! 237: break;
! 238: case 's':
! 239: options.aggregate_src ^= 1;
! 240: printf("%s source host\n\n", options.aggregate_src ? "Hide" : "Show");
! 241: tick(1);
! 242: break;
! 243: case 'd':
! 244: options.aggregate_dest ^= 1;
! 245: printf("%s destination host\n\n", options.aggregate_dest ? "Hide" : "Show");
! 246: tick(1);
! 247: break;
! 248: case 'S':
! 249: if (options.showports == OPTION_PORTS_OFF) {
! 250: options.showports = OPTION_PORTS_SRC;
! 251: }
! 252: else if (options.showports == OPTION_PORTS_DEST) {
! 253: options.showports = OPTION_PORTS_ON;
! 254: }
! 255: else if(options.showports == OPTION_PORTS_ON) {
! 256: options.showports = OPTION_PORTS_DEST;
! 257: }
! 258: else {
! 259: options.showports = OPTION_PORTS_OFF;
! 260: }
! 261: printf("Showing ports:%s%s%s%s.\n\n",
! 262: options.showports == OPTION_PORTS_SRC ? " src" : "",
! 263: options.showports == OPTION_PORTS_DEST ? " dest" : "",
! 264: options.showports == OPTION_PORTS_ON ? " both" : "",
! 265: options.showports == OPTION_PORTS_OFF ? " none" : "");
! 266: tick(1);
! 267: break;
! 268: case 'D':
! 269: if (options.showports == OPTION_PORTS_OFF) {
! 270: options.showports = OPTION_PORTS_DEST;
! 271: }
! 272: else if (options.showports == OPTION_PORTS_SRC) {
! 273: options.showports = OPTION_PORTS_ON;
! 274: }
! 275: else if(options.showports == OPTION_PORTS_ON) {
! 276: options.showports = OPTION_PORTS_SRC;
! 277: }
! 278: else {
! 279: options.showports = OPTION_PORTS_OFF;
! 280: }
! 281: printf("Showing ports:%s%s%s%s.\n\n",
! 282: options.showports == OPTION_PORTS_SRC ? " src" : "",
! 283: options.showports == OPTION_PORTS_DEST ? " dest" : "",
! 284: options.showports == OPTION_PORTS_ON ? " both" : "",
! 285: options.showports == OPTION_PORTS_OFF ? " none" : "");
! 286: tick(1);
! 287: break;
! 288: case 'p':
! 289: options.showports =
! 290: (options.showports == OPTION_PORTS_OFF) ?
! 291: OPTION_PORTS_ON :
! 292: OPTION_PORTS_OFF;
! 293: printf("Showing ports:%s%s%s%s.\n\n",
! 294: options.showports == OPTION_PORTS_SRC ? " src" : "",
! 295: options.showports == OPTION_PORTS_DEST ? " dest" : "",
! 296: options.showports == OPTION_PORTS_ON ? " both" : "",
! 297: options.showports == OPTION_PORTS_OFF ? " none" : "");
! 298: tick(1);
! 299: break;
! 300: case 'P':
! 301: options.paused ^= 1;
! 302: if (options.paused) {
! 303: printf("Pausing... press 'P' again to continue.\n");
! 304: }
! 305: else {
! 306: printf("Continuing.\n\n");
! 307: tick(1);
! 308: }
! 309: break;
! 310: case 'o':
! 311: options.freezeorder ^= 1;
! 312: printf("Order %s.\n\n", options.freezeorder ? "frozen" : "unfrozen");
! 313: tick(1);
! 314: break;
! 315: case '1':
! 316: options.sort = OPTION_SORT_DIV1;
! 317: printf("Sorting by column 1.\n\n");
! 318: tick(1);
! 319: break;
! 320: case '2':
! 321: options.sort = OPTION_SORT_DIV2;
! 322: printf("Sorting by column 2.\n\n");
! 323: tick(1);
! 324: break;
! 325: case '3':
! 326: options.sort = OPTION_SORT_DIV3;
! 327: printf("Sorting by column 3.\n\n");
! 328: tick(1);
! 329: break;
! 330: case '<':
! 331: options.sort = OPTION_SORT_SRC;
! 332: printf("Sorting by column source.\n\n");
! 333: tick(1);
! 334: break;
! 335: case '>':
! 336: options.sort = OPTION_SORT_DEST;
! 337: printf("Sorting by column destination.\n\n");
! 338: tick(1);
! 339: break;
! 340: default:
! 341: break;
! 342: }
! 343: }
! 344:
! 345: #if defined(HAVE_TERMIOS_H)
! 346: tcsetattr(STDIN_FILENO, TCSANOW, &old_termios);
! 347: #elif defined(HAVE_SGTTY_H) && defined(TIOCSETP)
! 348: ioctl(0, TIOCSETP, &old_tty);
! 349: #elif defined(HAVE_TERMIO_H)
! 350: ioctl(0, TCSETA, &old_termio);
! 351: #else
! 352: system("/bin/stty -cbreak echo >/dev/null 2>&1");
! 353: #endif
! 354: }
! 355:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>