⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmodem.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 2 页
字号:
{    int     i;    char    *pkt;    uchar   seq[2];    getbytes(seq,2,1);    Mtrace("*");    if (xip->flags & VERIFY) {        getbytes(tmppkt,xip->pktlen,1);        for(i=0;i<xip->pktlen;i++) {            if (tmppkt[i] != ((char *)xip->dataddr)[i]) {                if (xip->errcnt++ == 0)                    xip->firsterrat = (char *)(xip->dataddr+i);            }        }        pkt = (char *)tmppkt;    }    else {        getbytes((char *)xip->dataddr,xip->pktlen,1);        pkt = (char *)xip->dataddr;    }    Mtrace("*");    if (xip->flags & USECRC) {        ushort  crc, xcrc;                /* An "endian independent way to combine the CRC bytes. */        crc  = (ushort)getchar() << 8;        crc += (ushort)getchar();        xcrc = xcrc16((uchar *)pkt,(ulong)(xip->pktlen));        if (crc != xcrc) {            rputchar(CAN);            Mtrace("1 %04x != %04x",crc,xcrc);            return(-1);        }    }    else {        uchar   csum, xcsum;        xcsum = (uchar)getchar();        Mtrace("*");        csum = 0;        for(i=0;i<xip->pktlen;i++)            csum += *pkt++;        if (csum != xcsum) {            rputchar(CAN);            Mtrace("2");            Mtrace("2 %02x != %02x",csum,xcsum);            return(-1);        }    }    if ((uchar)seq[0] !=  xip->sno) {        if ((xip->sno == 0x02) && (seq[0] == 0x01)) {   /* TeraTerm has a */            xip->sno = 0x01;                            /* "peculiarity". */            Mtrace("--TERABUG--");        }        else {            rputchar(CAN);            Mtrace("3 %02x != %02x",seq[0],xip->sno);            return(-1);        }    }    if ((uchar)seq[1] != (uchar)~(xip->sno)) {        rputchar(CAN);        Mtrace("4 %02x != %02x",seq[1],(uchar)~(xip->sno));        return(-1);    }    /* First packet of YMODEM contains information about the transfer: */    /* FILENAME SP FILESIZE SP MOD_DATE SP FILEMODE SP FILE_SNO */    /* Only the FILENAME is required and if others are present, then none */    /* can be skipped. */    if ((xip->flags & YMODEM) && (xip->pktcnt == 0)) {        char *slash, *space, *fname;        slash = strrchr((char *)(xip->dataddr),'/');        space = strchr((char *)(xip->dataddr),' ');        if (slash)            fname = slash+1;        else            fname = (char *)(xip->dataddr);        Mtrace("<fname=%s>",fname);        if (space) {            *space = 0;            xip->size = atoi(space+1);        }        strcpy(xip->fname,fname);        if (fname[0])            xip->filcnt++;    }    else        xip->dataddr += xip->pktlen;    xip->sno++;    xip->pktcnt++;    xip->xfertot += xip->pktlen;    rputchar(ACK);    if (xip->flags & YMODEM) {        if (xip->fname[0] == 0) {            printf("\nRcvd %d file%c\n",                xip->filcnt,xip->filcnt > 1 ? 's' : ' ');            return(1);        }    }    return(0);}/* Xup(): * Called when a transfer from target to host is being made (considered * an upload). */static intXup(struct xinfo *xip){    uchar   c, buf[PKTLEN_128];    int     done, pktlen;    long    actualsize;    Mtrace("Xup starting");    actualsize = xip->size;    if (xip->size & 0x7f) {        xip->size += 128;        xip->size &= 0xffffff80L;    }    printf("Upload %ld bytes from 0x%lx\n",xip->size,(ulong)xip->base);    /* Startup synchronization... */    /* Wait to receive a NAK or 'C' from receiver. */    done = 0;    while(!done) {        c = (uchar)getchar();        switch(c) {        case NAK:            done = 1;            Mtrace("CSM");            break;        case 'C':            xip->flags |= USECRC;            done = 1;            Mtrace("CRC");            break;        case 'q':   /* ELS addition, not part of XMODEM spec. */            return(0);        default:            break;        }    }    if (xip->flags & YMODEM) {        Mtrace("SNO_0");        xip->sno = 0;        xip->pktcnt = -1;        memset((char *)buf,0,PKTLEN_128);        sprintf(buf,"%s",xip->fname);        pktlen = xip->pktlen;        xip->pktlen = PKTLEN_128;        putPacket(buf,xip);        xip->pktlen = pktlen;    }    done = 0;    xip->sno = 1;    xip->pktcnt = 0;    while(!done) {        c = (uchar)putPacket((uchar *)(xip->dataddr),xip);        switch(c) {        case ACK:            xip->sno++;            xip->pktcnt++;            xip->size -= xip->pktlen;            xip->dataddr += xip->pktlen;            Mtrace("A");            break;        case NAK:            Mtrace("N");            break;        case CAN:            done = -1;            Mtrace("C");            break;        case EOT:            done = -1;            Mtrace("E");            break;        default:            done = -1;            Mtrace("<%2x>",c);            break;        }        if (xip->size <= 0) {            rputchar(EOT);            getchar();  /* Flush the ACK */            break;        }        Mtrace("!");    }    Mtrace("Xup_almost");    if ((done != -1) && (xip->flags & YMODEM)) {         xip->sno = 0;        memset((char *)buf,0,PKTLEN_128);        pktlen = xip->pktlen;        xip->pktlen = PKTLEN_128;        putPacket(buf,xip);        xip->pktlen = pktlen;    }    Mtrace("Xup_done.");    return(0);}/* Xdown(): * Called when a transfer from host to target is being made (considered * an download). */static intXdown(struct xinfo *xip){    long    timeout;    char    c, *tmppkt;    int     done;    tmppkt = malloc(PKTLEN_1K);    if (!tmppkt) {        Mtrace("malloc failed");        return(-1);    }nextfile:    if (xip->flags & YMODEM)        xip->sno = 0x00;    else        xip->sno = 0x01;    xip->pktcnt = 0;    xip->errcnt = 0;    xip->xfertot = 0;    xip->firsterrat = 0;    /* Startup synchronization... */    /* Continuously send NAK or 'C' until sender responds. */restart:    Mtrace("Xdown");    while(1) {        if (xip->flags & USECRC)            rputchar('C');        else            rputchar(NAK);        timeout = LoopsPerSecond;        while(!gotachar() && timeout)            timeout--;        if (timeout)            break;    }    done = 0;    Mtrace("Got response");    while(done == 0) {        c = (char)getchar();        switch(c) {        case SOH:               /* 128-byte incoming packet */            Mtrace("O");            xip->pktlen = 128;            done = getPacket(tmppkt,xip);            if (!done && (xip->pktcnt == 1) && (xip->flags & YMODEM))                goto restart;            break;        case STX:               /* 1024-byte incoming packet */            Mtrace("T");            xip->pktlen = 1024;            done = getPacket(tmppkt,xip);            if (!done && (xip->pktcnt == 1) && (xip->flags & YMODEM))                goto restart;            break;        case CAN:            Mtrace("C");            done = -1;            break;        case EOT:            Mtrace("E");            rputchar(ACK);            if (xip->flags & YMODEM) {#if INCLUDE_TFS                if (!xip->size)                    xip->size = xip->pktcnt * xip->pktlen;                if (xip->fname[0])                    tfsadd(xip->fname,0,0,(uchar *)xip->base,xip->size);                xip->dataddr = xip->base;#endif                goto nextfile;            }            else {                done = xip->xfertot;                printf("\nRcvd %d pkt%c (%d bytes)\n",xip->pktcnt,                        xip->pktcnt > 1 ? 's' : ' ',xip->xfertot);            }            break;        case ESC:       /* User-invoked abort */            Mtrace("X");            done = -1;            break;        default:            Mtrace("<%02x>",c);            done = -1;            break;        }        Mtrace("!");    }    if (xip->flags & VERIFY) {        if (xip->errcnt)            printf("%d errors, first at 0x%lx\n",                xip->errcnt,(ulong)(xip->firsterrat));        else            printf("verification passed\n");    }    free(tmppkt);    return(done);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -