home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ckc190.zip / ck9con.c < prev    next >
C/C++ Source or Header  |  1993-12-09  |  16KB  |  432 lines

  1. char *connv = "OS-9 Connect Command, 5A(06) 9 Oct 92";
  2.  
  3. /*  C K 9 C O N  --  Dumb terminal connection to remote system, for osk  */
  4. /*
  5.  Modified from ckucon.c by Bob Larson (blarson@ecla.usc.edu)
  6.  Edition: 5A(01)
  7.     by Chris Hemsing ,Aachen,   W Germany (chris@lfm.rwth-aachen.de):
  8.     More efficient using sigmask, added character set translation
  9.  Edition: 5A(02)
  10.  07/25/91 Chris  Hemsing        minor bug fixes, changes for gnu (ansi) C
  11.                                 flow control on both sides
  12.  Edition: 5A(03)
  13.  03/04/92 Chris Hemsing        Kanji bug fix
  14.  Edition: 5A(04)
  15.  08/20/92 Chris Hemsing        flow control bug fix on return from local shell
  16.  Edition: 5A(05)
  17.  10/01/92 Chris Hemsing        added sending xon via escape character
  18.  Edition: 5A(06)
  19.  10/09/92 Chris Hemsing        escape back to local even on receive burst
  20.  
  21.   Author: Frank da Cruz (fdc@columbia.edu, FDCCU@CUVMA.BITNET),
  22.   Columbia University Center for Computing Activities, January 1985.
  23.   Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
  24.   York.  Permission is granted to any individual or institution to use this
  25.   software as long as it is not sold for profit.  This copyright notice must be
  26.   retained.  This software may not be included in commercial products without
  27.   written permission of Columbia University.
  28. */
  29.  
  30. #include "ckcdeb.h"
  31. #include "ckcker.h"
  32. #include "ckcasc.h"
  33. #ifndef NOCSETS
  34. #include "ckcxla.h"                     /* Character set translation */
  35. #endif /* NOCSETS */
  36. #include <sgstat.h>     /* Set/Get tty modes */
  37.  
  38.  
  39. extern int local, speed, escape, duplex, parity, flow, seslog, mdmtyp;
  40. extern int errno, cmask, fmask, sosi, cmdmsk;
  41. extern char ttname[], sesfil[];
  42. extern struct csinfo fcsinfo[];
  43.  
  44. static int active;                  /* Variables global to this module */
  45. static char *chstr();
  46.  
  47. #define LBUFL 200                   /* Line buffer */
  48. CHAR lbuf[LBUFL];
  49.  
  50. /*  C O N E C T  --  Perform terminal connection  */
  51.  
  52. #ifndef NOCSETS
  53. extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(); /* Character set xlate */
  54. extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(); /* functions. */
  55. extern int language;            /* Current language. */
  56. extern struct langinfo langs[]; /* Language info. */
  57. extern int tcsr, tcsl;          /* Terminal character sets, remote & local.*/
  58. static int langsv;              /* Remember language */
  59. static int tcs;                 /* Intermediate (xfer) char set */
  60. static CHAR (*sxo)();           /* Local translation functions */
  61. static CHAR (*rxo)();           /* for output (sending) terminal chars */
  62. static CHAR (*sxi)();           /* and for input (receiving) terminal chars.*/
  63. static CHAR (*rxi)();
  64. #endif /* NOCSETS */
  65.  
  66. int shift = 0;                  /* SO/SI shift state */
  67.  
  68. static struct sgbuf opt;    /* sgtty info... */
  69.  
  70. conect() {
  71.     register int c;               /* c is a character, but must be signed
  72.                                    integer to pass thru -1, which is the
  73.                                    modem disconnection signal, and is
  74.                                    different from the character 0377 */
  75.     register int i;
  76.     register int csave;           /* Another copy   of c */
  77.     char errmsg[50], *erp;
  78.     int n,we_have_data;
  79.     extern int ttypn;
  80. VOID
  81. doesc();
  82.         if (!local) {
  83.             printf("Sorry, you must 'set line' first\n");
  84.             return(-2);
  85.         }
  86.         if (speed < 0) {
  87.             printf("Sorry, you must 'set speed' first\n");
  88.             return(-2);
  89.         }
  90.         if ((escape < 0) || (escape > 0177)) {
  91.             printf("Your escape character is not ASCII - %d\n",escape);
  92.             return(-2);
  93.         }
  94.         if (ttopen(ttname,&local,mdmtyp,0) < 0) {
  95.             erp = errmsg;
  96.             sprintf(erp,"Sorry, can't open %s",ttname);
  97.             perror(errmsg);
  98.             return(-2);
  99.         }
  100.         printf("Connecting thru %s, speed %d.\n",ttname,speed);
  101.         printf("The escape character is %s (%d).\n",chstr(escape),escape);
  102.         printf("Type the escape character followed by C to get back,\n");
  103.         printf("or followed by ? to see other options.\n");
  104.         if (seslog) printf("(Session logged to %s.)\n",sesfil);
  105.  
  106. /* Condition console terminal and communication line */
  107.  
  108.         if (conbin(escape) < 0) {
  109.             printf("Sorry, can't condition console terminal\n");
  110.             return(-2);
  111.         }
  112.         if (flow==1) { /*if xon/xoff you should have it running on both*/
  113.             if (_gs_opt(0,&opt) <0)  /* Structure for restoring */
  114.             {
  115.               printf("Sorry, can't condition console terminal\n");
  116.               return(-2);
  117.             }
  118.             opt.sg_xon = 0x11;
  119.             opt.sg_xoff = 0x13;
  120.             _ss_opt(0,&opt);
  121.             _ss_opt(1,&opt);            /* set new modes . */
  122.         }
  123.         if (ttvt(speed,flow) < 0) {
  124.             conres();
  125.             printf("Sorry, Can't condition communication line\n");
  126.             return(-2);
  127.         }
  128.  
  129. #ifndef NOCSETS
  130. /* Set up character set translations */
  131.  
  132. #ifdef KANJI
  133. /* Kanji not supported yet */
  134.     if (fcsinfo[tcsr].alphabet == AL_JAPAN ||
  135.     fcsinfo[tcsl].alphabet == AL_JAPAN ) {
  136.     tcs = TC_TRANSP;
  137.     } else
  138. #endif /* KANJI */
  139. #ifdef CYRILLIC
  140.       if (fcsinfo[tcsl].alphabet == AL_CYRIL) {
  141.       tcs = TC_CYRILL;
  142.       } else
  143. #endif /* CYRILLIC */
  144. /* Set up character set translations */
  145.     tcs = TC_1LATIN;
  146.  
  147.     if (tcsr == tcsl) {            /* Remote and local sets the same? */
  148.     sxo = rxo = NULL;        /* If so, no translation. */
  149.     sxi = rxi = NULL;
  150.     } else {                /* Otherwise, set up */
  151.     sxo = xls[tcs][tcsl];        /* translation function */
  152.     rxo = xlr[tcs][tcsr];        /* pointers for output functions */
  153.     sxi = xls[tcs][tcsr];        /* and for input functions. */
  154.     rxi = xlr[tcs][tcsl];
  155.     }
  156. /*
  157.   This is to prevent use of zmstuff() and zdstuff() by translation functions.
  158.   They only work with disk i/o, not with communication i/o.  Luckily Russian
  159.   translation functions don't do any stuffing...
  160. */
  161.     langsv = language;
  162. #ifndef NOCYRIL
  163.     if (language != L_RUSSIAN)
  164. #endif /* NOCYRIL */
  165.       language = L_USASCII;
  166. #endif /* NOCSETS */
  167.  
  168.         shift = 0;                  /* Initial shift state. */
  169. /*
  170.   Main loop. The treatment of the 8th bit of keyboard characters
  171.   is governed by SET COMMAND BYTESIZE (cmdmsk).  The treatment of the 8th bit
  172.   of characters sent to the remote is governed by SET TERMINAL BYTESIZE
  173.   (cmask).   This distinction was introduced in edit C-Kermit 5A(164).
  174. */
  175.         active = 1;
  176.         while (active)
  177.         {
  178.           sigmask(1);                /* increment signal mask, signals must */
  179.           _ss_ssig(0, SIGARB);       /* be masked between _ss_sig and sleep*/
  180.           _ss_ssig(ttypn, SIGARB);
  181.           sleep(0);
  182.           _ss_rel(0, SIGARB);
  183.           _ss_rel(ttypn, SIGARB);
  184.           we_have_data = 1;
  185.           while(we_have_data) /* loop while data on keybord or remote port*/
  186.           {                   /* do check console to get characters through */
  187.             we_have_data = 0; /* even if communication line receives a burst*/
  188.             if(_gs_rdy(0)>0)
  189.             {
  190.               we_have_data = 1;
  191.               c = coninc(0) & cmdmsk;       /* Get character from keyboard */
  192.               csave = c;
  193.               if ((c & 0177) == escape)
  194.               { /* Look for escape char */
  195.                 c = coninc(0) & 0177;   /* Got esc, get its arg */
  196.                 doesc(c);               /* And process it */
  197.                 if (active == 0) break; /* immediately leave we_have_data
  198.                                            loop to avoid burst receive */
  199.               }
  200.               else
  201.               {             /* Ordinary character */
  202. #ifndef NOCSETS
  203.                 /* Translate character sets */
  204.                 if (sxo) c = (*sxo)(c); /* From local to intermediate. */
  205.                 if (rxo) c = (*rxo)(c); /* From intermediate to remote. */
  206. #endif /* NOCSETS */
  207. /*
  208.  If Shift-In/Shift-Out selected and we have a 7-bit connection,
  209.  handle shifting here.
  210. */
  211.                 if (sosi)        /* Shift-In/Out selected? */
  212.                 {
  213.                     if (cmask == 0177)  /*  In 7-bit environment? */
  214.                     {
  215.                         if (c & 0200)            /* 8-bit character? */
  216.                         {
  217.                             if (shift == 0)      /* If not shifted, */
  218.                             {
  219.                                 ttoc(dopar(SO)); /* shift. */
  220.                                 shift = 1;
  221.                             }
  222.                         }
  223.                         else
  224.                         {
  225.                             if (shift == 1)      /* 7-bit character */
  226.                             {
  227.                                 ttoc(dopar(SI)); /* If shifted, */
  228.                                 shift = 0;       /* unshift. */
  229.                             }
  230.                         }
  231.                     }
  232.                     if (c == SO) shift = 1; /* User typed SO */
  233.                     if (c == SI) shift = 0; /* User typed SI */
  234.                 }
  235.                 c &= cmask;         /* Apply Kermit-to-host mask now. */
  236.                 if (ttoc(dopar(c)) > -1)
  237.                 {
  238.                   if (duplex)
  239.                   {         /* Half duplex? */
  240.                     conoc(csave);       /* Yes, also echo it. */
  241.                     if (seslog)     /* And maybe log it. */
  242.                     if (zchout(ZSFILE,c) < 0) seslog = 0;
  243.                   }
  244.                 }
  245.                 else
  246.                 {
  247.                   perror("\r\lCan't send character");
  248.                   active = 0;
  249.                 }
  250.               } /* end if ((c & 0177) == escape) */
  251.             } /* end if(_gs_rdy(0)>0) */
  252.             if ((n = ttchk()) > 0)
  253.             {       /* Any more left in buffer? */
  254.               we_have_data = 1;
  255.               if (n > LBUFL) n = LBUFL;   /* Get them all at once. */
  256.               if ((n = ttxin(n,lbuf)) > 0)
  257.               {
  258.                 if (sosi) /* only one character at a time */
  259.                 {
  260.                     for (i = 0; i < n; i++)
  261.                     {
  262.                         c = lbuf[i] & cmask;
  263.                         if (c == SO)
  264.                         {
  265.                             shift = 1;
  266.                             continue;
  267.                         }
  268.                         else if (c ==   SI)
  269.                         {
  270.                             shift = 0;
  271.                             continue;
  272.                         }
  273.                         if (shift)
  274.                           c = (c | 0200);
  275. #ifndef NOCSETS
  276.                         /* Translate character sets */
  277.                         if (sxi) c = (*sxi)(c);
  278.                         if (rxi) c = (*rxi)(c);
  279. #endif /* NOCSETS */
  280.                         c &= cmdmsk; /* Apply command mask. */
  281.                         conoc(c);    /* Output to screen */
  282.                         if (seslog) zchout(ZSFILE,c);      /* Log */
  283.                     }
  284.                 }
  285.                 else    /* All at once */
  286.                 {
  287.                     for (i = 0; i < n; i++)
  288.                     {
  289.                         c = lbuf[i] & cmask;
  290. #ifndef NOCSETS
  291.                         /* Translate character sets */
  292.                         if (sxi) c = (*sxi)(c);
  293.                         if (rxi) c = (*rxi)(c);
  294. #endif /* NOCSETS */
  295.                         lbuf[i] = c & cmdmsk; /* Replace in buffer. */
  296.                         if (seslog) zchout(ZSFILE,c);      /* Log */
  297.                     }
  298.                     conxo(n,(char *)lbuf); /* Output whole buffer at once */
  299.                 } /* end SI/SO or not */
  300.               }  /* end successful read on comm line */
  301.             }  /* end data on communications line */
  302.           }  /* end while(we_have_data) */
  303.         }  /* end while(active) */
  304.         conres();                       /* Reset the console. */
  305.         printf("[Back at Local System]\n");
  306. #ifndef NOCSETS
  307.         language = langsv;          /* Restore language */
  308. #endif /* NOCSETS */
  309.         return(1);
  310. }
  311.  
  312.  
  313. /*  H C O N N E  --  Give help message for connect.  */
  314.  
  315. hconne() {
  316.     int c;
  317.     static char *hlpmsg[] = {"\
  318. \r\lC to close the connection, or:\r",
  319. "  0 (zero) to send a null\r",
  320. "  B to send a BREAK\r",
  321. "  H to hangup and close connection\r",
  322. "  S for status\r",
  323. "  X to send an XON\r",
  324. "  ! to push to local shell\r",
  325. "  ? for help\r",
  326. " escape character twice to send the escape character.\r\l\r\l\r",
  327. "" };
  328.  
  329.     conola(hlpmsg);                     /* Print the help message. */
  330.     conol("Command>");                  /* Prompt for command. */
  331.     c = coninc(0) & 0177;               /* Get character, strip any parity. */
  332.     conoc(c);                           /* Echo it. */
  333.     conoll("");
  334.     return(c);                          /* Return it. */
  335. }
  336.  
  337.  
  338. /*  C H S T R  --  Make a printable string out of a character  */
  339.  
  340. static char *
  341. chstr(c) int c; {
  342.     static char s[8];
  343.  
  344.     if (c < SP) sprintf(s,"CTRL-%c",ctl(c));
  345.     else sprintf(s,"'%c'\n",c);
  346.     return(s);
  347. }
  348.  
  349.  
  350. /*  D O E S C  --  Process an escape character argument  */
  351. VOID
  352. doesc(c) char c; {
  353.     CHAR d;
  354.     CHAR temp[50];
  355.  
  356.     while (1) {
  357.         if (c == escape) {              /* Send escape character */
  358.             d = dopar(c); ttoc(d); return;
  359.         } else                          /* Or else look it up below. */
  360.             if (isupper(c)) c = tolower(c);
  361.  
  362.         switch (c) {
  363.  
  364.         case 'c':                       /* Close connection */
  365.         case '\03':
  366.             active = 0; conol("\r\l"); return;
  367.  
  368.         case 'b':                       /* Send a BREAK signal */
  369.         case '\02':
  370.             if (ttsndb()<0) conol("\r\nCan't send break\r\l");
  371.             return;
  372.  
  373.         case 'h':                       /* Hangup */
  374.         case '\010':
  375.             tthang(); active = 0; conol("\r\l"); return;
  376.  
  377.         case '!':
  378.             conres();
  379.             zshcmd("");
  380.             if (conbin(escape) < 0) {
  381.                 printf("Error returning to remote session\n");
  382.                 active = 0;
  383.             }
  384.             if (flow==1)
  385.             { /*if xon/xoff you should have it running on both*/
  386.               if ((_ss_opt(0,&opt) < 0)||(_ss_opt(1,&opt) < 0))
  387.               {
  388.                 printf("Error returning to remote session\n");
  389.                 active = 0;
  390.               }
  391.             }
  392.             return;
  393.  
  394.         case 's':                       /* Status */
  395.             conol("\r\lConnected thru ");
  396.             conol(ttname);
  397.             if (speed >= 0) {
  398.                 sprintf((char *)temp,", speed %d",speed); conol((char *)temp);
  399.             }
  400.             sprintf((char *)temp,", %d bits",(cmask == 0177) ? 7 : 8);
  401.             if (parity) {
  402.                 conol(", ");
  403.                 switch (parity) {
  404.                     case 'e': conol("even");  break;
  405.                     case 'o': conol("odd");   break;
  406.                     case 's': conol("space"); break;
  407.                     case 'm': conol("mark");  break;
  408.                 }
  409.                 conol(" parity");
  410.             }
  411.             if (seslog) {
  412.                 conol(", logging to "); conol(sesfil);
  413.             }
  414.             conoll(""); return;
  415.  
  416.         case '?':                       /* Help */
  417.             c = hconne(); continue;
  418.  
  419.         case 'x': /* send xon */
  420.             ttoc(dopar(XON)); return;
  421.         case '0':                       /* Send a null */
  422.             c = '\0'; d = dopar(c); ttoc(d); return;
  423.  
  424.         case SP:                        /* Space, ignore */
  425.             return;
  426.  
  427.         default:                        /* Other */
  428.             conoc(BEL); return;         /* Invalid esc arg, beep */
  429.         }
  430.     }
  431. }
  432.