Annotation of sbbs/src/sbbs3/zmodem.c, revision 1.1.1.2

1.1       root        1: /* zmodem.c */
                      2: 
                      3: /* Synchronet ZMODEM Functions */
                      4: 
1.1.1.2 ! root        5: /* $Id: zmodem.c,v 1.113 2010/03/12 19:29:58 deuce Exp $ */
1.1       root        6: 
                      7: /******************************************************************************/
                      8: /* Project : Unite!       File : zmodem general        Version : 1.02         */
                      9: /*                                                                            */
                     10: /* (C) Mattheij Computer Service 1994                                         */
                     11: /*                                                                            */
                     12: /* contact us through (in order of preference)                                */
                     13: /*                                                                            */
                     14: /*   email:          [email protected]                                      */
                     15: /*   mail:           MCS                                                      */
                     16: /*                   Prinses Beatrixlaan 535                                  */
                     17: /*                   2284 AT  RIJSWIJK                                        */
                     18: /*                   The Netherlands                                          */
                     19: /*   voice phone:    31+070-3936926                                           */
                     20: /******************************************************************************/
                     21: 
                     22: /*
                     23:  * zmodem primitives and other code common to zmtx and zmrx
                     24:  */
                     25: 
                     26: #include <stdio.h>
                     27: #include <string.h>
                     28: #include <stdarg.h>    /* va_list */
                     29: #include <sys/stat.h>  /* struct stat */
                     30: 
                     31: #include "genwrap.h"
                     32: #include "dirwrap.h"   /* getfname() */
                     33: #include "filewrap.h"  /* filelength() */
                     34: 
                     35: #include "zmodem.h"
                     36: #include "crc16.h"
                     37: #include "crc32.h"
                     38: 
                     39: #include "sexyz.h"
                     40: #include "telnet.h"
                     41: 
1.1.1.2 ! root       42: #define ENDOFFRAME     2
        !            43: #define FRAMEOK                1
        !            44: #define TIMEOUT                        -1      /* rx routine did not receive a character within timeout */
        !            45: #define INVHDR                 -2      /* invalid header received; but within timeout */
        !            46: #define ABORTED                        -3      /* Aborted *or* disconnected */
        !            47: #define SUBPKTOVERFLOW  -4     /* Subpacket received more than block length */
        !            48: #define CRCFAILED              -5      /* Failed CRC comparison */
        !            49: #define INVALIDSUBPKT  -6      /* Invalid Subpacket Type */
1.1       root       50: #define ZDLEESC 0x8000 /* one of ZCRCE; ZCRCG; ZCRCQ or ZCRCW was received; ZDLE escaped */
                     51: 
                     52: #define BADSUBPKT      0x80
                     53: 
                     54: #define HDRLEN     5   /* size of a zmodem header */
                     55: 
                     56: static int lprintf(zmodem_t* zm, int level, const char *fmt, ...)
                     57: {
                     58:        va_list argptr;
                     59:        char    sbuf[1024];
                     60: 
                     61:        if(zm->lputs==NULL)
                     62:                return(-1);
1.1.1.2 ! root       63:        if(zm->log_level != NULL)
        !            64:                if(level > *zm->log_level)
        !            65:                        return 0;
1.1       root       66: 
                     67:     va_start(argptr,fmt);
                     68:     vsnprintf(sbuf,sizeof(sbuf),fmt,argptr);
                     69:        sbuf[sizeof(sbuf)-1]=0;
                     70:     va_end(argptr);
                     71:     return(zm->lputs(zm->cbdata,level,sbuf));
                     72: }
                     73: 
                     74: static BOOL is_connected(zmodem_t* zm)
                     75: {
                     76:        if(zm->is_connected!=NULL)
                     77:                return(zm->is_connected(zm->cbdata));
                     78:        return(TRUE);
                     79: }
                     80: 
                     81: static BOOL is_cancelled(zmodem_t* zm)
                     82: {
                     83:        if(zm->is_cancelled!=NULL)
                     84:                return(zm->cancelled=zm->is_cancelled(zm->cbdata));
                     85:        return(zm->cancelled);
                     86: }
1.1.1.2 ! root       87: 
1.1       root       88: int zmodem_data_waiting(zmodem_t* zm, unsigned timeout)
                     89: {
                     90:        if(zm->data_waiting)
                     91:                return(zm->data_waiting(zm->cbdata, timeout));
                     92:        return(FALSE);
                     93: }
                     94: 
                     95: static char *chr(int ch)
                     96: {
                     97:        static char str[25];
                     98: 
                     99:        switch(ch) {
1.1.1.2 ! root      100:                case TIMEOUT:                   return("TIMEOUT");
        !           101:                case ABORTED:                   return("ABORTED");
        !           102:                case SUBPKTOVERFLOW:    return "Subpacket Overflow";
        !           103:                case CRCFAILED:                 return "CRC Failure";
        !           104:                case INVALIDSUBPKT:             return "Invalid Subpacket";
        !           105:                case ZRQINIT:                   return("ZRQINIT");
        !           106:                case ZRINIT:                    return("ZRINIT");
        !           107:                case ZSINIT:                    return("ZSINIT");
        !           108:                case ZACK:                              return("ZACK");
        !           109:                case ZFILE:                             return("ZFILE");
        !           110:                case ZSKIP:                             return("ZSKIP");
        !           111:                case ZCRC:                              return("ZCRC");
        !           112:                case ZNAK:                              return("ZNAK");
        !           113:                case ZABORT:                    return("ZABORT");
        !           114:                case ZFIN:                              return("ZFIN");
        !           115:                case ZRPOS:                             return("ZRPOS");
        !           116:                case ZDATA:                             return("ZDATA");
        !           117:                case ZEOF:                              return("ZEOF");
        !           118:                case ZFERR:                             return("ZFERR");
        !           119:                case ZPAD:                              return("ZPAD");
        !           120:                case ZCAN:                              return("ZCAN");
        !           121:                case ZDLE:                              return("ZDLE");
        !           122:                case ZDLEE:                             return("ZDLEE");
        !           123:                case ZBIN:                              return("ZBIN");
        !           124:                case ZHEX:                              return("ZHEX");
        !           125:                case ZBIN32:                    return("ZBIN32");
        !           126:                case ZRESC:                             return("ZRESC");
        !           127:                case ZCRCE:                             return("ZCRCE");
        !           128:                case ZCRCG:                             return("ZCRCG");
        !           129:                case ZCRCQ:                             return("ZCRCQ");
        !           130:                case ZCRCW:                             return("ZCRCW");
        !           131: 
        !           132:        }
        !           133:        if(ch<0)
        !           134:                sprintf(str,"%d",ch);
        !           135:        else if(ch>=' ' && ch<='~')
1.1       root      136:                sprintf(str,"'%c' (%02Xh)",(uchar)ch,(uchar)ch);
                    137:        else
                    138:                sprintf(str,"%u (%02Xh)",(uchar)ch,(uchar)ch);
                    139:        return(str); 
                    140: }
                    141: 
                    142: static char* frame_desc(int frame)
                    143: {
                    144:        static char str[25];
                    145: 
                    146:        if(frame==TIMEOUT)
1.1.1.2 ! root      147:                return "TIMEOUT";
1.1       root      148: 
                    149:        if(frame==INVHDR)
1.1.1.2 ! root      150:                return "Invalid Header";
1.1       root      151: 
1.1.1.2 ! root      152:        if(frame==ABORTED)
        !           153:                return "Aborted";
1.1       root      154: 
1.1.1.2 ! root      155:        if(frame >= 0 && (frame&BADSUBPKT)) {
        !           156:                strcpy(str,"BAD ");
        !           157:                switch(frame&~BADSUBPKT) {
        !           158:                        case ZRQINIT:           strcat(str,"ZRQINIT");          break;
        !           159:                        case ZRINIT:            strcat(str,"ZRINIT");           break;
        !           160:                        case ZSINIT:            strcat(str,"ZSINIT");           break;
        !           161:                        case ZACK:                      strcat(str,"ZACK");                     break;
        !           162:                        case ZFILE:                     strcat(str,"ZFILE");            break;
        !           163:                        case ZSKIP:                     strcat(str,"ZSKIP");            break;
        !           164:                        case ZNAK:                      strcat(str,"ZNAK");                     break;
        !           165:                        case ZABORT:            strcat(str,"ZABORT");           break;
        !           166:                        case ZFIN:                      strcat(str,"ZFIN");                     break;
        !           167:                        case ZRPOS:                     strcat(str,"ZRPOS");            break;
        !           168:                        case ZDATA:                     strcat(str,"ZDATA");            break;
        !           169:                        case ZEOF:                      strcat(str,"ZEOF");                     break;
        !           170:                        case ZFERR:                     strcat(str,"ZFERR");            break;
        !           171:                        case ZCRC:                      strcat(str,"ZCRC");                     break;
        !           172:                        case ZCHALLENGE:        strcat(str,"ZCHALLENGE");       break;
        !           173:                        case ZCOMPL:            strcat(str,"ZCOMPL");           break;
        !           174:                        case ZCAN:                      strcat(str,"ZCAN");                     break;
        !           175:                        case ZFREECNT:          strcat(str,"ZFREECNT");         break;
        !           176:                        case ZCOMMAND:          strcat(str,"ZCOMMAND");         break;  
        !           177:                        case ZSTDERR:           strcat(str,"ZSTDERR");          break;          
        !           178:                        default: 
        !           179:                                sprintf(str,"Unknown (%08X)", frame);
        !           180:                                break;
        !           181:                }
        !           182:        } else
        !           183:                sprintf(str,"%d",frame);
1.1       root      184:        return(str); 
                    185: }
                    186: 
1.1.1.2 ! root      187: ulong frame_pos(zmodem_t* zm, int type)
        !           188: {
        !           189:        switch(type) {
        !           190:                case ZRPOS:
        !           191:                case ZACK:
        !           192:                case ZEOF:
        !           193:                case ZDATA:
        !           194:                        return(zm->rxd_header_pos);
        !           195:        }
        !           196: 
        !           197:        return 0;
        !           198: }
1.1       root      199: 
                    200: /*
                    201:  * read bytes as long as rdchk indicates that
                    202:  * more data is available.
                    203:  */
                    204: 
                    205: void zmodem_recv_purge(zmodem_t* zm)
                    206: {
                    207:        while(zm->recv_byte(zm->cbdata,0)>=0);
                    208: }
                    209: 
                    210: /* 
1.1.1.2 ! root      211:  * Flush the output buffer
        !           212:  */
        !           213: void zmodem_flush(zmodem_t* zm)
        !           214: {
        !           215:        if(zm->flush!=NULL)
        !           216:                zm->flush(zm);
        !           217: }
        !           218: 
        !           219: /* 
1.1       root      220:  * transmit a character. 
                    221:  * this is the raw modem interface
                    222:  */
