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