1 /*
2     mtr  --  a network diagnostic tool
3     Copyright (C) 1997  Matt Kimball
4 
5     split.c -- raw output (for inclusion in KDE Network Utilities or others
6                          GUI based tools)
7     Copyright (C) 1998  Bertrand Leconte <B.Leconte@mail.dotcom.fr>
8 
9     This program is free software; you can redistribute it and/or modify
10     it under the terms of the GNU General Public License version 2 as
11     published by the Free Software Foundation.
12 
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17 
18     You should have received a copy of the GNU General Public License along
19     with this program; if not, write to the Free Software Foundation, Inc.,
20     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22 
23 #include "config.h"
24 
25 #include <ctype.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <sys/types.h>
30 
31 #include "mtr.h"
32 #include "display.h"
33 #include "dns.h"
34 
35 #include "net.h"
36 #include "split.h"
37 #include "utils.h"
38 
39 #ifdef HAVE_CURSES
40 #if defined(HAVE_NCURSES_H)
41 #include <ncurses.h>
42 #elif defined(HAVE_NCURSES_CURSES_H)
43 #include <ncurses/curses.h>
44 #elif defined(HAVE_CURSES_H)
45 #include <curses.h>
46 #else
47 #error No curses header file available
48 #endif
49 #else
50 #include <sys/time.h>
51 #include <sys/types.h>
52 #include <unistd.h>
53 #endif
54 
55 
56 /* There is 256 hops max in the IP header (coded with a byte) */
57 #define MAX_LINE_COUNT 256
58 #define MAX_LINE_SIZE  256
59 
60 static char Lines[MAX_LINE_COUNT][MAX_LINE_SIZE];
61 static int LineCount;
62 
63 
64 #define DEBUG 0
65 
66 
split_redraw(struct mtr_ctl * ctl)67 void split_redraw(
68     struct mtr_ctl *ctl)
69 {
70     int max;
71     int at;
72     ip_t *addr;
73     char newLine[MAX_LINE_SIZE];
74     int i;
75 
76 #if DEBUG
77     fprintf(stderr, "split_redraw()\n");
78 #endif
79 
80     /*
81      * If there is less lines than last time, we delete them
82      * TEST THIS PLEASE
83      */
84     max = net_max(ctl);
85     for (i = LineCount; i > max; i--) {
86         printf("-%d\n", i);
87         LineCount--;
88     }
89 
90     /*
91      * For each line, we compute the new one and we compare it to the old one
92      */
93     for (at = 0; at < max; at++) {
94         addr = net_addr(at);
95         if (addrcmp(addr, &ctl->unspec_addr, ctl->af)) {
96             char str[256], *name;
97             if (!(name = dns_lookup(ctl, addr)))
98                 name = strlongip(ctl, addr);
99             if (ctl->show_ips) {
100                 snprintf(str, sizeof(str), "%s %s", name,
101                          strlongip(ctl, addr));
102                 name = str;
103             }
104             /* May be we should test name's length */
105             snprintf(newLine, sizeof(newLine), "%s %d %d %d %d %d %d",
106                      name, net_loss(at), net_returned(at), net_xmit(at),
107                      net_best(at) / 1000, net_avg(at) / 1000,
108                      net_worst(at) / 1000);
109         } else {
110             snprintf(newLine, sizeof(newLine), "???");
111         }
112 
113         if (strcmp(newLine, Lines[at]) == 0) {
114             /* The same, so do nothing */
115 #if DEBUG
116             printf("SAME LINE\n");
117 #endif
118         } else {
119             printf("%d %s\n", at + 1, newLine);
120             fflush(stdout);
121             xstrncpy(Lines[at], newLine, MAX_LINE_SIZE);
122             if (LineCount < (at + 1)) {
123                 LineCount = at + 1;
124             }
125         }
126     }
127 }
128 
129 
split_open(void)130 void split_open(
131     void)
132 {
133     int i;
134 #if DEBUG
135     printf("split_open()\n");
136 #endif
137     LineCount = -1;
138     for (i = 0; i < MAX_LINE_COUNT; i++) {
139         xstrncpy(Lines[i], "???", MAX_LINE_SIZE);
140     }
141 }
142 
143 
split_close(void)144 void split_close(
145     void)
146 {
147 #if DEBUG
148     printf("split_close()\n");
149 #endif
150 }
151 
152 
split_keyaction(void)153 int split_keyaction(
154     void)
155 {
156 #ifdef HAVE_CURSES
157     unsigned char c = getch();
158 #else
159     fd_set readfds;
160     struct timeval tv;
161     char c;
162 
163     FD_ZERO(&readfds);
164     FD_SET(0, &readfds);
165     tv.tv_sec = 0;
166     tv.tv_usec = 0;
167 
168     if (select(1, &readfds, NULL, NULL, &tv) > 0) {
169         if (read(0, &c, 1) <= 0)
170           return ActionQuit;
171     } else
172         return 0;
173 #endif
174 
175 #if DEBUG
176     printf("split_keyaction()\n");
177 #endif
178     if (tolower(c) == 'q')
179         return ActionQuit;
180     if (c == 3)
181         return ActionQuit;
182     if (tolower(c) == 'r')
183         return ActionReset;
184 
185     return 0;
186 }
187