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>