1.1.1.2 ! root      223: /* Returns 0 on success */
1.1       root      224: int zmodem_send_raw(zmodem_t* zm, unsigned char ch)
                    225: {
                    226:        int     result;
                    227: 
                    228:        if((result=zm->send_byte(zm->cbdata,ch,zm->send_timeout))!=0)
                    229:                lprintf(zm,LOG_ERR,"send_raw SEND ERROR: %d",result);
                    230: 
                    231:        zm->last_sent = ch;
                    232: 
                    233:        return result;
                    234: }
                    235: 
                    236: /*
                    237:  * transmit a character ZDLE escaped
                    238:  */
                    239: 
                    240: int zmodem_send_esc(zmodem_t* zm, unsigned char c)
                    241: {
                    242:        int     result;
                    243: 
                    244:        if((result=zmodem_send_raw(zm, ZDLE))!=0)
                    245:                return(result);
                    246:        /*
                    247:         * exclusive or; not an or so ZDLE becomes ZDLEE
                    248:         */
                    249:        return zmodem_send_raw(zm, (uchar)(c ^ 0x40));
                    250: }
                    251: 
                    252: /*
                    253:  * transmit a character; ZDLE escaping if appropriate
                    254:  */
                    255: 
                    256: int zmodem_tx(zmodem_t* zm, unsigned char c)
                    257: {
                    258:        int result;
                    259: 
                    260:        switch (c) {
                    261:                case DLE:
                    262:                case DLE|0x80:          /* even if high-bit set */
                    263:                case XON:
                    264:                case XON|0x80:
                    265:                case XOFF:
                    266:                case XOFF|0x80:
                    267:                case ZDLE:
                    268:                        return zmodem_send_esc(zm, c);
                    269:                case CR:
                    270:                case CR|0x80:
                    271:                        if(zm->escape_ctrl_chars && (zm->last_sent&0x7f) == '@')
                    272:                                return zmodem_send_esc(zm, c);
                    273:                        break;
                    274:                case TELNET_IAC:
                    275:                        if(zm->escape_telnet_iac) {
                    276:                                if((result=zmodem_send_raw(zm, ZDLE))!=0)
                    277:                                        return(result);
                    278:                                return zmodem_send_raw(zm, ZRUB1);
                    279:                        }
                    280:                        break;
                    281:                default:
                    282:                        if(zm->escape_ctrl_chars && (c&0x60)==0)
                    283:                                return zmodem_send_esc(zm, c);
                    284:                        break;
                    285:        }
                    286:        /*
                    287:         * anything that ends here is so normal we might as well transmit it.
                    288:         */
                    289:        return zmodem_send_raw(zm, c);
                    290: }
                    291: 
                    292: /**********************************************/
                    293: /* Output single byte as two hex ASCII digits */
                    294: /**********************************************/
                    295: int zmodem_send_hex(zmodem_t* zm, uchar val)
                    296: {
                    297:        char* xdigit="0123456789abcdef";
                    298:        int     result;
                    299: 
                    300:        lprintf(zm,LOG_DEBUG,"send_hex: %02X ",val);
                    301: 
                    302:        if((result=zmodem_send_raw(zm, xdigit[val>>4]))!=0)
                    303:                return result;
                    304:        return zmodem_send_raw(zm, xdigit[val&0xf]);
                    305: }
                    306: 
                    307: int zmodem_send_padded_zdle(zmodem_t* zm)
                    308: {
                    309:        int result;
                    310: 
                    311:        if((result=zmodem_send_raw(zm, ZPAD))!=0)
                    312:                return result;
                    313:        if((result=zmodem_send_raw(zm, ZPAD))!=0)
                    314:                return result;
                    315:        return zmodem_send_raw(zm, ZDLE);
                    316: }
                    317: 
                    318: /* 
                    319:  * transmit a hex header.
                    320:  * these routines use tx_raw because we're sure that all the
                    321:  * characters are not to be escaped.
                    322:  */
                    323: int zmodem_send_hex_header(zmodem_t* zm, unsigned char * p)
                    324: {
                    325:        int i;
                    326:        int result;
                    327:        uchar type=*p;
                    328:        unsigned short int crc;
                    329: 
                    330:        lprintf(zm,LOG_DEBUG,"send_hex_header: %s", chr(type));
                    331: 
                    332:        if((result=zmodem_send_padded_zdle(zm))!=0)
                    333:                return result;
                    334: 
                    335:        if((result=zmodem_send_raw(zm, ZHEX))!=0)
                    336:                return result;
                    337: 
                    338:        /*
                    339:         * initialise the crc
                    340:         */
                    341: 
                    342:        crc = 0;
                    343: 
                    344:        /*
                    345:         * transmit the header
                    346:         */
                    347: 
                    348:        for(i=0;i<HDRLEN;i++) {
                    349:                if((result=zmodem_send_hex(zm, *p))!=0)
                    350:                        return result;
                    351:                crc = ucrc16(*p, crc);
                    352:                p++;
                    353:        }
                    354: 
                    355:        /*
                    356:         * update the crc as though it were zero
                    357:         */
                    358: 
                    359:        /* 
                    360:         * transmit the crc
                    361:         */
                    362: 
                    363:        if((result=zmodem_send_hex(zm, (uchar)(crc>>8)))!=0)
                    364:                return result;
                    365:        if((result=zmodem_send_hex(zm, (uchar)(crc&0xff)))!=0)
                    366:                return result;
                    367: 
                    368:        /*
                    369:         * end of line sequence
                    370:         */
                    371: 
                    372:        if((result=zmodem_send_raw(zm, '\r'))!=0)
                    373:                return result;
                    374:        if((result=zmodem_send_raw(zm, '\n'))!=0)       /* FDSZ sends 0x8a instead of 0x0a */
                    375:                return result;
                    376: 
                    377:        if(type!=ZACK && type!=ZFIN)
                    378:                result=zmodem_send_raw(zm, XON);
                    379: 
1.1.1.2 ! root      380:        zmodem_flush(zm);
        !           381: 
1.1       root      382:        return(result);
                    383: }
                    384: 
                    385: /*
                    386:  * Send ZMODEM binary header hdr
                    387:  */
                    388: 
                    389: int zmodem_send_bin32_header(zmodem_t* zm, unsigned char * p)
                    390: {
                    391:        int i;
                    392:        int result;
1.1.1.2 ! root      393:        uint32_t crc;
1.1       root      394: 
                    395:        lprintf(zm,LOG_DEBUG,"send_bin32_header: %s", chr(*p));
                    396: 
                    397:        if((result=zmodem_send_padded_zdle(zm))!=0)
                    398:                return result;
                    399: 
                    400:        if((result=zmodem_send_raw(zm, ZBIN32))!=0)
                    401:                return result;
                    402: 
                    403:        crc = 0xffffffffL;
                    404: 
                    405:        for(i=0;i<HDRLEN;i++) {
                    406:                crc = ucrc32(*p,crc);
                    407:                if((result=zmodem_tx(zm, *p++))!=0)
                    408:                        return result;
                    409:        }
                    410: 
                    411:        crc = ~crc;
                    412: 
                    413:        if((result=     zmodem_tx(zm, (uchar)((crc      ) & 0xff)))!=0)
                    414:                return result;
                    415:        if((result=     zmodem_tx(zm, (uchar)((crc >>  8) & 0xff)))!=0)
                    416:                return result;
                    417:        if((result=     zmodem_tx(zm, (uchar)((crc >> 16) & 0xff)))!=0)
                    418:                return result;
                    419:        return          zmodem_tx(zm, (uchar)((crc >> 24) & 0xff));
                    420: }
                    421: 
                    422: int zmodem_send_bin16_header(zmodem_t* zm, unsigned char * p)
                    423: {
                    424:        int i;
                    425:        int result;
                    426:        unsigned int crc;
                    427: 
                    428:        lprintf(zm,LOG_DEBUG,"send_bin16_header: %s", chr(*p));
                    429: 
                    430:        if((result=zmodem_send_padded_zdle(zm))!=0)
                    431:                return result;
                    432: 
                    433:        if((result=zmodem_send_raw(zm, ZBIN))!=0)
                    434:                return result;
                    435: 
                    436:        crc = 0;
                    437: 
                    438:        for(i=0;i<HDRLEN;i++) {
                    439:                crc = ucrc16(*p,crc);
                    440:                if((result=zmodem_tx(zm, *p++))!=0)
                    441:                        return result;
                    442:        }
                    443: 
                    444:        if((result=     zmodem_tx(zm, (uchar)(crc >> 8)))!=0)
                    445:                return result;
                    446:        return          zmodem_tx(zm, (uchar)(crc&0xff));
                    447: }
                    448: 
                    449: 
                    450: /* 
                    451:  * transmit a header using either hex 16 bit crc or binary 32 bit crc
                    452:  * depending on the receivers capabilities
                    453:  * we dont bother with variable length headers. I dont really see their
                    454:  * advantage and they would clutter the code unneccesarily
                    455:  */
                    456: 
                    457: int zmodem_send_bin_header(zmodem_t* zm, unsigned char * p)
                    458: {
                    459:        if(zm->can_fcs_32 && !zm->want_fcs_16)
                    460:                return zmodem_send_bin32_header(zm, p);
                    461:        return zmodem_send_bin16_header(zm, p);
                    462: }
                    463: 
                    464: /*
                    465:  * data subpacket transmission
                    466:  */
                    467: 
                    468: int zmodem_send_data32(zmodem_t* zm, uchar subpkt_type, unsigned char * p, size_t l)
                    469: {
                    470:        int     result;
1.1.1.2 ! root      471:        uint32_t crc;
1.1       root      472: 
1.1.1.2 ! root      473: //     lprintf(zm,LOG_DEBUG,"send_data32: %s (%u bytes)", chr(subpkt_type), l);
1.1       root      474: 
                    475:        crc = 0xffffffffl;
                    476: 
                    477:        while(l > 0) {
                    478:                crc = ucrc32(*p,crc);
                    479:                if((result=zmodem_tx(zm, *p++))!=0)
                    480:                        return result;
                    481:                l--;
                    482:        }
                    483: 
                    484:        crc = ucrc32(subpkt_type, crc);
                    485: 
                    486:        if((result=zmodem_send_raw(zm, ZDLE))!=0)
                    487:                return result;
                    488:        if((result=zmodem_send_raw(zm, subpkt_type))!=0)
                    489:                return result;
                    490: 
                    491:        crc = ~crc;
                    492: 
                    493:        if((result=     zmodem_tx(zm, (uchar) ((crc      ) & 0xff)))!=0)
                    494:                return result;
                    495:        if((result=     zmodem_tx(zm, (uchar) ((crc >> 8 ) & 0xff)))!=0)
                    496:                return result;
                    497:        if((result=     zmodem_tx(zm, (uchar) ((crc >> 16) & 0xff)))!=0)
                    498:                return result;
                    499:        return          zmodem_tx(zm, (uchar) ((crc >> 24) & 0xff));
                    500: }
                    501: 
                    502: int zmodem_send_data16(zmodem_t* zm, uchar subpkt_type,unsigned char * p, size_t l)
                    503: {
                    504:        int     result;
                    505:        unsigned short crc;
                    506: 
                    507:        lprintf(zm,LOG_DEBUG,"send_data16: %s (%u bytes)", chr(subpkt_type), l);
                    508: 
                    509:        crc = 0;
                    510: 
                    511:        while(l > 0) {
                    512:                crc = ucrc16(*p,crc);
                    513:                if((result=zmodem_tx(zm, *p++))!=0)
                    514:                        return result;
                    515:                l--;
                    516:        }
                    517: 
                    518:        crc = ucrc16(subpkt_type,crc);
                    519: 
                    520:        if((result=zmodem_send_raw(zm, ZDLE))!=0)
                    521:                return result;
                    522:        if((result=zmodem_send_raw(zm, subpkt_type))!=0)
                    523:                return result;
                    524:        
                    525:        if((result=     zmodem_tx(zm, (uchar)(crc >> 8)))!=0)
                    526:                return result;
                    527:        return          zmodem_tx(zm, (uchar)(crc&0xff));
                    528: }
                    529: 
                    530: /*
                    531:  * send a data subpacket using crc 16 or crc 32 as desired by the receiver
                    532:  */
                    533: 
1.1.1.2 ! root      534: int zmodem_send_data_subpkt(zmodem_t* zm, uchar subpkt_type, unsigned char * p, size_t l)
1.1       root      535: {
                    536:        int result;
                    537: 
1.1.1.2 ! root      538:        if(subpkt_type == ZCRCW || subpkt_type == ZCRCE)        /* subpacket indicating 'end-of-frame' */
        !           539:                zm->frame_in_transit=FALSE;
        !           540:        else    /* other subpacket (mid-frame) */
        !           541:                zm->frame_in_transit=TRUE;
        !           542: 
1.1       root      543:        if(!zm->want_fcs_16 && zm->can_fcs_32) {
                    544:                if((result=zmodem_send_data32(zm, subpkt_type,p,l))!=0)
                    545:                        return result;
                    546:        }
                    547:        else {  
                    548:                if((result=zmodem_send_data16(zm, subpkt_type,p,l))!=0)
                    549:                        return result;
                    550:        }
                    551: 
                    552:        if(subpkt_type == ZCRCW)
                    553:                result=zmodem_send_raw(zm, XON);
                    554: 
1.1.1.2 ! root      555:        zmodem_flush(zm);
        !           556: 
1.1       root      557:        return result;
                    558: }
                    559: 
1.1.1.2 ! root      560: int zmodem_send_data(zmodem_t* zm, uchar subpkt_type, unsigned char * p, size_t l)
        !           561: {
        !           562:        if(!zm->frame_in_transit)       { /* Start of frame, include ZDATA header */
        !           563:                lprintf(zm,LOG_DEBUG,"send_data: start of frame, offset %u"
        !           564:                        ,zm->current_file_pos);
        !           565:                zmodem_send_pos_header(zm, ZDATA, (uint32_t)zm->current_file_pos, /* Hex? */ FALSE);
        !           566:        }
        !           567: 
        !           568:        return zmodem_send_data_subpkt(zm, subpkt_type, p, l);
        !           569: }
        !           570: 
        !           571: int zmodem_send_pos_header(zmodem_t* zm, int type, int32_t pos, BOOL hex) 
1.1       root      572: {
                    573:        uchar header[5];
                    574: 
                    575:        header[0]   = type;
                    576:        header[ZP0] = (uchar) (pos        & 0xff);
                    577:        header[ZP1] = (uchar)((pos >>  8) & 0xff);
                    578:        header[ZP2] = (uchar)((pos >> 16) & 0xff);
                    579:        header[ZP3] = (uchar)((pos >> 24) & 0xff);
                    580: 
                    581:        if(hex)
                    582:                return zmodem_send_hex_header(zm, header);
                    583:        else
                    584:                return zmodem_send_bin_header(zm, header);
                    585: }
                    586: 
1.1.1.2 ! root      587: int zmodem_send_ack(zmodem_t* zm, int32_t pos)
1.1       root      588: {
                    589:        return zmodem_send_pos_header(zm, ZACK, pos, /* Hex? */ TRUE);
                    590: }
                    591: 
                    592: int zmodem_send_zfin(zmodem_t* zm)
                    593: {
                    594:        unsigned char zfin_header[] = { ZFIN, 0, 0, 0, 0 };
                    595: 
1.1.1.2 ! root      596:        lprintf(zm,LOG_NOTICE,"Finishing Session (Sending ZFIN)");
1.1       root      597:        return zmodem_send_hex_header(zm,zfin_header);
                    598: }
                    599: 
1.1.1.2 ! root      600: int zmodem_send_zabort(zmodem_t* zm)
1.1       root      601: {
1.1.1.2 ! root      602:        lprintf(zm,LOG_WARNING,"Aborting Transfer (Sending ZABORT)");
1.1       root      603:        return zmodem_send_pos_header(zm, ZABORT, 0, /* Hex? */ TRUE);
                    604: }
                    605: 
                    606: int zmodem_send_znak(zmodem_t* zm)
                    607: {
1.1.1.2 ! root      608:        lprintf(zm,LOG_INFO,"Sending ZNAK");
        !           609:        return zmodem_send_pos_header(zm, ZNAK, 0, /* Hex? */ TRUE);
1.1       root      610: }
                    611: 
                    612: int zmodem_send_zskip(zmodem_t* zm)
                    613: {
1.1.1.2 ! root      614:        lprintf(zm,LOG_INFO,"Sending ZSKIP");
1.1       root      615:        return zmodem_send_pos_header(zm, ZSKIP, 0L, /* Hex? */ TRUE);
                    616: }
                    617: 
