Annotation of embedaddon/lrzsz/src/rbsb.c, revision 1.1

1.1     ! misho       1: /*
        !             2:   rbsb.c - terminal handling stuff for lrzsz
        !             3:   Copyright (C) until 1988 Chuck Forsberg (Omen Technology INC)
        !             4:   Copyright (C) 1994 Matt Porter, Michael D. Black
        !             5:   Copyright (C) 1996, 1997 Uwe Ohse
        !             6: 
        !             7:   This program is free software; you can redistribute it and/or modify
        !             8:   it under the terms of the GNU General Public License as published by
        !             9:   the Free Software Foundation; either version 2, or (at your option)
        !            10:   any later version.
        !            11: 
        !            12:   This program is distributed in the hope that it will be useful,
        !            13:   but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14:   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            15:   GNU General Public License for more details.
        !            16: 
        !            17:   You should have received a copy of the GNU General Public License
        !            18:   along with this program; if not, write to the Free Software
        !            19:   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
        !            20:   02111-1307, USA.
        !            21: 
        !            22:   originally written by Chuck Forsberg
        !            23: */
        !            24: 
        !            25: /*
        !            26:  *  Rev 05-05-1988
        !            27:  *  ============== (not quite, but originated there :-). -- uwe 
        !            28:  */
        !            29: #include "zglobal.h"
        !            30: 
        !            31: #include <stdio.h>
        !            32: #include <errno.h>
        !            33: 
        !            34: #ifndef HAVE_ERRNO_DECLARATION
        !            35: extern int errno;
        !            36: #endif
        !            37: 
        !            38: #ifdef USE_SGTTY
        !            39: #  ifdef LLITOUT
        !            40: long Locmode;          /* Saved "local mode" for 4.x BSD "new driver" */
        !            41: long Locbit = LLITOUT; /* Bit SUPPOSED to disable output translations */
        !            42: #  endif
        !            43: #endif
        !            44: 
        !            45: #ifdef HAVE_SYS_IOCTL_H
        !            46: #include <sys/ioctl.h>
        !            47: #endif
        !            48: 
        !            49: #ifdef MAJOR_IN_MKDEV
        !            50: #include <sys/mkdev.h>
        !            51: #else
        !            52: # ifdef MAJOR_IN_SYSMACROS
        !            53: # include <sys/sysmacros.h>
        !            54: # endif
        !            55: #endif
        !            56: 
        !            57: #if defined(HOWMANY) && HOWMANY  > 255
        !            58: #ifndef NFGVMIN
        !            59: Howmany must be 255 or less
        !            60: #endif
        !            61: #endif
        !            62: 
        !            63: static struct {
        !            64:        unsigned baudr;
        !            65:        speed_t speedcode;
        !            66: } speeds[] = {
        !            67:        {110,   B110},
        !            68:        {300,   B300},
        !            69:        {600,   B600},
        !            70:        {1200,  B1200},
        !            71:        {2400,  B2400},
        !            72:        {4800,  B4800},
        !            73:        {9600,  B9600},
        !            74: #ifdef B19200
        !            75:     {19200,  B19200},
        !            76: #endif
        !            77: #ifdef B38400
        !            78:     {38400,  B38400},
        !            79: #endif
        !            80: #ifdef B57600
        !            81:     {57600,  B57600},
        !            82: #endif
        !            83: #ifdef B115200
        !            84:     {115200,  B115200},
        !            85: #endif
        !            86: #ifdef B230400
        !            87:     {230400,  B230400},
        !            88: #endif
        !            89: #ifdef B460800
        !            90:     {460800,  B460800},
        !            91: #endif
        !            92: #ifdef EXTA
        !            93:        {19200, EXTA},
        !            94: #endif
        !            95: #ifdef EXTB
        !            96:        {38400, EXTB},
        !            97: #endif
        !            98:        {0, 0}
        !            99: };
        !           100: 
        !           101: static unsigned
        !           102: getspeed(speed_t code)
        !           103: {
        !           104:        int n;
        !           105: 
        !           106:        for (n=0; speeds[n].baudr; ++n)
        !           107:                if (speeds[n].speedcode == code)
        !           108:                        return speeds[n].baudr;
        !           109:        return 38400;   /* Assume fifo if ioctl failed */
        !           110: }
        !           111: 
        !           112: /*
        !           113:  * return 1 if stdout and stderr are different devices
        !           114:  *  indicating this program operating with a modem on a
        !           115:  *  different line
        !           116:  */
        !           117: int Fromcu;            /* Were called from cu or yam */
        !           118: int 
        !           119: from_cu(void)
        !           120: {
        !           121: #ifdef HAVE_ST_RDEV
        !           122:        struct stat a, b;
        !           123: #if defined(makedev)
        !           124:        dev_t help=makedev(0,0);
        !           125: #else
        !           126:        int help=0;
        !           127: #endif
        !           128: 
        !           129:        /* in case fstat fails */
        !           130:        a.st_rdev=b.st_rdev=a.st_dev=b.st_dev=help;
        !           131: 
        !           132:        fstat(1, &a); fstat(2, &b);
        !           133: 
        !           134: #if defined(major) && defined(minor)
        !           135:        if (major(a.st_rdev) != major(b.st_rdev) 
        !           136:                || minor(a.st_rdev) != minor(b.st_rdev))
        !           137:                Fromcu=1;
        !           138:        else if (major(a.st_dev) != major(b.st_dev) 
        !           139:                || minor(a.st_dev) != minor(b.st_dev))
        !           140:                Fromcu=1;
        !           141:        else
        !           142:                Fromcu=0;
        !           143: #else
        !           144:        Fromcu = (a.st_rdev != b.st_rdev) || (a.st_dev != b.st_dev);
        !           145: #endif
        !           146: #else
        !           147:        Fromcu = 1; /* a bad guess .. */
        !           148: #endif
        !           149:        return Fromcu;
        !           150: }
        !           151: 
        !           152: 
        !           153: 
        !           154: int Twostop;           /* Use two stop bits */
        !           155: 
        !           156: 
        !           157: #ifdef READCHECK_FIONREAD
        !           158: /*
        !           159:  *  Return non 0 if something to read from io descriptor f
        !           160:  */
        !           161: int 
        !           162: rdchk(int fd)
        !           163: {
        !           164:        static long lf;
        !           165: 
        !           166:        ioctl(fd, FIONREAD, &lf);
        !           167:        return ((int) lf);
        !           168: }
        !           169: #endif
        !           170: 
        !           171: #ifdef READCHECK_GETFL
        !           172: unsigned char checked = '\0' ;
        !           173: /*
        !           174:  * Nonblocking I/O is a bit different in System V, Release 2
        !           175:  */
        !           176: int 
        !           177: rdchk(int fd)
        !           178: {
        !           179:        int lf, savestat;
        !           180: 
        !           181:        savestat = fcntl(fd, F_GETFL) ;
        !           182:        if (savestat == -1)
        !           183:                return 0;
        !           184: #ifdef OVERLY_PARANOID
        !           185:        if (-1==fcntl(fd, F_SETFL, savestat | O_NDELAY))
        !           186:                return 0;
        !           187:        lf = read(fd, &checked, 1) ;
        !           188:        if (-1==fcntl(fd, F_SETFL, savestat)) {
        !           189: #ifdef ENABLE_SYSLOG
        !           190:                if (enable_syslog)
        !           191:                        lsyslog(LOG_CRIT,"F_SETFL failed in rdchk(): %s",       
        !           192:                                strerror(errno));
        !           193: #endif
        !           194:                zpfatal("rdchk: F_SETFL failed\n"); /* lose */
        !           195:                /* there is really no way to recover. And we can't tell
        !           196:                 * the other side what's going on if we can't write to
        !           197:                 * fd, but we try.
        !           198:                 */
        !           199:                canit(fd);
        !           200:                exit(1)        !           201:        }
        !           202: #else
        !           203:        fcntl(fd, F_SETFL, savestat | O_NDELAY);
        !           204:        lf = read(fd, &checked, 1) ;
        !           205:        fcntl(fd, F_SETFL, savestat);
        !           206: #endif
        !           207:        return(lf == -1 && errno==EWOULDBLOCK ? 0 : lf) ;
        !           208: }
        !           209: #endif
        !           210: 
        !           211: 
        !           212: 
        !           213: 
        !           214: 
        !           215: #ifdef USE_TERMIOS
        !           216: struct termios oldtty, tty;
        !           217: #else
        !           218: #  if defined(USE_TERMIO)
        !           219: struct termio oldtty, tty;
        !           220: #  else
        !           221: struct sgttyb oldtty, tty;
        !           222: struct tchars oldtch, tch;
        !           223: #  endif
        !           224: #endif
        !           225: 
        !           226: 
        !           227: /*
        !           228:  * mode(n)
        !           229:  *  3: save old tty stat, set raw mode with flow control
        !           230:  *  2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g
        !           231:  *  1: save old tty stat, set raw mode 
        !           232:  *  0: restore original tty mode
        !           233:  */
        !           234: int 
        !           235: io_mode(int fd, int n)
        !           236: {
        !           237:        static int did0 = FALSE;
        !           238: 
        !           239:        vfile("mode:%d", n);
        !           240: 
        !           241:        switch(n) {
        !           242: 
        !           243: #ifdef USE_TERMIOS
        !           244:        case 2:         /* Un-raw mode used by sz, sb when -g detected */
        !           245:                if(!did0) {
        !           246:                        did0 = TRUE;
        !           247:                        tcgetattr(fd,&oldtty);
        !           248:                }
        !           249:                tty = oldtty;
        !           250: 
        !           251:                tty.c_iflag = BRKINT|IXON;
        !           252: 
        !           253:                tty.c_oflag = 0;        /* Transparent output */
        !           254: 
        !           255:                tty.c_cflag &= ~PARENB; /* Disable parity */
        !           256:                tty.c_cflag |= CS8;     /* Set character size = 8 */
        !           257:                if (Twostop)
        !           258:                        tty.c_cflag |= CSTOPB;  /* Set two stop bits */
        !           259: 
        !           260: #ifdef READCHECK
        !           261:                tty.c_lflag = protocol==ZM_ZMODEM ? 0 : ISIG;
        !           262:                tty.c_cc[VINTR] = protocol==ZM_ZMODEM ? -1 : 030;       /* Interrupt char */
        !           263: #else
        !           264:                tty.c_lflag = 0;
        !           265:                tty.c_cc[VINTR] = protocol==ZM_ZMODEM ? 03 : 030;       /* Interrupt char */
        !           266: #endif
        !           267: #ifdef _POSIX_VDISABLE
        !           268:                if (((int) _POSIX_VDISABLE)!=(-1)) {
        !           269:                        tty.c_cc[VQUIT] = _POSIX_VDISABLE;              /* Quit char */
        !           270:                } else {
        !           271:                        tty.c_cc[VQUIT] = -1;                   /* Quit char */
        !           272:                }
        !           273: #else
        !           274:                tty.c_cc[VQUIT] = -1;                   /* Quit char */
        !           275: #endif
        !           276: #ifdef NFGVMIN
        !           277:                tty.c_cc[VMIN] = 1;
        !           278: #else
        !           279:                tty.c_cc[VMIN] = 3;      /* This many chars satisfies reads */
        !           280: #endif
        !           281:                tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
        !           282: 
        !           283:                tcsetattr(fd,TCSADRAIN,&tty);
        !           284: 
        !           285:                return OK;
        !           286:        case 1:
        !           287:        case 3:
        !           288:                if(!did0) {
        !           289:                        did0 = TRUE;
        !           290:                        tcgetattr(fd,&oldtty);
        !           291:                }
        !           292:                tty = oldtty;
        !           293: 
        !           294:                tty.c_iflag = IGNBRK;
        !           295:                if (n==3) /* with flow control */
        !           296:                        tty.c_iflag |= IXOFF;
        !           297: 
        !           298:                 /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */
        !           299:                tty.c_lflag &= ~(ECHO | ICANON | ISIG | IEXTEN);
        !           300:                tty.c_oflag = 0;        /* Transparent output */
        !           301: 
        !           302:                tty.c_cflag &= ~(PARENB);       /* Same baud rate, disable parity */
        !           303:                /* Set character size = 8 */
        !           304:                tty.c_cflag &= ~(CSIZE);
        !           305:                tty.c_cflag |= CS8;     
        !           306:                if (Twostop)
        !           307:                        tty.c_cflag |= CSTOPB;  /* Set two stop bits */
        !           308: #ifdef NFGVMIN
        !           309:                tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */
        !           310: #else
        !           311:                tty.c_cc[VMIN] = HOWMANY; /* This many chars satisfies reads */
        !           312: #endif
        !           313:                tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
        !           314:                tcsetattr(fd,TCSADRAIN,&tty);
        !           315:                Baudrate = getspeed(cfgetospeed(&tty));
        !           316:                return OK;
        !           317:        case 0:
        !           318:                if(!did0)
        !           319:                        return ERROR;
        !           320:                tcdrain (fd); /* wait until everything is sent */
        !           321:                tcflush (fd,TCIOFLUSH); /* flush input queue */
        !           322:                tcsetattr (fd,TCSADRAIN,&oldtty);
        !           323:                tcflow (fd,TCOON); /* restart output */
        !           324: 
        !           325:                return OK;
        !           326: #endif
        !           327: 
        !           328: #ifdef USE_TERMIO
        !           329:        case 2:         /* Un-raw mode used by sz, sb when -g detected */
        !           330:                if(!did0)
        !           331:                        (void) ioctl(fd, TCGETA, &oldtty);
        !           332:                tty = oldtty;
        !           333: 
        !           334:                tty.c_iflag = BRKINT|IXON;
        !           335: 
        !           336:                tty.c_oflag = 0;        /* Transparent output */
        !           337: 
        !           338:                tty.c_cflag &= ~PARENB; /* Disable parity */
        !           339:                tty.c_cflag |= CS8;     /* Set character size = 8 */
        !           340:                if (Twostop)
        !           341:                        tty.c_cflag |= CSTOPB;  /* Set two stop bits */
        !           342: 
        !           343: 
        !           344: #ifdef READCHECK
        !           345:                tty.c_lflag = protocol==ZM_ZMODEM ? 0 : ISIG;
        !           346:                tty.c_cc[VINTR] = protocol==ZM_ZMODEM ? -1 : 030;       /* Interrupt char */
        !           347: #else
        !           348:                tty.c_lflag = 0;
        !           349:                tty.c_cc[VINTR] = protocol==ZM_ZMODEM ? 03 : 030;       /* Interrupt char */
        !           350: #endif
        !           351:                tty.c_cc[VQUIT] = -1;                   /* Quit char */
        !           352: #ifdef NFGVMIN
        !           353:                tty.c_cc[VMIN] = 1;
        !           354: #else
        !           355:                tty.c_cc[VMIN] = 3;      /* This many chars satisfies reads */
        !           356: #endif
        !           357:                tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
        !           358: 
        !           359:                (void) ioctl(fd, TCSETAW, &tty);
        !           360:                did0 = TRUE;
        !           361:                return OK;
        !           362:        case 1:
        !           363:        case 3:
        !           364:                if(!did0)
        !           365:                        (void) ioctl(fd, TCGETA, &oldtty);
        !           366:                tty = oldtty;
        !           367: 
        !           368:                tty.c_iflag = n==3 ? (IGNBRK|IXOFF) : IGNBRK;
        !           369: 
        !           370:                 /* No echo, crlf mapping, delays, no erase/kill */
        !           371:                tty.c_lflag &= ~(ECHO | ICANON | ISIG);
        !           372: 
        !           373:                tty.c_oflag = 0;        /* Transparent output */
        !           374: 
        !           375:                tty.c_cflag &= ~PARENB; /* Same baud rate, disable parity */
        !           376:                tty.c_cflag |= CS8;     /* Set character size = 8 */
        !           377:                if (Twostop)
        !           378:                        tty.c_cflag |= CSTOPB;  /* Set two stop bits */
        !           379: #ifdef NFGVMIN
        !           380:                tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */
        !           381: #else
        !           382:                tty.c_cc[VMIN] = HOWMANY; /* This many chars satisfies reads */
        !           383: #endif
        !           384:                tty.c_cc[VTIME] = 1;    /* or in this many tenths of seconds */
        !           385:                (void) ioctl(fd, TCSETAW, &tty);
        !           386:                did0 = TRUE;
        !           387:                Baudrate = getspeed(tty.c_cflag & CBAUD);
        !           388:                return OK;
        !           389:        case 0:
        !           390:                if(!did0)
        !           391:                        return ERROR;
        !           392:                (void) ioctl(fd, TCSBRK, 1);    /* Wait for output to drain */
        !           393:                (void) ioctl(fd, TCFLSH, 0);    /* Flush input queue */
        !           394:                (void) ioctl(fd, TCSETAW, &oldtty);     /* Restore modes */
        !           395:                (void) ioctl(fd, TCXONC,1);     /* Restart output */
        !           396:                return OK;
        !           397: #endif
        !           398: 
        !           399: 
        !           400: #ifdef USE_SGTTY
        !           401:        /*
        !           402:         *  NOTE: this should transmit all 8 bits and at the same time
        !           403:         *   respond to XOFF/XON flow control.  If no FIONREAD or other
        !           404:         *   READCHECK alternative, also must respond to INTRRUPT char
        !           405:         *   This doesn't work with V7.  It should work with LLITOUT,
        !           406:         *   but LLITOUT was broken on the machine I tried it on.
        !           407:         */
        !           408:        case 2:         /* Un-raw mode used by sz, sb when -g detected */
        !           409:                if(!did0) {
        !           410:                        ioctl(fd, TIOCEXCL, 0);
        !           411:                        ioctl(fd, TIOCGETP, &oldtty);
        !           412:                        ioctl(fd, TIOCGETC, &oldtch);
        !           413: #ifdef LLITOUT
        !           414:                        ioctl(fd, TIOCLGET, &Locmode);
        !           415: #endif
        !           416:                }
        !           417:                tty = oldtty;
        !           418:                tch = oldtch;
        !           419: #ifdef READCHECK
        !           420:                tch.t_intrc = Zmodem ? -1:030;  /* Interrupt char */
        !           421: #else
        !           422:                tch.t_intrc = Zmodem ? 03:030;  /* Interrupt char */
        !           423: #endif
        !           424:                tty.sg_flags |= (ODDP|EVENP|CBREAK);
        !           425:                tty.sg_flags &= ~(ALLDELAY|CRMOD|ECHO|LCASE);
        !           426:                ioctl(fd, TIOCSETP, &tty);
        !           427:                ioctl(fd, TIOCSETC, &tch);
        !           428: #ifdef LLITOUT
        !           429:                ioctl(fd, TIOCLBIS, &Locbit);
        !           430: #else
        !           431:                bibi(99);       /* un-raw doesn't work w/o lit out */
        !           432: #endif
        !           433:                did0 = TRUE;
        !           434:                return OK;
        !           435:        case 1:
        !           436:        case 3:
        !           437:                if(!did0) {
        !           438:                        ioctl(fd, TIOCEXCL, 0);
        !           439:                        ioctl(fd, TIOCGETP, &oldtty);
        !           440:                        ioctl(fd, TIOCGETC, &oldtch);
        !           441: #ifdef LLITOUT
        !           442:                        ioctl(fd, TIOCLGET, &Locmode);
        !           443: #endif
        !           444:                }
        !           445:                tty = oldtty;
        !           446:                tty.sg_flags |= RAW;
        !           447:                tty.sg_flags &= ~ECHO;
        !           448:                ioctl(fd, TIOCSETP, &tty);
        !           449:                did0 = TRUE;
        !           450:                Baudrate = getspeed(tty.sg_ospeed);
        !           451:                return OK;
        !           452:        case 0:
        !           453:                if(!did0)
        !           454:                        return ERROR;
        !           455:                ioctl(fd, TIOCSETP, &oldtty);
        !           456:                ioctl(fd, TIOCSETC, &oldtch);
        !           457:                ioctl(fd, TIOCNXCL, 0);
        !           458: #ifdef LLITOUT
        !           459:                ioctl(fd, TIOCLSET, &Locmode);
        !           460: #endif
        !           461: #ifdef TIOCFLUSH
        !           462:                { int x=1; ioctl(fd,TIOCFLUSH,&x); }
        !           463: #endif
        !           464: #endif
        !           465: 
        !           466:                return OK;
        !           467:        default:
        !           468:                return ERROR;
        !           469:        }
        !           470: }
        !           471: 
        !           472: void
        !           473: sendbrk(int fd)
        !           474: {
        !           475: #ifdef USE_TERMIOS
        !           476:        tcsendbreak(fd,0);
        !           477: #endif
        !           478: #ifdef USE_TERMIO
        !           479:        ioctl(fd, TCSBRK, 0);
        !           480: #endif
        !           481: #ifdef USE_SGTTY
        !           482: #ifdef TIOCSBRK
        !           483:        sleep(1);
        !           484:        ioctl(fd, TIOCSBRK, 0);
        !           485:        sleep(1);
        !           486:        ioctl(fd, TIOCCBRK, 0);
        !           487: #endif
        !           488: #endif
        !           489: }
        !           490: 
        !           491: void
        !           492: purgeline(int fd)
        !           493: {
        !           494:        readline_purge();
        !           495: #ifdef TCFLSH
        !           496:        ioctl(fd, TCFLSH, 0);
        !           497: #else
        !           498:        lseek(fd, 0L, 2);
        !           499: #endif
        !           500: }
        !           501: 
        !           502: /* End of rbsb.c */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>