Annotation of sbbs/sbbs3/xmodem.c, revision 1.1

1.1     ! root        1: /* xmodem.c */
        !             2: 
        !             3: /* Synchronet X/YMODEM Functions */
        !             4: 
        !             5: /* $Id: xmodem.c,v 1.3 2003/09/17 03:51:58 rswindell Exp $ */
        !             6: 
        !             7: /****************************************************************************
        !             8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
        !             9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
        !            10:  *                                                                                                                                                     *
        !            11:  * Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html         *
        !            12:  *                                                                                                                                                     *
        !            13:  * This program is free software; you can redistribute it and/or                       *
        !            14:  * modify it under the terms of the GNU General Public License                         *
        !            15:  * as published by the Free Software Foundation; either version 2                      *
        !            16:  * of the License, or (at your option) any later version.                                      *
        !            17:  * See the GNU General Public License for more details: gpl.txt or                     *
        !            18:  * http://www.fsf.org/copyleft/gpl.html                                                                                *
        !            19:  *                                                                                                                                                     *
        !            20:  * Anonymous FTP access to the most recent released source is available at     *
        !            21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
        !            22:  *                                                                                                                                                     *
        !            23:  * Anonymous CVS access to the development source and modification history     *
        !            24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
        !            25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
        !            26:  *     (just hit return, no password is necessary)                                                     *
        !            27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
        !            28:  *                                                                                                                                                     *
        !            29:  * For Synchronet coding style and modification guidelines, see                                *
        !            30:  * http://www.synchro.net/source.html                                                                          *
        !            31:  *                                                                                                                                                     *
        !            32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
        !            33:  * format) via e-mail to [email protected]                                                                      *
        !            34:  *                                                                                                                                                     *
        !            35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
        !            36:  ****************************************************************************/
        !            37: 
        !            38: #include "sexyz.h"
        !            39: #include "genwrap.h"   /* YIELD */
        !            40: #include "conwrap.h"   /* kbhit */
        !            41: 
        !            42: #define getcom(t)      recv_byte(xm->sock,t,xm->mode)
        !            43: #define putcom(ch)     send_byte(xm->sock,ch,10,xm->mode)
        !            44: #define newline()      fprintf(xm->statfp,"\n");
        !            45: 
        !            46: void xmodem_put_nak(xmodem_t* xm)
        !            47: {
        !            48:        while(getcom(1)!=NOINP)
        !            49:                ;                               /* wait for any trailing data */
        !            50:        putcom(NAK);
        !            51: }
        !            52: 
        !            53: void xmodem_cancel(xmodem_t* xm)
        !            54: {
        !            55:        int i;
        !            56: 
        !            57:        for(i=0;i<8;i++)
        !            58:                putcom(CAN);
        !            59:        for(i=0;i<10;i++)
        !            60:                putcom('\b');
        !            61: }
        !            62: 
        !            63: /****************************************************************************/
        !            64: /* Receive a X/Ymodem block (sector) from COM port                                                     */
        !            65: /* hdrblock is 1 if attempting to get Ymodem header block, 0 if data block     */
        !            66: /* Returns blocknum if all went well, -1 on error or CAN, and -EOT if EOT      */
        !            67: /****************************************************************************/
        !            68: int xmodem_get_block(xmodem_t* xm, uchar* block, uint block_size, BOOL hdrblock)
        !            69: {
        !            70:        uchar   block_num;                                      /* Block number received in header      */
        !            71:        uchar   chksum,calc_chksum;
        !            72:        int             i,errors,eot=0,can=0;
        !            73:        uint    b;
        !            74:        ushort  crc,calc_crc;
        !            75: 
        !            76:        for(errors=0;errors<MAXERRORS;errors++) {
        !            77:                i=getcom(10);
        !            78:                if(eot && i!=EOT)
        !            79:                        eot=0;
        !            80:                if(can && i!=CAN)
        !            81:                        can=0;
        !            82:                switch(i) {
        !            83:                        case SOH: /* 128 byte blocks */
        !            84:                                block_size=128;
        !            85:                                break;
        !            86:                        case STX: /* 1024 byte blocks */
        !            87:                                block_size=1024;
        !            88:                                break;
        !            89:                        case EOT:
        !            90:                                if((xm->mode&(YMODEM|GMODE))==YMODEM && !eot) {
        !            91:                                        eot=1;
        !            92:                                        xmodem_put_nak(xm);             /* chuck's double EOT trick */
        !            93:                                        continue; 
        !            94:                                }
        !            95:                                return(-EOT);
        !            96:                        case CAN:
        !            97:                                newline();
        !            98:                                if(!can) {                      /* must get two CANs in a row */
        !            99:                                        can=1;
        !           100:                                        fprintf(xm->statfp,"Received CAN  Expected SOH, STX, or EOT\n");
        !           101:                                        continue; 
        !           102:                                }
        !           103:                                fprintf(xm->statfp,"Cancelled remotely\n");
        !           104:                                bail(-1);
        !           105:                                break;
        !           106:                        case NOINP:     /* Nothing came in */
        !           107:                                continue;
        !           108:                        default:
        !           109:                                newline();
        !           110:                                fprintf(xm->statfp,"Received %s  Expected SOH, STX, or EOT\n",chr((uchar)i));
        !           111:                                if(hdrblock)  /* Trying to get Ymodem header block */
        !           112:                                        return(-1);
        !           113:                                xmodem_put_nak(xm);
        !           114:                                continue; 
        !           115:                }
        !           116:                i=getcom(1);
        !           117:                if(i==NOINP) {
        !           118:                        xmodem_put_nak(xm);
        !           119:                        continue; 
        !           120:                }
        !           121:                block_num=i;
        !           122:                i=getcom(1);
        !           123:                if(i==NOINP) {
        !           124:                        xmodem_put_nak(xm);
        !           125:                        continue; 
        !           126:                }
        !           127:                if(block_num!=(uchar)~i) {
        !           128:                        newline();
        !           129:                        fprintf(xm->statfp,"Block number error\n");
        !           130:                        xmodem_put_nak(xm);
        !           131:                        continue; 
        !           132:                }
        !           133:                calc_crc=calc_chksum=0;
        !           134:                for(b=0;b<block_size;b++) {
        !           135:                        i=getcom(1);
        !           136:                        if(i==NOINP)
        !           137:                                break;
        !           138:                        block[b]=i;
        !           139:                        if(xm->mode&CRC)
        !           140:                                calc_crc=ucrc16(block[b],calc_crc);
        !           141:                        else
        !           142:                                calc_chksum+=block[b]; 
        !           143:                }
        !           144: 
        !           145:                if(b<block_size) {
        !           146:                        xmodem_put_nak(xm);
        !           147:                        continue; 
        !           148:                }
        !           149: 
        !           150:                if(xm->mode&CRC) {
        !           151:                        crc=getcom(1)<<8;
        !           152:                        crc|=getcom(1)        !           153:                }
        !           154:                else
        !           155:                        chksum=getcom(1);
        !           156: 
        !           157:                if(xm->mode&CRC) {
        !           158:                        if(crc==calc_crc)
        !           159:                                break;
        !           160:                        newline();
        !           161:                        fprintf(xm->statfp,"CRC error\n"); 
        !           162:                }
        !           163:                else    /* CHKSUM */
        !           164:                {       
        !           165:                        if(chksum==calc_chksum)
        !           166:                                break;
        !           167:                        newline();
        !           168:                        fprintf(xm->statfp,"Checksum error\n"); 
        !           169:                }
        !           170: 
        !           171:                if(xm->mode&GMODE) {    /* Don't bother sending a NAK. He's not listening */
        !           172:                        xmodem_cancel(xm);
        !           173:                        bail(1)        !           174:                }
        !           175:                xmodem_put_nak(xm); 
        !           176:        }
        !           177: 
        !           178:        if(errors>=MAXERRORS) {
        !           179:                newline();
        !           180:                fprintf(xm->statfp,"Too many errors\n");
        !           181:                return(-1); 
        !           182:        }
        !           183:        return(block_num);
        !           184: }
        !           185: 
        !           186: /*****************/
        !           187: /* Sends a block */
        !           188: /*****************/
        !           189: void xmodem_put_block(xmodem_t* xm, uchar* block, uint block_size, ulong block_num)
        !           190: {
        !           191:        uchar   ch,chksum;
        !           192:     uint       i;
        !           193:        ushort  crc;
        !           194: 
        !           195:        if(block_size==128)
        !           196:                putcom(SOH);
        !           197:        else                    /* 1024 */
        !           198:                putcom(STX);
        !           199:        ch=(uchar)(block_num&0xff);
        !           200:        putcom(ch);
        !           201:        putcom((uchar)~ch);
        !           202:        chksum=0;
        !           203:        crc=0;
        !           204:        for(i=0;i<block_size;i++) {
        !           205:                putcom(block[i]);
        !           206:                if(xm->mode&CRC)
        !           207:                        crc=ucrc16(block[i],crc);
        !           208:                else
        !           209:                        chksum+=block[i]; 
        !           210:        }
        !           211: 
        !           212:        if(xm->mode&CRC) {
        !           213:                putcom((uchar)(crc >> 8));
        !           214:                putcom((uchar)(crc&0xff)); 
        !           215:        }
        !           216:        else
        !           217:                putcom(chksum);
        !           218:        YIELD();
        !           219: }
        !           220: 
        !           221: /************************************************************/
        !           222: /* Gets an acknowledgement - usually after sending a block     */
        !           223: /* Returns 1 if ack received, 0 otherwise.                                     */
        !           224: /************************************************************/
        !           225: int xmodem_get_ack(xmodem_t* xm, int tries)
        !           226: {
        !           227:        int i,errors,can=0;
        !           228: 
        !           229:        for(errors=0;errors<tries;errors++) {
        !           230: 
        !           231:                if(xm->mode&GMODE) {            /* Don't wait for ACK on Ymodem-G */
        !           232:                        if(getcom(0)==CAN) {
        !           233:                                newline();
        !           234:                                fprintf(xm->statfp,"Cancelled remotely\n");
        !           235:                                xmodem_cancel(xm);
        !           236:                                bail(1)        !           237:                        }
        !           238:                        return(1)        !           239:                }
        !           240: 
        !           241:                i=getcom(10);
        !           242:                if(can && i!=CAN)
        !           243:                        can=0;
        !           244:                if(i==ACK)
        !           245:                        return(1);
        !           246:                if(i==CAN) {
        !           247:                        if(can) {
        !           248:                                newline();
        !           249:                                fprintf(xm->statfp,"Cancelled remotely\n");
        !           250:                                xmodem_cancel(xm);
        !           251:                                bail(1)        !           252:                        }
        !           253:                        can=1; 
        !           254:                }
        !           255:                if(i!=NOINP) {
        !           256:                        newline();
        !           257:                        fprintf(xm->statfp,"Received %s  Expected ACK\n",chr((uchar)i));
        !           258:                        if(i!=CAN)
        !           259:                                return(0)        !           260:                } 
        !           261:        }
        !           262: 
        !           263:        return(0);
        !           264: }
        !           265: 
        !           266: const char* xmodem_source(void)
        !           267: {
        !           268:        return(__FILE__);
        !           269: }
        !           270: 
        !           271: char* xmodem_ver(char *buf)
        !           272: {
        !           273:        sscanf("$Revision: 1.3 $", "%*s %s", buf);
        !           274: 
        !           275:        return(buf);
        !           276: }
        !           277: 

unix.superglobalmegacorp.com

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