1.1.1.2 ! root      618: int zmodem_send_zeof(zmodem_t* zm, uint32_t pos)
1.1       root      619: {
1.1.1.2 ! root      620:        lprintf(zm,LOG_INFO,"Sending End-of-File (ZEOF) frame (pos=%lu)", pos);
        !           621:        return zmodem_send_pos_header(zm, ZEOF, pos, /* Hex? */ TRUE);
1.1       root      622: }
                    623: 
                    624: 
                    625: /*
                    626:  * rx_raw ; receive a single byte from the line.
                    627:  * reads as many are available and then processes them one at a time
                    628:  * check the data stream for 5 consecutive CAN characters;
                    629:  * and if you see them abort. this saves a lot of clutter in
                    630:  * the rest of the code; even though it is a very strange place
                    631:  * for an exit. (but that was wat session abort was all about.)
                    632:  */
                    633: 
                    634: int zmodem_recv_raw(zmodem_t* zm)
                    635: {
                    636:        int c;
1.1.1.2 ! root      637:        unsigned attempt;
1.1       root      638: 
1.1.1.2 ! root      639:        for(attempt=0;attempt<=zm->recv_timeout;attempt++) {
        !           640:                if((c=zm->recv_byte(zm->cbdata,1 /* second timeout */)) >= 0)
        !           641:                        break;
        !           642:                if(is_cancelled(zm))
        !           643:                        return(ZCAN);
        !           644:                if(!is_connected(zm))
        !           645:                        return(ABORTED);
        !           646:        }
        !           647:        if(attempt>zm->recv_timeout)
1.1       root      648:                return(TIMEOUT);
                    649: 
                    650:        if(c == CAN) {
                    651:                zm->n_cans++;
                    652:                if(zm->n_cans == 5) {
                    653:                        zm->cancelled=TRUE;
                    654:                        lprintf(zm,LOG_WARNING,"recv_raw: Cancelled remotely");
                    655: /*                     return(TIMEOUT);        removed June-12-2005 */
                    656:                }
                    657:        }
                    658:        else {
                    659:                zm->n_cans = 0;
                    660:        }
                    661: 
                    662:        return c;
                    663: }
                    664: 
                    665: /*
                    666:  * rx; receive a single byte undoing any escaping at the
                    667:  * sending site. this bit looks like a mess. sorry for that
                    668:  * but there seems to be no other way without incurring a lot
                    669:  * of overhead. at least like this the path for a normal character
                    670:  * is relatively short.
                    671:  */
                    672: 
                    673: int zmodem_rx(zmodem_t* zm)
                    674: {
                    675:        int c;
                    676: 
                    677:        /*
                    678:         * outer loop for ever so for sure something valid
                    679:         * will come in; a timeout will occur or a session abort
                    680:         * will be received.
                    681:         */
                    682: 
1.1.1.2 ! root      683:        while(is_connected(zm) && !is_cancelled(zm)) {
1.1       root      684: 
1.1.1.2 ! root      685:                do {
        !           686:                        switch(c = zmodem_recv_raw(zm)) {
1.1       root      687:                                case ZDLE:
                    688:                                        break;
                    689:                                case XON:
                    690:                                case XON|0x80:
                    691:                                case XOFF:
                    692:                                case XOFF|0x80:
1.1.1.2 ! root      693:                                        lprintf(zm,LOG_WARNING,"rx: dropping flow ctrl char: %s"
        !           694:                                                ,chr(c));
1.1       root      695:                                        continue;                       
                    696:                                default:
                    697:                                        /*
                    698:                                         * if all control characters should be escaped and 
                    699:                                         * this one wasnt then its spurious and should be dropped.
                    700:                                         */
1.1.1.2 ! root      701:                                        if(zm->escape_ctrl_chars && (c >= 0) && (c & 0x60) == 0) {
        !           702:                                                lprintf(zm,LOG_WARNING,"rx: dropping unescaped ctrl char: %s"
        !           703:                                                        ,chr(c));
1.1       root      704:                                                continue;
                    705:                                        }
                    706:                                        /*
                    707:                                         * normal character; return it.
                    708:                                         */
                    709:                                        return c;
                    710:                        }
                    711:                        break;
1.1.1.2 ! root      712:                } while(!is_cancelled(zm));
1.1       root      713:        
                    714:                /*
                    715:                 * ZDLE encoded sequence or session abort.
                    716:                 * (or something illegal; then back to the top)
                    717:                 */
                    718: 
1.1.1.2 ! root      719:                while(!is_cancelled(zm)) {
1.1       root      720: 
1.1.1.2 ! root      721:                        switch(c=zmodem_recv_raw(zm)) {
        !           722:                                case XON:
        !           723:                                case XON|0x80:
        !           724:                                case XOFF:
        !           725:                                case XOFF|0x80:
        !           726:                                case ZDLE:
        !           727:                                        lprintf(zm,LOG_WARNING,"rx: dropping escaped flow ctrl char: %s"
        !           728:                                                ,chr(c));
        !           729:                                        continue;                       
1.1       root      730:                                /*
                    731:                                 * these four are really nasty.
                    732:                                 * for convenience we just change them into 
                    733:                                 * special characters by setting a bit outside the
                    734:                                 * first 8. that way they can be recognized and still
                    735:                                 * be processed as characters by the rest of the code.
                    736:                                 */
                    737:                                case ZCRCE:
                    738:                                case ZCRCG:
                    739:                                case ZCRCQ:
                    740:                                case ZCRCW:
                    741:                                        lprintf(zm,LOG_DEBUG,"rx: encoding data subpacket type: %s"
                    742:                                                ,chr(c));
                    743:                                        return (c | ZDLEESC);
                    744:                                case ZRUB0:
                    745:                                        return 0x7f;
                    746:                                case ZRUB1:
                    747:                                        return 0xff;
                    748:                                default:
1.1.1.2 ! root      749:                                        if(c < 0)
        !           750:                                                return c;
        !           751: 
1.1       root      752:                                        if(zm->escape_ctrl_chars && (c & 0x60) == 0) {
                    753:                                                /*
                    754:                                                 * a not escaped control character; probably
                    755:                                                 * something from a network. just drop it.
                    756:                                                 */
1.1.1.2 ! root      757:                                                lprintf(zm,LOG_WARNING,"rx: dropping unescaped ctrl char: %s"
        !           758:                                                        ,chr(c));
1.1       root      759:                                                continue;
                    760:                                        }
                    761:                                        /*
                    762:                                         * legitimate escape sequence.
                    763:                                         * rebuild the orignal and return it.
                    764:                                         */
                    765:                                        if((c & 0x60) == 0x40) {
                    766:                                                return c ^ 0x40;
                    767:                                        }
                    768:                                        lprintf(zm,LOG_WARNING,"rx: illegal sequence: ZDLE %s"
                    769:                                                ,chr(c));
                    770:                                        break;
                    771:                        }
                    772:                        break;
                    773:                } 
                    774:        }
                    775: 
                    776:        /*
1.1.1.2 ! root      777:         * not reached (unless cancelled).
1.1       root      778:         */
                    779: 
1.1.1.2 ! root      780:        return ABORTED;
1.1       root      781: }
                    782: 
                    783: /*
                    784:  * receive a data subpacket as dictated by the last received header.
                    785:  * return 2 with correct packet and end of frame
                    786:  * return 1 with correct packet frame continues
                    787:  * return 0 with incorrect frame.
                    788:  * return TIMEOUT with a timeout
                    789:  * if an acknowledgement is requested it is generated automatically
                    790:  * here. 
                    791:  */
                    792: 
                    793: /*
                    794:  * data subpacket reception
                    795:  */
                    796: 
                    797: int zmodem_recv_data32(zmodem_t* zm, unsigned char * p, unsigned maxlen, unsigned* l)
                    798: {
                    799:        int c;
1.1.1.2 ! root      800:        uint32_t rxd_crc;
        !           801:        uint32_t crc;
1.1       root      802:        int subpkt_type;
                    803: 
                    804:        lprintf(zm,LOG_DEBUG,"recv_data32");
                    805: 
                    806:        crc = 0xffffffffl;
                    807: 
                    808:        do {
                    809:                c = zmodem_rx(zm);
                    810: 
1.1.1.2 ! root      811:                if(c < 0)
        !           812:                        return c;
        !           813: 
        !           814:                if(c > 0xff)
        !           815:                        break;
        !           816: 
        !           817:                if(*l >= maxlen)
        !           818:                        return SUBPKTOVERFLOW;
        !           819:                crc = ucrc32(c,crc);
        !           820:                *p++ = c;
        !           821:                (*l)++;
        !           822:        } while(1);
1.1       root      823: 
                    824:        subpkt_type = c & 0xff;
                    825: 
                    826:        crc = ucrc32(subpkt_type, crc);
                    827: 
                    828:        crc = ~crc;
                    829: 
                    830:        rxd_crc  = zmodem_rx(zm);
                    831:        rxd_crc |= zmodem_rx(zm) << 8;
                    832:        rxd_crc |= zmodem_rx(zm) << 16;
                    833:        rxd_crc |= zmodem_rx(zm) << 24;
                    834: 
                    835:        if(rxd_crc != crc) {
                    836:                lprintf(zm,LOG_WARNING,"CRC32 ERROR (%08lX, expected: %08lX) Bytes=%u, subpacket-type=%s"
                    837:                        ,rxd_crc, crc, *l, chr(subpkt_type));
1.1.1.2 ! root      838:                return CRCFAILED;
1.1       root      839:        }
                    840:        lprintf(zm,LOG_DEBUG,"GOOD CRC32: %08lX (Bytes=%u, subpacket-type=%s)"
                    841:                ,crc, *l, chr(subpkt_type));
                    842: 
                    843:        zm->ack_file_pos += *l;
                    844: 
                    845:        return subpkt_type;
                    846: }
                    847: 
                    848: int zmodem_recv_data16(zmodem_t* zm, register unsigned char* p, unsigned maxlen, unsigned* l)
                    849: {
                    850:        int c;
                    851:        int subpkt_type;
                    852:        unsigned short crc;
                    853:        unsigned short rxd_crc;
                    854: 
                    855:        lprintf(zm,LOG_DEBUG,"recv_data16");
                    856: 
                    857:        crc = 0;
                    858: 
                    859:        do {
                    860:                c = zmodem_rx(zm);
                    861: 
1.1.1.2 ! root      862:                if(c < 0)
        !           863:                        return c;
        !           864: 
        !           865:                if(c > 0xff)
        !           866:                        break;
        !           867: 
        !           868:                if(*l >= maxlen)
        !           869:                        return SUBPKTOVERFLOW;
        !           870:                crc = ucrc16(c,crc);
        !           871:                *p++ = c;
        !           872:                (*l)++;
        !           873:        } while(1);
1.1       root      874: 
                    875:        subpkt_type = c & 0xff;
                    876: 
                    877:        crc = ucrc16(subpkt_type,crc);
                    878: 
                    879:        rxd_crc  = zmodem_rx(zm) << 8;
                    880:        rxd_crc |= zmodem_rx(zm);
                    881: 
                    882:        if(rxd_crc != crc) {
                    883:                lprintf(zm,LOG_WARNING,"CRC16 ERROR (%04hX, expected: %04hX) Bytes=%d"
                    884:                        ,rxd_crc, crc, *l);
1.1.1.2 ! root      885:                return CRCFAILED;
1.1       root      886:        }
                    887:        lprintf(zm,LOG_DEBUG,"GOOD CRC16: %04hX (Bytes=%d)", crc, *l);
                    888: 
                    889:        zm->ack_file_pos += *l;
                    890: 
                    891:        return subpkt_type;
                    892: }
                    893: 
                    894: int zmodem_recv_data(zmodem_t* zm, unsigned char* p, size_t maxlen, unsigned* l, BOOL ack)
                    895: {
                    896:        int subpkt_type;
                    897:        unsigned n=0;
                    898: 
                    899:        if(l==NULL)
                    900:                l=&n;
                    901: 
                    902:        lprintf(zm,LOG_DEBUG,"recv_data (%u-bit)", zm->receive_32bit_data ? 32:16);
                    903: 
                    904:        /*
                    905:         * receive the right type of frame
                    906:         */
                    907: 
                    908:        *l = 0;
                    909: 
                    910:        if(zm->receive_32bit_data) {
                    911:                subpkt_type = zmodem_recv_data32(zm, p, maxlen, l);
                    912:        }
                    913:        else {  
                    914:                subpkt_type = zmodem_recv_data16(zm, p, maxlen, l);
                    915:        }
                    916: 
1.1.1.2 ! root      917:        if(subpkt_type <= 0)    /* e.g. TIMEOUT, SUBPKTOVERFLOW, CRCFAILED */
        !           918:                return(subpkt_type);
        !           919: 
1.1       root      920:        lprintf(zm,LOG_DEBUG,"recv_data received subpacket-type: %s"
                    921:                ,chr(subpkt_type));
                    922: 
1.1.1.2 ! root      923:        switch(subpkt_type)  {
1.1       root      924:                /*
                    925:                 * frame continues non-stop
                    926:                 */
                    927:                case ZCRCG:
                    928:                        return FRAMEOK;
                    929:                /*
                    930:                 * frame ends
                    931:                 */
                    932:                case ZCRCE:
                    933:                        return ENDOFFRAME;
                    934:                /*
                    935:                 * frame continues; ZACK expected
                    936:                 */
                    937:                case ZCRCQ:             
                    938:                        if(ack)
                    939:                                zmodem_send_ack(zm, zm->ack_file_pos);
                    940:                        return FRAMEOK;
                    941:                /*
                    942:                 * frame ends; ZACK expected
                    943:                 */
                    944:                case ZCRCW:
                    945:                        if(ack)
                    946:                                zmodem_send_ack(zm, zm->ack_file_pos);
                    947:                        return ENDOFFRAME;
                    948:        }
                    949: 
1.1.1.2 ! root      950:        lprintf(zm,LOG_WARNING,"Received invalid subpacket-type: %s", chr(subpkt_type));
1.1       root      951: 
1.1.1.2 ! root      952:        return INVALIDSUBPKT;
1.1       root      953: }
                    954: 
                    955: BOOL zmodem_recv_subpacket(zmodem_t* zm, BOOL ack)
                    956: {
                    957:        int type;
                    958: 
                    959:        type=zmodem_recv_data(zm,zm->rx_data_subpacket,sizeof(zm->rx_data_subpacket),NULL,ack);
                    960:        if(type!=FRAMEOK && type!=ENDOFFRAME) {
1.1.1.2 ! root      961:                zmodem_send_znak(zm);
1.1       root      962:                return(FALSE);
                    963:        }
                    964: 
                    965:        return(TRUE);
                    966: }
                    967: 
                    968: int zmodem_recv_nibble(zmodem_t* zm) 
                    969: {
                    970:        int c;
                    971: 
                    972:        c = zmodem_rx(zm);
                    973: 
1.1.1.2 ! root      974:        if(c < 0)
1.1       root      975:                return c;
                    976: 
                    977:        if(c > '9') {
                    978:                if(c < 'a' || c > 'f') {
                    979:                        /*
                    980:                         * illegal hex; different than expected.
                    981:                         * we might as well time out.
                    982:                         */
1.1.1.2 ! root      983:                        return -1;
1.1       root      984:                }
                    985: 
                    986:                c -= 'a' - 10;
                    987:        }
                    988:        else {
                    989:                if(c < '0') {
                    990:                        /*
                    991:                         * illegal hex; different than expected.
                    992:                         * we might as well time out.
                    993:                         */
1.1.1.2 ! root      994:                        return -1;
1.1       root      995:                }
                    996:                c -= '0';
                    997:        }
                    998: 
                    999:        return c;
                   1000: }
                   1001: 
                   1002: int zmodem_recv_hex(zmodem_t* zm)
                   1003: {
                   1004:        int n1;
                   1005:        int n0;
                   1006:        int ret;
                   1007: 
                   1008:        n1 = zmodem_recv_nibble(zm);
                   1009: 
1.1.1.2 ! root     1010:        if(n1 < 0)
1.1       root     1011:                return n1;
                   1012: 
                   1013:        n0 = zmodem_recv_nibble(zm);
                   1014: 
1.1.1.2 ! root     1015:        if(n0 < 0)
1.1       root     1016:                return n0;
                   1017: 
                   1018:        ret = (n1 << 4) | n0;
                   1019: 
                   1020:        lprintf(zm,LOG_DEBUG,"recv_hex returning: 0x%02X", ret);
                   1021: 
                   1022:        return ret;
                   1023: }
                   1024: 
                   1025: /*
                   1026:  * receive routines for each of the six different styles of header.
                   1027:  * each of these leaves zm->rxd_header_len set to 0 if the end result is
                   1028:  * not a valid header.
                   1029:  */
                   1030: 
                   1031: BOOL zmodem_recv_bin16_header(zmodem_t* zm)
                   1032: {
                   1033:        int c;
                   1034:        int n;
                   1035:        unsigned short int crc;
                   1036:        unsigned short int rxd_crc;
                   1037: 
                   1038:        lprintf(zm,LOG_DEBUG,"recv_bin16_header");
                   1039: 
                   1040:        crc = 0;
                   1041: 
                   1042:        for(n=0;n<HDRLEN;n++) {
                   1043:                c = zmodem_rx(zm);
1.1.1.2 ! root     1044:                if(c < 0) {
        !          1045:                        lprintf(zm,LOG_WARNING,"recv_bin16_header: %s", chr(c));
1.1       root     1046:                        return(FALSE);
                   1047:                }
                   1048:                crc = ucrc16(c,crc);
                   1049:                zm->rxd_header[n] = c;
                   1050:        }
                   1051: 
                   1052:        rxd_crc  = zmodem_rx(zm) << 8;
                   1053:        rxd_crc |= zmodem_rx(zm);
                   1054: 
                   1055:        if(rxd_crc != crc) {
                   1056:                lprintf(zm,LOG_WARNING,"CRC16 ERROR: 0x%hX, expected: 0x%hX", rxd_crc, crc);
                   1057:                return(FALSE);
                   1058:        }
                   1059:        lprintf(zm,LOG_DEBUG,"GOOD CRC16: %04hX", crc);
                   1060: 
                   1061:        zm->rxd_header_len = 5;
                   1062: 
                   1063:        return(TRUE);
                   1064: }
                   1065: 
