home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / s / seyon197.tz / seyon197 / seyon / SeTerm.c < prev    next >
C/C++ Source or Header  |  1993-02-16  |  5KB  |  229 lines

  1. /*
  2.  * This file is part of the Seyon, Copyright (c) 1992-1993 by Muhammad M.
  3.  * Saggaf. All rights reserved.
  4.  *
  5.  * See the file COPYING (1-COPYING) or the manual page seyon(1) for a full
  6.  * statement of rights and permissions for this program.
  7.  */
  8.  
  9. /*
  10.  * This file contains routines for Seyon's terminal. The main routine is
  11.  * terminal(), which reads characters from the terminal and sends them to the
  12.  * port. That routine also forks a child process that reads characters from
  13.  * the port and writes them to the temrinal. Once the parent receives SIGTERM
  14.  * (which should be sent by the grand parent), it kills the child and exits.
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <unistd.h>
  19. #include <signal.h>
  20. #include <sys/types.h>
  21. #include <sys/wait.h>
  22.  
  23. #include <X11/Intrinsic.h>
  24.  
  25. #include "seyon.h"
  26. #include "SeDecl.h"
  27.  
  28. extern int readStr();
  29.  
  30. extern FILE    *tfp,        /* terminal pointer */
  31.                *cfp;        /* capture file pointer */
  32. extern Boolean  capture;    /* are we capturing or not ? */
  33.  
  34. void            send_tbyte(),
  35.                 toggle(),
  36.                 cleanup();
  37.  
  38. pid_t           term_pid = 0,    /* pid of the terminal subprocess */
  39.                 read_pid = 0;    /* pid of child process */
  40.  
  41. void
  42. term_exit(dummy)
  43.      int             dummy;
  44. {
  45.   /* Once the signal is received and we're outside the loop, disable catching
  46.      the signal */
  47.   signal(SIGTERM, SIG_IGN);
  48.  
  49.   /* Kill the child process and wait for it to die, sounds vicious, 
  50.      doesn't it? The child process is the read process from the port */
  51.   if (read_pid) {
  52.     kill(read_pid, SIGTERM);
  53.     while (wait((int *)0) >= 0);
  54.   }
  55.  
  56.   exit(0);
  57. }
  58.  
  59. /*
  60.  * main routine. has two processes one to read from terminal and send to the
  61.  * port and the other to do the oppsite.
  62.  */
  63.  
  64. void
  65. terminal()
  66. {
  67.   /* Tell the program where to go when SIGTERM is received */
  68.   signal(SIGTERM, term_exit);
  69.  
  70.   term_pid = getpid();
  71.  
  72.   /* Split into read and write processes */
  73.  
  74.   /* Child, read proc: read from port and write to tty */
  75.   if ((read_pid = se_fork()) == 0)
  76.     PortToTty();
  77.  
  78.   /* Parent, write proc: read from tty and write to port */
  79.   while (1)
  80.     send_tbyte(coninp());
  81. }
  82.  
  83. /*
  84.  * send a translated character to the modem
  85.  */
  86.  
  87. void
  88. send_tbyte(c)
  89.      int             c;
  90. {
  91.   switch (c) {
  92.  
  93.     /*Translate new line to carriage return if newline translation mode is
  94.       in effect*/
  95.   case '\n':
  96.     switch (newlineTrMode) {
  97.     case 2:
  98.       c = '\r';
  99.       break;
  100.     case 3:
  101.       sendbyte('\r');
  102.     default:
  103.       break;
  104.     }
  105.     break;
  106.  
  107.     /*Translate backspace to delete if del translation mode is in effect*/
  108.   case 0x08:
  109.     if (qres.backspaceTranslation)
  110.       c = 0x7f;
  111.     break;
  112.  
  113.   default:
  114.     break;
  115.   }
  116.  
  117.   /*Send ESC before the character if meta key is pressed with the  character
  118.     and the meta key translation mode is on*/
  119.   if (qres.metaKeyTranslation && (c & 0x80)) {
  120.     sendbyte('\033');
  121.     sendbyte(c);
  122.   }
  123.  
  124.   /*Send the character to the port*/
  125.   else
  126.     sendbyte(c);
  127. }
  128.  
  129. /*
  130.  * Cleanup, flush and exit
  131.  */
  132.  
  133. void
  134. cleanup()
  135. {
  136.   fflush(tfp);
  137.   exit(0);
  138. }
  139.  
  140. /*
  141.  * Read from the port and write to the tty
  142.  */
  143.  
  144. void
  145. PortToTty()
  146. {
  147.   static char           zmSig[] = "**\030B00";
  148.   static char          *zmSigPtr = zmSig;
  149.   char                  buf[BUFSIZ], c;
  150.   int                   n, i;
  151.  
  152.   signal(SIGTERM, cleanup);
  153.  
  154.   while (1) {
  155.  
  156.     /* Read incoming charaters and exit the process if a read error
  157.        is encountered */
  158.     if ((n = readStr(buf)) < 0) {
  159.       se_error("Read error. Terminal process exiting");
  160.       se_notice("Use REFRESH to restart");
  161.       write_child_info(child_pipe, KILL_TERM, "Terminal Proc Exited");
  162.       exit(0);
  163.     }
  164.  
  165.     /* Write incoming characters to the tty */
  166.     fwrite(buf, sizeof(char), n, tfp); 
  167.     fflush(tfp);
  168.  
  169.     for(i = 0; i < n; i++) {
  170.       c = buf[i];
  171.       
  172.       /* Write to capture file if capture is enabled */
  173.       if (capture /*&& c != '\r'*/)
  174.         fputc(c, cfp);
  175.  
  176.       /* Look for Zmodem signature */
  177.       if (c != *zmSigPtr)
  178.         zmSigPtr = zmSig;
  179.       else if (*++zmSigPtr == '\0' && qres.zmodemAutoDownload) {
  180.         write_child_info(child_pipe, START_AUTO_ZM, "Zmodem Auto-Download");
  181.         exit(0);
  182.       }
  183.     } /* for... */
  184.   }    /* while(1)... */
  185.   /*NOT REACHED*/
  186. }
  187.  
  188. /*
  189.  * Start the terminal process
  190.  */
  191.  
  192. void
  193. start_terminal()
  194. {
  195.   if (!term_pid)
  196.     if ((term_pid = se_fork()) == 0) {
  197.       terminal();
  198.       exit(0);
  199.     }
  200. }
  201.  
  202. /*
  203.  * Kill the terminal process
  204.  */
  205.  
  206. void
  207. kill_terminal()
  208. {
  209.   if (term_pid) {
  210.     kill(term_pid, SIGTERM);
  211.  
  212.     /*Wait for the child to die*/
  213.     wait((int *)0);
  214.     term_pid = 0;
  215.   }
  216. }
  217.  
  218. /*
  219.  * Restart the terminal process (refresh) by killing it and starting a new
  220.  * one
  221.  */
  222.  
  223. void
  224. restart_terminal()
  225. {
  226.   kill_terminal();
  227.   start_terminal();
  228. }
  229.