home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
WADS of WADS
/
WadsOfWads.1994.zip
/
UNSORTED
/
IHHD.ZIP
/
dialer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-20
|
7KB
|
338 lines
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <sgtty.h>
#include <signal.h>
#include <time.h>
/*
* udpdialer - talk to a switch and remote dialer.
*
* usage: udpdialer [ -e escape_char ] [ -l logfile ] [ -s ] [ -rp port ] [ -lp port ] host
*
* ARGUMENTS
* -e escape_char Change escape character, enter as numeric value of the
* character, use '\01' to set it to CNTRL-A
* -l logfile Log data transfer to logfile.out and logfile.in.
* -s Generate I/O stats when done.
* -lp port Local port number to use.
* -rp port Port number to use when on remote host.
* host Remote host to contact.
*
* Terminate using by typing ^C^C^C (three control-Cs).
*/
static char* sccsid = "@(#)dialer.c 1.9 10/29/93";
#define MOUTHPIECE 0
#define MAXPKTSIZE 1024
#define ON 1
#define OFF 0
#define CTRLC '\003'
FILE* outputlogf = NULL;
FILE* inputlogf = NULL;
struct sockaddr_in datagram;
struct sgttyb saved_tty;
time_t start_time = 0;
char* program;
char* remotehost = NULL;
char* logfile = NULL;
char packet[MAXPKTSIZE];
char escape_char = CTRLC;
short remoteport = 6123;
short localport = 6123;
short statistics = 0;
int pktcount = 0;
int minpktsize = MAXPKTSIZE + 1;
int maxpktsize = 0;
int totalsize = 0;
int sock;
void terminate();
void sig_child_handler();
main(argc, argv)
int argc;
char** argv;
{
program = *argv;
for (argc--, argv++; argc; argc--, argv++) {
if (!strcmp(*argv, "-rp")) {
remoteport = atoi(*(argv+1));
argc--;
argv++;
}
else if (!strcmp(*argv, "-lp")) {
localport = atoi(*(argv+1));
argc--;
argv++;
}
else if (!strcmp(*argv, "-e")) {
argv++;
argc--;
escape_char = atoi(*argv) && 0xff;
fprintf(stderr, "escape char set to %d\n",escape_char);
}
else if (!strcmp(*argv, "-l")) {
logfile = *(argv+1);
argv++;
argc--;
}
else if (!strcmp(*argv, "-s")) {
statistics = 1;
}
else if (!strncmp(*argv, "-", 1)) {
fprintf(stderr, "usage: dialer [ -e escape_char ] [ -l logfile ] [ -s ] [ -rp port ] [ -lp port ] host \n");
exit(1);
}
else {
remotehost = *argv;
break;
}
}
/* verify proper mode */
if ( !remotehost ) {
fprintf(stderr, "usage: dialer [ -s ] [ -rp port ] [ -lp port ] host \n");
exit(1);
}
init_socket();
init_datagram(remotehost, remoteport);
save_tty_settings();
raw();
echo(OFF);
/* the following never return */
if (make_handset() == MOUTHPIECE) {
signal(SIGTERM, terminate);
do_mouthpiece();
}
else {
/* when mouthpiece dies, we should too */
signal(SIGCHLD, sig_child_handler);
do_earpiece();
}
exit(0);
}
/* this socket will be used for both sending and receiving */
init_socket() {
struct sockaddr_in name;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
perror("opening datagram socket");
exit(2);
}
/* bind it */
name.sin_family = AF_INET;
name.sin_addr.s_addr = INADDR_ANY;
name.sin_port = htons(localport);
if (bind(sock, (struct sockaddr*)&name, sizeof name) < 0) {
perror("binding datagram socket");
exit(2);
}
}
/* setup the the socket structure for sending datagrams to the remote site */
init_datagram(hostname, port)
char* hostname;
short port;
{
struct hostent* hp;
if (!(hp = gethostbyname(hostname))) {
fprintf(stderr, "%s: unknown host\n", hostname);
exit(2);
}
bcopy((char*)hp->h_addr, (char*)&datagram.sin_addr, hp->h_length);
datagram.sin_family = AF_INET;
datagram.sin_port = htons(port);
}
/* create a reader process */
make_handset() {
/*
* The reader process reads the tty and sends the data
* to the remote host.
*/
int pid = fork();
if (pid < 0) {
perror("forking reader process");
exit(3);
}
return pid;
}
do_mouthpiece() {
struct timeval tv;
int bytecount;
int endsequence = 0;
char logname[1024];
/* logfile prep */
if (logfile) {
strcpy(logname, logfile);
strcat(logname, ".out");
outputlogf = fopen(logname, "w");
}
/* record starting time */
time(&start_time);
while (1) {
/* keep delay between read/write to a minimum! */
bytecount = read(0, packet, 1024);
if (bytecount) {
if (sendto(sock, packet, bytecount, 0,
(struct sockaddr*)&datagram, sizeof datagram) < 0)
perror("sending datagram message");
/* log data */
if (outputlogf) {
gettimeofday(&tv, NULL);
fwrite(&tv, sizeof(tv), 1, outputlogf);
fwrite(&bytecount, sizeof(bytecount), 1, outputlogf);
fwrite(packet, sizeof(char), bytecount, outputlogf);
}
if (bytecount == 1 && (packet[0]&0177) == escape_char) {
if (++endsequence == 3)
terminate();
}
else
endsequence = 0;
/* statistics generation */
pktcount++;
totalsize += bytecount;
if (bytecount < minpktsize) minpktsize = bytecount;
else if (bytecount > maxpktsize) maxpktsize = bytecount;
}
}
}
do_earpiece() {
struct timeval tv;
int bytecount;
char logname[1024];
/* logfile prep */
if (logfile) {
strcpy(logname, logfile);
strcat(logname, ".in");
inputlogf = fopen(logname, "w");
}
while (1) {
bytecount = read(sock, packet, 1024);
write(1, packet, bytecount);
/* log data */
if (inputlogf) {
gettimeofday(&tv, NULL);
fwrite(&tv, sizeof(tv), 1, inputlogf);
fwrite(&bytecount, sizeof(bytecount), 1, inputlogf);
fwrite(packet, sizeof(char), bytecount, inputlogf);
}
}
}
/* save the original tty settings */
save_tty_settings() {
gtty(0, &saved_tty);
}
/* restore the original tty settings */
restore_tty_settings() {
stty(0, &saved_tty);
}
/* place the terminal in raw mode */
raw() {
struct sgttyb tty;
gtty(0, &tty);
tty.sg_flags |= RAW;
stty(0, &tty);
}
/* place the terminal in cooked mode */
cooked() {
struct sgttyb tty;
gtty(0, &tty);
tty.sg_flags &= ~RAW;
stty(0, &tty);
}
echo(on)
int on;
{
struct sgttyb tty;
gtty(0, &tty);
if (on) {
tty.sg_flags |= ECHO;
}
else
tty.sg_flags &= ~ECHO;
stty(0, &tty);
}
void sig_child_handler() {
restore_tty_settings();
if (outputlogf)
fclose(outputlogf);
if (inputlogf)
fclose(inputlogf);
exit(0);
}
void terminate() {
time_t time_diff = time(0) - start_time;
if (outputlogf)
fclose(outputlogf);
if (inputlogf)
fclose(inputlogf);
/* report statistics */
if (statistics) {
printf("%d packets, %d bytes, %d/%d/%d min/avg/max pkt size\r\n",
pktcount, totalsize, minpktsize, totalsize/pktcount,
maxpktsize);
if (time_diff)
printf("%d seconds, %g pkt/s, %d b/s\r\n",
time_diff, (float)pktcount / (float)time_diff,
totalsize/time_diff);
}
exit(0);
}