1.1.1.2 ! root     1066: BOOL zmodem_recv_hex_header(zmodem_t* zm)
1.1       root     1067: {
                   1068:        int c;
                   1069:        int i;
                   1070:        unsigned short int crc = 0;
                   1071:        unsigned short int rxd_crc;
                   1072: 
                   1073:        lprintf(zm,LOG_DEBUG,"recv_hex_header");
                   1074: 
                   1075:        for(i=0;i<HDRLEN;i++) {
                   1076:                c = zmodem_recv_hex(zm);
1.1.1.2 ! root     1077:                if(c < 0 )
        !          1078:                        return FALSE;
1.1       root     1079:                crc = ucrc16(c,crc);
                   1080: 
                   1081:                zm->rxd_header[i] = c;
                   1082:        }
                   1083: 
                   1084:        /*
                   1085:         * receive the crc
                   1086:         */
                   1087: 
                   1088:        c = zmodem_recv_hex(zm);
                   1089: 
1.1.1.2 ! root     1090:        if(c < 0)
        !          1091:                return FALSE;
1.1       root     1092: 
                   1093:        rxd_crc = c << 8;
                   1094: 
                   1095:        c = zmodem_recv_hex(zm);
                   1096: 
1.1.1.2 ! root     1097:        if(c < 0 )
        !          1098:                return FALSE;
1.1       root     1099: 
                   1100:        rxd_crc |= c;
                   1101: 
                   1102:        if(rxd_crc == crc) {
                   1103:                lprintf(zm,LOG_DEBUG,"GOOD CRC16: %04hX", crc);
                   1104:                zm->rxd_header_len = 5;
                   1105:        }
                   1106:        else {
                   1107:                lprintf(zm,LOG_WARNING,"CRC16 ERROR: 0x%hX, expected: 0x%hX", rxd_crc, crc);
1.1.1.2 ! root     1108:                return FALSE;
1.1       root     1109:        }
                   1110: 
                   1111:        /*
                   1112:         * drop the end of line sequence after a hex header
                   1113:         */
                   1114:        c = zmodem_rx(zm);
                   1115:        if(c == '\r') {
                   1116:                /*
                   1117:                 * both are expected with CR
                   1118:                 */
                   1119:                zmodem_rx(zm);  /* drop LF */
                   1120:        }
1.1.1.2 ! root     1121: 
        !          1122:        return TRUE;
1.1       root     1123: }
                   1124: 
                   1125: BOOL zmodem_recv_bin32_header(zmodem_t* zm)
                   1126: {
                   1127:        int c;
                   1128:        int n;
1.1.1.2 ! root     1129:        uint32_t crc;
        !          1130:        uint32_t rxd_crc;
1.1       root     1131: 
                   1132:        lprintf(zm,LOG_DEBUG,"recv_bin32_header");
                   1133: 
                   1134:        crc = 0xffffffffL;
                   1135: 
                   1136:        for(n=0;n<HDRLEN;n++) {
                   1137:                c = zmodem_rx(zm);
1.1.1.2 ! root     1138:                if(c < 0)
1.1       root     1139:                        return(TRUE);
                   1140:                crc = ucrc32(c,crc);
                   1141:                zm->rxd_header[n] = c;
                   1142:        }
                   1143: 
                   1144:        crc = ~crc;
                   1145: 
                   1146:        rxd_crc  = zmodem_rx(zm);
                   1147:        rxd_crc |= zmodem_rx(zm) << 8;
                   1148:        rxd_crc |= zmodem_rx(zm) << 16;
                   1149:        rxd_crc |= zmodem_rx(zm) << 24;
                   1150: 
                   1151:        if(rxd_crc != crc) {
                   1152:                lprintf(zm,LOG_WARNING,"CRC32 ERROR (%08lX, expected: %08lX)"
                   1153:                        ,rxd_crc, crc);
                   1154:                return(FALSE);
                   1155:        }
                   1156:        lprintf(zm,LOG_DEBUG,"GOOD CRC32: %08lX", crc);
                   1157: 
                   1158:        zm->rxd_header_len = 5;
                   1159:        return(TRUE);
                   1160: }
                   1161: 
                   1162: /*
                   1163:  * receive any style header
                   1164:  * if the errors flag is set than whenever an invalid header packet is
                   1165:  * received INVHDR will be returned. otherwise we wait for a good header
                   1166:  * also; a flag (receive_32bit_data) will be set to indicate whether data
                   1167:  * packets following this header will have 16 or 32 bit data attached.
                   1168:  * variable headers are not implemented.
                   1169:  */
                   1170: 
                   1171: int zmodem_recv_header_raw(zmodem_t* zm, int errors)
                   1172: {
                   1173:        int c;
                   1174:        int     frame_type;
                   1175: 
                   1176:        lprintf(zm,LOG_DEBUG,"recv_header_raw");
                   1177: 
                   1178:        zm->rxd_header_len = 0;
                   1179: 
                   1180:        do {
                   1181:                do {
                   1182:                        if((c = zmodem_recv_raw(zm)) < 0)
                   1183:                                return(c);
                   1184:                        if(is_cancelled(zm))
                   1185:                                return(ZCAN);
                   1186:                } while(c != ZPAD);
                   1187: 
                   1188:                if((c = zmodem_recv_raw(zm)) < 0)
                   1189:                        return(c);
                   1190: 
                   1191:                if(c == ZPAD) {
                   1192:                        if((c = zmodem_recv_raw(zm)) < 0)
                   1193:                                return(c);
                   1194:                }
                   1195: 
                   1196:                /*
                   1197:                 * spurious ZPAD check
                   1198:                 */
                   1199: 
                   1200:                if(c != ZDLE) {
                   1201:                        lprintf(zm,LOG_WARNING,"recv_header_raw: Expected ZDLE, received: %s"
                   1202:                                ,chr(c));
                   1203:                        continue;
                   1204:                }
                   1205: 
                   1206:                /*
                   1207:                 * now read the header style
                   1208:                 */
                   1209: 
                   1210:                c = zmodem_rx(zm);
                   1211: 
                   1212:                switch (c) {
                   1213:                        case ZBIN:
1.1.1.2 ! root     1214:                                if(!zmodem_recv_bin16_header(zm))
        !          1215:                                        return INVHDR;
1.1       root     1216:                                zm->receive_32bit_data = FALSE;
                   1217:                                break;
                   1218:                        case ZHEX:
1.1.1.2 ! root     1219:                                if(!zmodem_recv_hex_header(zm))
        !          1220:                                        return INVHDR;
1.1       root     1221:                                zm->receive_32bit_data = FALSE;
                   1222:                                break;
                   1223:                        case ZBIN32:
1.1.1.2 ! root     1224:                                if(!zmodem_recv_bin32_header(zm))
        !          1225:                                        return INVHDR;
1.1       root     1226:                                zm->receive_32bit_data = TRUE;
                   1227:                                break;
                   1228:                        default:
1.1.1.2 ! root     1229:                                if(c < 0) {
        !          1230:                                        lprintf(zm,LOG_WARNING,"recv_header_raw: %s", chr(c));
        !          1231:                                        return c;
        !          1232:                                }
1.1       root     1233:                                /*
                   1234:                                 * unrecognized header style
                   1235:                                 */
                   1236:                                lprintf(zm,LOG_ERR,"recv_header_raw: UNRECOGNIZED header style: %s"
                   1237:                                        ,chr(c));
                   1238:                                if(errors) {
                   1239:                                        return INVHDR;
                   1240:                                }
                   1241: 
                   1242:                                continue;
                   1243:                }
                   1244:                if(errors && zm->rxd_header_len == 0) {
                   1245:                        return INVHDR;
                   1246:                }
                   1247: 
                   1248:        } while(zm->rxd_header_len == 0 && !is_cancelled(zm));
                   1249: 
                   1250:        if(is_cancelled(zm))
                   1251:                return(ZCAN);
                   1252: 
                   1253:        /*
                   1254:         * this appears to have been a valid header.
                   1255:         * return its type.
                   1256:         */
                   1257: 
                   1258:        frame_type = zm->rxd_header[0];
                   1259: 
                   1260:        zm->rxd_header_pos = zm->rxd_header[ZP0] | (zm->rxd_header[ZP1] << 8) |
                   1261:                                (zm->rxd_header[ZP2] << 16) | (zm->rxd_header[ZP3] << 24);
                   1262: 
                   1263:        switch(frame_type) {
                   1264:                case ZCRC:
                   1265:                        zm->crc_request = zm->rxd_header_pos;
                   1266:                        break;
                   1267:                case ZDATA:
                   1268:                        zm->ack_file_pos = zm->rxd_header_pos;
                   1269:                        break;
                   1270:                case ZFILE:
                   1271:                        zm->ack_file_pos = 0l;
                   1272:                        if(!zmodem_recv_subpacket(zm,/* ack? */FALSE))
                   1273:                                frame_type |= BADSUBPKT;
                   1274:                        break;
                   1275:                case ZSINIT:
                   1276:                case ZCOMMAND:
                   1277:                        if(!zmodem_recv_subpacket(zm,/* ack? */TRUE))
                   1278:                                frame_type |= BADSUBPKT;
                   1279:                        break;
                   1280:                case ZFREECNT:
                   1281:                        zmodem_send_pos_header(zm, ZACK, getfreediskspace(".",1), /* Hex? */ TRUE);
                   1282:                        break;
                   1283:        }
                   1284: 
1.1.1.2 ! root     1285: #if 0 /* def _DEBUG */
1.1       root     1286:        lprintf(zm,LOG_DEBUG,"recv_header_raw received header type: %s"
                   1287:                ,frame_desc(frame_type));
                   1288: #endif
                   1289: 
                   1290:        return frame_type;
                   1291: }
                   1292: 
                   1293: int zmodem_recv_header(zmodem_t* zm)
                   1294: {
                   1295:        int ret;
                   1296:        
1.1.1.2 ! root     1297:        switch(ret = zmodem_recv_header_raw(zm, FALSE)) {
        !          1298:                case TIMEOUT:
        !          1299:                        lprintf(zm,LOG_WARNING,"recv_header TIMEOUT");
        !          1300:                        break;
        !          1301:                case INVHDR:
        !          1302:                        lprintf(zm,LOG_WARNING,"recv_header detected an invalid header");
        !          1303:                        break;
        !          1304:                default:
        !          1305:                        lprintf(zm,LOG_DEBUG,"recv_header returning: %s (pos=%lu)"
        !          1306:                                ,frame_desc(ret), frame_pos(zm, ret));
1.1       root     1307: 
1.1.1.2 ! root     1308:                        if(ret==ZCAN)
        !          1309:                                zm->cancelled=TRUE;
        !          1310:                        else if(ret==ZRINIT)
        !          1311:                                zmodem_parse_zrinit(zm);
        !          1312:                        break;
        !          1313:        }
1.1       root     1314: 
                   1315:        return ret;
                   1316: }
                   1317: 
                   1318: int zmodem_recv_header_and_check(zmodem_t* zm)
                   1319: {
1.1.1.2 ! root     1320:        int type=ABORTED;
1.1       root     1321: 
1.1.1.2 ! root     1322:        while(is_connected(zm) && !is_cancelled(zm)) {
1.1       root     1323:                type = zmodem_recv_header_raw(zm,TRUE);         
                   1324: 
1.1.1.2 ! root     1325:                if(type == TIMEOUT)
        !          1326:                        break;
        !          1327: 
        !          1328:                if(type != INVHDR && (type&BADSUBPKT) == 0)
1.1       root     1329:                        break;
                   1330: 
                   1331:                zmodem_send_znak(zm);
                   1332:        }
                   1333: 
1.1.1.2 ! root     1334:        lprintf(zm,LOG_DEBUG,"recv_header_and_check returning: %s (pos=%lu)"
        !          1335:                ,frame_desc(type), frame_pos(zm, type));
        !          1336: 
        !          1337:        if(type==ZCAN)
        !          1338:                zm->cancelled=TRUE;
        !          1339: 
1.1       root     1340:        return type;
                   1341: }
                   1342: 
