home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / t / tel2305s.zip / ENGINE / LINEMODE.C < prev    next >
C/C++ Source or Header  |  1992-04-09  |  16KB  |  354 lines

  1. /*
  2. *   linemode.c
  3. *
  4. *   Linemode Specific functions
  5. *
  6. *   Quincey Koziol
  7. *
  8. *    Date        Notes
  9. *    --------------------------------------------
  10. *   2/92       Started
  11. */
  12.  
  13. /*
  14. * Includes
  15. */
  16. #ifdef __TURBOC__
  17. #include "turboc.h"
  18. #endif
  19. #ifdef MOUSE
  20. #include "mouse.h"
  21. #endif
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <stdio.h>
  25. #include <fcntl.h>
  26. #include <ctype.h>
  27. #include <direct.h>
  28. #include <time.h>
  29. #include <conio.h>
  30. #include <process.h>
  31. #include <stdarg.h>
  32. #include <bios.h>
  33. #ifdef MSC
  34. #include <malloc.h>
  35. #endif
  36. #ifdef CHECKNULL
  37. #include <dos.h>
  38. #endif
  39.  
  40. #include "whatami.h"
  41. #include "nkeys.h"
  42. #include "windat.h"
  43. #include "hostform.h"
  44. #include "protocol.h"
  45. #include "data.h"
  46. #include "confile.h"
  47. #include "telopts.h"
  48. #include "externs.h"
  49.  
  50. /*
  51. * Macro definitions
  52. */
  53. #define MAX_LINE_LEN        79
  54.  
  55. /*
  56. * Static function declarations
  57. */
  58. static int LMissep(int );
  59.  
  60. /*
  61. * Static variable declarations
  62. */
  63. static char bk[]={8,' ',8};
  64.  
  65. /**********************************************************************
  66. *  Function :   LMissep()
  67. *  Purpose  :   Checks if a character is a word seperator for line mode
  68. *               word checking.
  69. *  Parameters   :
  70. *           c - the character to check
  71. *  Returns  :   (1) for the character is a word seperator, (0) for false
  72. *  Calls    :   none
  73. *  Called by    :   LMgets()
  74. **********************************************************************/
  75. static int LMissep(int c)
  76. {
  77.     if(isspace(c) || c=='_' || c=='*' || c=='!')
  78.         return(1);
  79.     return(0);
  80. }
  81.  
  82. /**********************************************************************
  83. *  Function :   LMgets()
  84. *  Purpose  :   Non-blocking gets(),  This routine will continually add
  85. *               to a string that is re-submitted until a special
  86. *               character is hit.  It never block the network from
  87. *               being serviced.
  88. *               This routine is structurally similar to RSgets() (in rspc.c)
  89. *               except that it uses the currently defined line mode
  90. *               editting characters instead of hard-wiring backspace,etc.
  91. *  Parameters   :
  92. *           t - the telnet window structure
  93. *  Returns  :   none
  94. *  Calls    :
  95. *  Called by    :   newkey()
  96. **********************************************************************/
  97. int LMgets(struct twin *t)
  98. {
  99.     int lm_char,        /* whether the character was handled by a linemode special character */
  100.         echo,           /* whether to echo the characters typed */
  101.         vs,             /* the virtual screen this telnet session is attached to */
  102.         c,              /* the character typed */
  103.         count,          /* the length of the line */
  104.         line_len,       /* length of the line before we start erasing words */
  105.         found_sep,      /* flag for end of word movements when editting line mode stuff */
  106.         found_nonsep;   /* flag for word movements when editting line mode stuff */
  107.     char *save,
  108.         *s;             /* pointer to the end of the line */
  109.     int i;              /* local counting variable */
  110.  
  111.     vs=t->vs;           /* get the virtual screen */
  112.     echo=!t->echo;      /* get the echo status */
  113.  
  114.     count=strlen(t->linemode);  /* set up the string variables */
  115.     save=t->linemode;
  116.     s=save+count;
  117.  
  118.     while(0<(c=n_chkchar())) {
  119.         lm_char=0;
  120.         if(t->litflag) {    /* check if the "literal character" flag is on */
  121.             if(c>31 && c<127) { /* check for printable ASCII */
  122.                 if(echo)
  123.                     VSwrite(vs,(char *)&c,1);
  124.               } /* end if */
  125.             else {
  126.                 if(c>0 && c<27) {   /* print ASCII control char */
  127.                     if(echo) {
  128.                         if(t->litecho)  /* check for a literal echo of the character */
  129.                             VSwrite(vs,(char *)&c,1);
  130.                         else {
  131.                             c+=64;
  132.                             VSwrite(vs,"^",1);
  133.                             VSwrite(vs,(char *)&c,1);
  134.                             c-=64;
  135.                           } /* end if */
  136.                       } /* end if */
  137.                   } /* end if */
  138.               } /* end else */
  139.             *s++=(char)c;       /* add to string */
  140.             count++;            /* length of string */
  141.             t->litflag=0;       /* reset the literal flag */
  142.  
  143.             continue;           /* don't try to do anything else with the character */
  144.           } /* end if */
  145.         if(c==BACKSPACE || c==t->slc[SLC_EC]) { /* check for an "erase character" character */
  146. #ifdef QAK
  147. tprintf(console->vs,"erasing a character\r\n");
  148. #endif
  149.             if(count) {
  150.                 if(echo)
  151.                     VSwrite(vs,bk,3);
  152.                 count--;        /* one less character */
  153.                 s--;            /* move pointer backward */
  154.               } /* end if */
  155.             lm_char=1;  /* set the flag so we avoid the large switch */
  156.           } /* end if */
  157.         if(c==t->slc[SLC_EL]) { /* check for an "erase line" character */
  158.             if(echo)
  159.                 for(i=0; i<s-save; i++)
  160.                     VSwrite(vs,bk,3);
  161.             s=save;
  162.             lm_char=1;  /* set the flag so we avoid the large switch */
  163.           } /* end if */
  164.         if(c==t->slc[SLC_EW]) { /* check for an "erase word" character */
  165. #ifdef QAK
  166. tprintf(console->vs,"erasing a word, s=%p\r\n",s);
  167. #endif
  168.             if(count) {
  169.                 found_sep=0;    /* set the flag to indicate that we found another word seperator */
  170.                 found_nonsep=0; /* set the flag to indicate we haven't found any non-seperators yet */
  171.                 line_len=s-save;
  172.                 s--;            /* back to to the previous character */
  173.                 for(i=0; i<line_len; i++) {
  174.                     if(LMissep(*s)) {   /* this is a line mode seperator */
  175.                         if(found_nonsep) {  /* if we've actually erased part of a word, stop now */
  176.                             found_sep=1;    /* indicate we found another word seperator */
  177.                             s++;    /* move to the character after the seperator */
  178.                             break;
  179.                           } /* end if */
  180.                       } /* end if */
  181.                     else {
  182.                         if(!found_nonsep)   /* check if we've previous found a word seperator */
  183.                             found_nonsep=1;
  184.                       } /* end if */
  185.                     if(echo)
  186.                         VSwrite(vs,bk,3);
  187.                     count--;        /* one less character */
  188.                     s--;            /* move pointer backward */
  189.                   } /* end for */
  190.               } /* end if */
  191.             if(!found_sep)  /* check for a word seperator found */
  192.                 s=save;
  193. #ifdef QAK
  194. tprintf(console->vs,"done erasing a word, s=%p\r\n",s);
  195. #endif
  196.             lm_char=1;  /* set the flag so we avoid the large switch */
  197.           } /* end if */
  198.         if(!lm_char) {  /* check if this character was already handled by a line mode special character */
  199.             switch(c) {                 /* allow certain editing chars */
  200. #ifndef OLD_WAY
  201.                 case 13:
  202.                 case 9:
  203.                 case TAB:
  204.                     *s='\0';            /* terminate the string */
  205.                     return(c);
  206. #else
  207.  
  208.                 case TAB:       /* check if we are doing local tab expansion */
  209.                 case 9:
  210.                     if(t->softtab) {    /* check whether we are supposed to expand this tab */
  211.                       } /* end if */
  212.                     else {
  213.                       } /* end else */
  214.                     break;
  215.  
  216.                 case 13:
  217.                     *s='\0';            /* terminate the string */
  218.                     return(c);
  219. #endif
  220.                 default:
  221.                     if(count==MAX_LINE_LEN) {            /* to length limit */
  222.                         RSbell(vs);
  223.                         *s='\0';                /* terminate */
  224.                         return(0);
  225.                       } /* end if */
  226.                     if(c>31 && c<127) { /* check for printable ASCII */
  227.                         if(echo)
  228.                             VSwrite(vs,(char *)&c,1);
  229.                         *s++=(char)c;           /* add to string */
  230.                         count++;                /* length of string */
  231.                       } /* end if */
  232.                     else {
  233.                         if(c>0 && c<27) {   /* print ASCII control char */
  234.                             if(echo) {
  235.                                 if(t->litecho)  /* check if we are supposed to echo this echo literally */
  236.                                     VSwrite(vs,(char *)&c,1);
  237.                                 else {
  238.                                     c+=64;
  239.                                     VSwrite(vs,"^",1);
  240.                                     VSwrite(vs,(char *)&c,1);
  241.                                     c-=64;
  242.                                   } /* end else */
  243.                               } /* end if */
  244.                           } /* end if */
  245.                         *s='\0';            /* terminate the string */
  246.                         return(c);
  247.                       } /* end else */
  248.                 break;
  249.               } /* end switch */
  250.           } /* end if */
  251.       } /* end while */
  252.     *s='\0';            /* terminate the string */
  253.     return(c);
  254. }   /* end LMgets() */
  255.  
  256. /**********************************************************************
  257. *  Function :   LMinterp_char()
  258. *  Purpose  :   Interpret a character according to the current settings
  259. *               for the line mode special characters
  260. *  Parameters   :
  261. *           t - the telnet window structure
  262. *           c - the character to interpret
  263. *  Returns  :   (1) - for no further process on the character being
  264. *                   necessary, (0) for further processing allowed
  265. *  Calls    :
  266. *  Called by    :   newkey()
  267. **********************************************************************/
  268. int LMinterp_char(struct twin *t,int c)
  269. {
  270.     int char_handled=0;     /* flag to indicate that no further processing is need for the character */
  271.  
  272.     if(t->litflag) {       /* transmit this character with no processing */
  273.         t->litflag=0;      /* reset the literal flag */
  274.         strchar(t->linemode,(char)c);
  275.         char_handled=1;     /* set the flag to indicate to further processing is not needed for this character */
  276.       } /* end if */
  277.     else {  /* interpret this character */
  278.         if(c==13) {
  279. #ifdef QAK
  280. tprintf(console->vs,"c=%d, t->linemode=%s\r\n",(int)c,t->linemode);
  281. #endif
  282.             parse(t,"\r\n",2);     /* echo the return */
  283.             strcat(t->linemode,"\n");
  284.             netpush(t->pnum);
  285.             netwrite(t->pnum,t->linemode,strlen(t->linemode));
  286.             t->linemode[0]='\0';
  287.             char_handled=1;     /* set the flag to indicate to further processing is not needed for this character */
  288.           } /* end if */
  289.         if(t->trapsig) {    /* check if we are supposed to trap telnet signals */
  290.             if(c==t->slc[SLC_BRK]) {  /* send telnet BRK command */
  291.                 netprintf(t->pnum,"%c%c",IAC,BREAK);
  292.                 tprintf(console->vs,"SEND: IAC BREAK\r\n");
  293.                 char_handled=1;     /* set the flag to indicate to further processing is not needed for this character */
  294.               } /* end if */
  295.             if(c==t->slc[SLC_IP]) {  /* send telnet interrupt process command */
  296.                 netprintf(t->pnum,"%c%c",IAC,IP);
  297.                 tprintf(console->vs,"SEND: IAC IP\r\n");
  298.                 char_handled=1;     /* set the flag to indicate to further processing is not needed for this character */
  299.               } /* end if */
  300.             if(c==t->slc[SLC_AO]) {   /* send telnet about output command */
  301.                 netprintf(t->pnum,"%c%c",IAC,AO);
  302.                 tprintf(console->vs,"SEND: IAC AO\r\n");
  303.                 char_handled=1;     /* set the flag to indicate to further processing is not needed for this character */
  304.               } /* end if */
  305.             if(c==t->slc[SLC_AYT]) {  /* send telnet AYT command */
  306.                 netprintf(t->pnum,"%c%c",IAC,AYT);
  307.                 tprintf(console->vs,"SEND: IAC AYT\r\n");
  308.                 char_handled=1;     /* set the flag to indicate to further processing is not needed for this character */
  309.               } /* end if */
  310.             if(c==t->slc[SLC_ABORT]) {  /* send telnet abort process command */
  311.                 netprintf(t->pnum,"%c%c",IAC,ABORT);
  312.                 tprintf(console->vs,"SEND: IAC ABORT\r\n");
  313.                 char_handled=1;     /* set the flag to indicate to further processing is not needed for this character */
  314.               } /* end if */
  315.             if(c==t->slc[SLC_EOF]) {  /* send telnet EOF command */
  316.                 netprintf(t->pnum,"%c%c",IAC,TEL_EOF);
  317.                 tprintf(console->vs,"SEND: IAC EOF\r\n");
  318.                 char_handled=1;     /* set the flag to indicate to further processing is not needed for this character */
  319.               } /* end if */
  320.             if(c==t->slc[SLC_SUSP]) {  /* send telnet suspend command */
  321.                 netprintf(t->pnum,"%c%c",IAC,SUSP);
  322.                 tprintf(console->vs,"SEND: IAC SUSP\r\n");
  323.                 char_handled=1;     /* set the flag to indicate to further processing is not needed for this character */
  324.               } /* end if */
  325.           } /* end if */
  326.         if(c==t->slc[SLC_FORW1] || c==t->slc[SLC_FORW2]) { /* pass the current string and the "forward" character immediately */
  327.             strchar(t->linemode,(char)c);
  328.             netpush(t->pnum);
  329.             netwrite(t->pnum,t->linemode,strlen(t->linemode));
  330.             t->linemode[0]='\0';
  331.             char_handled=1;     /* set the flag to indicate to further processing is not needed for this character */
  332.           } /* end if */
  333.         if(c==t->slc[SLC_LNEXT]) { /* check for sending a literal character */
  334.             t->litflag=1;      /* set the literal character flag */
  335.             char_handled=1;     /* set the flag to indicate to further processing is not needed for this character */
  336.           } /* end if */
  337.         if(c==t->slc[SLC_XON]) {    /* check for XON character */
  338.             strchar(t->linemode,(char)c);   /* we don't support flow of control right now, so just append the character to the line */
  339.             char_handled=1;     /* set the flag to indicate to further processing is not needed for this character */
  340.           } /* end if */
  341.         if(c==t->slc[SLC_XOFF]) {   /* check for XOFF character */
  342.             strchar(t->linemode,(char)c);   /* we don't support flow of control right now, so just append the character to the line */
  343.             char_handled=1;     /* set the flag to indicate to further processing is not needed for this character */
  344.           } /* end if */
  345.         if(c==t->slc[SLC_RP]) {   /* check for RP character */
  346.             VSredraw(t->vs,0,0,79,numline); /*   kinda a kludge, instead of just re-displaying the line, we re-display the entire screen */
  347.             char_handled=1;     /* set the flag to indicate to further processing is not needed for this character */
  348.           } /* end if */
  349.       } /* end else */
  350.  
  351.     return(char_handled);   /* return whether we handled the character */
  352. }   /* end LMinterp_char() */
  353.  
  354.