home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume3 / pcmail / part03 / xpres.c < prev   
C/C++ Source or Header  |  1989-02-03  |  7KB  |  332 lines

  1. /*++
  2. /* NAME
  3. /*      xpres 3
  4. /* SUMMARY
  5. /*      communications port i/o
  6. /* PROJECT
  7. /*      pc-mail
  8. /* PACKAGE
  9. /*      cico
  10. /* SYNOPSIS
  11. /*      xopen()
  12. /*
  13. /*      xclose()
  14. /*
  15. /*      xread(dummy,buf,len)
  16. /*      int dummy,len;
  17. /*      char *buf;
  18. /*
  19. /*      xwrite(dummy,buf,len)
  20. /*      int dummy,len;
  21. /*      char *buf;
  22. /*
  23. /*      xioctl(flag)
  24. /*      int flag;
  25. /* DESCRIPTION
  26. /*      The functions in this module perform functions analogous
  27. /*      to unix system calls, for the serial port of IBM-PC workalikes.
  28. /*
  29. /*      xopen() initializes a serial port. Also needed under UNIX.
  30. /*
  31. /*      xclose() closes a port.
  32. /*
  33. /*      xread(), xwrite() do not use their first argument. Under UNIX
  34. /*    one should use the standard read() and write() system calls.
  35. /*
  36. /*      xioctl() enables xon/xoff flow control if its argument
  37. /*      is nonzero. Not used under UNIX.
  38. /* SEE ALSO
  39. /*      comport.asm, IBM-PC comm routines by Tim Pozar
  40. /* DIAGNOSTICS
  41. /*      The read functions returns EOF in case of timeout; the write
  42. /*      function never detects any failure.
  43. /* BUGS
  44. /*      The xioctl() function is utterly primitive.
  45. /* AUTHOR(S)
  46. /*      MS-DOS parts derived from uuslave software (John Gilmore)
  47. /*    published on usenet early 1987. Bugs fixed & severely hacked by
  48. /*
  49. /*      W.Z. Venema
  50. /*      Eindhoven University of Technology
  51. /*      Department of Mathematics and Computer Science
  52. /*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  53. /* CREATION DATE
  54. /*      Sat Mar 28 23:01:43 GMT+1:00 1987
  55. /* LAST MODIFICATION
  56. /*    Mon Apr  4 23:51:55 MET 1988
  57. /* VERSION/RELEASE
  58. /*    1.3
  59. /*--*/
  60.  
  61. #include "defs.h"
  62. #include "params.h"
  63. #include "comm.h"            /* baud rates, tty ports,... */
  64. #include "status.h"
  65. #include "sysdep.h"            /* other system dependencies */
  66. #include "logs.h"
  67.  
  68. #ifdef    unix
  69. #   include <sgtty.h>
  70. #   include <signal.h>
  71. #   include <setjmp.h>
  72. #endif
  73.  
  74. #ifdef    MSDOS
  75. #   define B(x)    (115200/(x))
  76.     static int sigint();
  77.     static void get_time();
  78. #endif
  79.  
  80. typedef struct {            /* baud-rate lookup table */
  81.     char *name;
  82.     int code;
  83. } Baud_table;
  84.  
  85. Baud_table btable[] = {
  86. #ifdef    unix
  87.     "50",    B50,
  88.     "75",    B75,
  89.     "110",    B110,
  90.     "134",    B134,
  91.     "150",    B150,
  92.     "300",    B300,
  93.     "600",    B600,
  94.     "1200",    B1200,
  95.     "1800",    B1800,
  96.     "2400",    B2400,
  97.     "4800",    B4800,
  98.     "9600",    B9600,
  99. #endif
  100. #ifdef    MSDOS
  101.     "50",    B(50),
  102.     "75",    B(75),
  103.     "110",    B(110),
  104.     "134",    B(134),
  105.     "150",    B(150),
  106.     "300",    B(300),
  107.     "600",    B(600),
  108.     "1200",    B(1200),
  109.     "1800",    B(1800),
  110.     "2400",    B(2400),
  111.     "4800",    B(4800),
  112.     "9600",    B(9600),
  113. #endif
  114.     0,        0,
  115. };
  116.  
  117. /* xopen - open communications port; parameters taken from setup table */
  118.  
  119. xopen()
  120. {
  121.     register Baud_table *bp;
  122. #ifdef    unix
  123.     struct sgttyb ttmode;
  124. #endif
  125.  
  126.     for (bp = btable; bp->name; bp++)        /* look up baud rate */
  127.     if (strcmp(bp->name,COMM_RATE) == 0)
  128.         break;
  129.     if (bp->name == 0) {            /* bad baud rate in setup */
  130.     debug(4)("Invalid baud rate %s\n",COMM_RATE);
  131.     exit(E_BADSETUP);
  132.     }
  133.  
  134. #ifdef    unix
  135.     if ((ttfd = open(COMM_LINE,2)) < 0) {    /* try to access port */
  136.     debug(4)("Cannot access %s\n",COMM_LINE);
  137.     exit(E_BADSETUP);
  138.     }
  139. #ifndef SIII
  140.     if (ioctl(ttfd,TIOCEXCL))            /* exclusive access */
  141.     exit(E_BADSETUP);            /* not a terminal */
  142. #endif
  143.     ioctl(ttfd,TIOCHPCL);            /* hangup when done */
  144.     gtty(ttfd,&ttmode);                /* get port status */
  145.     ttmode.sg_ispeed = ttmode.sg_ospeed = bp->code;/* set baud rate */
  146.     ttmode.sg_flags |= (RAW);            /* raw mode */
  147. #ifdef    SIII
  148.     ttmode.sg_flags &= ~ECHO;
  149. #else
  150.     ttmode.sg_flags &= ~(ECHO|TANDEM|CBREAK);    /* no echo, crlf, flow ctrl */
  151. #endif
  152.     stty(ttfd,&ttmode);
  153. #endif
  154.  
  155. #ifdef MSDOS
  156.     set_tty(bp->code);                /* set baud rate, DTR */
  157.     init_comm();                /* turn interrupts on */
  158.     signal(SIGINT,sigint);            /* must reset tty */
  159.     inp_flush();                /* flush garbage */
  160.     sleep(3);
  161. #endif
  162. }
  163.  
  164. /* xclose - release the communications port */
  165.  
  166. xclose()
  167. {
  168. #ifdef    unix
  169.     close(ttfd);
  170. #endif
  171.  
  172. #ifdef MSDOS
  173.     uninit_comm();
  174. #endif
  175. }
  176.  
  177. /* xread - read from the serial port */
  178.  
  179. #ifdef    MSDOS
  180.  
  181. xread(fd,buf,cnt)
  182. int fd;
  183. char *buf;
  184. register int cnt;
  185. {
  186.     register char *p = buf;
  187.     register int c;
  188.  
  189.     while (cnt > 0 && (c = xgetc()) != EOF) {
  190.     *p++ = c;
  191.     cnt--;
  192.     }
  193.     return(p-buf ? p-buf : -1);
  194. }
  195. #endif    /* MSDOS xwrite() */
  196.  
  197. /* xgetc - read one character from serial port */
  198.  
  199. #ifdef    unix
  200. jmp_buf xbuf;
  201.  
  202. static timeout()                /* aux function for xgetc */
  203. {
  204.     longjmp(xbuf,1);
  205. }
  206.  
  207. xgetc()                        /* return next char */
  208. {
  209.     char ch;
  210.  
  211.     if (setjmp(xbuf))                /* in case we time out */
  212.     return(EOF);                /* we just did */
  213.     signal(SIGALRM,timeout);            /* set timer response */
  214.     alarm(BYTE_TIMEOUT);            /* set timer */
  215.  
  216.     read(ttfd,&ch,1);                /* go wait for character */
  217.     alarm(0);                    /* turn timer off */
  218.     return(ch&0377);                /* successfull termination */
  219. }
  220. #endif    /* unix xgetc() */
  221.  
  222. #ifdef MSDOS
  223.  
  224. xgetc()
  225. {
  226.     char data;
  227.  
  228.     int i;
  229.     unsigned s;
  230.     TIME n;
  231.  
  232.     i = 0;
  233.     get_time(&n);
  234.     s = n.sec;
  235.  
  236.     /*
  237.     * Implement timeouts by staring at the clock while we wait.
  238.     * When the second hand moves, bump our counter.  This is a lot
  239.     * easier than figuring out the time when we'd time out (in hours,
  240.     * minutes, and seconds!) and comparing against that, which is
  241.     * what people tend to do in Unix where the time is just an integer
  242.     * number of seconds.
  243.     */
  244.     while (i < BYTE_TIMEOUT) {
  245.     while (s == n.sec) {
  246.         if(inp_cnt() != 0) {
  247.         data = inp_char();
  248.         return (data & 0xFF);
  249.         }
  250.         get_time (&n);
  251.     }
  252.     s = n.sec;
  253.     ++i;
  254.     }
  255.     return(EOF);
  256. }
  257.  
  258. /* xwrite - write buffer to serial port */
  259.  
  260. xwrite(fd,buf,ctr)
  261. int fd;
  262. register char *buf;
  263. int ctr;
  264. {
  265.     register int i = ctr;
  266.  
  267.     while (i-- > 0)
  268.     outp_char(*buf++);
  269.     return ctr;
  270. }
  271.  
  272. /*
  273. * Routines specific to MS-DOS
  274. * xioctl()    enable xon/xoff
  275. * get_timer()    read current time
  276. * sigint()    clean up interrupt handler and exit
  277. * sleep()    unix lookalike
  278. */
  279.  
  280. /* xioctl - enable xon/xoff protocol */
  281.  
  282. xioctl(flag)
  283. int flag;
  284. {
  285.     set_xoff(flag);     /* Enable (flag != 0) or disable flow control */
  286. }
  287.  
  288. /* sigint - restore terminal settings on dialout line */
  289.  
  290. static int sigint()
  291. {
  292.     uninit_comm();
  293.     reset_tty();
  294.     exit(0);
  295. }
  296.  
  297. /* get_time - read time with dos call */
  298.  
  299. static void get_time(n)
  300. TIME_PTR n;
  301. {
  302.     union REGS inregs;
  303.     union REGS outregs;
  304.  
  305.     inregs.h.ah = 0x2c;        /* Please make a #define for this, Tim */
  306.  
  307.     int86(0x21, &inregs, &outregs);/* Please #define the 0x21 too */
  308.  
  309.     n->hour = outregs.h.ch;
  310.     n->minute  = outregs.h.cl;
  311.     n->sec  = outregs.h.dh;
  312.     n->hsec = outregs.h.dl;
  313. }
  314.  
  315. #define    get_sec(n)    (get_time(&n),n.sec)
  316.  
  317. sleep(x)
  318. int x;
  319. {
  320.     TIME n;               /* current time record */
  321.     unsigned s = get_sec(n);
  322.  
  323.     while (x-- > 0) {
  324.     while (s == get_sec(n))
  325.         /* void */ ;
  326.     s = n.sec;
  327.     }
  328. }
  329.  
  330. #endif /* MSDOS */
  331.