1.1.1.2 ! root     1343: BOOL zmodem_request_crc(zmodem_t* zm, int32_t length)
1.1       root     1344: {
1.1.1.2 ! root     1345:        zmodem_recv_purge(zm);
1.1       root     1346:        zmodem_send_pos_header(zm,ZCRC,length,TRUE);
1.1.1.2 ! root     1347:        return TRUE;
        !          1348: }
        !          1349: 
        !          1350: BOOL zmodem_recv_crc(zmodem_t* zm, uint32_t* crc)
        !          1351: {
        !          1352:        int type;
        !          1353: 
        !          1354:        if(!zmodem_data_waiting(zm,zm->crc_timeout)) {
        !          1355:                lprintf(zm,LOG_ERR,"Timeout waiting for response (%u seconds)", zm->crc_timeout);
1.1       root     1356:                return(FALSE);
1.1.1.2 ! root     1357:        }
        !          1358:        if((type=zmodem_recv_header(zm))!=ZCRC) {
        !          1359:                lprintf(zm,LOG_ERR,"Received %s instead of ZCRC", frame_desc(type));
1.1       root     1360:                return(FALSE);
1.1.1.2 ! root     1361:        }
1.1       root     1362:        if(crc!=NULL)
                   1363:                *crc = zm->crc_request;
1.1.1.2 ! root     1364:        return TRUE;
        !          1365: }
        !          1366: 
        !          1367: BOOL zmodem_get_crc(zmodem_t* zm, int32_t length, uint32_t* crc)
        !          1368: {
        !          1369:        if(zmodem_request_crc(zm, length))
        !          1370:                return zmodem_recv_crc(zm, crc);
        !          1371:        return FALSE;
1.1       root     1372: }
                   1373: 
                   1374: void zmodem_parse_zrinit(zmodem_t* zm)
                   1375: {
                   1376:        zm->can_full_duplex                                     = INT_TO_BOOL(zm->rxd_header[ZF0] & ZF0_CANFDX);
                   1377:        zm->can_overlap_io                                      = INT_TO_BOOL(zm->rxd_header[ZF0] & ZF0_CANOVIO);
                   1378:        zm->can_break                                           = INT_TO_BOOL(zm->rxd_header[ZF0] & ZF0_CANBRK);
                   1379:        zm->can_fcs_32                                          = INT_TO_BOOL(zm->rxd_header[ZF0] & ZF0_CANFC32);
                   1380:        zm->escape_ctrl_chars                           = INT_TO_BOOL(zm->rxd_header[ZF0] & ZF0_ESCCTL);
                   1381:        zm->escape_8th_bit                                      = INT_TO_BOOL(zm->rxd_header[ZF0] & ZF0_ESC8);
                   1382: 
                   1383:        lprintf(zm,LOG_INFO,"Receiver requested mode (0x%02X):\r\n"
                   1384:                "%s-duplex, %s overlap I/O, CRC-%u, Escape: %s"
                   1385:                ,zm->rxd_header[ZF0]
                   1386:                ,zm->can_full_duplex ? "Full" : "Half"
                   1387:                ,zm->can_overlap_io ? "Can" : "Cannot"
                   1388:                ,zm->can_fcs_32 ? 32 : 16
                   1389:                ,zm->escape_ctrl_chars ? "ALL" : "Normal"
                   1390:                );
                   1391: 
                   1392:        if((zm->recv_bufsize = (zm->rxd_header[ZP0] | zm->rxd_header[ZP1]<<8)) != 0)
                   1393:                lprintf(zm,LOG_INFO,"Receiver specified buffer size of: %u", zm->recv_bufsize);
                   1394: }
                   1395: 
                   1396: int zmodem_get_zrinit(zmodem_t* zm)
                   1397: {
                   1398:        unsigned char zrqinit_header[] = { ZRQINIT, /* ZF3: */0, 0, 0, /* ZF0: */0 };
                   1399:        /* Note: sz/dsz/fdsz sends 0x80 in ZF3 because it supports var-length headers. */
                   1400:        /* We do not, so we send 0x00, resulting in a CRC-16 value of 0x0000 as well. */
                   1401: 
                   1402:        zmodem_send_raw(zm,'r');
                   1403:        zmodem_send_raw(zm,'z');
                   1404:        zmodem_send_raw(zm,'\r');
                   1405:        zmodem_send_hex_header(zm,zrqinit_header);
                   1406:        
1.1.1.2 ! root     1407:        if(!zmodem_data_waiting(zm,zm->init_timeout))
1.1       root     1408:                return(TIMEOUT);
                   1409:        return zmodem_recv_header(zm);
                   1410: }
                   1411: 
                   1412: int zmodem_send_zrinit(zmodem_t* zm)
                   1413: {
                   1414:        unsigned char zrinit_header[] = { ZRINIT, 0, 0, 0, 0 };
                   1415:        
                   1416:        zrinit_header[ZF0] = ZF0_CANFDX;
                   1417: 
                   1418:        if(!zm->no_streaming)
                   1419:                zrinit_header[ZF0] |= ZF0_CANOVIO;
                   1420: 
                   1421:        if(zm->can_break)
                   1422:                zrinit_header[ZF0] |= ZF0_CANBRK;
                   1423: 
                   1424:        if(!zm->want_fcs_16)
                   1425:                zrinit_header[ZF0] |= ZF0_CANFC32;
                   1426: 
                   1427:        if(zm->escape_ctrl_chars)
                   1428:                zrinit_header[ZF0] |= ZF0_ESCCTL;
                   1429: 
                   1430:        if(zm->escape_8th_bit)
                   1431:                zrinit_header[ZF0] |= ZF0_ESC8;
                   1432: 
                   1433:        if(zm->no_streaming && zm->recv_bufsize==0)
                   1434:                zm->recv_bufsize = sizeof(zm->rx_data_subpacket);
                   1435: 
                   1436:        zrinit_header[ZP0] = zm->recv_bufsize & 0xff;
                   1437:        zrinit_header[ZP1] = zm->recv_bufsize >> 8;
                   1438: 
                   1439:        return zmodem_send_hex_header(zm, zrinit_header);
                   1440: }
                   1441: 
1.1.1.2 ! root     1442: /* Returns ZFIN on success */
1.1       root     1443: int zmodem_get_zfin(zmodem_t* zm)
                   1444: {
1.1.1.2 ! root     1445:        int result;
        !          1446:        int type=ZCAN;
        !          1447:        unsigned attempts;
1.1       root     1448: 
1.1.1.2 ! root     1449:        for(attempts=0; attempts<zm->max_errors && is_connected(zm) && !is_cancelled(zm); attempts++) {
        !          1450:                if(attempts&1)  /* Alternate between ZABORT and ZFIN */
        !          1451:                        result = zmodem_send_zabort(zm);
        !          1452:                else
        !          1453:                        result = zmodem_send_zfin(zm);
        !          1454:                if(result != 0)
        !          1455:                        return result;
        !          1456:                if((type = zmodem_recv_header(zm)) == ZFIN)
        !          1457:                        break;
        !          1458:        }
1.1       root     1459:        
                   1460:        /*
                   1461:         * these Os are formally required; but they don't do a thing
                   1462:         * unfortunately many programs require them to exit 
                   1463:         * (both programs already sent a ZFIN so why bother ?)
                   1464:         */
                   1465: 
1.1.1.2 ! root     1466:        if(type == ZFIN) {
1.1       root     1467:                zmodem_send_raw(zm,'O');
                   1468:                zmodem_send_raw(zm,'O');
                   1469:        }
                   1470: 
1.1.1.2 ! root     1471:        return type;
        !          1472: }
        !          1473: 
        !          1474: BOOL zmodem_handle_zrpos(zmodem_t* zm, uint64_t* pos)
        !          1475: {
        !          1476:        if(zm->rxd_header_pos <= zm->current_file_size) {
        !          1477:                if(*pos != zm->rxd_header_pos) {
        !          1478:                        *pos = zm->rxd_header_pos;
        !          1479:                        lprintf(zm,LOG_INFO,"Resuming transfer from offset: %"PRIu64, *pos);
        !          1480:                }
        !          1481:                return TRUE;
        !          1482:        }
        !          1483:        lprintf(zm,LOG_WARNING,"Invalid ZRPOS offset: %lu", zm->rxd_header_pos);
        !          1484:        return FALSE;
1.1       root     1485: }
                   1486: 
1.1.1.2 ! root     1487: BOOL zmodem_handle_zack(zmodem_t* zm)
        !          1488: {
        !          1489:        if(zm->rxd_header_pos == zm->current_file_pos)
        !          1490:                return TRUE;
        !          1491:        lprintf(zm,LOG_WARNING,"ZACK for incorrect offset (%lu vs %lu)"
        !          1492:                ,zm->rxd_header_pos, (ulong)zm->current_file_pos);
        !          1493:        return FALSE;
        !          1494: }
1.1       root     1495: 
                   1496: /*
                   1497:  * send from the current position in the file
                   1498:  * all the way to end of file or until something goes wrong.
                   1499:  * (ZNAK or ZRPOS received)
1.1.1.2 ! root     1500:  * returns ZRINIT on success.
1.1       root     1501:  */
                   1502: 
