Annotation of sbbs/sbbs3/xmodem.c, revision 1.1.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.