home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / pub / uniflex / ufkerm.uue / ufkerm.arc / UFIO.C < prev    next >
C/C++ Source or Header  |  1989-01-09  |  9KB  |  293 lines

  1. #include "ufk.h"
  2. #include <sgtty.h>
  3. #include <signal.h>
  4. #include <setjmp.h>
  5. #include <stat.h>
  6. #include <modes.h>
  7.  
  8. #define R_CHUNK_SIZE  50          /* Number of characters to read at a time */
  9.  
  10. char lastchar,
  11.      cons_set;
  12. jmp_buf env, popenv;
  13. struct sgttyb old_mode, new_mode,
  14.               old_c_mode, new_c_mode;
  15.  
  16. /*
  17.  * Open communication port
  18.  */
  19.  
  20. open_port(setcons,check_only)
  21. char setcons,
  22.      check_only;
  23. {
  24.    int opnint();
  25.    char tmpprt[20];
  26.    struct stat buf;
  27.  
  28.    sprintf(tmpprt,"/dev/tty%02d",ttyslot()); /* Get controlling terminal */
  29.    if ((strcmp(tty_descr,"Remote") == 0) ||
  30.        (strcmp(tty_descr,tmpprt) == 0))
  31.       remote = TRUE;
  32.    else
  33.    {
  34.       remote = FALSE;
  35.       strcpy(tmpprt,tty_descr);
  36.    }
  37.    if (stat(tmpprt,&buf))
  38.       return (NULL);                         /* unable to obtain status */
  39.    if ((buf.st_mode & S_IFMT) != S_IFCHR)
  40.       return (NULL);                         /* Not a character device */
  41.    if (!check_only)                          /* Real open */
  42.    {
  43.       if (!port_open || remote)
  44.       {
  45.          if (setjmp(popenv))
  46.             return (NULL);                      /* Interrupted during open */
  47.          signal(SIGINT,opnint);                 /* Catch ctrl-C interrupt */
  48.          ttyfd = open(tmpprt,2);
  49.          if (ttyfd == ERROR)
  50.          {
  51.             signal(SIGINT,SIG_DFL);             /* Default kbd interrupt */
  52.             return(NULL);
  53.          }
  54.          if (!nooutput || bg)                   /* Background ? */
  55.             signal(SIGINT,SIG_IGN);             /* Ignore kbd interrupt */
  56.          else
  57.             signal(SIGINT,SIG_DFL);             /* Default if no output */
  58.          gtty(ttyfd,&old_mode);                 /* Get old characteristics */
  59.          gtty(ttyfd,&new_mode);                 /* Get copy */
  60.          new_mode.sg_speed &= ~0x1c;            /* Mask old config bits */
  61.          new_mode.sg_speed |= (config << 2);    /* Set new configuration */
  62.          new_mode.sg_flag |= RAW;               /* Set raw mode */
  63.          new_mode.sg_flag &= ~(ECHO|CRMOD);     /* No echo, no auto lf */
  64.          stty(ttyfd,&new_mode);                 /* Set new parameters */
  65.          port_open = TRUE;                      /* Flag it's open now */
  66.       }
  67.       cons_set = FALSE;
  68.       if (!remote)
  69.       {
  70.          if (call_baud)                      /* Only the first time ... */
  71.          {
  72.             baud(tmpprt,speed);              /* set baudrate */
  73.             call_baud = FALSE;               /* Don't set it anymore */
  74.          }
  75.          if (setcons && !nooutput)
  76.          {
  77.             cons_set = TRUE;                 /* Console set as well */
  78.             gtty(0,&old_c_mode);             /* Get console characteristics */
  79.             gtty(0,&new_c_mode);             /* Get copy */
  80.             new_c_mode.sg_flag |= RAW;       /* Set raw mode */
  81.             new_c_mode.sg_flag &= ~(ECHO|CRMOD); /* No echo, no auto lf */
  82.             stty(0,&new_c_mode);             /* Set new console parameters */
  83.          }
  84.       }
  85.       purgeline(ttyfd);                      /* eat old input */
  86.       aborted = FALSE;
  87.       port_open = TRUE;                      /* Mark port open */
  88.    }
  89.    return (TRUE);                            /* valid port found */
  90. }
  91.  
  92. opnint()
  93. {
  94.    longjmp(popenv,TRUE);                  /* timeout during port open */
  95. }
  96.  
  97. /*
  98.  * Close communication port
  99.  */
  100.  
  101. close_port(scrflag,real_close)
  102. int scrflag,
  103.     real_close;
  104. {
  105.    if (!remote && cons_set)
  106.       stty(0,&old_c_mode);
  107.    if ((real_close || remote) && port_open)
  108.    {
  109.       stty(ttyfd,&old_mode);
  110.       close(ttyfd);
  111.       signal(SIGINT,SIG_DFL);                /* Restore keyboard interrupt */
  112.       port_open = FALSE;
  113.    }
  114.    if (scrflag)
  115.       posit(0,23);
  116.    curs_on();                                /* Re-enable cursor */
  117. }
  118.  
  119. /*
  120.  * read data from port
  121.  */
  122.  
  123. kread(dev,data,count)
  124. int   dev,count;
  125. char  *data;
  126. {
  127.    int   i, n, p, left,
  128.          clkint();
  129.  
  130.    i = 0;                           /* Timeout counter */
  131.    if (setjmp(env))
  132.       if ((aborted && !(sflg || rflg)) || ((i += 2) >= timint))
  133.   /* Return TIMOUT if aborted during inactive period, or after real timeout */
  134.          return TIMEOUT;            /* Limit reached, timeout */
  135.    signal(SIGALRM,clkint);          /* Setup timeout catch */
  136. /* Due to the accuracy of the 'alarm' call one second can cause problems */
  137.    alarm(2);                        /* Set two seconds timeout */
  138.    read(dev,data,1);                /* Try to get first character */
  139.    alarm(0);                        /* Got one character, reset timeout */
  140.    if (count > 1)                   /* If more to do ... */
  141.    {
  142.       left = count - 1;             /* What's left to do */
  143.       n = 1;                        /* Starting offset in data array */
  144.       while (left > 0)              /* Until all has been done */
  145.       {
  146.          p = (left > R_CHUNK_SIZE ? R_CHUNK_SIZE : left); /* Read in chunks */
  147.                                     /* of R_CHUNK_SIZE characters or less */
  148.          i = timint;                /* so we will return at timeout */
  149.          alarm(timint);             /* Set selected timeout */
  150.          read(dev,&data[n],p);      /* Try to get the rest of the data */
  151.          alarm(0);                  /* Got the rest, reset timeout */
  152.          left -= R_CHUNK_SIZE;      /* Count down */
  153.          n += R_CHUNK_SIZE;         /* Adjust next array index */
  154.       }
  155.    }
  156.    lastchar = data[count-1];        /* get last entered character */
  157.    if (rflg || sflg)
  158.       chr_rec += count;             /* count chars if sending or receiving */
  159.    if (!remote && !nooutput)
  160.       check_abort();                /* check for abort or toggle debug */
  161.    return NULL;                     /* normal termination */
  162. }
  163.  
  164.  
  165. clkint()
  166. {
  167.    check_abort();                   /* check for user abort after timeout */
  168.    longjmp(env,TRUE);
  169. }
  170.  
  171. /*
  172.  * write characters to port
  173.  */
  174.  
  175. kwrite(dev,data,count)
  176. int   dev,count;
  177. char  *data;
  178. {
  179.    if (count == 0)                  /* determine count if not given */
  180.       count = strlen(data);
  181.    write(dev,data,count);
  182.    if (rflg || sflg)
  183.       chr_sent += count;            /* count chars if sending or receiving */
  184. }
  185.  
  186. /*
  187.  * check for user abort
  188.  */
  189.  
  190. check_abort()
  191. {
  192.    char c;
  193.    struct sgttyb mode;
  194.  
  195.    if (!cflg)                             /* only when connect is inactive */
  196.    {
  197.       gtty(0,&mode);
  198.       if (mode.sg_speed & INCHR)          /* if character available */
  199.          read(0,&c,1);
  200.       else
  201.       {
  202.          if (remote)
  203.             c = lastchar;                 /* Only check typed character */
  204.          else                             /* if remote */
  205.             c = 0;
  206.       }
  207.       c &= 0177;                          /* strip parity */
  208.       lastchar = 0;
  209.       if ((c == ABORTX) || (c == ABORTZ))
  210.       {                                   /* and if it's the abort char */
  211.          aborted = c;                     /* flag abort */
  212.          return c;
  213.       }
  214.       else if (c == TOGDBG)               /* Toggle debug ? */
  215.       {
  216.          if (debug)
  217.          {
  218.             debug = FALSE;                /* Switch off debug */
  219.             if (dbgfil != ERROR)
  220.             {
  221.                fclose(dbgfil);            /* Close debug output file if open */
  222.                dbgfil = ERROR;
  223.             }
  224.          }
  225.          else
  226.             debug = TRUE;                 /* Switch on debug */
  227.          set_frame();                     /* Make new display frame */
  228.          disp_params();                   /* With the current parameters */
  229.       }
  230.       else if (c == PANIC)
  231.       {
  232.          for (c = 0; c < 3; c++)
  233.             beep();                       /* Ring the bell three times */
  234.          kerm_exit();                     /* Get the hell out of here */
  235.       }
  236.       else if (dstop != NULL && c == dstop) /* Wait.... */
  237.       {
  238.          do
  239.             read(0,&c,1);
  240.          while ((c & 0177) != dstart);    /* Wait for start */
  241.       }
  242.    }
  243.    return NULL;                           /* no abort */
  244. }
  245.  
  246. /*
  247.  * purge a line of input data
  248.  */
  249.  
  250. purgeline(port)
  251. int port;
  252. {
  253.    struct sgttyb mode;
  254.    char c;
  255.  
  256.    while(TRUE)
  257.    {
  258.       gtty(port,&mode);
  259.       if (mode.sg_speed & INCHR)       /* eat characters */
  260.          read(port,&c,1);
  261.       else
  262.          break;
  263.    }
  264. }
  265.  
  266. /*
  267.   send break
  268. */
  269.  
  270. send_break(port)
  271. int port;                       /* Not used */
  272. {
  273.    do_break(tty_descr);         /* Use fixed string descriptor */
  274. }
  275.  
  276.  
  277. kdelay(time)
  278. int time;
  279. {
  280.    int timdummy();
  281.  
  282.    if (time != 0)
  283.    {
  284.       signal(SIGALRM,timdummy);
  285.       alarm(time);
  286.       pause();
  287.    }
  288. }
  289.  
  290. timdummy()
  291. {
  292. }
  293.