1.1.1.2 ! root     1503: int zmodem_send_from(zmodem_t* zm, FILE* fp, uint64_t pos, uint64_t* sent)
1.1       root     1504: {
                   1505:        size_t n;
                   1506:        uchar type;
                   1507:        unsigned buf_sent=0;
1.1.1.2 ! root     1508:        unsigned subpkts_sent=0;
1.1       root     1509: 
                   1510:        if(sent!=NULL)
                   1511:                *sent=0;
                   1512: 
1.1.1.2 ! root     1513:        if(fseeko(fp,(off_t)pos,SEEK_SET)!=0) {
        !          1514:                lprintf(zm,LOG_ERR,"ERROR %d seeking to file offset %"PRIu64
        !          1515:                        ,errno, pos);
        !          1516:                zmodem_send_pos_header(zm, ZFERR, (uint32_t)pos, /* Hex? */ TRUE);
        !          1517:                return ZFERR;
        !          1518:        }
        !          1519:        zm->current_file_pos=pos;
1.1       root     1520: 
                   1521: 
                   1522:        /*
                   1523:         * send the data in the file
                   1524:         */
                   1525: 
                   1526:        while(is_connected(zm)) {
                   1527: 
                   1528:                /*
                   1529:                 * read a block from the file
                   1530:                 */
                   1531: 
                   1532:                n = fread(zm->tx_data_subpacket,sizeof(BYTE),zm->block_size,fp);
                   1533: 
                   1534:                if(zm->progress!=NULL)
1.1.1.2 ! root     1535:                        zm->progress(zm->cbdata, ftello(fp));
        !          1536:                
        !          1537:                type = ZCRCW;
1.1       root     1538: 
                   1539:                /** ZMODEM.DOC:
                   1540:                        ZCRCW data subpackets expect a response before the next frame is sent.
                   1541:                        If the receiver does not indicate overlapped I/O capability with the
                   1542:                        CANOVIO bit, or sets a buffer size, the sender uses the ZCRCW to allow
                   1543:                        the receiver to write its buffer before sending more data.
                   1544:                ***/
1.1.1.2 ! root     1545:                /* Note: we always use ZCRCW for the first frame */
        !          1546:                if(subpkts_sent || n < zm->block_size) {
        !          1547:                        /*  ZMODEM.DOC:
        !          1548:                                In the absence of fatal error, the sender eventually encounters end of
        !          1549:                                file.  If the end of file is encountered within a frame, the frame is
        !          1550:                                closed with a ZCRCE data subpacket which does not elicit a response
        !          1551:                                except in case of error.
        !          1552:                        */
        !          1553:                        if(n < zm->block_size)
        !          1554:                                type = ZCRCE;
        !          1555:                        else {
        !          1556:                                if(zm->can_overlap_io && !zm->no_streaming && (zm->recv_bufsize==0 || buf_sent+n < zm->recv_bufsize))
        !          1557:                                        type = ZCRCG;
        !          1558:                                else    /* Send a ZCRCW frame */
        !          1559:                                        buf_sent = 0;   
        !          1560:                        }
1.1       root     1561:                }
                   1562: 
1.1.1.2 ! root     1563:                /* Note: No support for sending ZCRCQ data sub-packets here */
1.1       root     1564: 
                   1565:                if(zmodem_send_data(zm, type, zm->tx_data_subpacket, n)!=0)
                   1566:                        return(TIMEOUT);
                   1567: 
1.1.1.2 ! root     1568:                zm->current_file_pos += n;
        !          1569:                if(zm->current_file_pos > zm->current_file_size)
        !          1570:                        zm->current_file_size = zm->current_file_pos;
        !          1571:                subpkts_sent++;
        !          1572: 
1.1       root     1573:                if(type == ZCRCW || type == ZCRCE) {    
                   1574:                        lprintf(zm,LOG_DEBUG,"Sent end-of-frame (%s sub-packet)", chr(type));
                   1575:                        if(type==ZCRCW) {       /* ZACK expected */
                   1576:                                lprintf(zm,LOG_DEBUG,"Waiting for ZACK");
                   1577:                                while(is_connected(zm)) {
1.1.1.2 ! root     1578:                                        int ack;
1.1       root     1579:                                        if((ack = zmodem_recv_header(zm)) != ZACK)
                   1580:                                                return(ack);
                   1581: 
                   1582:                                        if(is_cancelled(zm))
                   1583:                                                return(ZCAN);
                   1584: 
1.1.1.2 ! root     1585:                                        if(zmodem_handle_zack(zm))
1.1       root     1586:                                                break;
                   1587:                                } 
                   1588:                        }
                   1589:                }
                   1590: 
                   1591:                if(sent!=NULL)
                   1592:                        *sent+=n;
                   1593: 
                   1594:                buf_sent+=n;
                   1595: 
1.1.1.2 ! root     1596:                if(n < zm->block_size) {
        !          1597:                        lprintf(zm,LOG_DEBUG,"send_from: end of file (or read error) reached at offset: %"PRId64, zm->current_file_pos);
        !          1598:                        zmodem_send_zeof(zm, (uint32_t)zm->current_file_pos);
        !          1599:                        return zmodem_recv_header(zm);  /* If this is ZRINIT, Success */
1.1       root     1600:                }
                   1601: 
                   1602:                /* 
                   1603:                 * characters from the other side
                   1604:                 * check out that header
                   1605:                 */
                   1606: 
1.1.1.2 ! root     1607:                while(zmodem_data_waiting(zm, zm->consecutive_errors ? 1:0) 
1.1       root     1608:                        && !is_cancelled(zm) && is_connected(zm)) {
1.1.1.2 ! root     1609:                        int rx_type;
1.1       root     1610:                        int c;
                   1611:                        lprintf(zm,LOG_DEBUG,"Back-channel traffic detected:");
                   1612:                        if((c = zmodem_recv_raw(zm)) < 0)
                   1613:                                return(c);
                   1614:                        if(c == ZPAD) {
1.1.1.2 ! root     1615:                                /* ZMODEM.DOC: 
        !          1616:                                        FULL STREAMING WITH SAMPLING
        !          1617:                                        If one of these characters (CAN or ZPAD) is seen, an
        !          1618:                                        empty ZCRCE data subpacket is sent.
        !          1619:                                */
        !          1620:                                zmodem_send_data(zm, ZCRCE, NULL, 0);
        !          1621:                                rx_type = zmodem_recv_header(zm);
        !          1622:                                lprintf(zm,LOG_DEBUG,"Received back-channel data: %s", chr(rx_type));
        !          1623:                                if(rx_type >= 0) {
        !          1624:                                        return rx_type;
1.1       root     1625:                                }
                   1626:                        } else
                   1627:                                lprintf(zm,LOG_DEBUG,"Received: %s",chr(c));
                   1628:                }
                   1629:                if(is_cancelled(zm))
                   1630:                        return(ZCAN);
                   1631: 
                   1632:                zm->consecutive_errors = 0;
                   1633: 
                   1634:                if(zm->block_size < zm->max_block_size) {
                   1635:                        zm->block_size*=2;
                   1636:                        if(zm->block_size > zm->max_block_size)
                   1637:                                zm->block_size = zm->max_block_size;
                   1638:                }
                   1639:        }
                   1640: 
                   1641:        lprintf(zm,LOG_DEBUG,"send_from: returning unexpectedly!");
                   1642: 
                   1643:        /*
                   1644:         * end of file reached.
                   1645:         * should receive something... so fake ZACK
                   1646:         */
                   1647: 
                   1648:        return ZACK;
                   1649: }
                   1650: 
                   1651: /*
1.1.1.2 ! root     1652:  * send a file; returns true when session is successful. (or file is skipped)
1.1       root     1653:  */
                   1654: 
1.1.1.2 ! root     1655: BOOL zmodem_send_file(zmodem_t* zm, char* fname, FILE* fp, BOOL request_init, time_t* start, int64_t* sent)
1.1       root     1656: {
1.1.1.2 ! root     1657:        uint64_t        pos=0;
        !          1658:        uint64_t        sent_bytes;
        !          1659:        struct stat             s;
1.1       root     1660:        unsigned char * p;
1.1.1.2 ! root     1661:        uchar           zfile_frame[] = { ZFILE, 0, 0, 0, 0 };
        !          1662:        int                     type;
        !          1663:        int                     i;
        !          1664:        unsigned        attempts;
1.1       root     1665: 
                   1666:        if(zm->block_size == 0)
                   1667:                zm->block_size = ZBLOCKLEN;     
                   1668: 
                   1669:        if(zm->block_size < 128)
                   1670:                zm->block_size = 128;   
                   1671: 
                   1672:        if(zm->block_size > sizeof(zm->tx_data_subpacket))
                   1673:                zm->block_size = sizeof(zm->tx_data_subpacket);
                   1674: 
                   1675:        if(zm->max_block_size < zm->block_size)
                   1676:                zm->max_block_size = zm->block_size;
                   1677: 
                   1678:        if(zm->max_block_size > sizeof(zm->rx_data_subpacket))
                   1679:                zm->max_block_size = sizeof(zm->rx_data_subpacket);
                   1680: 
                   1681:        if(sent!=NULL)  
                   1682:                *sent=0;
                   1683: 
                   1684:        if(start!=NULL)         
                   1685:                *start=time(NULL);
                   1686: 
                   1687:        zm->file_skipped=FALSE;
                   1688: 
                   1689:        if(zm->no_streaming)
                   1690:                lprintf(zm,LOG_WARNING,"Streaming disabled");
                   1691: 
                   1692:        if(request_init) {
                   1693:                for(zm->errors=0; zm->errors<=zm->max_errors && !is_cancelled(zm) && is_connected(zm); zm->errors++) {
1.1.1.2 ! root     1694:                        if(zm->errors)
        !          1695:                                lprintf(zm,LOG_NOTICE,"Sending ZRQINIT (%u of %u)"
        !          1696:                                        ,zm->errors+1,zm->max_errors+1);
        !          1697:                        else
        !          1698:                                lprintf(zm,LOG_INFO,"Sending ZRQINIT");
1.1       root     1699:                        i = zmodem_get_zrinit(zm);
1.1.1.2 ! root     1700:                        if(i == ZRINIT)
1.1       root     1701:                                break;
1.1.1.2 ! root     1702:                        lprintf(zm,LOG_WARNING,"send_file: received %s instead of ZRINIT"
1.1       root     1703:                                ,frame_desc(i));
                   1704:                }
1.1.1.2 ! root     1705:                if(zm->errors>=zm->max_errors || is_cancelled(zm) || !is_connected(zm))
1.1       root     1706:                        return(FALSE);
                   1707:        }
                   1708: 
                   1709:        fstat(fileno(fp),&s);
                   1710:        zm->current_file_size = s.st_size;
                   1711:        SAFECOPY(zm->current_file_name, getfname(fname));
                   1712: 
                   1713:        /*
                   1714:         * the file exists. now build the ZFILE frame
                   1715:         */
                   1716: 
                   1717:        /*
                   1718:         * set conversion option
                   1719:         * (not used; always binary)
                   1720:         */
                   1721: 
                   1722:        zfile_frame[ZF0] = ZF0_ZCBIN;
                   1723: 
                   1724:        /*
                   1725:         * management option
                   1726:         */
                   1727: 
                   1728:        if(zm->management_protect) {
                   1729:                zfile_frame[ZF1] = ZF1_ZMPROT;          
                   1730:                lprintf(zm,LOG_DEBUG,"send_file: protecting destination");
                   1731:        }
                   1732:        else if(zm->management_clobber) {
                   1733:                zfile_frame[ZF1] = ZF1_ZMCLOB;
                   1734:                lprintf(zm,LOG_DEBUG,"send_file: overwriting destination");
                   1735:        }
                   1736:        else if(zm->management_newer) {
                   1737:                zfile_frame[ZF1] = ZF1_ZMNEW;
                   1738:                lprintf(zm,LOG_DEBUG,"send_file: overwriting destination if newer");
                   1739:        }
                   1740:        else
                   1741:                zfile_frame[ZF1] = ZF1_ZMCRC;
                   1742: 
                   1743:        /*
                   1744:         * transport options
                   1745:         * (just plain normal transfer)
                   1746:         */
                   1747: 
                   1748:        zfile_frame[ZF2] = ZF2_ZTNOR;
                   1749: 
                   1750:        /*
                   1751:         * extended options
                   1752:         */
                   1753: 
                   1754:        zfile_frame[ZF3] = 0;
                   1755: 
                   1756:        /*
                   1757:         * now build the data subpacket with the file name and lots of other
                   1758:         * useful information.
                   1759:         */
                   1760: 
                   1761:        /*
                   1762:         * first enter the name and a 0
                   1763:         */
                   1764: 
                   1765:        p = zm->tx_data_subpacket;
                   1766: 
                   1767:        strcpy(p,getfname(fname));
                   1768: 
                   1769:        p += strlen(p) + 1;
                   1770: 
1.1.1.2 ! root     1771:        sprintf(p,"%"PRId64" %lo 0 0 %u %"PRId64" 0"
        !          1772:                ,zm->current_file_size  /* use for estimating only, could be zero! */
1.1       root     1773:                ,s.st_mtime
                   1774:                ,zm->files_remaining
                   1775:                ,zm->bytes_remaining
                   1776:                );
                   1777: 
                   1778:        p += strlen(p) + 1;
                   1779: 
1.1.1.2 ! root     1780:        for(attempts=0;;attempts++) {
        !          1781: 
        !          1782:                if(attempts > zm->max_errors)
        !          1783:                        return(FALSE);
        !          1784: 
1.1       root     1785:                /*
                   1786:                 * send the header and the data
                   1787:                 */
                   1788: 
1.1.1.2 ! root     1789:                lprintf(zm,LOG_DEBUG,"Sending ZFILE frame: '%s'"
1.1       root     1790:                        ,zm->tx_data_subpacket+strlen(zm->tx_data_subpacket)+1);
                   1791: 
1.1.1.2 ! root     1792:                if((i=zmodem_send_bin_header(zm,zfile_frame))!=0) {
        !          1793:                        lprintf(zm,LOG_DEBUG,"zmodem_send_bin_header returned %d",i);
        !          1794:                        continue;
        !          1795:                }
        !          1796:                if((i=zmodem_send_data_subpkt(zm,ZCRCW,zm->tx_data_subpacket,p - zm->tx_data_subpacket))!=0) {
        !          1797:                        lprintf(zm,LOG_DEBUG,"zmodem_send_data_subpkt returned %d",i);
        !          1798:                        continue;
        !          1799:                }
1.1       root     1800:                /*
                   1801:                 * wait for anything but an ZACK packet
                   1802:                 */
                   1803: 
                   1804:                do {
                   1805:                        type = zmodem_recv_header(zm);
                   1806:                        if(is_cancelled(zm))
                   1807:                                return(FALSE);
                   1808:                } while(type == ZACK && is_connected(zm));
                   1809: 
                   1810:                if(!is_connected(zm))
                   1811:                        return(FALSE);
                   1812: 
                   1813: #if 0
                   1814:                lprintf(zm,LOG_INFO,"type : %d",type);
                   1815: #endif
                   1816: 
                   1817:                if(type == ZSKIP) {
                   1818:                        zm->file_skipped=TRUE;
                   1819:                        lprintf(zm,LOG_WARNING,"File skipped by receiver");
1.1.1.2 ! root     1820:                        return(TRUE);
1.1       root     1821:                }
                   1822: 
                   1823:                if(type == ZCRC) {
                   1824:                        if(zm->crc_request==0)
                   1825:                                lprintf(zm,LOG_NOTICE,"Receiver requested CRC of entire file");
                   1826:                        else
                   1827:                                lprintf(zm,LOG_NOTICE,"Receiver requested CRC of first %lu bytes"
                   1828:                                        ,zm->crc_request);
                   1829:                        zmodem_send_pos_header(zm,ZCRC,fcrc32(fp,zm->crc_request),TRUE);
                   1830:                        type = zmodem_recv_header(zm);
                   1831:                }
                   1832: 
1.1.1.2 ! root     1833:                if(type == ZRPOS)
        !          1834:                        break;
        !          1835:        }
        !          1836: 
        !          1837:        if(!zmodem_handle_zrpos(zm, &pos))
        !          1838:                return(FALSE);
1.1       root     1839: 
1.1.1.2 ! root     1840:        zm->transfer_start_pos = pos;
1.1       root     1841:        zm->transfer_start_time = time(NULL);
                   1842: 
                   1843:        if(start!=NULL)         
                   1844:                *start=zm->transfer_start_time;
                   1845: 
                   1846:        rewind(fp);
                   1847:        zm->errors = 0;
                   1848:        zm->consecutive_errors = 0;
1.1.1.2 ! root     1849: 
        !          1850:        lprintf(zm,LOG_DEBUG,"Sending %s from offset %"PRIu64, fname, pos);
1.1       root     1851:        do {
                   1852:                /*
                   1853:                 * and start sending
                   1854:                 */
                   1855: 
                   1856:                type = zmodem_send_from(zm, fp, pos, &sent_bytes);
                   1857: 
                   1858:                if(!is_connected(zm))
                   1859:                        return(FALSE);
                   1860: 
                   1861:                if(type == ZFERR || type == ZABORT || is_cancelled(zm))
1.1.1.2 ! root     1862:                        break;
        !          1863: 
        !          1864:                if(type == ZSKIP) {
        !          1865:                        zm->file_skipped=TRUE;
        !          1866:                        lprintf(zm,LOG_WARNING,"File skipped by receiver at offset: %"PRIu64, pos + sent_bytes);
        !          1867:                        /* ZOC sends a ZRINIT after mid-file ZSKIP, so consume the ZRINIT here */
        !          1868:                        zmodem_recv_header(zm);
        !          1869:                        return(TRUE);
        !          1870:                }
1.1       root     1871: 
                   1872:                if(sent != NULL)
                   1873:                        *sent += sent_bytes;
                   1874: 
1.1.1.2 ! root     1875:                if(type == ZRINIT)
        !          1876:                        return(TRUE);   /* Success */
1.1       root     1877: 
1.1.1.2 ! root     1878:                if(type==ZACK && zmodem_handle_zack(zm)) {
        !          1879:                        pos += sent_bytes;
        !          1880:                        continue;
        !          1881:                }
        !          1882: 
        !          1883:                /* Error of some kind */
1.1       root     1884: 
1.1.1.2 ! root     1885:                lprintf(zm,LOG_ERR,"Received %s at offset: %"PRId64, chr(type), zm->current_file_pos);
1.1       root     1886: 
                   1887:                if(zm->block_size == zm->max_block_size && zm->max_block_size > ZBLOCKLEN)
                   1888:                        zm->max_block_size /= 2;
                   1889: 
                   1890:                if(zm->block_size > 128)
                   1891:                        zm->block_size /= 2; 
                   1892: 
                   1893:                zm->errors++;
                   1894:                if(++zm->consecutive_errors > zm->max_errors)
1.1.1.2 ! root     1895:                        break;  /* failure */
1.1       root     1896: 
1.1.1.2 ! root     1897:                if(type==ZRPOS) {
        !          1898:                        if(!zmodem_handle_zrpos(zm, &pos))
        !          1899:                                break;
1.1       root     1900:                }
1.1.1.2 ! root     1901:        } while(TRUE);
1.1       root     1902: 
1.1.1.2 ! root     1903:        lprintf(zm,LOG_WARNING,"Transfer failed on receipt of: %s", chr(type));
1.1       root     1904: 
1.1.1.2 ! root     1905:        return(FALSE);
1.1       root     1906: }
                   1907: 
