home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / RZSZ0127.ZIP / RBSB.C < prev    next >
C/C++ Source or Header  |  1994-01-27  |  10KB  |  541 lines

  1. /*
  2.  *    V7/BSD HACKERS:  SEE NOTES UNDER mode(2) !!!
  3.  *
  4.  *   This file is #included so the main file can set parameters such as HOWMANY.
  5.  *   See the main files (rz.c/sz.c) for compile instructions.
  6.  */
  7.  
  8. char *Copyr = "Copyright 1994 Omen Technology Inc All Rights Reserved";
  9.  
  10. #ifdef V7
  11. #include <sys/types.h>
  12. #include <sys/stat.h>
  13. #define STAT
  14. #include <sgtty.h>
  15. #define OS "V7/BSD"
  16. #ifdef LLITOUT
  17. long Locmode;        /* Saved "local mode" for 4.x BSD "new driver" */
  18. long Locbit = LLITOUT;    /* Bit SUPPOSED to disable output translations */
  19. #include <strings.h>
  20. #endif
  21. #endif
  22.  
  23. #ifdef USG
  24. #include <sys/types.h>
  25. #include <sys/stat.h>
  26. #define STAT
  27. #include <termio.h>
  28. #define OS "SYS III/V"
  29. #define MODE2OK
  30. #include <string.h>
  31. #include <stdlib.h>
  32. #include <unistd.h>
  33. #endif
  34.  
  35. #ifdef POSIX
  36. #define USG
  37. #include <sys/types.h>
  38. #include <sys/stat.h>
  39. #include <sys/ioctl.h>
  40. #define STAT
  41. #include <termios.h>
  42. #define OS "POSIX"
  43. #include <string.h>
  44. #include <stdlib.h>
  45. #include <unistd.h>
  46. #ifndef READCHECK
  47. #ifndef FIONREAD
  48. #define SV
  49. #endif
  50. #endif
  51. #endif
  52.  
  53.  
  54. #ifdef T6K
  55. #include <sys/ioctl.h>        /* JPRadley: for the Tandy 6000 */
  56. #endif
  57.  
  58. #include <setjmp.h>
  59.  
  60. #if HOWMANY  > 255
  61. Howmany must be 255 or less
  62. #endif
  63.  
  64.  /*
  65.  *  Some systems (Venix, Coherent, Regulus) may not support tty raw mode
  66.  *  read(2) the same way as Unix. ONEREAD must be defined to force one
  67.  *  character reads for these systems. Added 7-01-84 CAF
  68.  */
  69.  
  70. #define sendline(c) putc(c & 0377, Ttystream)
  71. #define xsendline(c) putc(c, Ttystream)
  72.  
  73. char *Nametty;
  74. FILE *Ttystream;
  75. int Tty;
  76. char linbuf[HOWMANY];
  77. char xXbuf[BUFSIZ];
  78. int Lleft=0;        /* number of characters in linbuf */
  79. jmp_buf tohere;        /* For the interrupt on RX timeout */
  80. #ifdef ONEREAD
  81. /* Sorry, Regulus and some others don't work right in raw mode! */
  82. int Readnum = 1;    /* Number of bytes to ask for in read() from modem */
  83. #else
  84. int Readnum = HOWMANY;    /* Number of bytes to ask for in read() from modem */
  85. #endif
  86. int Verbose=0;
  87.  
  88.  
  89. /*
  90.  *  The following uses an external rdchk() routine if available,
  91.  *  otherwise defines the function for BSD or fakes it for SYSV.
  92.  */
  93.  
  94. #ifndef READCHECK
  95. #ifdef FIONREAD
  96. #define READCHECK
  97. /*
  98.  *  Return non 0 iff something to read from io descriptor f
  99.  */
  100. rdchk(f)
  101. {
  102.     static long lf;
  103.  
  104.     ioctl(f, FIONREAD, &lf);
  105.     return ((int) lf);
  106. }
  107.  
  108. #else        /* FIONREAD */
  109.  
  110. #ifdef SV
  111. #define READCHECK
  112. #include <fcntl.h>
  113.  
  114. int checked = 0;
  115. /*
  116.  * Nonblocking I/O is a bit different in System V, Release 2
  117.  *  Note: this rdchk vsn throws away a byte, OK for ZMODEM
  118.  *  sender because protocol design anticipates this problem.
  119.  */
  120. #define EATSIT
  121. rdchk(f)
  122. {
  123.     int lf, savestat;
  124.     static char bchecked;
  125.  
  126.     savestat = fcntl(f, F_GETFL) ;
  127. #ifdef O_NDELAY
  128.     fcntl(f, F_SETFL, savestat | O_NDELAY) ;
  129. #else
  130.     fcntl(f, F_SETFL, savestat | O_NONBLOCK) ;
  131. #endif
  132.     lf = read(f, &bchecked, 1) ;
  133.     fcntl(f, F_SETFL, savestat) ;
  134.     checked = bchecked & 0377;    /* force unsigned byte */
  135.     return(lf) ;
  136. }
  137. #endif
  138. #endif
  139. #endif
  140.  
  141.  
  142. struct {
  143.     unsigned baudr;
  144.     int speedcode;
  145. } speeds[] = {
  146.     110,    B110,
  147. #ifdef B150
  148.     150,    B150,
  149. #endif
  150.     300,    B300,
  151.     600,    B600,
  152.     1200,    B1200,
  153.     2400,    B2400,
  154.     4800,    B4800,
  155.     9600,    B9600,
  156. #ifdef B19200
  157.     19200,    B19200,
  158. #endif
  159. #ifdef EXTA
  160.     19200,    EXTA,
  161. #endif
  162. #ifdef B38400
  163.     38400,    B38400,
  164. #endif
  165. #ifdef EXTB
  166.     38400,    EXTB,
  167. #endif
  168.     0,    0
  169. };
  170. static unsigned
  171. getspeed(code)
  172. {
  173.     register n;
  174.  
  175.     for (n=0; speeds[n].baudr; ++n)
  176.         if (speeds[n].speedcode == code)
  177.             return speeds[n].baudr;
  178.     if (code > 49)
  179.         return ((unsigned)code);
  180.     return 1;    /* Assume fifo if ioctl failed */
  181. }
  182.  
  183.  
  184. #ifdef ICANON
  185. #ifdef POSIX
  186. struct termios oldtty, tty;
  187. #else
  188. struct termio oldtty, tty;
  189. #endif
  190. #else
  191. struct sgttyb oldtty, tty;
  192. struct tchars oldtch, tch;
  193. #endif
  194.  
  195. /*
  196.  * mode(n)
  197.  *  3: save old tty stat, set raw mode with flow control
  198.  *  2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g
  199.  *  1: save old tty stat, set raw mode 
  200.  *  0: restore original tty mode
  201.  */
  202. mode(n)
  203. {
  204.     static did0 = FALSE;
  205.  
  206.     vfile("mode:%d", n);
  207.     switch(n) {
  208. #ifdef USG
  209.     case 2:        /* Un-raw mode used by sz, sb when -g detected */
  210. #ifdef POSIX
  211.         if(!did0)
  212.             (void) tcgetattr(Tty, &oldtty);
  213. #else
  214.         if(!did0)
  215.             (void) ioctl(Tty, TCGETA, &oldtty);
  216. #endif
  217.         tty = oldtty;
  218.  
  219.         tty.c_iflag = BRKINT|IXON;
  220.  
  221.         tty.c_oflag = 0;    /* Transparent output */
  222.  
  223.         tty.c_cflag &= ~(PARENB|CSIZE);        /* Disable parity */
  224.         tty.c_cflag |= (CREAD|CS8);    /* Set character size = 8 */
  225.  
  226.  
  227. #ifdef READCHECK
  228.         tty.c_lflag = Zmodem ? 0 : ISIG;
  229.         tty.c_cc[VINTR] = Zmodem ? -1:030;    /* Interrupt char */
  230. #else
  231.         tty.c_lflag = ISIG;
  232.         tty.c_cc[VINTR] = Zmodem ? 03:030;    /* Interrupt char */
  233. #endif
  234.         tty.c_cc[VQUIT] = -1;            /* Quit char */
  235. #ifdef NFGVMIN
  236.         tty.c_cc[VMIN] = 1;
  237. #else
  238.         tty.c_cc[VMIN] = 3;     /* This many chars satisfies reads */
  239. #endif
  240.         tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
  241.  
  242. #ifdef POSIX
  243.         (void) tcsetattr(Tty, TCSADRAIN, &tty);
  244. #else
  245.         (void) ioctl(Tty, TCSETAW, &tty);
  246. #endif
  247.         did0 = TRUE;
  248.         return OK;
  249.     case 1:
  250.     case 3:
  251. #ifdef POSIX
  252.         if(!did0)
  253.             (void) tcgetattr(Tty, &oldtty);
  254. #else
  255.         if(!did0)
  256.             (void) ioctl(Tty, TCGETA, &oldtty);
  257. #endif
  258.         tty = oldtty;
  259.  
  260.         tty.c_iflag = n==3 ? (IXON|IXOFF) : IXOFF;
  261.  
  262.         tty.c_lflag = 0;
  263.  
  264.         tty.c_oflag = 0;
  265.  
  266.         tty.c_cflag &= ~(CSIZE|PARENB);    /* disable parity */
  267.         tty.c_cflag |= CS8;    /* Set character size = 8 */
  268. #ifdef NFGVMIN
  269.         tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */
  270. #else
  271.         tty.c_cc[VMIN] = HOWMANY; /* This many chars satisfies reads */
  272. #endif
  273.         tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
  274. #ifdef POSIX
  275.         (void) tcsetattr(Tty, TCSADRAIN, &tty);
  276. #else
  277.         (void) ioctl(Tty, TCSETAW, &tty);
  278. #endif
  279.         did0 = TRUE;
  280. #ifdef POSIX
  281.         Effbaud = Baudrate = getspeed(cfgetospeed(&tty));
  282. #else
  283.         Effbaud = Baudrate = getspeed(tty.c_cflag & CBAUD);
  284. #endif
  285.         vfile("Baudrate = %u\n", Baudrate);
  286.         return OK;
  287. #endif
  288. #ifdef V7
  289.     /*
  290.      *  NOTE: this should transmit all 8 bits and at the same time
  291.      *   respond to XOFF/XON flow control.  If no FIONREAD or other
  292.      *   rdchk() alternative, also must respond to INTRRUPT char
  293.      *   This doesn't work with V7.  It should work with LLITOUT,
  294.      *   but LLITOUT was broken on the machine I tried it on.
  295.      */
  296.     case 2:        /* Un-raw mode used by sz, sb when -g detected */
  297.         if(!did0) {
  298.             ioctl(Tty, TIOCEXCL, 0);
  299.             ioctl(Tty, TIOCGETP, &oldtty);
  300.             ioctl(Tty, TIOCGETC, &oldtch);
  301. #ifdef LLITOUT
  302.             ioctl(Tty, TIOCLGET, &Locmode);
  303. #endif
  304.         }
  305.         tty = oldtty;
  306.         tch = oldtch;
  307. #ifdef READCHECK
  308.         tch.t_intrc = Zmodem ? -1:030;    /* Interrupt char */
  309. #else
  310.         tch.t_intrc = Zmodem ? 03:030;    /* Interrupt char */
  311. #endif
  312.         tty.sg_flags |= (ODDP|EVENP|CBREAK);
  313.         tty.sg_flags &= ~(ALLDELAY|CRMOD|ECHO|LCASE);
  314.         ioctl(Tty, TIOCSETP, &tty);
  315.         ioctl(Tty, TIOCSETC, &tch);
  316. #ifdef LLITOUT
  317.         ioctl(Tty, TIOCLBIS, &Locbit);
  318. #else
  319.         bibi(99);    /* un-raw doesn't work w/o lit out */
  320. #endif
  321.         did0 = TRUE;
  322.         return OK;
  323.     case 1:
  324.     case 3:
  325.         if(!did0) {
  326.             ioctl(Tty, TIOCEXCL, 0);
  327.             ioctl(Tty, TIOCGETP, &oldtty);
  328.             ioctl(Tty, TIOCGETC, &oldtch);
  329. #ifdef LLITOUT
  330.             ioctl(Tty, TIOCLGET, &Locmode);
  331. #endif
  332.         }
  333.         tty = oldtty;
  334.         tty.sg_flags |= (RAW|TANDEM);
  335.         tty.sg_flags &= ~ECHO;
  336.         ioctl(Tty, TIOCSETP, &tty);
  337.         did0 = TRUE;
  338.         Effbaud = Baudrate = getspeed(tty.sg_ospeed);
  339.         return OK;
  340. #endif
  341.     case 0:
  342.         if(!did0)
  343.             return ERROR;
  344. #ifdef USG
  345. #ifdef POSIX
  346.         (void) tcdrain(Tty);    /* Wait for output to drain */
  347.         (void) tcflush(Tty, TCIFLUSH);    /* Flush input queue */
  348.         (void) tcsetattr(Tty, TCSADRAIN, &oldtty);    /* Restore */
  349.         (void) tcflow(Tty, TCOON);    /* Restart output */
  350. #else
  351.         (void) ioctl(Tty, TCSBRK, 1);    /* Wait for output to drain */
  352.         (void) ioctl(Tty, TCFLSH, 1);    /* Flush input queue */
  353.         (void) ioctl(Tty, TCSETAW, &oldtty);    /* Restore modes */
  354.         (void) ioctl(Tty, TCXONC,1);    /* Restart output */
  355. #endif
  356. #endif
  357. #ifdef V7
  358.         ioctl(Tty, TIOCSETP, &oldtty);
  359.         ioctl(Tty, TIOCSETC, &oldtch);
  360.         ioctl(Tty, TIOCNXCL, 0);
  361. #ifdef LLITOUT
  362.         ioctl(Tty, TIOCLSET, &Locmode);
  363. #endif
  364. #endif
  365.  
  366.         return OK;
  367.     default:
  368.         return ERROR;
  369.     }
  370. }
  371.  
  372. sendbrk()
  373. {
  374. #ifdef V7
  375. #ifdef TIOCSBRK
  376. #define CANBREAK
  377.     sleep(1);
  378.     ioctl(Tty, TIOCSBRK, 0);
  379.     sleep(1);
  380.     ioctl(Tty, TIOCCBRK, 0);
  381. #endif
  382. #endif
  383. #ifdef USG
  384. #define CANBREAK
  385. #ifdef POSIX
  386.     tcsendbreak(Tty, 200);
  387. #else
  388.     ioctl(Tty, TCSBRK, 0);
  389. #endif
  390. #endif
  391. }
  392.  
  393. /* Initialize tty device for serial file xfer */
  394. inittty()
  395. {
  396.     if ((Nametty = ttyname(2)) && *Nametty) {
  397.         Tty = open(Nametty, 2);
  398.     } else {
  399.         Tty = open(Nametty = "/dev/tty", 2);
  400.     }
  401.  
  402.     if (Tty <= 0) {
  403.         perror(Nametty);  exit(2);
  404.     }
  405.     Ttystream = fdopen(Tty, "w");
  406. }
  407.  
  408. flushmoc()
  409. {
  410.     fflush(Ttystream);
  411. }
  412. flushmo()
  413. {
  414.     fflush(Ttystream);
  415. }
  416.  
  417. /*
  418.  * This version of readline is reasoably well suited for
  419.  * reading many characters.
  420.  *
  421.  * timeout is in tenths of seconds
  422.  */
  423. void
  424. alrm(c)
  425. {
  426.     longjmp(tohere, -1);
  427. }
  428. readline(timeout)
  429. int timeout;
  430. {
  431.     register n;
  432.     static char *cdq;    /* pointer for removing chars from linbuf */
  433.  
  434.     if (--Lleft >= 0) {
  435.         if (Verbose > 8) {
  436.             fprintf(stderr, "%02x ", *cdq&0377);
  437.         }
  438.         return (*cdq++ & 0377);
  439.     }
  440.     n = timeout/10;
  441.     if (n < 2)
  442.         n = 2;
  443.     if (Verbose > 5)
  444.         fprintf(stderr, "Calling read: alarm=%d  Readnum=%d ",
  445.           n, Readnum);
  446.     if (setjmp(tohere)) {
  447. #ifdef TIOCFLUSH
  448. /*        ioctl(Tty, TIOCFLUSH, 0); */
  449. #endif
  450.         Lleft = 0;
  451.         if (Verbose>1)
  452.             fprintf(stderr, "Readline:TIMEOUT\n");
  453.         return TIMEOUT;
  454.     }
  455.     signal(SIGALRM, alrm); alarm(n);
  456.     errno = 0;
  457.     Lleft=read(Tty, cdq=linbuf, Readnum);
  458.     alarm(0);
  459.     if (Verbose > 5) {
  460.         fprintf(stderr, "Read returned %d bytes errno=%d\n",
  461.           Lleft, errno);
  462.     }
  463.     if (Lleft < 1)
  464.         return TIMEOUT;
  465.     if (Verbose > 8) {
  466.         for (n = Lleft; --n >= 0; ) {
  467.             fprintf(stderr, "%02x ", *cdq&0377);
  468.         }
  469.         fprintf(stderr, "\n");
  470.     }
  471.     --Lleft;
  472.     return (*cdq++ & 0377);
  473. }
  474.  
  475.  
  476.  
  477. /*
  478.  * Purge the modem input queue of all characters
  479.  */
  480. purgeline()
  481. {
  482.     Lleft = 0;
  483. #ifdef USG
  484. #ifdef POSIX
  485.     tcflush(Tty, 0);
  486. #else
  487.     ioctl(Tty, TCFLSH, 0);
  488. #endif
  489. #else
  490.     lseek(Tty, 0L, 2);
  491. #endif
  492. }
  493.  
  494.  
  495. /* send cancel string to get the other end to shut up */
  496. canit()
  497. {
  498.     static char canistr[] = {
  499.      24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
  500.     };
  501.  
  502.     zmputs(canistr);
  503.     Lleft=0;    /* Do read next time ... */
  504. }
  505.  
  506. /*
  507.  * Send a string to the modem, processing for \336 (sleep 1 sec)
  508.  *   and \335 (break signal)
  509.  */
  510. zmputs(s)
  511. char *s;
  512. {
  513.     register c;
  514.  
  515.     while (*s) {
  516.         switch (c = *s++) {
  517.         case '\336':
  518.             sleep(1); continue;
  519.         case '\335':
  520.             sendbrk(); continue;
  521.         default:
  522.             sendline(c);
  523.         }
  524.     }
  525.     flushmo();
  526. }
  527.  
  528.  
  529. /* VARARGS1 */
  530. vfile(f, a, b, c, d)
  531. char *f;
  532. long a, b, c, d;
  533. {
  534.     if (Verbose > 2) {
  535.         fprintf(stderr, f, a, b, c, d);
  536.         fprintf(stderr, "\n");
  537.     }
  538. }
  539.  
  540. /* End of rbsb.c */
  541.