home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / xc-4.1 / part01 / xcterm.c < prev   
Encoding:
C/C++ Source or Header  |  1993-04-13  |  5.2 KB  |  294 lines

  1. /*    xcterm.c -- terminal mode module for XC
  2.     This file uses 4-character tabstops
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <ctype.h>
  9. #include <signal.h>
  10. #include <setjmp.h>
  11. #include <termio.h>
  12. #include "xc.h"
  13.  
  14. char captfile[SM_BUFF] = CAPTFILE,    /* capture file's name */
  15.      phonefile[SM_BUFF] = PHFILE,    /* phone number file's name */
  16.      ddsname[SM_BUFF];
  17. FILE    *cfp;                /* capture file pointer */
  18. static FILE    *fp;            /* file to transmit */
  19. static child_pid;            /* ID of child process */
  20. static jmp_buf rtm, stop;
  21. static void (*oldvec)();
  22. short    s_flag, capture = FALSE;
  23. extern short autoflag, hdplxflag, nl2cr;
  24. extern get_bound_char();
  25.  
  26. /*  start capturing */
  27. static void 
  28. capt_on(junk)
  29. int junk;
  30. {
  31.     if (capture)
  32.         sprintf(Msg, "Already capturing to \"%s\"", captfile);
  33.     else {
  34.         if (!(cfp = fopen(captfile, "a")))
  35.             sprintf(Msg,"Can't open \"%s\" for capturing",captfile);
  36.         else
  37.             capture = TRUE,
  38.             sprintf(Msg,"Capturing to \"%s\"",captfile),
  39.             setbuf(cfp, NIL(char));
  40.     }
  41.     S2(Msg);
  42.  
  43.     signal(SIGUSR1, capt_on);    /* set signal for next capt_on */
  44. }
  45.  
  46. /*  stop capturing */
  47. static void 
  48. capt_off(junk)
  49. int junk;
  50. {
  51.     if (!capture)
  52.         sprintf(Msg,"Sorry, we haven't been capturing lately");
  53.     else
  54.         fclose(cfp),
  55.         capture = FALSE,
  56.         sprintf(Msg,"\"%s\" closed for capturing",captfile);
  57.  
  58.     S2(Msg);
  59.  
  60.     signal(SIGUSR2, capt_off);    /* set signal for next capt_off */
  61. }
  62.  
  63. /*    cleanup, flush and exit */
  64. static void 
  65. cleanup(junk)
  66. int junk;
  67. {
  68.     if (capture)
  69.         fclose(cfp),
  70.         sprintf(Msg,"\"%s\" closed for capturing",captfile),
  71.         S2(Msg);
  72.  
  73.     exit(0);
  74. }
  75.  
  76. static void 
  77. cisbmode(junk)
  78. int junk;
  79. {
  80.     cismode = 2;
  81.     signal(SIGCLD, SIG_IGN);
  82.     longjmp(rtm,1);
  83. }
  84.  
  85. static void 
  86. end_divert(junk)
  87. int junk;
  88. {
  89.     show_abort();
  90.     fclose(fp);
  91.     signal(SIGINT, oldvec);
  92.     longjmp(stop,1);
  93. }
  94.  
  95. /*    Divert file into input stream, with delay after each newline. */
  96. void 
  97. divert(script)
  98. short script;
  99. {
  100.     int c;
  101.     long i = 1;
  102.  
  103.     if (!script)
  104.         fputc('\r',tfp),
  105.         fputc('\n',tfp),
  106.         show(-1,"File?"),
  107.         getline(),
  108.         getword();
  109.  
  110.     if (word[0] == '\0')
  111.         return;
  112.  
  113.     if (!(fp = fopen(word, "r"))){
  114.         sprintf(Msg,"Can't access '%s'",word);
  115.         S2(Msg);
  116.         return;
  117.     }
  118.  
  119.     oldvec = signal(SIGINT,end_divert);
  120.     if (setjmp(stop))
  121.         return;
  122.  
  123.     while ((c = getc(fp)) != EOF){
  124.         if (c != '\n')
  125.             sendbyte(c),
  126.             i++;
  127.         else {
  128.             sendbyte(nl2cr ? '\r' : '\n');
  129.             /*i = (CBAUD-cbaud)*80 + 4*i + 50; /* season to taste... */
  130.             i *= 3;
  131.             if (script)
  132.                 k_waitfor(-i, "");
  133.             else
  134.                 msecs(i);
  135.             i = 1;
  136.         }
  137.     }
  138.     fclose(fp);
  139.     signal(SIGINT,oldvec);
  140. }
  141.  
  142. /*    Select a script file. */
  143. static 
  144. get_script()
  145. {
  146.     fputc('\r',tfp),
  147.     fputc('\n',tfp);
  148.     show(-1,"Enter script file:");
  149.     fputc(' ',tfp);
  150.     getline();
  151.     if (line[0] == '\0'){
  152.         fputc('\r',tfp),
  153.         fputc('\n',tfp);
  154.         S1("Script file not specified");
  155.         return FAILURE;
  156.     }
  157.     linkflag = FALSE;
  158.     getword();
  159.     sprintf(ddsname,"%s",word);
  160.     return SUCCESS;
  161. }
  162.  
  163. void 
  164. terminal(todir)
  165. short todir;
  166. {
  167.     register c;
  168.     short doneyet_dd = FALSE;
  169.  
  170.  
  171. Reterm:
  172.     if (setjmp(rtm) || doneyet_dd)
  173.         return;
  174.  
  175.     mode(NEWMODE);
  176.     s_flag = FALSE;        /* reset scripting flag */
  177.  
  178.     if (!todir)
  179.         sprintf(Msg, "Entering TERMINAL mode - Escape character is '%s'",
  180.                        unctrl(my_escape)),
  181.         S2(Msg);
  182.  
  183.     /* split into read and write processes */
  184.     if ((child_pid = forkem()) == 0){
  185.         /* child, read proc: read from port and write to tty */
  186.         cfp = NIL(FILE);
  187.         if (autoflag && !todir)
  188.             capt_on(0);
  189.         signal(SIGUSR1, capt_on);
  190.         signal(SIGUSR2, capt_off);
  191.         signal(SIGTERM, cleanup);
  192.  
  193.         while (1){
  194.             while ((c = readbyte(0)) == -1)
  195.                 ;
  196.             if (cismode && c == ENQ)
  197.                 cleanup(0);
  198.  
  199.             fputc(c,tfp);
  200.  
  201.             if (capture && c != '\r')
  202.                 fputc(c,cfp);
  203.         }
  204.         /*NOTREACHED*/
  205.     }
  206.     /* parent, write proc: read from tty and write to port */
  207.     if (cismode)
  208.         signal(SIGCLD, cisbmode);
  209.  
  210.     if (todir)
  211.         goto dialdir;
  212.     do {
  213.         switch (c = get_bound_char()){
  214.         case CAPTYES:        /* signal child to open capture file */
  215.             kill(child_pid, SIGUSR1);
  216.             break;
  217.  
  218.         case CAPTEND:        /* signal child to close capture file */
  219.             kill(child_pid, SIGUSR2);
  220.             break;
  221.  
  222.         case DIVCHAR:        /* divert a file through modem port */
  223.             mode(SIGMODE);
  224.             divert(FALSE);
  225.             mode(NEWMODE);
  226.             break;
  227.     
  228.         case BRKCHAR:
  229.             xmitbrk();
  230.             break;
  231.  
  232.         case HLPCHAR:
  233.             show_bindings();
  234.             break;
  235.  
  236.         case SCRPCHR:        /* execute a script file */
  237.             if (get_script()==FAILURE)
  238.                 break;
  239.  
  240.             /* fall through...  */
  241.  
  242.         case DOSCRPT:        /* named script file */
  243.             s_flag = TRUE;
  244.             goto filicide;
  245.  
  246.         case DIALCHR:        /* select and dial a phone number */
  247. dialdir:
  248.             doneyet_dd = TRUE;
  249.             if ((dial_dir()==FAILURE && todir) || s_flag)
  250.                 goto filicide;
  251.             break;
  252.  
  253.         case ENDCHAR:        /* signal child to cleanup and exit */
  254. filicide:
  255.             c = ENDCHAR;
  256.             signal(SIGCLD, SIG_IGN);
  257.             kill(child_pid, SIGTERM);
  258.             break;
  259.         
  260.         case QUITCHR:
  261.             signal(SIGCLD, SIG_IGN);
  262.             kill(child_pid, SIGTERM);
  263.             s_exit();
  264.             break;
  265.  
  266.         case HUPCHAR:        /* Hangup */
  267.             hangup();
  268.             break;
  269.  
  270.         case '\n':        /* See if NL translation in effect */
  271.             if (nl2cr)
  272.                 c = '\r';
  273.  
  274.         default:    /* just send the character to the port */
  275.             sendbyte(c);
  276.             if (hdplxflag)
  277.                 fputc(c,tfp);
  278.             break;
  279.         }
  280.         todir = FALSE;
  281.     } while (c != ENDCHAR);
  282.  
  283.     while (wait(NIL(int)) >= 0)    /* wait for the read process to die */
  284.         ;
  285.  
  286.     if (s_flag){
  287.         mode(SIGMODE);
  288.         do_script(ddsname);
  289.         goto Reterm;
  290.     }
  291.  
  292.     reterm = FALSE;
  293. }
  294.