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