/* xdown.c Xmodem download program */ #include #include #include #define Auxis() Bconstat(BC_AUX) #define Auxos() Bcostat(BC_AUX) #define Auxin() ((unsigned char) Bconin(BC_AUX)) #define Auxout(c) Bconout(BC_AUX,c) #define SOH 0x01 #define EOT 0x04 #define ACK 0x06 #define NAK 0x15 #define CAN 0x18 #define NULL (char *)0 #define SIZE 128 #define FALSE 0 #define TRUE 1 extern char *itoa(); unsigned char get_char(); char packet[SIZE+1]; main(argc,argv) int argc; char *argv[]; { char *name; int fp,bw,ec,n; unsigned int packets,xpackets,oldxpackets; unsigned char chr,packet_num,packet_xnum,checksum; if (argc<2 || argc>3) fatal("Usage: xdown file [errors]"); name=argv[1]; ec=10; if (argc==3) if ((ec=atoi(argv[2]))<1) fatal("Illegal error count value"); Cconws("\r\nxdown v1.0 by Jason Blochowiak\r\n"); if ((fp=creat(name,1))==-1) fatal("Unable to create target file."); send_char(NAK); oldxpackets=0xFFFF; for (packets=1;;) { Cconws("\rR#"); Cconws(itoa(packets)); Cconws(" ("); Cconws(itoa(ec)); Cconws(" errs left)"); xpackets=packets & 0xFF; if ((chr=get_char(10))==EOT) { send_char(ACK); break; }; if (chr==CAN) fatal("Transmission aborted remotely"); if ( chr!=SOH || ((packet_num=get_char(1))==-1) || ((packet_num!=xpackets)&&(packet_num!=oldxpackets)) || ((packet_xnum=get_char(1))==-1) || ((packet_xnum ^ 0xFF)!=packet_num) || ((n=read_packet(SIZE,&checksum))!=SIZE) || (checksum!=0) ) { if (chr!=SOH) prerror("Not SOH"); else if ((packet_xnum ^ 0xFF)!=packet_num) prerror("Unmatching packet #s"); else if (checksum!=0) prerror("Non-zero checksum value."); else if (n!=SIZE) prerror("Incomplete packet."); send_char(NAK); if (ec--==0) fatal("Too many errors"); } else { send_char(ACK); if (xpackets==packet_num) { oldxpackets=xpackets; packets++; } else if (oldxpackets==packet_num) lseek(fp,(long) (packets-1)*128,0); if ((bw=write(fp,packet,SIZE))