Removed bogus files

buffered-read-3-0-BETA
Stephane Bortzmeyer 24 years ago
parent aab38992d2
commit e4f0e5612e

@ -1,33 +0,0 @@
CC = gcc
#CC = cc
CFLAGS = -c -O
#CFLAGS = -g -c -O0
LD = $(CC)
LDFLAGS = -o echoping
OBJS = echoping.o error.o readline.o writen.o util.o
SOURCES = echoping.c error.c readline.c writen.c util.c inet.h
MISC = README Makefile
DISTRIB= echo/README echo/Makefile echo/echoping.ptk echo/echoping.c echo/error.c echo/readline.c echo/writen.c echo/util.c echo/inet.h
all: echoping
echoping: $(OBJS)
@ echo Linking $@ with new $?
$(LD) $(LDFLAGS) $(OBJS)
.c.o:
$(CC) $(CFLAGS) $<
clean:
-rm echoping $(OBJS)
@ echo Erased
distrib:
@(cd .. ; \
tar cvf "echo/echoping.tar" $(DISTRIB); \
gzip -v -f "echo/echoping.tar")
checkout:
co -l $(SOURCES) README

@ -1,120 +0,0 @@
"echoping" is a small program to test (approximatively) performances of a
remote host by sending it TCP "echo" packets.
It assumes the remote host accepts such connections. Experience show that
most Internet routers do and many hosts also. However, some Unices are not
shipped with this service enabled and, anyway, the administrator is always
free to close it (I think they shouldn't). echoping has therefore less chance
to succeed than ping or bing. (On a typical Unix box, "echo" service is
configured in /etc/inetd.conf.)
In any case, be polite: don't bother the remote host with many repeated
requests, especially with large size.
The current version is very rough. It was written quickly and not debugged
in detail.
It appears to compile and run at least on OSF/1 3.2, Solaris (?),
Linux 1.1, SunOS 4.1 and Ultrix 4.3. You do not have to be root to
install it: just type make and copy the "echoping" executable anywhere you
want. There is no man page.
To use it, simply:
% echoping machine.somewhere.org
or use the options before the machine name:
-v : verbose
-s nnn : size of the data to send
-n nnn : numbers of repeated tests
-w nnn : number of seconds to wait between two tests (default is one)
-t nnn : number of seconds to wait a reply before giving up
-u : use UDP instead of TCP
-d : use the "discard" service instead of echo
-c : use the "chargen" service instead of echo
echoping simply shows the elapsed time, including the time to set up the TCP
connection and to transfer the data. Therefore, it is unsuitable to physical
line raw throughput measures (unlike bing). On the other end, the action it
performs are close from a HTTP request and it is meaningful to use it
(carefully) to measure Web performances.
With the '-n' option, you have also the minimum, maximum, average and median
time. The median is the value such that half of the measures are under it
and the other half is above. When you measure highly variables values, like
it is often the case on the whole Internet, median is better than average
to avoid "extreme" values.
There are many, many traps when measuring something on the Internet. Just one
example: 'echoping -w 0 -n 4 a-sunOS-machine' and you'll see the first test
succeed in a very short time (if you are close from the machine) and all of
the others take a much longer time (one second). With '-w 1' (wait one second
between tests, the default), everything works fine: it seems the sockets on
SunOS need time to recover :-)
With UDP servers you can have other surprises: the first test is quite often
much slower since inetd has to launch the process. After that, the process
stays a while so the next texts run faster.
If you have the Perl/Tk <http://pubweb.bnl.gov/~ptk/> package, you can use a
(quite rough) windowing interface, "echoping.ptk". To use it, you should
define FLUSH_OUTPUT at the beginning of echoping.c (this seems to work
on only a few Unices, including DEC's OSF/1).
Known bugs:
- UDP isn't really useable with large packets because of sockets
limitations and the lack of workaround code
To do:
- display statistics even when interrupted by Control-C
- display other calculations such as standard deviation
- timeouts even on TCP connections
To measure performances on the Internet you can also see:
Unix:
- bing, a bandwidth measurement tool <ftp://ftp.ibp.fr/pub/networking>
- ping, probably available with your system
- traceroute, idem (otherwise, see <ftp://ftp.ee.lbl.gov/>)
- ttcp, the best measurement tool but it needs some control over the
two machines <ftp://ftp.arl.mil/pub/ttcp>
- spray is a tool which I dont't know very well. It is available on some
machines (Sun, OSF/1).
I've also heard of but never tried:
- NetPerf <http://www.cup.hp.com/netperf/NetperfPage.html>
- a suite of Bandwidth Measuring programs from gnn@netcom.com
<ftp.netcom.com/~ftp/gnn/bwmeas-0.3.tar.Z>. These are several
programs that measure bandwidth and jitter over several kinds of
IPC links, including TCP and UDP.
Macintosh:
- TCP Watcher, a very nice "swiss-army knife" tool, to test ping, DNS, echo.
It includes an echo server. Available on Info-Mac in "comm/tcp".
Web clients:
- You can ping or traceroute on the Web. See
<http://hplyot.obspm.fr/cgi-bin/nph-traceroute>, <http://www.fr.net/>,
and <gopher://ns.urec.fr/11/Reseaux/Annuaires>.
Use all of them with care, the result is not obvious to interpret.
And don't forget to read RFC 1470 ("Tools for Monitoring and Debugging
TCP/IP Internets and Interconnected Devices"), specially its "Benchmark"
section and the Richard Stevens' books (all of them), published by
Addison-Wesley.
The reference site for echoping is:
ftp://ftp.pasteur.fr/pub/Network/echoping
Stephane Bortzmeyer <bortzmeyer@pasteur.fr>. October 1995 for the
first version. December 1995 for this one.

@ -1,475 +0,0 @@
/*
* echoping : uses the TCP echo service to measure (roughly) response times.
*
* Written by Stephane Bortzmeyer <bortzmeyer@pasteur.fr>. A lot of code stolen
* from Richard Stevens' book "Unix network programming" and Pierre Beyssac's
* "bing" tool
*
*/
char *progname;
unsigned short timeout_flag;
#include "inet.h"
/*
* An option to define only if you want to drive echoping from another
* process. Useless but harmless otherwise. In practice, while OSF/1 is happy
* with it, SunOS refuses to use fflush on a NULL and Linux fails.
*/
#undef FLUSH_OUTPUT
void
main(argc, argv)
int argc;
char *argv[];
{
extern char *optarg;
extern int optind;
extern int opterr;
extern int optopt;
extern int tvcmp();
char ch;
int sockfd;
struct hostent *hostptr;
struct sockaddr_in serv_addr;
struct sockaddr_in udp_cli_addr; /* client's Internet socket
* addr */
struct servent *sp;
int verbose = FALSE;
char *server_address;
u_int addr;
struct in_addr *ptr;
int n, nr;
char *sendline, recvline[MAXLINE + 1];
struct timeval newtv, oldtv;
unsigned int size = DEFLINE;
unsigned int number = 1;
unsigned int wait = 1;
unsigned char fill;
unsigned short fill_requested = 0;
unsigned int i, j = 0;
unsigned int successes = 0;
struct result {
unsigned short valid;
struct timeval timevalue;
};
struct result results[MAXNUMBER];
struct timeval good_results[MAXNUMBER];
struct timeval max, min, total, median, temp;
void to_alarm(); /* our alarm() signal handler */
void interrupted();
unsigned int timeout = 10;
unsigned short timeout_requested = 0;
char *port_name = ECHO_TCP_PORT;
unsigned short port_to_use = USE_ECHO;
unsigned short udp = 0;
unsigned short ttcp = 0;
unsigned short stop_at_newlines = 1;
null_timeval.tv_sec = 0;
null_timeval.tv_usec = 0;
max_timeval.tv_sec = 1000000000;
max_timeval.tv_usec = 999999;
total = null_timeval;
median = null_timeval;
max = null_timeval;
min = max_timeval;
for (i = 0; i <= MAXNUMBER; i++) {
results[i].valid = 0;
}
progname = argv[0];
while ((ch = getopt(argc, argv, "vs:n:w:dcrut:f:")) != EOF) {
switch (ch) {
case 'v':
verbose = TRUE;
break;
case 'r':
ttcp = 1;
break;
case 'u':
udp = 1;
break;
case 'd':
port_name = DISCARD_TCP_PORT;
port_to_use = USE_DISCARD;
break;
case 'c':
port_name = CHARACTER_GENERATOR_TCP_PORT;
port_to_use = USE_CHARGEN;
stop_at_newlines = 0;
break;
case 'f':
fill = optarg;
fill_requested = 1;
break;
case 's':
size = atoi(optarg);
if (size > MAXLINE) {
(void) fprintf(stderr,
"%s: packet size too large, max is %d.\n",
progname, MAXLINE);
exit(1);
}
if (size <= 0) {
(void) fprintf(stderr,
"%s: illegal packet size.\n", progname);
exit(1);
}
break;
case 't':
timeout = atoi(optarg);
timeout_requested = 1;
if (size <= 0) {
(void) fprintf(stderr,
"%s: illegal timeout.\n", progname);
exit(1);
}
break;
case 'n':
number = atoi(optarg);
if (number > MAXNUMBER) {
(void) fprintf(stderr,
"%s: number of iterations too large, max is %d.\n",
progname, MAXNUMBER);
exit(1);
}
if (number <= 0) {
(void) fprintf(stderr,
"%s: illegal number of iterations.\n", progname);
exit(1);
}
break;
case 'w':
wait = atoi(optarg);
if (wait < 0) {
(void) fprintf(stderr,
"%s: illegal waiting time.\n", progname);
exit(1);
}
break;
default:
usage();
}
}
if (udp && (port_to_use == USE_CHARGEN)) {
(void) fprintf(stderr,
"%s: I don't know how to use CHARGEN with UDP.\n", progname);
exit(1);
}
if (!udp && (timeout_requested)) {
(void) fprintf(stderr,
"%s: Time out ignored for TCP connections.\n", progname);
exit(1);
}
if (udp && ttcp) {
(void) fprintf(stderr,
"%s: UDP and T/TCP are incompatible.\n", progname);
exit(1);
}
argc -= optind;
argv += optind;
if (argc != 1) {
usage();
}
if (verbose) {
printf("\nThis is %s, version %s.\n\n", progname, VERSION);
}
server = argv[0];
signal(SIGINT, interrupted);
if ((addr = inet_addr(server)) == INADDR_NONE) {
if ((hostptr = gethostbyname(server)) == NULL) {
err_quit("gethostbyname error for host: %s %s",
server, sys_err_str());
}
server_address = *(hostptr->h_addr_list); /* First item of the
* list */
/*
* addr = (u_long) *server_address; /* hostptr->h_addr_list
* points actually to u_longs, not strings
*/
/* ptr.s_addr = addr; */
ptr = (struct in_addr *) server_address; /* hostptr->h_addr_list
* points actually to
* u_longs, not strings */
addr = ptr->s_addr;
} else {
ptr = (struct in_addr *) malloc(sizeof(struct in_addr));
ptr->s_addr = addr;
}
if (!udp) {
if ((sp = getservbyname(port_name, "tcp")) == NULL) {
err_quit("tcp_open: unknown service: %s/tcp", port_name);
}
} else {
if ((sp = getservbyname(port_name, "udp")) == NULL) {
err_quit("tcp_open: unknown service: %s/udp", port_name);
}
}
/*
* Fill in the structure "serv_addr" with the address of the server
* that we want to connect with.
*/
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = addr;
serv_addr.sin_port = sp->s_port;
if (!fill_requested) {
sendline = random_string(size);
} else {
sendline = (char *) malloc(size);
for (i = 0; i < size; i++)
sendline[i] = fill;
}
n = strlen(sendline) + 1;
for (i = 1; i <= number; i++) {
if (!udp) {
/*
* Open a TCP socket (an Internet stream socket).
*/
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_sys("Can't open stream socket");
} else {
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
err_sys("Can't open datagram socket");
/* Bind socket for reply. Not necessary? */
bzero((char *) &udp_cli_addr, sizeof(udp_cli_addr));
udp_cli_addr.sin_family = AF_INET;
udp_cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);
udp_cli_addr.sin_port = htons(0);
if (bind(sockfd, (struct sockaddr *) & udp_cli_addr,
sizeof(udp_cli_addr)) < 0) {
err_sys("bind error");
}
}
if (verbose) {
printf("Trying to connect to internet address %s to transmit %u bytes...\n",
inet_ntoa(*ptr), size);
#ifdef FLUSH_OUTPUT
if (fflush((FILE *) NULL) != 0) {
err_sys("I cannot flush");
}
#endif
}
(void) gettimeofday(&oldtv, (struct timezone *) NULL);
if (!ttcp) {
/*
* Connect to the server.
*/
if (connect(sockfd, (struct sockaddr *) & serv_addr,
sizeof(serv_addr)) < 0)
err_sys("Can't connect to server");
if (verbose) {
printf("Connected...\n");
#ifdef FLUSH_OUTPUT
if (fflush((FILE *) NULL) != 0) {
err_sys("I cannot flush");
}
#endif
}
}
/* Not T/TCP */
else {
/* No initial connection */
}
if ((port_to_use == USE_ECHO) || (port_to_use == USE_DISCARD)) {
if (ttcp) {
if (sendto(sockfd, sendline, n, MSG_EOF,
(struct sockaddr *) & serv_addr, sizeof(serv_addr)) != n)
err_sys("sendto error on socket");
if (verbose) {
printf("T/TCP connection done\n");
}
} else if (!udp) {
/* Write something to the server */
if (writen(sockfd, sendline, n) != n)
err_sys("writen error on socket");
} else {
/*
* if (sendto(sockfd, sendline, n, 0,
* &serv_addr, sizeof(serv_addr)) != n)
* err_sys("sendto error on socket");
*/
if (send(sockfd, sendline, n, 0) != n)
err_sys("send error on socket");
}
if (verbose) {
printf("Sent (%d bytes)...\n", n);
#ifdef FLUSH_OUTPUT
if (fflush((FILE *) NULL) != 0) {
err_sys("I cannot flush");
}
#endif
}
}
if ((port_to_use == USE_ECHO) || (port_to_use == USE_CHARGEN)) {
if (!udp) {
/* Read from the server */
nr = readline(sockfd, recvline, n, stop_at_newlines);
} else {
signal(SIGALRM, to_alarm);
timeout_flag = 0; /* for signal handler */
alarm(timeout);
nr = recv(sockfd, recvline, n, 0);
/*
* nr = recvfrom(sockfd, recvline, n, 0,
* (struct sockaddr *) 0, (int *) 0);
* recvfrom fails on SunOS on connected
* sockets.
*/
/*
* BUG: in UDP, we should loop to read: we
* can have several reads necessary.
*/
alarm(0);
if ((nr < 0) && (errno == EINTR) && (timeout_flag)) {
nr = n;
printf("Timeout\n");
#ifdef FLUSH_OUTPUT
if (fflush((FILE *) NULL) != 0) {
err_sys("I cannot flush");
}
#endif
}
}
if (nr < 0 || nr != n)
err_sys("readline error: %d bytes read, %d bytes requested", nr, n);
}
/* That's all, folks */
close(sockfd);
(void) gettimeofday(&newtv, (struct timezone *) NULL);
temp = newtv;
tvsub(&temp, &oldtv);
if (!timeout_flag) {
tvadd(&total, &temp);
/* Check */
if (port_to_use == USE_ECHO) {
if (strcmp(sendline, recvline) != 0) {
printf(" I wrote:\n%s\n", sendline);
printf(" and I got back:\n%s\n", recvline);
err_quit("Strange server");
}
if (verbose) {
printf("Checked\n");
#ifdef FLUSH_OUTPUT
if (fflush((FILE *) NULL) != 0) {
err_sys("I cannot flush");
}
#endif
}
}
if (port_to_use == USE_CHARGEN) {
sendline = CHARGENERATED;
recvline[strlen(sendline)] = 0;
if (strcmp(sendline, recvline) != 0) {
printf(" I got back:\n%s\n", recvline);
printf(" instead of the most common:\n%s\n", sendline);
err_ret("Strange server");
}
if (verbose) {
printf("Checked\n");
}
}
tvsub(&newtv, &oldtv);
tvmin(&min, &newtv);
tvmax(&max, &newtv);
printf("Elapsed time: %d.%06d seconds\n", newtv.tv_sec, newtv.tv_usec);
#ifdef FLUSH_OUTPUT
if (fflush((FILE *) NULL) != 0) {
err_sys("I cannot flush");
}
#endif
results[i - 1].valid = 1;
results[i - 1].timevalue = newtv;
successes++;
}
if (number > 1) {
sleep(wait);
}
}
printstats:
/* if ((number > 1) && ((!udp) || (successes > 0))) { */
if (successes > 1) {
printf("---\n");
if (successes < number)
printf("Warning: %d messages lost (%d %%)\n", number - successes,
((number - successes) * 100) / number);
printf("Minimum time: %d.%06d seconds (%.0f bytes per sec.)\n",
min.tv_sec, min.tv_usec, (double) size / tv2double(min));
printf("Maximum time: %d.%06d seconds (%.0f bytes per sec.)\n",
max.tv_sec, max.tv_usec, (double) size / tv2double(max));
tvavg(&total, successes);
printf("Average time: %d.%06d seconds (%.0f bytes per sec.)\n",
total.tv_sec, total.tv_usec, (double) size / tv2double(total));
for (i = 0; i < number; i++) {
if (results[i].valid)
good_results[j++] = results[i].timevalue;
}
if (successes != j) /* Bug! */
err_quit("successes (%d) is different from j (%d)", successes, j);
qsort(good_results, successes, sizeof(struct timeval), tvcmp);
/*
* for (i = 1; i <= number; i++) { printf("---\nTime %d th:
* %d.%06d seconds\n", i, results[i-1].tv_sec,
* results[i-1].tv_usec); }
*/
if ((successes % 2) == 1) {
/*
* printf("Searching good_results[%d]\n", (successes
* + 1) / 2 - 1);
*/
median = good_results[((successes + 1) / 2 - 1)];
} else {
/*
* printf("Searching good_results[%d] and [%d]\n",
* (successes / 2) - 1, successes / 2);
*/
tvadd(&median, &good_results[(successes / 2) - 1]);
tvadd(&median, &good_results[successes / 2]);
tvavg(&median, 2);
}
printf("Median time: %d.%06d seconds (%.0f bytes per sec.)\n",
median.tv_sec, median.tv_usec, (double) size / tv2double(median));
}
exit(0);
}
/*
* Signal handler for timeouts (SIGALRM). This function is called when the
* alarm() value that was set counts down to zero. This indicates that we
* haven't received a response from the server to the last datagram we sent.
* All we do is set a flag and return from the signal handler. The occurrence
* of the signal interrupts the recvfrom() system call (errno = EINTR) above,
* and we then check the tout_flag flag.
*/
void
to_alarm()
{
timeout_flag = 1; /* set flag for function above */
}
void
interrupted()
{
printf("Interrupted by user\n");
exit(1);
}

@ -1,314 +0,0 @@
#!/usr/local/bin/perl -w
require 5.001;
use Tk;
use Tk::IO;
require 'sys/socket.ph';
# Let's be paranoid
use strict;
require "newgetopt.pl";
&NGetOpt (("geometry=s", "font=s", "background=s", "bg=s", "foreground=s", "fg=s", "title=s"));
my $default_host;
if (@ARGV) {
$default_host = shift (@ARGV);
#TODO: shouldn't we try to echoping it right now?
}
else {
$default_host = "localhost";
}
if (@ARGV) {
print STDERR "Ignoring extra arguments \"" . join (' ', @ARGV) . "\"\n";
}
my $top = MainWindow->new;
if ($main::opt_geometry) {
$top->geometry ($main::opt_geometry);
}
if ($main::opt_title) {
$top->title ($main::opt_title);
}
else {
$top->title ("EchoPing Driver");
}
#TODO: how to set background, font, etc for all the widgets?
if ($main::opt_bg) {
$main::opt_background = $main::opt_bg;
}
if ($main::opt_background) {
$top->configure (-background => $main::opt_background);
}
if ($main::opt_fg) {
$main::opt_foreground = $main::opt_fg;
}
if ($main::opt_foreground) {
$top->configure (-foreground => $main::opt_foreground);
}
if ($main::opt_font) {
$top->configure (-font => $main::opt_font);
}
#TODO : on line help with context => 'connection refused' will give an explanation
$main::echoping = &find_pg ("echoping");
if (! $main::echoping) {
print STDERR "Cannot find the echoping program in the path.\n";
exit 1;
#TODO: a nice pop-up window with an hypertext link to the FTP server :-)
}
my $message;
open (ECHOPING, "$main::echoping -v localhost 2>&1 |") || &panic ("Cannot echoping");
my $result = <ECHOPING>;
chop $result;
if ($result) { # Something was wrong
if ($result =~ /Connection refused/) {
$message = "localhost refused echo: egoist!";
#TODO: better explanations
}
else {
$message = "Problem localhost: $result";
}
}
else {
$message = <ECHOPING>;
}
close (ECHOPING);
# Some useful declarations
my $text;
my $results;
my $number;
my $size;
my $delay;
my $frame1 = $top->Frame(-borderwidth => '2m');
$frame1->pack(-fill => 'x');
# Entry field
my $entry = $frame1->Entry(-relief => 'sunken', -width => 45);
my $label = $frame1->Label(-text => 'Enter host name');
$label->pack(-side => 'left');
$entry->pack(-side => 'left');
$entry->insert('insert', $default_host);
$entry->selection ('range', 0, length ($default_host));
$entry->focus;
# I believe the following binding is necessary only on OSF/1?
$entry->bind('<Delete>' => 'Backspace');
# Doit button
my $doit = $frame1->Button(-text => 'Do it',
-command => sub {doit ($top, $entry, $results, $number->get, $size->get, $delay->get, $text)});
$doit->pack(-side => 'left', -fill => 'x', -padx => '2m');
$top->bind ('<Return>' => sub {doit ($top, $entry, $results, $number->get, $size->get, $delay->get, $text)});
my $cancel = $frame1->Button(-text => 'Cancel',
-command => sub {$main::cancel_requested = 1;});
#TODO: Cancel should test if an operation is in progress, otherwise, it will
# be "recorded" for the next time.
$cancel->pack(-side => 'left', -fill => 'x', -padx => '2m');
my $frame2 = $top->Frame(-borderwidth => '2m');
$frame2->pack(-fill => 'x');
#TODO: every number should be in the settings section at the beginning
$number = $frame2->Scale(-from => '1', -to => '10', -orient => 'horizontal', -label => 'Number of connections');
$number->set ('1');
$number->pack (-side => 'top', -fill => 'x');
$size = $frame2->Scale(-from => '1', -to => '1000', '-length' => '500', -orient => 'horizontal', -label => 'Size of packets');
$size->set ('256'); #TODO: finds a way to enter value directly
$size->pack (-side => 'top', -fill => 'x');
$delay = $frame2->Scale(-from => '0', -to => '20', '-length' => '500', -orient => 'horizontal', -label => 'Delay between connections');
$delay->set ('1');
$delay->pack (-side => 'top', -fill => 'x');
my $frame3 = $top->Frame(-borderwidth => '2m');
$frame3->pack (-fill => 'both', -expand => 'yes');
# Status text
$text = $frame3->Label(
-justify => 'center',
-text => "$message",
);
$text->pack(-side => 'top', -fill => 'none', -expand => 'no');
# Results text with scrollbar
#TODO: nice tags and hypertext tags
$results = $frame3->Text(-relief => 'sunken', -state => 'disabled');
my $scrollbar = $frame3->Scrollbar(-command => ['yview', $results]);
$results->configure(-yscrollcommand => ['set', $scrollbar]);
$scrollbar->pack(-side => 'right', -fill => 'y');
$results->pack(-side => 'left', -expand => 'yes', -fill => 'both');
my $frame4 = $top->Frame(-borderwidth => '2m');
$frame4->pack(-fill => 'x');
# Quit button
my $quit = $frame4->Button(-text => 'Quit', -command => sub {exit 0;});
$quit->pack(-side => 'bottom', -fill => 'x');
#TODO: a "clear results" button and a "shrink results"
@main::to_disable = ($entry, $doit, $quit, $number, $size, $delay);
@main::to_mark = ($label, $frame1, $frame2, $frame3, $frame4);
#TODO: better resizing: the Quit button disappears when shrinking
MainLoop;
sub doit {
my ($top_window, $entry, $text, $number, $size, $delay, $label) = @_;
my ($date) = `date`;
my $line;
my $index;
chop $date;
my $host = $entry->get;
&disable (@main::to_disable);
&mark_used (@main::to_mark);
&status ($label, "Looking up $host");
$label->update;
my ($name, $aliases, $addrtype, $length, @addrs) = gethostbyname ($host);
if (! $name) {
$text->configure (-state => 'normal');
$text->insert ('end', "\n----------\nHost $host unknown at $date\n\n");
$text->configure (-state => 'disabled');
&status ($label, "Idle");
&enable (@main::to_disable);
&mark_unused (@main::to_mark);
return;
}
my $address = join ('.', unpack('C4', $addrs[0]));
&status ($label, "Echopinging $name");
my $handle = Tk::IO->open ("$main::echoping -v -n $number -s $size -w $delay $address 2>&1 |") || &panic ("Cannot echoping");
# Some messages to ignore. May be we should check them?
my $garbage = $handle->readline;
$garbage = $handle->readline;
$garbage = $handle->readline;
$text->configure (-state => 'normal');
$text->insert ('end', "\n----------\n$main::echoping of $host ($name [" .
$address . "])\n" .
" (with $size bytes and $delay s interval)\n" .
" at $date:\n");
$text->configure (-state => 'disabled');
while ($line = $handle->readline) {
#TODO: cancel will only be taken into account when there is something to read :-(
# may be more feedback would be good?
if ($main::cancel_requested) {
last; # The only problem is that we lose the last line received
# but the test is here to have more opportunities to
# catch a cancel.
}
if ($line =~ /^Trying to connect to internet address/) {
&status ($label, "Trying to connect");
next;
}
elsif ($line =~ /^Connected/) {
&status ($label, "Connected");
next;
}
elsif ($line =~ /^Sent/) {
&status ($label, "Data sent");
next;
}
elsif ($line =~ /^Checked/) {
&status ($label, "Data received and checked");
next;
}
elsif ($line =~ /^Elapsed time/) {
&status ($label, "Sleeping");
}
$text->configure (-state => 'normal');
$text->insert ('end', $line);
#$text->update;
#TODO: scroll to see the end since it doesn't seem automatic
$text->configure (-state => 'disabled');
}
$text->configure (-state => 'normal');
if ($main::cancel_requested) {
undef $main::cancel_requested;
$text->insert ('end', "\nCancelled by user\n");
}
$handle->close;
$date = `date`;
chop $date;
&status ($label, "Idle");
$text->insert ('end', "Over at $date\n");
$text->configure (-state => 'disabled');
&enable (@main::to_disable);
&mark_unused (@main::to_mark);
}
sub status {
my ($label, $message) = @_;
$label->configure (-text=>"Status: $message");
}
# Disable a list of widgets
sub disable {
my (@widgets) = @_;
my $w;
for $w (@widgets) {
$w->configure (-state=>'disabled', -cursor=>'watch');
}
}
# Enable a list of widgets
sub enable {
my (@widgets) = @_;
my $w;
for $w (@widgets) {
$w->configure (-state=>'normal', -cursor=>'top_left_arrow');
}
}
# Mark a list of widgets as used
sub mark_used {
my (@widgets) = @_;
my $w;
for $w (@widgets) {
$w->configure (-cursor=>'watch');
}
}
# Mark a list of widgets as unused
sub mark_unused {
my (@widgets) = @_;
my $w;
for $w (@widgets) {
$w->configure (-cursor=>'top_left_arrow');
}
}
# The "find_pg" (find program) code has been stolen from "aub"
# and lightly adapted.
sub find_pg {
#
# find_pg: find the specified executable on this machine, if possible.
#
# We try using which first, assuming that if the desired executable is in
# our path, it's the one we want.
#
# If it's not in our path, we try whereis, returning the first program
# whereis names for us which is executable.
#
# If we can't find what we need, we return an empty string.
#
my ($pg) = @_;
my ($ex) = 1;
my ($try, @found);
return $pg if ($pg =~ m/^\//); # Absolute paths know best
chop($try = `which $pg`);
return $try if ($try =~ m/^\//);
chop($try = `whereis $pg`);
if ($try =~ m/^$pg:\s+\//) {
@found = split(/\s/, $try);
$ex++ while (! -x $found[$ex]);
return $found[$ex] unless ($found[$ex] eq "");
}
return "";
}

@ -1,129 +0,0 @@
#include "inet.h"
/* Most of error-handling routines stolen from Stevens' books */
/*
* Recoverable error. Print a message, and return to caller.
*
* err_ret(str, arg1, arg2, ...)
*
* The string "str" must specify the conversion specification for any args.
*/
/* VARARGS1 */
err_ret(va_alist)
va_dcl
{
va_list args;
char *fmt;
va_start(args);
fmt = va_arg(args, char *);
vfprintf(stderr, fmt, args);
va_end(args);
my_perror();
fflush(stdout);
fflush(stderr);
return;
}
/*
* Fatal error. Print a message and terminate. Don't dump core and don't
* print the system's errno value.
*
* err_quit(str, arg1, arg2, ...)
*
* The string "str" must specify the conversion specification for any args.
*/
/* VARARGS1 */
err_quit(va_alist)
va_dcl
{
va_list args;
char *fmt;
va_start(args);
fmt = va_arg(args, char *);
vfprintf(stderr, fmt, args);
fputc('\n', stderr);
va_end(args);
exit(1);
}
/*
* Fatal error related to a system call. Print a message and terminate.
* Don't dump core, but do print the system's errno value and its associated
* message.
*
* err_sys(str, arg1, arg2, ...)
*
* The string "str" must specify the conversion specification for any args.
*/
/* VARARGS1 */
err_sys(va_alist)
va_dcl
{
va_list args;
char *fmt;
va_start(args);
fmt = va_arg(args, char *);
vfprintf(stderr, fmt, args);
va_end(args);
my_perror();
exit(1);
}
my_perror()
{
fprintf(stderr, " %s\n", sys_err_str());
}
usage()
{
fprintf(stderr, "Usage: %s [-v] [-t timeout] [-c] [-d] [-u] [-s size] [-n number] [-w delay] server-name\n", progname);
exit(1);
}
extern int errno; /* Unix error number */
extern int sys_nerr; /* # of error message strings in sys table */
#ifdef __FreeBSD__
#else
extern char *sys_errlist[]; /* the system error message table */
#endif
/*
* Return a string containing some additional operating-system dependent
* information. Note that different versions of UNIX assign different
* meanings to the same value of "errno" (compare errno's starting with 35
* between System V and BSD, for example). This means that if an error
* condition is being sent to another UNIX system, we must interpret the
* errno value on the system that generated the error, and not just send the
* decimal value of errno to the other system.
*/
char *
sys_err_str()
{
static char msgstr[200];
if (errno != 0) {
if (errno > 0 && errno < sys_nerr)
sprintf(msgstr, "(%s)", sys_errlist[errno]);
else
sprintf(msgstr, "(errno = %d)", errno);
} else {
msgstr[0] = '\0';
}
return (msgstr);
}

@ -1,61 +0,0 @@
/*
* Definitions for TCP and UDP client/server programs.
*/
#define VERSION "1.3.0-beta-T/TCP"
#include <stdio.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <varargs.h>
#include <sys/time.h>
#include <errno.h>
#include <unistd.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef SIGALRM /* Linux Slackware... */
#define SIGALRM 14 /* alarm clock timeout */
#endif
#ifndef SIGINT /* Linux Slackware... */
#define SIGINT 2 /* interrupt, generated from terminal special char */
#endif
#ifndef INADDR_NONE
#define INADDR_NONE (-1)
#endif
struct timeval null_timeval;
struct timeval max_timeval;
#define ECHO_TCP_PORT "echo"
#define DISCARD_TCP_PORT "discard"
#define CHARACTER_GENERATOR_TCP_PORT "chargen"
#define USE_ECHO 1
#define USE_DISCARD 2
#define USE_CHARGEN 3
#define CHARGENERATED " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefg";
char *server;
char *sys_err_str();
char *random_string();
double tv2double();
#define DEFLINE 256
#define MAXLINE 1500
#define MAXNUMBER 20
extern char *progname;

@ -1,35 +0,0 @@
/*
* Read a line from a descriptor. Read the line one byte at a time, looking
* for the newline. We store the newline in the buffer, then follow it with
* a null (the same as fgets(3)). We return the number of characters up to,
* but not including, the null (the same as strlen(3)). If ln == 0, we treat
* newline as an ordinary charracter.
*/
int
readline(fd, ptr, maxlen, ln)
int fd;
char *ptr;
int maxlen;
unsigned short ln;
{
int n, rc;
char c;
for (n = 1; n < maxlen; n++) {
if ((rc = read(fd, &c, 1)) == 1) {
*ptr++ = c;
if (c == '\n' && ln == 1)
break;
} else if (rc == 0) {
if (n == 1)
return (0); /* EOF, no data read */
else
break; /* EOF, some data was read */
} else
return (-1); /* error */
}
*ptr = 0;
return (n);
}

@ -1,129 +0,0 @@
#include "inet.h"
#define STATES 32
#include <time.h>
char *
random_string(unsigned length)
{
char *state = (char *) malloc(sizeof(char) * STATES);
char *result = (char *) malloc(length);
int i, number;
unsigned seed = (unsigned) time((time_t *) NULL);
/* printf ("Seed is %u\n", seed); */
/* Initialize random generator */
(void) initstate(seed, state, STATES);
for (i = 0; i < (length - 1); i++) {
number = (random() % 94) + 33;
/* printf ("Number for %d is %d\n", i, number); */
result[i] = (char) number;
}
result[length - 1] = '\0';
/* printf ("Result is %s\n", result); */
return result;
}
/*
* tvsub -- Subtract 2 timeval structs: out = out - in. Out is assumed to be
* >= in. Comes from the bing program.
*/
void
tvsub(out, in)
struct timeval *out, *in;
{
if ((out->tv_usec -= in->tv_usec) < 0) {
--out->tv_sec;
out->tv_usec += 1000000;
}
out->tv_sec -= in->tv_sec;
}
/* tvadd -- Adds 2 timeval structs: out = out + in. */
void
tvadd(out, in)
struct timeval *out, *in;
{
if ((out->tv_usec += in->tv_usec) >= 1000000) {
++out->tv_sec;
out->tv_usec -= 1000000;
}
out->tv_sec += in->tv_sec;
}
/* tvavg -- Averages a timeval struct */
void
tvavg(out, number)
struct timeval *out;
int number;
{
double result;
/*
* out->tv_sec = out->tv_sec/number; out->tv_usec =
* out->tv_usec/number;
*/
result = (1000000 * out->tv_sec + out->tv_usec) / number;
/* printf ("Result of average is %f\n", result) */ ;
out->tv_sec = (long) (result / 1000000);
out->tv_usec = (long) (result - (out->tv_sec * 1000000));
}
/* tvcmp -- Compares two timeval structs */
int
tvcmp(left, right)
struct timeval *left, *right;
{
if (left->tv_sec < right->tv_sec) {
return -1;
}
if (left->tv_sec > right->tv_sec) {
return 1;
}
if (left->tv_usec < right->tv_usec) {
return -1;
}
if (left->tv_usec > right->tv_usec) {
return 1;
}
return 0;
}
/* tvmin */
int
tvmin(champion, challenger)
struct timeval *champion, *challenger;
{
if (tvcmp(champion, challenger) == 1) {
champion->tv_sec = challenger->tv_sec;
champion->tv_usec = challenger->tv_usec;
}
}
/* tvmax */
int
tvmax(champion, challenger)
struct timeval *champion, *challenger;
{
if (tvcmp(champion, challenger) == -1) {
champion->tv_sec = challenger->tv_sec;
champion->tv_usec = challenger->tv_usec;
}
}
double
tv2double(tv)
struct timeval tv;
{
double result;
result = (((((double) tv.tv_sec) * 1000000.0) + (double) tv.tv_usec) / 1000000.0);
/* printf ("Double is %9.3f\n", result); */
return result;
}

@ -1,24 +0,0 @@
/*
* Write "n" bytes to a descriptor. Use in place of write() when fd is a
* stream socket.
*/
int
writen(fd, ptr, nbytes)
register int fd;
register char *ptr;
register int nbytes;
{
int nleft, nwritten;
nleft = nbytes;
while (nleft > 0) {
nwritten = write(fd, ptr, nleft);
if (nwritten <= 0)
return (nwritten); /* error */
nleft -= nwritten;
ptr += nwritten;
}
return (nbytes - nleft);
}
Loading…
Cancel
Save