1.1.1.2 ! root     1908: int zmodem_recv_files(zmodem_t* zm, const char* download_dir, int64_t* bytes_received)
1.1       root     1909: {
                   1910:        char            fpath[MAX_PATH+1];
                   1911:        FILE*           fp;
1.1.1.2 ! root     1912:        int64_t         l;
1.1       root     1913:        BOOL            skip;
1.1.1.2 ! root     1914:        BOOL            loop;
        !          1915:        uint64_t        b;
        !          1916:        uint32_t        crc;
        !          1917:        uint32_t        rcrc;
        !          1918:        int64_t         bytes;
        !          1919:        int64_t         kbytes;
        !          1920:        int64_t         start_bytes;
1.1       root     1921:        unsigned        files_received=0;
                   1922:        time_t          t;
                   1923:        unsigned        cps;
                   1924:        unsigned        timeout;
                   1925:        unsigned        errors;
                   1926: 
                   1927:        if(bytes_received!=NULL)
                   1928:                *bytes_received=0;
                   1929:        zm->current_file_num=1;
                   1930:        while(zmodem_recv_init(zm)==ZFILE) {
                   1931:                bytes=zm->current_file_size;
                   1932:                kbytes=bytes/1024;
                   1933:                if(kbytes<1) kbytes=0;
1.1.1.2 ! root     1934:                lprintf(zm,LOG_INFO,"Downloading %s (%"PRId64" KBytes) via Zmodem", zm->current_file_name, kbytes);
1.1       root     1935: 
                   1936:                do {    /* try */
                   1937:                        skip=TRUE;
1.1.1.2 ! root     1938:                        loop=FALSE;
1.1       root     1939: 
                   1940:                        sprintf(fpath,"%s/%s",download_dir,zm->current_file_name);
                   1941:                        lprintf(zm,LOG_DEBUG,"fpath=%s",fpath);
                   1942:                        if(fexist(fpath)) {
                   1943:                                l=flength(fpath);
1.1.1.2 ! root     1944:                                lprintf(zm,LOG_WARNING,"%s already exists (%"PRId64" bytes)",fpath,l);
        !          1945:                                if(l>=(int32_t)bytes) {
        !          1946:                                        lprintf(zm,LOG_WARNING,"Local file size >= remote file size (%"PRId64")"
1.1       root     1947:                                                ,bytes);
1.1.1.2 ! root     1948:                                        if(zm->duplicate_filename==NULL)
        !          1949:                                                break;
        !          1950:                                        else {
        !          1951:                                                if(l > (int32_t)bytes) {
        !          1952:                                                        if(zm->duplicate_filename(zm->cbdata, zm)) {
        !          1953:                                                                loop=TRUE;
        !          1954:                                                                continue;
        !          1955:                                                        }
        !          1956:                                                        break;
        !          1957:                                                }
        !          1958:                                        }
1.1       root     1959:                                }
                   1960:                                if((fp=fopen(fpath,"rb"))==NULL) {
                   1961:                                        lprintf(zm,LOG_ERR,"Error %d opening %s", errno, fpath);
                   1962:                                        break;
                   1963:                                }
                   1964:                                setvbuf(fp,NULL,_IOFBF,0x10000);
                   1965: 
1.1.1.2 ! root     1966:                                lprintf(zm,LOG_NOTICE,"Requesting CRC of remote file: %s", zm->current_file_name);
        !          1967:                                if(!zmodem_request_crc(zm, (uint32_t)l)) {
        !          1968:                                        fclose(fp);
        !          1969:                                        lprintf(zm,LOG_ERR,"Failed to request CRC of remote file");
        !          1970:                                        break;
        !          1971:                                }
        !          1972:                                lprintf(zm,LOG_NOTICE,"Calculating CRC of: %s", fpath);
        !          1973:                                crc=fcrc32(fp,(uint32_t)l);     /* Warning: 4GB limit! */
1.1       root     1974:                                fclose(fp);
                   1975:                                lprintf(zm,LOG_INFO,"CRC of %s (%lu bytes): %08lX"
1.1.1.2 ! root     1976:                                        ,getfname(fpath), (ulong)l, crc);
        !          1977:                                lprintf(zm,LOG_NOTICE,"Waiting for CRC of remote file: %s", zm->current_file_name);
        !          1978:                                if(!zmodem_recv_crc(zm,&rcrc)) {
1.1       root     1979:                                        lprintf(zm,LOG_ERR,"Failed to get CRC of remote file");
                   1980:                                        break;
                   1981:                                }
                   1982:                                if(crc!=rcrc) {
                   1983:                                        lprintf(zm,LOG_WARNING,"Remote file has different CRC value: %08lX", rcrc);
1.1.1.2 ! root     1984:                                        if(zm->duplicate_filename) {
        !          1985:                                                if(zm->duplicate_filename(zm->cbdata, zm)) {
        !          1986:                                                        loop=TRUE;
        !          1987:                                                        continue;
        !          1988:                                                }
        !          1989:                                        }
        !          1990:                                        break;
        !          1991:                                }
        !          1992:                                if(l == (int32_t)bytes) {
        !          1993:                                        lprintf(zm,LOG_INFO,"CRC, length, and filename match.");
1.1       root     1994:                                        break;
                   1995:                                }
                   1996:                                lprintf(zm,LOG_INFO,"Resuming download of %s",fpath);
                   1997:                        }
                   1998: 
                   1999:                        if((fp=fopen(fpath,"ab"))==NULL) {
                   2000:                                lprintf(zm,LOG_ERR,"Error %d opening/creating/appending %s",errno,fpath);
                   2001:                                break;
                   2002:                        }
                   2003:                        start_bytes=filelength(fileno(fp));
                   2004: 
                   2005:                        skip=FALSE;
1.1.1.2 ! root     2006:                        errors=zmodem_recv_file_data(zm,fp,start_bytes);
1.1       root     2007: 
                   2008:                        fclose(fp);
                   2009:                        l=flength(fpath);
                   2010:                        if(errors && l==0)      {       /* aborted/failed download */
                   2011:                                if(remove(fpath))       /* don't save 0-byte file */
                   2012:                                        lprintf(zm,LOG_ERR,"Error %d removing %s",errno,fpath);
                   2013:                                else
                   2014:                                        lprintf(zm,LOG_INFO,"Deleted 0-byte file %s",fpath);
                   2015:                        }
                   2016:                        else {
1.1.1.2 ! root     2017:                                if(l!=bytes) {
        !          2018:                                        lprintf(zm,LOG_WARNING,"Incomplete download (%"PRId64" bytes received, expected %"PRId64")"
1.1       root     2019:                                                ,l,bytes);
                   2020:                                } else {
                   2021:                                        if((t=time(NULL)-zm->transfer_start_time)<=0)
                   2022:                                                t=1;
                   2023:                                        b=l-start_bytes;
1.1.1.2 ! root     2024:                                        if((cps=(unsigned)(b/t))==0)
1.1       root     2025:                                                cps=1;
1.1.1.2 ! root     2026:                                        lprintf(zm,LOG_INFO,"Received %"PRIu64" bytes successfully (%u CPS)",b,cps);
1.1       root     2027:                                        files_received++;
                   2028:                                        if(bytes_received!=NULL)
                   2029:                                                *bytes_received+=b;
                   2030:                                }
                   2031:                                if(zm->current_file_time)
                   2032:                                        setfdate(fpath,zm->current_file_time);
                   2033:                        }
                   2034: 
1.1.1.2 ! root     2035:                } while(loop);
1.1       root     2036:                /* finally */
                   2037: 
                   2038:                if(skip) {
                   2039:                        lprintf(zm,LOG_WARNING,"Skipping file");
                   2040:                        zmodem_send_zskip(zm);
                   2041:                }
                   2042:                zm->current_file_num++;
                   2043:        }
                   2044:        if(zm->local_abort)
1.1.1.2 ! root     2045:                zmodem_send_zabort(zm);
1.1       root     2046: 
                   2047:        /* wait for "over-and-out" */
                   2048:        timeout=zm->recv_timeout;
                   2049:        zm->recv_timeout=2;
                   2050:        if(zmodem_rx(zm)=='O')
                   2051:                zmodem_rx(zm);
                   2052:        zm->recv_timeout=timeout;
                   2053: 
                   2054:        return(files_received);
                   2055: }
                   2056: 
                   2057: int zmodem_recv_init(zmodem_t* zm)
                   2058: {
                   2059:        int                     type=CAN;
                   2060:        unsigned        errors;
                   2061: 
                   2062:        lprintf(zm,LOG_DEBUG,"recv_init");
                   2063: 
                   2064: #if 0
                   2065:        while(is_connected(zm) && !is_cancelled(zm) && (ch=zm->recv_byte(zm,0))!=NOINP)
                   2066:                lprintf(zm,LOG_DEBUG,"Throwing out received: %s",chr((uchar)ch));
                   2067: #endif
                   2068: 
                   2069:        for(errors=0; errors<=zm->max_errors && !is_cancelled(zm) && is_connected(zm); errors++) {
1.1.1.2 ! root     2070:                if(errors)
        !          2071:                        lprintf(zm,LOG_NOTICE,"Sending ZRINIT (%u of %u)"
        !          2072:                                ,errors+1, zm->max_errors+1);
        !          2073:                else
        !          2074:                        lprintf(zm,LOG_INFO,"Sending ZRINIT");
1.1       root     2075:                zmodem_send_zrinit(zm);
                   2076: 
                   2077:                type = zmodem_recv_header(zm);
                   2078: 
1.1.1.2 ! root     2079:                if(zm->local_abort)
        !          2080:                        break;
        !          2081: 
1.1       root     2082:                if(type==TIMEOUT)
                   2083:                        continue;
                   2084: 
1.1.1.2 ! root     2085:                lprintf(zm,LOG_DEBUG,"recv_init: Received %s",chr(type));
1.1       root     2086: 
                   2087:                if(type==ZFILE) {
                   2088:                        zmodem_parse_zfile_subpacket(zm);
                   2089:                        return(type);
                   2090:                }
                   2091: 
                   2092:                if(type==ZFIN) {
                   2093:                        zmodem_send_zfin(zm);   /* ACK */
                   2094:                        return(type);
                   2095:                }
                   2096: 
1.1.1.2 ! root     2097:                lprintf(zm,LOG_WARNING,"recv_init: Received %s instead of ZFILE or ZFIN"
1.1       root     2098:                        ,frame_desc(type));
                   2099:                lprintf(zm,LOG_DEBUG,"ZF0=%02X ZF1=%02X ZF2=%02X ZF3=%02X"
                   2100:                        ,zm->rxd_header[ZF0],zm->rxd_header[ZF1],zm->rxd_header[ZF2],zm->rxd_header[ZF3]);
                   2101:        }
                   2102: 
                   2103:        return(type);
                   2104: }
                   2105: 
                   2106: void zmodem_parse_zfile_subpacket(zmodem_t* zm)
                   2107: {
                   2108:        int                     i;
1.1.1.2 ! root     2109:        int                     mode=0;
        !          2110:        long            serial=-1L;
        !          2111:        ulong           tmptime;
1.1       root     2112: 
                   2113:        SAFECOPY(zm->current_file_name,getfname(zm->rx_data_subpacket));
                   2114: 
                   2115:        zm->current_file_size = 0;
                   2116:        zm->current_file_time = 0;
                   2117:        zm->files_remaining = 0;
                   2118:        zm->bytes_remaining = 0;
                   2119: 
1.1.1.2 ! root     2120:        i=sscanf(zm->rx_data_subpacket+strlen(zm->rx_data_subpacket)+1,"%"PRId64" %lo %o %lo %u %"PRId64
1.1       root     2121:                ,&zm->current_file_size /* file size (decimal) */
1.1.1.2 ! root     2122:                ,&tmptime                               /* file time (octal unix format) */
1.1       root     2123:                ,&mode                                  /* file mode */
                   2124:                ,&serial                                /* program serial number */
                   2125:                ,&zm->files_remaining   /* remaining files to be sent */
                   2126:                ,&zm->bytes_remaining   /* remaining bytes to be sent */
                   2127:                );
1.1.1.2 ! root     2128:        zm->current_file_time=tmptime;
1.1       root     2129: 
1.1.1.2 ! root     2130:        lprintf(zm,LOG_DEBUG,"Zmodem file (ZFILE) data (%u fields): %s"
1.1       root     2131:                ,i, zm->rx_data_subpacket+strlen(zm->rx_data_subpacket)+1);
                   2132: 
                   2133:        if(!zm->files_remaining)
                   2134:                zm->files_remaining = 1;
                   2135:        if(!zm->bytes_remaining)
                   2136:                zm->bytes_remaining = zm->current_file_size;
                   2137: 
                   2138:        if(!zm->total_files)
                   2139:                zm->total_files = zm->files_remaining;
                   2140:        if(!zm->total_bytes)
                   2141:                zm->total_bytes = zm->bytes_remaining;
                   2142: }
                   2143: 
                   2144: /*
                   2145:  * receive file data until the end of the file or until something goes wrong.
                   2146:  * the name is only used to show progress
                   2147:  */
                   2148: 
