📄 xmodem.c
字号:
{ 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 + -