Annotation of embedaddon/lrzsz/src/zm.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:   zm.c - zmodem protocol handling lowlevelstuff
                      3:   Copyright (C) until 1998 Chuck Forsberg (OMEN Technology Inc)
                      4:   Copyright (C) 1996, 1997 Uwe Ohse
                      5: 
                      6:   This program is free software; you can redistribute it and/or modify
                      7:   it under the terms of the GNU General Public License as published by
                      8:   the Free Software Foundation; either version 2, or (at your option)
                      9:   any later version.
                     10: 
                     11:   This program is distributed in the hope that it will be useful,
                     12:   but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14:   GNU General Public License for more details.
                     15: 
                     16:   You should have received a copy of the GNU General Public License
                     17:   along with this program; if not, write to the Free Software
                     18:   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
                     19:   02111-1307, USA.
                     20: 
                     21:   originally written by Chuck Forsberg
                     22: */
                     23: /* historical comment: -- uwe
                     24:  *   Z M . C
                     25:  *    ZMODEM protocol primitives
                     26:  *    05-09-88  Chuck Forsberg Omen Technology Inc
                     27:  *
                     28:  * Entry point Functions:
                     29:  *     zsbhdr(type, hdr) send binary header
                     30:  *     zshhdr(type, hdr) send hex header
                     31:  *     zgethdr(hdr, eflag) receive header - binary or hex
                     32:  *     zsdata(buf, len, frameend) send data
                     33:  *     zrdata(buf, len, bytes_received) receive data
                     34:  *     stohdr(pos) store position data in Txhdr
                     35:  *     long rclhdr(hdr) recover position offset from header
                     36:  */
                     37: 
                     38: 
                     39: #include "zglobal.h"
                     40: 
                     41: #include <stdio.h>
                     42: 
                     43: unsigned int Rxtimeout = 100;          /* Tenths of seconds to wait for something */
                     44: 
                     45: /* Globals used by ZMODEM functions */
                     46: int Rxframeind;                /* ZBIN ZBIN32, or ZHEX type of frame received */
                     47: int Rxtype;            /* Type of header received */
                     48: char Rxhdr[4];         /* Received header */
                     49: char Txhdr[4];         /* Transmitted header */
                     50: long Txpos;            /* Transmitted file position */
                     51: int Txfcs32;           /* TRUE means send binary frames with 32 bit FCS */
                     52: int Crc32t;            /* Display flag indicating 32 bit CRC being sent */
                     53: int Crc32;             /* Display flag indicating 32 bit CRC being received */
                     54: int Znulls;            /* Number of nulls to send at beginning of ZDATA hdr */
                     55: char Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */
                     56: 
                     57: static char lastsent;  /* Last char we sent */
                     58: int turbo_escape;
                     59: int bytes_per_error=0;
                     60: 
                     61: static const char *frametypes[] = {
                     62:        "Carrier Lost",         /* -3 */
                     63:        "TIMEOUT",              /* -2 */
                     64:        "ERROR",                /* -1 */
                     65: #define FTOFFSET 3
                     66:        "ZRQINIT",
                     67:        "ZRINIT",
                     68:        "ZSINIT",
                     69:        "ZACK",
                     70:        "ZFILE",
                     71:        "ZSKIP",
                     72:        "ZNAK",
                     73:        "ZABORT",
                     74:        "ZFIN",
                     75:        "ZRPOS",
                     76:        "ZDATA",
                     77:        "ZEOF",
                     78:        "ZFERR",
                     79:        "ZCRC",
                     80:        "ZCHALLENGE",
                     81:        "ZCOMPL",
                     82:        "ZCAN",
                     83:        "ZFREECNT",
                     84:        "ZCOMMAND",
                     85:        "ZSTDERR",
                     86:        "xxxxx"
                     87: #define FRTYPES 22     /* Total number of frame types in this array */
                     88:                        /*  not including psuedo negative entries */
                     89: };
                     90: 
                     91: #define badcrc _("Bad CRC")
                     92: /* static char *badcrc = "Bad CRC"; */
                     93: static inline int noxrd7 __P ((void));
                     94: static inline int zdlread __P ((void));
                     95: static int zdlread2 __P ((int)) LRZSZ_ATTRIB_REGPARM(1);
                     96: static inline int zgeth1 __P ((void));
                     97: static void zputhex __P ((int c, char *pos));
                     98: static inline int zgethex __P ((void));
                     99: static int zrbhdr __P ((char *hdr));
                    100: static int zrbhdr32 __P ((char *hdr));
                    101: static int zrhhdr __P ((char *hdr));
                    102: static char zsendline_tab[256];
                    103: static int zrdat32 __P ((char *buf, int length, size_t *));
                    104: static void zsbh32 __P ((char *hdr, int type));
                    105: 
                    106: extern int zmodem_requested;
                    107: 
                    108: #define sendline(c) putchar((c) & 0377)
                    109: #define xsendline(c) putchar(c)
                    110: 
                    111: /*
                    112:  * Read a character from the modem line with timeout.
                    113:  *  Eat parity, XON and XOFF characters.
                    114:  */
                    115: static inline int
                    116: noxrd7(void)
                    117: {
                    118:        register int c;
                    119: 
                    120:        for (;;) {
                    121:                if ((c = READLINE_PF(Rxtimeout)) < 0)
                    122:                        return c;
                    123:                switch (c &= 0177) {
                    124:                case XON:
                    125:                case XOFF:
                    126:                        continue;
                    127:                default:
                    128:                        if (Zctlesc && !(c & 0140))
                    129:                                continue;
                    130:                case '\r':
                    131:                case '\n':
                    132:                case ZDLE:
                    133:                        return c;
                    134:                }
                    135:        }
                    136: }
                    137: 
                    138: static inline int
                    139: zgeth1(void)
                    140: {
                    141:        register int c, n;
                    142: 
                    143:        if ((c = noxrd7()) < 0)
                    144:                return c;
                    145:        n = c - '0';
                    146:        if (n > 9)
                    147:                n -= ('a' - ':');
                    148:        if (n & ~0xF)
                    149:                return ERROR;
                    150:        if ((c = noxrd7()) < 0)
                    151:                return c;
                    152:        c -= '0';
                    153:        if (c > 9)
                    154:                c -= ('a' - ':');
                    155:        if (c & ~0xF)
                    156:                return ERROR;
                    157:        c += (n<<4);
                    158:        return c;
                    159: }
                    160: 
                    161: /* Decode two lower case hex digits into an 8 bit byte value */
                    162: static inline int
                    163: zgethex(void)
                    164: {
                    165:        register int c;
                    166: 
                    167:        c = zgeth1();
                    168:        VPRINTF(9,("zgethex: %02X", c));
                    169:        return c;
                    170: }
                    171: 
                    172: /*
                    173:  * Read a byte, checking for ZMODEM escape encoding
                    174:  *  including CAN*5 which represents a quick abort
                    175:  */
                    176: static inline int
                    177: zdlread(void)
                    178: {
                    179:        int c;
                    180:        /* Quick check for non control characters */
                    181:        if ((c = READLINE_PF(Rxtimeout)) & 0140)
                    182:                return c;
                    183:        return zdlread2(c);
                    184: }
                    185: /* no, i don't like gotos. -- uwe */
                    186: static int
                    187: zdlread2(int c)
                    188: {
                    189:        goto jump_over; /* bad style */
                    190: 
                    191: again:
                    192:        /* Quick check for non control characters */
                    193:        if ((c = READLINE_PF(Rxtimeout)) & 0140)
                    194:                return c;
                    195: jump_over:
                    196:        switch (c) {
                    197:        case ZDLE:
                    198:                break;
                    199:        case XON:
                    200:        case (XON|0200):
                    201:        case XOFF:
                    202:        case (XOFF|0200):
                    203:                goto again;
                    204:        default:
                    205:                if (Zctlesc && !(c & 0140)) {
                    206:                        goto again;
                    207:                }
                    208:                return c;
                    209:        }
                    210: again2:
                    211:        if ((c = READLINE_PF(Rxtimeout)) < 0)
                    212:                return c;
                    213:        if (c == CAN && (c = READLINE_PF(Rxtimeout)) < 0)
                    214:                return c;
                    215:        if (c == CAN && (c = READLINE_PF(Rxtimeout)) < 0)
                    216:                return c;
                    217:        if (c == CAN && (c = READLINE_PF(Rxtimeout)) < 0)
                    218:                return c;
                    219:        switch (c) {
                    220:        case CAN:
                    221:                return GOTCAN;
                    222:        case ZCRCE:
                    223:        case ZCRCG:
                    224:        case ZCRCQ:
                    225:        case ZCRCW:
                    226:                return (c | GOTOR);
                    227:        case ZRUB0:
                    228:                return 0177;
                    229:        case ZRUB1:
                    230:                return 0377;
                    231:        case XON:
                    232:        case (XON|0200):
                    233:        case XOFF:
                    234:        case (XOFF|0200):
                    235:                goto again2;
                    236:        default:
                    237:                if (Zctlesc && ! (c & 0140)) {
                    238:                        goto again2;
                    239:                }
                    240:                if ((c & 0140) ==  0100)
                    241:                        return (c ^ 0100);
                    242:                break;
                    243:        }
                    244:        VPRINTF(2,(_("Bad escape sequence %x"), c));
                    245:        return ERROR;
                    246: }
                    247: 
                    248: 
                    249: 
                    250: /*
                    251:  * Send character c with ZMODEM escape sequence encoding.
                    252:  *  Escape XON, XOFF. Escape CR following @ (Telenet net escape)
                    253:  */
                    254: inline void 
                    255: zsendline(int c)
                    256: {
                    257: 
                    258:        switch(zsendline_tab[(unsigned) (c&=0377)])
                    259:        {
                    260:        case 0: 
                    261:                xsendline(lastsent = c); 
                    262:                break;
                    263:        case 1:
                    264:                xsendline(ZDLE);
                    265:                c ^= 0100;
                    266:                xsendline(lastsent = c);
                    267:                break;
                    268:        case 2:
                    269:                if ((lastsent & 0177) != '@') {
                    270:                        xsendline(lastsent = c);
                    271:                } else {
                    272:                        xsendline(ZDLE);
                    273:                        c ^= 0100;
                    274:                        xsendline(lastsent = c);
                    275:                }
                    276:                break;
                    277:        }
                    278: }
                    279: 
                    280: static inline void 
                    281: zsendline_s(const char *s, size_t count) 
                    282: {
                    283:        const char *end=s+count;
                    284:        while(s!=end) {
                    285:                int last_esc=0;
                    286:                const char *t=s;
                    287:                while (t!=end) {
                    288:                        last_esc=zsendline_tab[(unsigned) ((*t) & 0377)];
                    289:                        if (last_esc) 
                    290:                                break;
                    291:                        t++;
                    292:                }
                    293:                if (t!=s) {
                    294:                        fwrite(s,(size_t)(t-s),1,stdout);
                    295:                        lastsent=t[-1];
                    296:                        s=t;
                    297:                }
                    298:                if (last_esc) {
                    299:                        int c=*s;
                    300:                        switch(last_esc) {
                    301:                        case 0: 
                    302:                                xsendline(lastsent = c); 
                    303:                                break;
                    304:                        case 1:
                    305:                                xsendline(ZDLE);
                    306:                                c ^= 0100;
                    307:                                xsendline(lastsent = c);
                    308:                                break;
                    309:                        case 2:
                    310:                                if ((lastsent & 0177) != '@') {
                    311:                                        xsendline(lastsent = c);
                    312:                                } else {
                    313:                                        xsendline(ZDLE);
                    314:                                        c ^= 0100;
                    315:                                        xsendline(lastsent = c);
                    316:                                }
                    317:                                break;
                    318:                        }
                    319:                        s++;
                    320:                }
                    321:        }
                    322: }
                    323: 
                    324: 
                    325: /* Send ZMODEM binary header hdr of type type */
                    326: void 
                    327: zsbhdr(int type, char *hdr)
                    328: {
                    329:        register int n;
                    330:        register unsigned short crc;
                    331: 
                    332:        VPRINTF(3,("zsbhdr: %s %lx", frametypes[type+FTOFFSET], rclhdr(hdr)));
                    333:        if (type == ZDATA)
                    334:                for (n = Znulls; --n >=0; )
                    335:                        xsendline(0);
                    336: 
                    337:        xsendline(ZPAD); xsendline(ZDLE);
                    338: 
                    339:        Crc32t=Txfcs32;
                    340:        if (Crc32t)
                    341:                zsbh32(hdr, type);
                    342:        else {
                    343:                xsendline(ZBIN); zsendline(type); crc = updcrc(type, 0);
                    344: 
                    345:                for (n=4; --n >= 0; ++hdr) {
                    346:                        zsendline(*hdr);
                    347:                        crc = updcrc((0377& *hdr), crc);
                    348:                }
                    349:                crc = updcrc(0,updcrc(0,crc));
                    350:                zsendline(crc>>8);
                    351:                zsendline(crc);
                    352:        }
                    353:        if (type != ZDATA)
                    354:                flushmo();
                    355: }
                    356: 
                    357: 
                    358: /* Send ZMODEM binary header hdr of type type */
                    359: static void
                    360: zsbh32(char *hdr, int type)
                    361: {
                    362:        register int n;
                    363:        register unsigned long crc;
                    364: 
                    365:        xsendline(ZBIN32);  zsendline(type);
                    366:        crc = 0xFFFFFFFFL; crc = UPDC32(type, crc);
                    367: 
                    368:        for (n=4; --n >= 0; ++hdr) {
                    369:                crc = UPDC32((0377 & *hdr), crc);
                    370:                zsendline(*hdr);
                    371:        }
                    372:        crc = ~crc;
                    373:        for (n=4; --n >= 0;) {
                    374:                zsendline((int)crc);
                    375:                crc >>= 8;
                    376:        }
                    377: }
                    378: 
                    379: /* Send ZMODEM HEX header hdr of type type */
                    380: void 
                    381: zshhdr(int type, char *hdr)
                    382: {
                    383:        register int n;
                    384:        register unsigned short crc;
                    385:        char s[30];
                    386:        size_t len;
                    387: 
                    388:        VPRINTF(3,("zshhdr: %s %lx", frametypes[(type & 0x7f)+FTOFFSET], rclhdr(hdr)));
                    389:        s[0]=ZPAD;
                    390:        s[1]=ZPAD;
                    391:        s[2]=ZDLE;
                    392:        s[3]=ZHEX;
                    393:        zputhex(type & 0x7f ,s+4);
                    394:        len=6;
                    395:        Crc32t = 0;
                    396: 
                    397:        crc = updcrc((type & 0x7f), 0);
                    398:        for (n=4; --n >= 0; ++hdr) {
                    399:                zputhex(*hdr,s+len); 
                    400:                len += 2;
                    401:                crc = updcrc((0377 & *hdr), crc);
                    402:        }
                    403:        crc = updcrc(0,updcrc(0,crc));
                    404:        zputhex(crc>>8,s+len); 
                    405:        zputhex(crc,s+len+2);
                    406:        len+=4;
                    407: 
                    408:        /* Make it printable on remote machine */
                    409:        s[len++]=015;
                    410:        s[len++]=0212;
                    411:        /*
                    412:         * Uncork the remote in case a fake XOFF has stopped data flow
                    413:         */
                    414:        if (type != ZFIN && type != ZACK)
                    415:        {
                    416:                s[len++]=021;
                    417:        }
                    418:        flushmo();
                    419:        write(1,s,len);
                    420: }
                    421: 
                    422: /*
                    423:  * Send binary array buf of length length, with ending ZDLE sequence frameend
                    424:  */
                    425: static const char *Zendnames[] = { "ZCRCE", "ZCRCG", "ZCRCQ", "ZCRCW"};
                    426: void 
                    427: zsdata(const char *buf, size_t length, int frameend)
                    428: {
                    429:        register unsigned short crc;
                    430: 
                    431:        VPRINTF(3,("zsdata: %lu %s", (unsigned long) length, 
                    432:                Zendnames[(frameend-ZCRCE)&3]));
                    433:        crc = 0;
                    434:        do {
                    435:                zsendline(*buf); crc = updcrc((0377 & *buf), crc);
                    436:                buf++;
                    437:        } while (--length>0);
                    438:        xsendline(ZDLE); xsendline(frameend);
                    439:        crc = updcrc(frameend, crc);
                    440: 
                    441:        crc = updcrc(0,updcrc(0,crc));
                    442:        zsendline(crc>>8); zsendline(crc);
                    443:        if (frameend == ZCRCW) {
                    444:                xsendline(XON);  flushmo();
                    445:        }
                    446: }
                    447: 
                    448: void
                    449: zsda32(const char *buf, size_t length, int frameend)
                    450: {
                    451:        int c;
                    452:        unsigned long crc;
                    453:        int i;
                    454:        VPRINTF(3,("zsdat32: %d %s", length, Zendnames[(frameend-ZCRCE)&3]));
                    455: 
                    456:        crc = 0xFFFFFFFFL;
                    457:        zsendline_s(buf,length);
                    458:        for (; length; length--) {
                    459:                c = *buf & 0377;
                    460:                crc = UPDC32(c, crc);
                    461:                buf++;
                    462:        }
                    463:        xsendline(ZDLE); xsendline(frameend);
                    464:        crc = UPDC32(frameend, crc);
                    465: 
                    466:        crc = ~crc;
                    467:        for (i=4; --i >= 0;) {
                    468:                c=(int) crc;
                    469:                if (c & 0140)
                    470:                        xsendline(lastsent = c);
                    471:                else
                    472:                        zsendline(c);
                    473:                crc >>= 8;
                    474:        }
                    475:        if (frameend == ZCRCW) {
                    476:                xsendline(XON);  flushmo();
                    477:        }
                    478: }
                    479: 
                    480: #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ <= 4)
                    481: #  undef DEBUG_BLOCKSIZE
                    482: #endif
                    483: 
                    484: #ifdef DEBUG_BLOCKSIZE
                    485: struct debug_blocksize {
                    486:        int size;
                    487:        long count;
                    488: };
                    489: struct debug_blocksize blocksizes[]={
                    490:        {32,0},
                    491:        {64,0},
                    492:        {128,0},
                    493:        {256,0},
                    494:        {512,0},
                    495:        {1024,0},
                    496:        {2048,0},
                    497:        {4096,0},
                    498:        {8192,0},
                    499:        {0,0}
                    500: };
                    501: static inline void
                    502: count_blk(int size)
                    503: {
                    504:        int i;
                    505:        for (i=0;blocksizes[i].size;i++) {
                    506:                if (blocksizes[i].size==size) {
                    507:                        blocksizes[i].count++;
                    508:                        return;
                    509:                }
                    510:        }
                    511:        blocksizes[i].count++;
                    512: }
                    513: 
                    514: static void printout_blocksizes(void) __attribute__((__destructor__));
                    515: static void 
                    516: printout_blocksizes(void) 
                    517: {
                    518:        int i;
                    519:        for (i=0;blocksizes[i].size;i++) {
                    520:                if (blocksizes[i].count) {
                    521:                        lsyslog(LOG_DEBUG,"%4d byte: %ld blocks\n",
                    522:                                   blocksizes[i].size,blocksizes[i].count);
                    523:                }
                    524:        }
                    525:        if (blocksizes[i].count) {
                    526:                lsyslog(LOG_DEBUG,"unk. byte: %ld blocks",
                    527:                           blocksizes[i].count);
                    528:        }
                    529: }
                    530: #define COUNT_BLK(x) count_blk(x)
                    531: #else
                    532: #define COUNT_BLK(x)
                    533: #endif
                    534: 
                    535: /*
                    536:  * Receive array buf of max length with ending ZDLE sequence
                    537:  *  and CRC.  Returns the ending character or error code.
                    538:  *  NB: On errors may store length+1 bytes!
                    539:  */
                    540: int
                    541: zrdata(char *buf, int length, size_t *bytes_received)
                    542: {
                    543:        register int c;
                    544:        register unsigned short crc;
                    545:        register char *end;
                    546:        register int d;
                    547: 
                    548:        *bytes_received=0;
                    549:        if (Rxframeind == ZBIN32)
                    550:                return zrdat32(buf, length, bytes_received);
                    551: 
                    552:        crc = 0;  end = buf + length;
                    553:        while (buf <= end) {
                    554:                if ((c = zdlread()) & ~0377) {
                    555: crcfoo:
                    556:                        switch (c) {
                    557:                        case GOTCRCE:
                    558:                        case GOTCRCG:
                    559:                        case GOTCRCQ:
                    560:                        case GOTCRCW:
                    561:                                { 
                    562:                                        d = c;
                    563:                                        c &= 0377;
                    564:                                        crc = updcrc(c, crc);
                    565:                                        if ((c = zdlread()) & ~0377)
                    566:                                                goto crcfoo;
                    567:                                        crc = updcrc(c, crc);
                    568:                                        if ((c = zdlread()) & ~0377)
                    569:                                                goto crcfoo;
                    570:                                        crc = updcrc(c, crc);
                    571:                                        if (crc & 0xFFFF) {
                    572:                                                zperr(badcrc);
                    573:                                                return ERROR;
                    574:                                        }
                    575:                                        *bytes_received = length - (end - buf);
                    576:                                        COUNT_BLK(*bytes_received);
                    577:                                        VPRINTF(3,("zrdata: %lu  %s", (unsigned long) (*bytes_received), 
                    578:                                                        Zendnames[(d-GOTCRCE)&3]));
                    579:                                        return d;
                    580:                                }
                    581:                        case GOTCAN:
                    582:                                zperr(_("Sender Canceled"));
                    583:                                return ZCAN;
                    584:                        case TIMEOUT:
                    585:                                zperr(_("TIMEOUT"));
                    586:                                return c;
                    587:                        default:
                    588:                                zperr(_("Bad data subpacket"));
                    589:                                return c;
                    590:                        }
                    591:                }
                    592:                *buf++ = c;
                    593:                crc = updcrc(c, crc);
                    594:        }
                    595:        zperr(_("Data subpacket too long"));
                    596:        return ERROR;
                    597: }
                    598: 
                    599: static int
                    600: zrdat32(char *buf, int length, size_t *bytes_received)
                    601: {
                    602:        register int c;
                    603:        register unsigned long crc;
                    604:        register char *end;
                    605:        register int d;
                    606: 
                    607:        crc = 0xFFFFFFFFL;  end = buf + length;
                    608:        while (buf <= end) {
                    609:                if ((c = zdlread()) & ~0377) {
                    610: crcfoo:
                    611:                        switch (c) {
                    612:                        case GOTCRCE:
                    613:                        case GOTCRCG:
                    614:                        case GOTCRCQ:
                    615:                        case GOTCRCW:
                    616:                                d = c;
                    617:                                c &= 0377;
                    618:                                crc = UPDC32(c, crc);
                    619:                                if ((c = zdlread()) & ~0377)
                    620:                                        goto crcfoo;
                    621:                                crc = UPDC32(c, crc);
                    622:                                if ((c = zdlread()) & ~0377)
                    623:                                        goto crcfoo;
                    624:                                crc = UPDC32(c, crc);
                    625:                                if ((c = zdlread()) & ~0377)
                    626:                                        goto crcfoo;
                    627:                                crc = UPDC32(c, crc);
                    628:                                if ((c = zdlread()) & ~0377)
                    629:                                        goto crcfoo;
                    630:                                crc = UPDC32(c, crc);
                    631:                                if (crc != 0xDEBB20E3) {
                    632:                                        zperr(badcrc);
                    633:                                        return ERROR;
                    634:                                }
                    635:                                *bytes_received = length - (end - buf);
                    636:                                COUNT_BLK(*bytes_received);
                    637:                                VPRINTF(3,("zrdat32: %lu %s", (unsigned long) *bytes_received, 
                    638:                                        Zendnames[(d-GOTCRCE)&3]));
                    639:                                return d;
                    640:                        case GOTCAN:
                    641:                                zperr(_("Sender Canceled"));
                    642:                                return ZCAN;
                    643:                        case TIMEOUT:
                    644:                                zperr(_("TIMEOUT"));
                    645:                                return c;
                    646:                        default:
                    647:                                zperr(_("Bad data subpacket"));
                    648:                                return c;
                    649:                        }
                    650:                }
                    651:                *buf++ = c;
                    652:                crc = UPDC32(c, crc);
                    653:        }
                    654:        zperr(_("Data subpacket too long"));
                    655:        return ERROR;
                    656: }
                    657: 
                    658: /*
                    659:  * Read a ZMODEM header to hdr, either binary or hex.
                    660:  *  eflag controls local display of non zmodem characters:
                    661:  *     0:  no display
                    662:  *     1:  display printing characters only
                    663:  *     2:  display all non ZMODEM characters
                    664:  *  On success, set Zmodem to 1, set Rxpos and return type of header.
                    665:  *   Otherwise return negative on error.
                    666:  *   Return ERROR instantly if ZCRCW sequence, for fast error recovery.
                    667:  */
                    668: int
                    669: zgethdr(char *hdr, int eflag, size_t *Rxpos)
                    670: {
                    671:        register int c, cancount;
                    672:        unsigned int max_garbage; /* Max bytes before start of frame */
                    673:        size_t rxpos=0; /* keep gcc happy */
                    674: 
                    675:        max_garbage = Zrwindow + Baudrate;
                    676:        Rxframeind = Rxtype = 0;
                    677: 
                    678: startover:
                    679:        cancount = 5;
                    680: again:
                    681:        /* Return immediate ERROR if ZCRCW sequence seen */
                    682:        switch (c = READLINE_PF(Rxtimeout)) {
                    683:        case RCDO:
                    684:        case TIMEOUT:
                    685:                goto fifi;
                    686:        case CAN:
                    687: gotcan:
                    688:                if (--cancount <= 0) {
                    689:                        c = ZCAN; goto fifi;
                    690:                }
                    691:                switch (c = READLINE_PF(1)) {
                    692:                case TIMEOUT:
                    693:                        goto again;
                    694:                case ZCRCW:
                    695:                        c = ERROR;
                    696:                /* **** FALL THRU TO **** */
                    697:                case RCDO:
                    698:                        goto fifi;
                    699:                default:
                    700:                        break;
                    701:                case CAN:
                    702:                        if (--cancount <= 0) {
                    703:                                c = ZCAN; goto fifi;
                    704:                        }
                    705:                        goto again;
                    706:                }
                    707:        /* **** FALL THRU TO **** */
                    708:        default:
                    709: agn2:
                    710:                if ( --max_garbage == 0) {
                    711:                        zperr(_("Garbage count exceeded"));
                    712:                        return(ERROR);
                    713:                }
                    714:                if (eflag && ((c &= 0177) & 0140) && Verbose)
                    715:                        vchar(c);
                    716:                else if (eflag > 1 && Verbose)
                    717:                        vchar(c);
                    718:                goto startover;
                    719:        case ZPAD|0200:         /* This is what we want. */
                    720:        case ZPAD:              /* This is what we want. */
                    721:                break;
                    722:        }
                    723:        cancount = 5;
                    724: splat:
                    725:        switch (c = noxrd7()) {
                    726:        case ZPAD:
                    727:                goto splat;
                    728:        case RCDO:
                    729:        case TIMEOUT:
                    730:                goto fifi;
                    731:        default:
                    732:                goto agn2;
                    733:        case ZDLE:              /* This is what we want. */
                    734:                break;
                    735:        }
                    736: 
                    737:        switch (c = noxrd7()) {
                    738:        case RCDO:
                    739:        case TIMEOUT:
                    740:                goto fifi;
                    741:        case ZBIN:
                    742:                Rxframeind = ZBIN;  Crc32 = FALSE;
                    743:                c =  zrbhdr(hdr);
                    744:                break;
                    745:        case ZBIN32:
                    746:                Crc32 = Rxframeind = ZBIN32;
                    747:                c =  zrbhdr32(hdr);
                    748:                break;
                    749:        case ZHEX:
                    750:                Rxframeind = ZHEX;  Crc32 = FALSE;
                    751:                c =  zrhhdr(hdr);
                    752:                break;
                    753:        case CAN:
                    754:                goto gotcan;
                    755:        default:
                    756:                goto agn2;
                    757:        }
                    758:        rxpos = hdr[ZP3] & 0377;
                    759:        rxpos = (rxpos<<8) + (hdr[ZP2] & 0377);
                    760:        rxpos = (rxpos<<8) + (hdr[ZP1] & 0377);
                    761:        rxpos = (rxpos<<8) + (hdr[ZP0] & 0377);
                    762: fifi:
                    763:        switch (c) {
                    764:        case GOTCAN:
                    765:                c = ZCAN;
                    766:        /* **** FALL THRU TO **** */
                    767:        case ZNAK:
                    768:        case ZCAN:
                    769:        case ERROR:
                    770:        case TIMEOUT:
                    771:        case RCDO:
                    772:                zperr(_("Got %s"), frametypes[c+FTOFFSET]);
                    773:        /* **** FALL THRU TO **** */
                    774:        default:
                    775:                if (c >= -3 && c <= FRTYPES)
                    776:                        VPRINTF(3,("zgethdr: %s %lx", frametypes[c+FTOFFSET], (unsigned long) rxpos));
                    777:                else
                    778:                        VPRINTF(3,("zgethdr: %d %lx", c, (unsigned long) rxpos));
                    779:        }
                    780:        if (Rxpos)
                    781:                *Rxpos=rxpos;
                    782:        return c;
                    783: }
                    784: 
                    785: /* Receive a binary style header (type and position) */
                    786: static int 
                    787: zrbhdr(char *hdr)
                    788: {
                    789:        register int c, n;
                    790:        register unsigned short crc;
                    791: 
                    792:        if ((c = zdlread()) & ~0377)
                    793:                return c;
                    794:        Rxtype = c;
                    795:        crc = updcrc(c, 0);
                    796: 
                    797:        for (n=4; --n >= 0; ++hdr) {
                    798:                if ((c = zdlread()) & ~0377)
                    799:                        return c;
                    800:                crc = updcrc(c, crc);
                    801:                *hdr = c;
                    802:        }
                    803:        if ((c = zdlread()) & ~0377)
                    804:                return c;
                    805:        crc = updcrc(c, crc);
                    806:        if ((c = zdlread()) & ~0377)
                    807:                return c;
                    808:        crc = updcrc(c, crc);
                    809:        if (crc & 0xFFFF) {
                    810:                zperr(badcrc); 
                    811:                return ERROR;
                    812:        }
                    813:        protocol = ZM_ZMODEM;
                    814:        zmodem_requested=TRUE;
                    815:        return Rxtype;
                    816: }
                    817: 
                    818: /* Receive a binary style header (type and position) with 32 bit FCS */
                    819: static int
                    820: zrbhdr32(char *hdr)
                    821: {
                    822:        register int c, n;
                    823:        register unsigned long crc;
                    824: 
                    825:        if ((c = zdlread()) & ~0377)
                    826:                return c;
                    827:        Rxtype = c;
                    828:        crc = 0xFFFFFFFFL; crc = UPDC32(c, crc);
                    829: #ifdef DEBUGZ
                    830:        VPRINTF(3,("zrbhdr32 c=%X  crc=%lX", c, crc)i);
                    831: #endif
                    832: 
                    833:        for (n=4; --n >= 0; ++hdr) {
                    834:                if ((c = zdlread()) & ~0377)
                    835:                        return c;
                    836:                crc = UPDC32(c, crc);
                    837:                *hdr = c;
                    838: #ifdef DEBUGZ
                    839:                VPRINTF(3,("zrbhdr32 c=%X  crc=%lX", c, crc));
                    840: #endif
                    841:        }
                    842:        for (n=4; --n >= 0;) {
                    843:                if ((c = zdlread()) & ~0377)
                    844:                        return c;
                    845:                crc = UPDC32(c, crc);
                    846: #ifdef DEBUGZ
                    847:                VPRINTF(3,("zrbhdr32 c=%X  crc=%lX", c, crc));
                    848: #endif
                    849:        }
                    850:        if (crc != 0xDEBB20E3) {
                    851:                zperr(badcrc);
                    852:                return ERROR;
                    853:        }
                    854:        protocol = ZM_ZMODEM;
                    855:        zmodem_requested=TRUE;
                    856:        return Rxtype;
                    857: }
                    858: 
                    859: 
                    860: /* Receive a hex style header (type and position) */
                    861: static int 
                    862: zrhhdr(char *hdr)
                    863: {
                    864:        register int c;
                    865:        register unsigned short crc;
                    866:        register int n;
                    867: 
                    868:        if ((c = zgethex()) < 0)
                    869:                return c;
                    870:        Rxtype = c;
                    871:        crc = updcrc(c, 0);
                    872: 
                    873:        for (n=4; --n >= 0; ++hdr) {
                    874:                if ((c = zgethex()) < 0)
                    875:                        return c;
                    876:                crc = updcrc(c, crc);
                    877:                *hdr = c;
                    878:        }
                    879:        if ((c = zgethex()) < 0)
                    880:                return c;
                    881:        crc = updcrc(c, crc);
                    882:        if ((c = zgethex()) < 0)
                    883:                return c;
                    884:        crc = updcrc(c, crc);
                    885:        if (crc & 0xFFFF) {
                    886:                zperr(badcrc); return ERROR;
                    887:        }
                    888:        switch ( c = READLINE_PF(1)) {
                    889:        case 0215:
                    890:                /* **** FALL THRU TO **** */
                    891:        case 015:
                    892:                /* Throw away possible cr/lf */
                    893:                READLINE_PF(1);
                    894:                break;
                    895:        }
                    896:        protocol = ZM_ZMODEM;
                    897:        zmodem_requested=TRUE;
                    898:        return Rxtype;
                    899: }
                    900: 
                    901: /* Write a byte as two hex digits */
                    902: static void 
                    903: zputhex(int c, char *pos)
                    904: {
                    905:        static char     digits[]        = "0123456789abcdef";
                    906: 
                    907:        VPRINTF(9,("zputhex: %02X", c));
                    908:        pos[0]=digits[(c&0xF0)>>4];
                    909:        pos[1]=digits[c&0x0F];
                    910: }
                    911: 
                    912: void
                    913: zsendline_init(void)
                    914: {
                    915:        int i;
                    916:        for (i=0;i<256;i++) {   
                    917:                if (i & 0140)
                    918:                        zsendline_tab[i]=0;
                    919:                else {
                    920:                        switch(i)
                    921:                        {
                    922:                        case ZDLE:
                    923:                        case XOFF: /* ^Q */
                    924:                        case XON: /* ^S */
                    925:                        case (XOFF | 0200):
                    926:                        case (XON | 0200):
                    927:                                zsendline_tab[i]=1;
                    928:                                break;
                    929:                        case 020: /* ^P */
                    930:                        case 0220:
                    931:                                if (turbo_escape)
                    932:                                        zsendline_tab[i]=0;
                    933:                                else
                    934:                                        zsendline_tab[i]=1;
                    935:                                break;
                    936:                        case 015:
                    937:                        case 0215:
                    938:                                if (Zctlesc)
                    939:                                        zsendline_tab[i]=1;
                    940:                                else if (!turbo_escape)
                    941:                                        zsendline_tab[i]=2;
                    942:                                else 
                    943:                                        zsendline_tab[i]=0;
                    944:                                break;
                    945:                        default:
                    946:                                if (Zctlesc)
                    947:                                        zsendline_tab[i]=1;
                    948:                                else
                    949:                                        zsendline_tab[i]=0;
                    950:                        }
                    951:                }
                    952:        }
                    953: }
                    954: 
                    955: 
                    956: 
                    957: /* Store pos in Txhdr */
                    958: void 
                    959: stohdr(size_t pos)
                    960: {
                    961:        long lpos=(long) pos;
                    962:        Txhdr[ZP0] = lpos;
                    963:        Txhdr[ZP1] = lpos>>8;
                    964:        Txhdr[ZP2] = lpos>>16;
                    965:        Txhdr[ZP3] = lpos>>24;
                    966: }
                    967: 
                    968: /* Recover a long integer from a header */
                    969: long
                    970: rclhdr(char *hdr)
                    971: {
                    972:        long l;
                    973: 
                    974:        l = (hdr[ZP3] & 0377);
                    975:        l = (l << 8) | (hdr[ZP2] & 0377);
                    976:        l = (l << 8) | (hdr[ZP1] & 0377);
                    977:        l = (l << 8) | (hdr[ZP0] & 0377);
                    978:        return l;
                    979: }
                    980: 
                    981: /* End of zm.c */

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