1.1.1.2 ! root     2149: unsigned zmodem_recv_file_data(zmodem_t* zm, FILE* fp, int64_t offset)
1.1       root     2150: {
1.1.1.2 ! root     2151:        int                     type=0;
1.1       root     2152:        unsigned        errors=0;
1.1.1.2 ! root     2153:        off_t           pos;
1.1       root     2154: 
                   2155:        zm->transfer_start_pos=offset;
                   2156:        zm->transfer_start_time=time(NULL);
                   2157: 
1.1.1.2 ! root     2158:        if(fseeko(fp,(off_t)offset,SEEK_SET)!=0) {
        !          2159:                lprintf(zm,LOG_ERR,"ERROR %d seeking to file offset %"PRId64
        !          2160:                        ,errno, offset);
        !          2161:                zmodem_send_pos_header(zm, ZFERR, (uint32_t)offset, /* Hex? */ TRUE);
        !          2162:                return 1; /* errors */
        !          2163:        }
        !          2164: 
        !          2165:        /*  zmodem.doc:
        !          2166: 
        !          2167:                The zmodem receiver uses the file length [from ZFILE data] as an estimate only.
        !          2168:                It may be used to display an estimate of the transmission time,
        !          2169:                and may be compared with the amount of free disk space.  The
        !          2170:                actual length of the received file is determined by the data
        !          2171:                transfer. A file may grow after transmission commences, and
        !          2172:                all the data will be sent.
        !          2173:        */
        !          2174:        while(errors<=zm->max_errors && is_connected(zm) && !is_cancelled(zm)) {
        !          2175: 
        !          2176:                if((pos=ftello(fp)) > zm->current_file_size)
        !          2177:                        zm->current_file_size = pos;
        !          2178: 
        !          2179:                if(zm->max_file_size!=0 && pos >= zm->max_file_size) {
        !          2180:                        lprintf(zm,LOG_WARNING,"Specified maximum file size (%"PRId64" bytes) reached at offset %"PRId64
        !          2181:                                ,zm->max_file_size, pos);
        !          2182:                        zmodem_send_pos_header(zm, ZFERR, (uint32_t)pos, /* Hex? */ TRUE);
        !          2183:                        break;
        !          2184:                }
1.1       root     2185: 
1.1.1.2 ! root     2186:                if(type!=ENDOFFRAME)
        !          2187:                        zmodem_send_pos_header(zm, ZRPOS, (uint32_t)pos, /* Hex? */ TRUE);
1.1       root     2188: 
1.1.1.2 ! root     2189:                type = zmodem_recv_file_frame(zm,fp);
        !          2190:                if(type == ZEOF || type == ZFIN)
1.1       root     2191:                        break;
1.1.1.2 ! root     2192:                if(type==ENDOFFRAME)
        !          2193:                        lprintf(zm,LOG_DEBUG,"Received complete frame at offset: %lu", (ulong)ftello(fp));
        !          2194:                else {
        !          2195:                        if(type>0 && !zm->local_abort)
        !          2196:                                lprintf(zm,LOG_ERR,"Received %s at offset: %lu", chr(type), (ulong)ftello(fp));
1.1       root     2197:                        errors++;
                   2198:                }
                   2199:        }
1.1.1.2 ! root     2200: 
        !          2201:        /*
        !          2202:         * wait for the eof header
        !          2203:         */
        !          2204:        for(;errors<=zm->max_errors && !is_cancelled(zm) && type!=ZEOF && type!=ZFIN; errors++)
        !          2205:                type = zmodem_recv_header_and_check(zm);
        !          2206: 
1.1       root     2207:        return(errors);
                   2208: }
                   2209: 
                   2210: 
                   2211: int zmodem_recv_file_frame(zmodem_t* zm, FILE* fp)
                   2212: {
1.1.1.2 ! root     2213:        unsigned        n;
        !          2214:        int                     type;
        !          2215:        unsigned        attempt;
1.1       root     2216: 
                   2217:        /*
                   2218:         * wait for a ZDATA header with the right file offset
                   2219:         * or a timeout or a ZFIN
                   2220:         */
                   2221: 
1.1.1.2 ! root     2222:        for(attempt=0;;attempt++) {
        !          2223:                if(attempt>=zm->max_errors)
        !          2224:                        return TIMEOUT;
        !          2225:                type = zmodem_recv_header(zm);
        !          2226:                switch(type) {
        !          2227:                        case ZEOF:
        !          2228:                                /* ZMODEM.DOC:
        !          2229:                                   If the receiver has not received all the bytes of the file, 
        !          2230:                                   the receiver ignores the ZEOF because a new ZDATA is coming.
        !          2231:                                */
        !          2232:                                if(zm->rxd_header_pos==(uint32_t)ftello(fp))    
        !          2233:                                        return type;
        !          2234:                                lprintf(zm,LOG_WARNING,"Ignoring ZEOF as all bytes (%lu) have not been received"
        !          2235:                                        ,zm->rxd_header_pos);
        !          2236:                                continue;
        !          2237:                        case ZFIN:
        !          2238:                        case TIMEOUT:
        !          2239:                                return type;
        !          2240:                }
        !          2241:                if(is_cancelled(zm) || !is_connected(zm))
        !          2242:                        return ZCAN;
1.1       root     2243: 
1.1.1.2 ! root     2244:                if(type==ZDATA)
1.1       root     2245:                        break;
                   2246: 
1.1.1.2 ! root     2247:                lprintf(zm,LOG_WARNING,"Received %s instead of ZDATA frame", frame_desc(type));
        !          2248:        }
        !          2249: 
        !          2250:        if(zm->rxd_header_pos!=(uint32_t)ftello(fp)) {
        !          2251:                lprintf(zm,LOG_WARNING,"Received wrong ZDATA frame (%lu vs %lu)"
        !          2252:                        ,zm->rxd_header_pos, (ulong)ftello(fp));
        !          2253:                return FALSE;
        !          2254:        }
        !          2255:        
1.1       root     2256:        do {
                   2257:                type = zmodem_recv_data(zm,zm->rx_data_subpacket,sizeof(zm->rx_data_subpacket),&n,TRUE);
                   2258: 
                   2259: /*             fprintf(stderr,"packet len %d type %d\n",n,type);
                   2260: */
                   2261:                if (type == ENDOFFRAME || type == FRAMEOK) {
1.1.1.2 ! root     2262:                        if(fwrite(zm->rx_data_subpacket,1,n,fp)!=n) {
        !          2263:                                lprintf(zm,LOG_ERR,"ERROR %d writing %u bytes at file offset %"PRIu64
        !          2264:                                                ,errno, n,(uint64_t)ftello(fp));
        !          2265:                                zmodem_send_pos_header(zm, ZFERR, (uint32_t)ftello(fp), /* Hex? */ TRUE);
        !          2266:                                return FALSE;
        !          2267:                        }
1.1       root     2268:                }
                   2269: 
                   2270:                if(type==FRAMEOK)
                   2271:                        zm->block_size = n;
                   2272: 
                   2273:                if(zm->progress!=NULL)
1.1.1.2 ! root     2274:                        zm->progress(zm->cbdata, ftello(fp));
1.1       root     2275: 
                   2276:                if(is_cancelled(zm))
                   2277:                        return(ZCAN);
                   2278: 
                   2279:        } while(type == FRAMEOK);
                   2280: 
                   2281:        return type;
                   2282: }
                   2283: 
                   2284: const char* zmodem_source(void)
                   2285: {
                   2286:        return(__FILE__);
                   2287: }
                   2288: 
                   2289: char* zmodem_ver(char *buf)
                   2290: {
1.1.1.2 ! root     2291:        sscanf("$Revision: 1.113 $", "%*s %s", buf);
1.1       root     2292: 
                   2293:        return(buf);
                   2294: }
                   2295: 
                   2296: void zmodem_init(zmodem_t* zm, void* cbdata
                   2297:                                ,int    (*lputs)(void*, int level, const char* str)
1.1.1.2 ! root     2298:                                ,void   (*progress)(void* unused, int64_t)
        !          2299:                                ,int    (*send_byte)(void*, uchar ch, unsigned timeout /* seconds */)
        !          2300:                                ,int    (*recv_byte)(void*, unsigned timeout /* seconds */)
1.1       root     2301:                                ,BOOL   (*is_connected)(void*)
                   2302:                                ,BOOL   (*is_cancelled)(void*)
1.1.1.2 ! root     2303:                                ,BOOL   (*data_waiting)(void*, unsigned timeout /* seconds */)
        !          2304:                                ,void   (*flush)(void*))
1.1       root     2305: {
                   2306:        memset(zm,0,sizeof(zmodem_t));
                   2307: 
                   2308:        /* Use sane default values */
                   2309:        zm->init_timeout=10;            /* seconds */
1.1.1.2 ! root     2310:        zm->send_timeout=10;            /* seconds (reduced from 15) */
        !          2311:        zm->recv_timeout=10;            /* seconds (reduced from 20) */
        !          2312:        zm->crc_timeout=120;            /* seconds */
1.1       root     2313:        zm->block_size=ZBLOCKLEN;
                   2314:        zm->max_block_size=ZBLOCKLEN;
                   2315:        zm->max_errors=9;
                   2316: 
                   2317:        zm->cbdata=cbdata;
                   2318:        zm->lputs=lputs;
                   2319:        zm->progress=progress;
                   2320:        zm->send_byte=send_byte;
                   2321:        zm->recv_byte=recv_byte;
                   2322:        zm->is_connected=is_connected;
                   2323:        zm->is_cancelled=is_cancelled;
                   2324:        zm->data_waiting=data_waiting;
1.1.1.2 ! root     2325:        zm->flush=flush;
1.1       root     2326: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.