home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR10 / MINCOM15.ZIP / SYSDEP1.C < prev    next >
C/C++ Source or Header  |  1993-10-16  |  10KB  |  546 lines

  1. /*
  2.  * This file is part of the Minicom Communications Program,
  3.  * written by Miquel van Smoorenburg 1991/1992/1993.
  4.  *
  5.  * sysdep1.c       - system dependant routines.
  6.  *
  7.  * m_dtrtoggle      - dropt dtr and raise it again
  8.  * m_break      - send BREAK signal
  9.  * m_getdcd      - get modem dcd status
  10.  * m_setdcd      - set modem dcd status
  11.  * m_savestate      - save modem state
  12.  * m_restorestate - restore saved modem state
  13.  * m_nohang      - tell driver not to hang up at DTR drop
  14.  * m_hupcl      - set hangup on close on/off (for Quit without reset)
  15.  * m_setparms      - set baudrate, parity and number of bits.
  16.  * m_wait      - wait for child to finish. System dependant too.
  17.  *
  18.  *  If it's possible, Posix termios are preferred.
  19.  */
  20. #include <sys/types.h>
  21. #if defined (_POSIX_SOURCE) || defined(_BSD43)
  22. #  include <stdlib.h>
  23. #  include <unistd.h>
  24. #endif
  25. #ifdef _NO_TERMIOS
  26. #  undef _POSIX_SOURCE
  27. #endif
  28. #ifndef _COH3
  29. #  include <sys/wait.h>
  30. #endif
  31. #if defined (_V7) && !defined(_POSIX_SOURCE)
  32. #  include <sgtty.h>
  33. #endif
  34. #if defined (_SYSV) && !defined(_POSIX_SOURCE)
  35. #  include <termio.h>
  36. #endif
  37. #ifdef _POSIX_SOURCE
  38. #  include <termios.h>
  39. #endif
  40. #ifdef _HPUX_SOURCE
  41. #  include <sys/modem.h>
  42. #endif
  43. #if defined(_BSD43) || defined (_SYSV)
  44. #  include <sys/ioctl.h>
  45. #endif
  46. #include <stdio.h>
  47. #include <setjmp.h>
  48. #include "window.h"
  49. #include "minicom.h"
  50.  
  51. /* Be sure we know WEXITSTATUS and WTERMSIG */
  52. #if !defined(_BSD43)
  53. #  ifndef WEXITSTATUS
  54. #    define WEXITSTATUS(s) (((s) >> 8) & 0377)
  55. #  endif
  56. #  ifndef WTERMSIG
  57. #    define WTERMSIG(s) ((s) & 0177)
  58. #  endif
  59. #endif
  60.  
  61. /* Some ancient SysV systems don't define these */
  62. #ifndef VMIN
  63. #  define VMIN 4
  64. #endif
  65. #ifndef VTIME
  66. #  define VTIME 5
  67. #endif
  68. #ifndef IUCLC
  69. #  define IUCLC 0
  70. #endif
  71. #ifndef IXANY
  72. #  define IXANY 0
  73. #endif
  74.  
  75. /* Different names for the same beast. */
  76. #ifndef TIOCMODG            /* BSD 4.3 */
  77. #  ifdef TIOCMGET
  78. #    define TIOCMODG TIOCMGET        /* Posix */
  79. #  else
  80. #    ifdef MCGETA
  81. #      define TIOCMODG MCGETA        /* HP/UX */
  82. #    endif
  83. #  endif
  84. #endif
  85.  
  86. #ifndef TIOCMODS
  87. #  ifdef TIOCMSET
  88. #    define TIOCMODS TIOCMSET
  89. #  else
  90. #    ifdef MCSETA
  91. #      define TIOCMODS MCSETA
  92. #    endif
  93. #  endif
  94. #endif
  95.  
  96. #ifndef TIOCM_CAR            /* BSD + Posix */
  97. #  ifdef MDCD
  98. #    define TIOCM_CAR MDCD        /* HP/UX */
  99. #  endif
  100. #endif
  101.  
  102. /* Define some thing that might not be there */
  103. #ifndef TANDEM
  104. #  define TANDEM 0
  105. #endif
  106. #ifndef BITS8
  107. #  define BITS8 0
  108. #endif
  109. #ifndef PASS8
  110. #  ifdef LLITOUT
  111. #  define PASS8 LLITOUT
  112. #  else
  113. #  define PASS8 0
  114. #  endif
  115. #endif
  116. #ifndef CRTSCTS
  117. #  define CRTSCTS 0
  118. #endif
  119.  
  120. /* If this is SysV without Posix, emulate Posix. */
  121. #if defined(_SYSV) && !defined(_POSIX_SOURCE)
  122. #  define termio termios
  123. #  define _POSIX_SOURCE
  124. #  ifndef TCSANOW
  125. #    define TCSANOW 0
  126. #  endif
  127. #  define tcgetattr(fd, tty)        ioctl(fd, TCGETA, tty)
  128. #  define tcsetattr(fd, flags, tty) ioctl(fd, TCSETA, tty)
  129. #  define tcsendbreak(fd, len)      ioctl(fd, TCSBRK, 0)
  130. #  define speed_t int
  131. #  define cfsetispeed(xtty, xspd) \
  132.         ((xtty)->c_cflag = ((xtty)->c_cflag & ~CBAUD) | (xspd))
  133. #  define cfsetospeed(tty, spd)
  134. #endif
  135.  
  136. /*
  137.  * Drop DTR line and raise it again.
  138.  */
  139. void m_dtrtoggle(fd) 
  140. int fd;
  141. {
  142. #if defined (_POSIX_SOURCE) && !defined(_HPUX_SOURCE)
  143.   struct termios tty, old;
  144.  
  145.   tcgetattr(fd, &tty);
  146.   tcgetattr(fd, &old);
  147.   cfsetospeed(&tty, B0);
  148.   cfsetispeed(&tty, B0);
  149.   tcsetattr(fd, TCSANOW, &tty);
  150.   sleep(1);
  151.   tcsetattr(fd, TCSANOW, &old);
  152. #else
  153. #  ifdef _V7
  154. #    ifndef TIOCCDTR
  155.   /* Just drop speed to 0 and back to normal again */
  156.   struct sgttyb sg, ng;
  157.   
  158.   ioctl(fd, TIOCGETP, &sg);
  159.   ioctl(fd, TIOCGETP, &ng);
  160.   
  161.   ng.sg_ispeed = ng.sg_ospeed = 0;
  162.   ioctl(fd, TIOCSETP, &ng);
  163.   sleep(1);
  164.   ioctl(fd, TIOCSETP, &sg);
  165. #    else
  166.   /* Use the ioctls meant for this type of thing. */
  167.   ioctl(fd, TIOCCDTR, 0);
  168.   sleep(1);
  169.   ioctl(fd, TIOCSDTR, 0);
  170. #    endif
  171. #  endif
  172. #  ifdef _HPUX_SOURCE
  173.   unsigned long mflag = 0L;
  174.  
  175.   ioctl(fd, MCSETAF, &mflag);
  176.   ioctl(fd, MCGETA, &mflag);
  177.   mflag = MRTS | MDTR;
  178.   sleep(1);
  179.   ioctl(fd, MCSETAF, &mflag);
  180. #  endif
  181. #endif
  182. }
  183.  
  184. /*
  185.  * Send a break
  186.  */
  187. void m_break(fd)
  188. int fd;
  189. #ifdef _POSIX_SOURCE
  190. #  ifdef linux
  191.   /* Linux kernels < .99pl8 don't support tcsendbreak() yet.. */
  192.   ioctl(fd, TCSBRK, 0);
  193. #  else
  194.   tcsendbreak(fd, 0);
  195. #  endif
  196. #else
  197. #  ifdef _V7
  198. #    ifndef TIOCSBRK
  199.   struct sgttyb sg, ng;
  200.  
  201.   ioctl(fd, TIOCGETP, &sg);
  202.   ioctl(fd, TIOCGETP, &ng);
  203.   ng.sg_ispeed = ng.sg_ospeed = B110;
  204.   ng.sg_flags = BITS8 | RAW;
  205.   ioctl(fd, TIOCSETP, &ng);
  206.   write(fd, "\0\0\0\0\0\0\0\0\0\0", 10);
  207.   ioctl(fd, TIOCSETP, &sg);
  208. #    else
  209.   ioctl(fd, TIOCSBRK, 0);
  210.   sleep(1);
  211.   ioctl(fd, TIOCCBRK, 0);
  212. #    endif
  213. #  endif
  214. #endif
  215. }
  216.  
  217. /*
  218.  * Get the dcd status
  219.  */
  220. int m_getdcd(fd)
  221. int fd;
  222. {
  223. #ifdef _MINIX
  224.   struct sgttyb sg;
  225.   
  226.   ioctl(fd, TIOCGETP, &sg);
  227.   return(sg.sg_flags & DCD ? 1 : 0);
  228. #else
  229. #  ifdef TIOCMODG
  230.   int mcs;
  231.    
  232.   ioctl(fd, TIOCMODG, &mcs);
  233.   return(mcs & TIOCM_CAR ? 1 : 0);
  234. #  else
  235.   return(0); /* Impossible!! */
  236. #  endif
  237. #endif
  238. }
  239.  
  240. /*
  241.  * Set the DCD status
  242.  */
  243. /*ARGSUSED*/
  244. void m_setdcd(fd, what)
  245. int fd, what;
  246. {
  247. #ifdef _MINIX
  248.   /* Just a kludge for my Minix rs 232 driver */
  249.   struct sgttyb sg;
  250.   
  251.   ioctl(fd, TIOCGETP, &sg);
  252.   if (what)
  253.       sg.sg_flags |= DCD;
  254.   else
  255.       sg.sg_flags &= ~DCD;
  256.   ioctl(fd, TIOCSETP, &sg);
  257. #endif
  258. }
  259.  
  260. /* Variables to save states in */
  261. #ifdef _POSIX_SOURCE
  262. static struct termios savetty;
  263. static int m_word;
  264. #else
  265. #  if defined (_BSD43) || defined (_V7)
  266. static struct sgttyb sg;
  267. static struct tchars tch;
  268. static int lsw;
  269. static int m_word;
  270. #  endif
  271. #endif
  272.  
  273. /*
  274.  * Save the state of a port
  275.  */
  276. void m_savestate(fd)
  277. int fd;
  278. {
  279. #ifdef _POSIX_SOURCE
  280.   tcgetattr(fd, &savetty);
  281. #else
  282. #  if defined(_BSD43) || defined(_V7)
  283.   ioctl(fd, TIOCGETP, &sg);
  284.   ioctl(fd, TIOCGETC, &tch);
  285. #  endif
  286. #  ifdef _BSD43
  287.   ioctl(fd, TIOCLGET, &lsw);
  288. #  endif
  289. #endif
  290. #ifdef TIOCMODG
  291.   ioctl(fd, TIOCMODG, &m_word);
  292. #endif
  293. }
  294.  
  295. /*
  296.  * Restore the state of a port
  297.  */
  298. void m_restorestate(fd)
  299. int fd;
  300. {
  301. #ifdef _POSIX_SOURCE
  302.   tcsetattr(fd, TCSANOW, &savetty);
  303. #else
  304. #  if defined(_BSD43) || defined(_V7)
  305.   ioctl(fd, TIOCSETP, &sg);
  306.   ioctl(fd, TIOCSETC, &tch);
  307. #  endif
  308. #  ifdef _BSD43  
  309.   ioctl(fd, TIOCLSET, &lsw);
  310. #  endif
  311. #endif
  312. #ifdef TIOCMODS
  313.   ioctl(fd, TIOCMODS, &m_word);
  314. #endif
  315. }
  316.  
  317. /*
  318.  * Set the line status so that it will not kill our process
  319.  * if the line hangs up.
  320.  */
  321. /*ARGSUSED*/ 
  322. void m_nohang(fd)
  323. int fd;
  324. {
  325. #ifdef _POSIX_SOURCE
  326.   struct termios sgg;
  327.   
  328.   tcgetattr(fd, &sgg);
  329.   sgg.c_cflag |= CLOCAL;
  330.   tcsetattr(fd, TCSANOW, &sgg);
  331. #else
  332. #  if defined (_BSD43) && defined(LNOHANG)
  333.   int lsw;
  334.   
  335.   ioctl(fd, TIOCLGET, &lsw);
  336.   lsw |= LNOHANG;
  337.   ioctl(fd, TIOCLSET, &lsw);
  338. #  endif
  339. #  ifdef _MINIX
  340.   /* So? What about 1.6 ? */
  341. #  endif
  342. #  ifdef _COHERENT
  343.   /* Doesn't know about this either, me thinks. */
  344. #  endif
  345. #endif
  346. }
  347.  
  348. /*
  349.  * Set hangup on close on/off.
  350.  */
  351. void m_hupcl(fd, on)
  352. int fd;
  353. int on;
  354. {
  355.   /* Eh, I don't know how to do this under BSD (yet..) */
  356. #ifdef _POSIX_SOURCE
  357.   struct termios sgg;
  358.   
  359.   tcgetattr(fd, &sgg);
  360.   if (on)
  361.       sgg.c_cflag |= HUPCL;
  362.   else
  363.     sgg.c_cflag &= ~HUPCL;
  364.   tcsetattr(fd, TCSANOW, &sgg);
  365. #endif
  366. }
  367.  
  368. /*
  369.  * Flush the buffers
  370.  */
  371. void m_flush(fd)
  372. int fd;
  373. {
  374. /* Should I Posixify this, or not? */
  375. #ifdef TCFLSH
  376.   ioctl(fd, TCFLSH, 2);
  377. #endif
  378. #ifdef TIOCFLUSH
  379. #ifdef _COHERENT
  380.   ioctl(fd, TIOCFLUSH, 0);
  381. #else
  382.   ioctl(fd, TIOCFLUSH, (void *)0);
  383. #endif
  384. #endif
  385. }
  386.  
  387. /*
  388.  * Set baudrate, parity and number of bits.
  389.  */
  390. void m_setparms(fd, baudr, par, bits)
  391. int fd;
  392. char *baudr;
  393. char *par;
  394. char *bits;
  395. {
  396.   int spd = -1;
  397.  
  398. #ifdef _POSIX_SOURCE
  399.   struct termios tty;
  400.  
  401.   tcgetattr(fd, &tty);
  402. #else
  403.   struct sgttyb tty;
  404.  
  405.   ioctl(fd, TIOCGETP, &tty);
  406. #endif
  407.  
  408.   switch(atoi(baudr)) {
  409.       case 0:
  410. #ifdef B0
  411.             spd = B0;    break;
  412. #else
  413.             spd = 0;    break;
  414. #endif
  415.       case 300:    spd = B300;    break;
  416.       case 600:    spd = B600;    break;
  417.       case 1200:    spd = B1200;    break;
  418.       case 2400:    spd = B2400;    break;
  419.       case 4800:    spd = B4800;    break;
  420.       case 9600:    spd = B9600;    break;
  421. #ifdef B19200
  422.       case 19200:    spd = B19200;    break;
  423. #else
  424. #  ifdef EXTA
  425.     case 19200:    spd = EXTA;    break;
  426. #   else
  427.     case 19200:    spd = B9600;    break;
  428. #   endif    
  429. #endif    
  430. #ifdef B38400
  431.       case 38400:    spd = B38400;    break;
  432. #else
  433. #  ifdef EXTA
  434.     case 38400:    spd = EXTA;    break;
  435. #   else
  436.     case 38400:    spd = B9600;    break;
  437. #   endif
  438. #endif    
  439.  
  440.   }
  441.   
  442. #if defined (_BSD43) && !defined(_POSIX_SOURCE)
  443.   if (spd != -1) tty.sg_ispeed = tty.sg_ospeed = spd;
  444.   /* Number of bits is ignored */
  445.  
  446.   tty.sg_flags = RAW | TANDEM;
  447.   if (par[0] == 'E')
  448.     tty.sg_flags |= EVENP;
  449.   else if (par[0] == 'O')
  450.     tty.sg_flags |= ODDP;
  451.   else
  452.       tty.sg_flags |= PASS8 | ANYP;
  453.  
  454.   ioctl(fd, TIOCSETP, &tty);
  455.  
  456. #  ifdef TIOCSDTR
  457.   ioctl(fd, TIOCSDTR, 0);
  458. #  endif
  459. #endif
  460.  
  461. #if defined (_V7) && !defined(_POSIX_SOURCE)
  462.   if (spd != -1) tty.sg_ispeed = tty.sg_ospeed = spd;
  463. #ifdef _MINIX
  464.   switch(bits[0]) {
  465.       case '5' : spd = BITS5; break;
  466.       case '6' : spd = BITS6; break;
  467.       case '7' : spd = BITS7; break;
  468.       case '8' :
  469.       default: spd = BITS8; break;
  470.   }
  471.   tty.sg_flags = RAW | spd;
  472. #else
  473.   tty.sg_flags = RAW;
  474. #endif
  475.   if (par[0] == 'E')
  476.     tty.sg_flags |= EVENP;
  477.   else if (par[0] == 'O')
  478.     tty.sg_flags |= ODDP;
  479.  
  480.   ioctl(fd, TIOCSETP, &tty);
  481. #endif
  482.  
  483. #ifdef _POSIX_SOURCE
  484.  
  485.   cfsetospeed(&tty, (speed_t)spd);
  486.   cfsetispeed(&tty, (speed_t)spd);
  487.  
  488.   switch (bits[0]) {
  489.       case '5':
  490.           tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS5;
  491.           break;
  492.       case '6':
  493.           tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS6;
  494.           break;
  495.       case '7':
  496.           tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS7;
  497.           break;
  498.       case '8':
  499.     default:
  500.           tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
  501.           break;
  502.   }        
  503.   /* Set into raw, no echo mode */
  504.   tty.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IUCLC | 
  505.       IXANY | IXON | IXOFF | INPCK | ISTRIP);
  506.   tty.c_iflag |= (BRKINT | IGNPAR);
  507.   tty.c_oflag &= ~OPOST;
  508.   tty.c_lflag = ~(ICANON | ISIG | ECHO | ECHONL | ECHOE | ECHOK);
  509.   tty.c_cflag |= CREAD | CRTSCTS;
  510.   tty.c_cc[VMIN] = 1;
  511.   tty.c_cc[VTIME] = 5;
  512.  
  513.   tty.c_cflag &= ~(PARENB | PARODD);
  514.   if (par[0] == 'E')
  515.     tty.c_cflag |= PARENB;
  516.   else if (par[0] == 'O')
  517.     tty.c_cflag |= PARODD;
  518.  
  519.   tcsetattr(fd, TCSANOW, &tty);
  520. #endif
  521. }
  522.  
  523. /*
  524.  * Wait for child and return pid + status
  525.  */
  526. int m_wait(stt)
  527. int *stt;
  528. {
  529. #if defined (_BSD43) && !defined(_POSIX_SOURCE)
  530.   int pid;
  531.   union wait st1;
  532.   
  533.   pid = wait((void *)&st1);
  534.   *stt = (unsigned)st1.w_retcode + 256 * (unsigned)st1.w_termsig;
  535.   return(pid);
  536. #else
  537.   int pid;
  538.   int st1;
  539.   
  540.   pid = wait(&st1);
  541.   *stt = (unsigned)WEXITSTATUS(st1) + 256 * (unsigned)WTERMSIG(st1);
  542.   return(pid);
  543. #endif
  544. }
  545.