home *** CD-ROM | disk | FTP | other *** search
/ WADS of WADS / WadsOfWads.1994.zip / UNSORTED / IHHD.ZIP / dialer.c < prev    next >
C/C++ Source or Header  |  1994-02-20  |  7KB  |  338 lines

  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. #include <sys/time.h>
  4. #include <netinet/in.h>
  5. #include <netdb.h>
  6. #include <stdio.h>
  7. #include <sgtty.h>
  8. #include <signal.h>
  9. #include <time.h>
  10.  
  11. /*
  12.  * udpdialer - talk to a switch and remote dialer.
  13.  *
  14.  * usage: udpdialer [ -e escape_char ] [ -l logfile ] [ -s ] [ -rp port ] [ -lp port ] host
  15.  * 
  16.  * ARGUMENTS
  17.  * -e escape_char Change escape character, enter as numeric value of the
  18.  *            character, use '\01' to set it to CNTRL-A
  19.  * -l logfile    Log data transfer to logfile.out and logfile.in.
  20.  * -s        Generate I/O stats when done.
  21.  * -lp port    Local port number to use.
  22.  * -rp port    Port number to use when on remote host.
  23.  * host        Remote host to contact.
  24.  *
  25.  * Terminate using by typing ^C^C^C (three control-Cs).
  26.  */
  27.  
  28. static char* sccsid = "@(#)dialer.c    1.9    10/29/93";
  29.  
  30. #define MOUTHPIECE    0
  31. #define MAXPKTSIZE    1024
  32. #define ON        1
  33. #define OFF        0
  34. #define CTRLC        '\003'
  35.  
  36. FILE* outputlogf = NULL;
  37. FILE* inputlogf = NULL;
  38. struct sockaddr_in datagram;
  39. struct sgttyb saved_tty;
  40. time_t start_time = 0;
  41. char* program;
  42. char* remotehost = NULL;
  43. char* logfile = NULL;
  44. char packet[MAXPKTSIZE];
  45. char escape_char = CTRLC;
  46. short remoteport = 6123;
  47. short localport = 6123;
  48. short statistics = 0;
  49. int pktcount = 0;
  50. int minpktsize = MAXPKTSIZE + 1;
  51. int maxpktsize = 0;
  52. int totalsize = 0;
  53. int sock;
  54.  
  55. void terminate();
  56. void sig_child_handler();
  57.  
  58. main(argc, argv)
  59.     int     argc;
  60.     char**    argv;
  61. {
  62.  
  63.     program = *argv;
  64.  
  65.     for (argc--, argv++; argc; argc--, argv++) {
  66.         if (!strcmp(*argv, "-rp")) {
  67.             remoteport = atoi(*(argv+1));
  68.             argc--;
  69.             argv++;
  70.         }
  71.         else if (!strcmp(*argv, "-lp")) {
  72.             localport = atoi(*(argv+1));
  73.             argc--;
  74.             argv++;
  75.         }
  76.         else if (!strcmp(*argv, "-e")) {
  77.             argv++;
  78.             argc--;
  79.             escape_char = atoi(*argv) && 0xff;
  80.             fprintf(stderr, "escape char set to %d\n",escape_char);
  81.         }
  82.         else if (!strcmp(*argv, "-l")) {
  83.             logfile = *(argv+1);
  84.             argv++;
  85.             argc--;
  86.         }
  87.         else if (!strcmp(*argv, "-s")) {
  88.             statistics = 1;
  89.         }
  90.         else if (!strncmp(*argv, "-", 1)) {
  91.             fprintf(stderr, "usage: dialer [ -e escape_char ] [ -l logfile ] [ -s ] [ -rp port ] [ -lp port ] host \n");
  92.             exit(1);
  93.         }
  94.         else {
  95.             remotehost = *argv;
  96.             break;
  97.         }
  98.     }
  99.  
  100.     /* verify proper mode */
  101.     if ( !remotehost ) {
  102.         fprintf(stderr, "usage: dialer [ -s ] [ -rp port ] [ -lp port ] host \n");
  103.         exit(1);
  104.     }
  105.  
  106.     init_socket();
  107.     init_datagram(remotehost, remoteport);
  108.  
  109.     save_tty_settings();
  110.     raw();
  111.     echo(OFF);
  112.  
  113.     /* the following never return */
  114.     if (make_handset() == MOUTHPIECE) {
  115.         signal(SIGTERM, terminate);
  116.         do_mouthpiece();
  117.     }
  118.     else {
  119.         /* when mouthpiece dies, we should too */
  120.         signal(SIGCHLD, sig_child_handler);
  121.  
  122.         do_earpiece();
  123.     }
  124.  
  125.     exit(0);
  126. }
  127.  
  128. /* this socket will be used for both sending and receiving */
  129. init_socket() {
  130.  
  131.     struct sockaddr_in name;
  132.  
  133.     sock = socket(AF_INET, SOCK_DGRAM, 0);
  134.     if (sock < 0) {
  135.         perror("opening datagram socket");
  136.         exit(2);
  137.     }
  138.  
  139.     /* bind it */
  140.     name.sin_family = AF_INET;
  141.     name.sin_addr.s_addr = INADDR_ANY;
  142.     name.sin_port = htons(localport);
  143.     if (bind(sock, (struct sockaddr*)&name, sizeof name) < 0) {
  144.         perror("binding datagram socket");
  145.         exit(2);
  146.     }
  147. }
  148.  
  149. /* setup the the socket structure for sending datagrams to the remote site */
  150. init_datagram(hostname, port)
  151.     char* hostname;
  152.     short port;
  153. {
  154.  
  155.     struct hostent* hp;
  156.  
  157.     if (!(hp = gethostbyname(hostname))) {
  158.         fprintf(stderr, "%s: unknown host\n", hostname);
  159.         exit(2);
  160.     }
  161.  
  162.     bcopy((char*)hp->h_addr, (char*)&datagram.sin_addr, hp->h_length);
  163.     datagram.sin_family = AF_INET;
  164.     datagram.sin_port = htons(port);
  165. }
  166.  
  167. /* create a reader process */
  168. make_handset() {
  169.  
  170.     /*
  171.      * The reader process reads the tty and sends the data
  172.      * to the remote host.
  173.      */
  174.  
  175.     int pid = fork();
  176.     if (pid < 0) {
  177.         perror("forking reader process");
  178.         exit(3);
  179.     }
  180.  
  181.     return pid;
  182. }
  183.  
  184. do_mouthpiece() {
  185.  
  186.     struct timeval tv;
  187.     int bytecount;
  188.     int endsequence = 0;
  189.     char logname[1024];
  190.  
  191.     /* logfile prep */
  192.     if (logfile) {
  193.         strcpy(logname, logfile);
  194.         strcat(logname, ".out");
  195.         outputlogf = fopen(logname, "w");
  196.     }
  197.  
  198.     /* record starting time */
  199.     time(&start_time);
  200.  
  201.     while (1) {
  202.         /* keep delay between read/write to a minimum! */
  203.         bytecount = read(0, packet, 1024);
  204.         if (bytecount) {
  205.             if (sendto(sock, packet, bytecount, 0,
  206.                    (struct sockaddr*)&datagram, sizeof datagram) < 0)
  207.                 perror("sending datagram message");
  208.  
  209.             /* log data */
  210.             if (outputlogf) {
  211.                 gettimeofday(&tv, NULL);
  212.                 fwrite(&tv, sizeof(tv), 1, outputlogf);
  213.                 fwrite(&bytecount, sizeof(bytecount), 1, outputlogf);
  214.                 fwrite(packet, sizeof(char), bytecount, outputlogf);
  215.             }
  216.  
  217.             if (bytecount == 1 && (packet[0]&0177) == escape_char) {
  218.                 if (++endsequence == 3)
  219.                     terminate();
  220.             }
  221.             else
  222.                 endsequence = 0;
  223.  
  224.             /* statistics generation */
  225.             pktcount++;
  226.             totalsize += bytecount;
  227.             if (bytecount < minpktsize) minpktsize = bytecount;
  228.             else if (bytecount > maxpktsize) maxpktsize = bytecount;
  229.         }
  230.     }
  231. }
  232.  
  233. do_earpiece() {
  234.  
  235.     struct timeval tv;
  236.     int bytecount;
  237.     char logname[1024];
  238.  
  239.     /* logfile prep */
  240.     if (logfile) {
  241.         strcpy(logname, logfile);
  242.         strcat(logname, ".in");
  243.         inputlogf = fopen(logname, "w");
  244.     }
  245.  
  246.     while (1) {
  247.         bytecount = read(sock, packet, 1024);
  248.         write(1, packet, bytecount);
  249.  
  250.         /* log data */
  251.         if (inputlogf) {
  252.             gettimeofday(&tv, NULL);
  253.             fwrite(&tv, sizeof(tv), 1, inputlogf);
  254.             fwrite(&bytecount, sizeof(bytecount), 1, inputlogf);
  255.             fwrite(packet, sizeof(char), bytecount, inputlogf);
  256.         }
  257.     }
  258. }
  259.  
  260. /* save the original tty settings */
  261. save_tty_settings() {
  262.     gtty(0, &saved_tty);
  263. }
  264.  
  265. /* restore the original tty settings */
  266. restore_tty_settings() {
  267.     stty(0, &saved_tty);
  268. }
  269.  
  270. /* place the terminal in raw mode */
  271. raw() {
  272.     struct sgttyb tty;
  273.  
  274.     gtty(0, &tty);
  275.     tty.sg_flags |= RAW;
  276.     stty(0, &tty);
  277. }
  278.  
  279. /* place the terminal in cooked mode */
  280. cooked() {
  281.     struct sgttyb tty;
  282.  
  283.     gtty(0, &tty);
  284.     tty.sg_flags &= ~RAW;
  285.     stty(0, &tty);
  286. }
  287.  
  288. echo(on) 
  289.     int on;
  290. {
  291.  
  292.     struct sgttyb tty;
  293.  
  294.     gtty(0, &tty);
  295.     if (on) {
  296.         tty.sg_flags |= ECHO;
  297.     }
  298.     else
  299.         tty.sg_flags &= ~ECHO;
  300.  
  301.     stty(0, &tty);
  302. }
  303.  
  304. void sig_child_handler() {
  305.  
  306.     restore_tty_settings();
  307.  
  308.     if (outputlogf)
  309.         fclose(outputlogf);
  310.     if (inputlogf)
  311.         fclose(inputlogf);
  312.  
  313.     exit(0);
  314. }
  315.  
  316. void terminate() {
  317.  
  318.     time_t time_diff = time(0) - start_time;
  319.  
  320.     if (outputlogf)
  321.         fclose(outputlogf);
  322.     if (inputlogf)
  323.         fclose(inputlogf);
  324.  
  325.     /* report statistics */
  326.     if (statistics) {
  327.         printf("%d packets, %d bytes, %d/%d/%d min/avg/max pkt size\r\n",
  328.             pktcount, totalsize, minpktsize, totalsize/pktcount, 
  329.             maxpktsize);
  330.         if (time_diff)
  331.             printf("%d seconds, %g pkt/s, %d b/s\r\n",
  332.                 time_diff, (float)pktcount / (float)time_diff, 
  333.                 totalsize/time_diff);
  334.     }
  335.  
  336.     exit(0);
  337. }
  338.