/* * UCBOOT -- UC Boot for Receive-Only * UCBOOT is a minimum program which receives a file via FTP 3, * converts it into UNIX text file format from CP/M text file * format, and stores it under the name ucboot.txt * Version 1.0 * by Richard Conn */ #define FALSE 0 #define TRUE ~FALSE /* ASCII Characters */ #define SOH 001 #define EOT 004 #define ACK 006 #define CR 015 #define NAK 025 #define CAN 030 #define CTRLZ 032 /* UC Constants */ #define TO -1 /* Timeout Flag */ #define ERRMAX 10 /* Max errors tolerated */ #define BLOCKSZ 128 /* Size of transmission block */ #define CREATE 0644 /* Mode for New Files */ #define DEST "ucboot.txt" /* Log File */ /* Library Utilities */ #include #include #include #include #include #include main () { int fd; /* file descriptor */ int blocknum; /* next block to receive */ int rbcnt; /* total number of received blocks */ int errorcnt; /* number of errors on current block */ int receiving; /* continuation flag */ int char1; /* first char received in block */ int rcode; /* received block code */ if (!access(DEST,2)) printf("File %s Exists -- Deleting", DEST); unlink(DEST); if ((fd = creat(DEST, CREATE)) == -1) { printf("Can't Create %s\n", DEST); return; } printf("UCBOOT Receiving File %s via FTP 3\n", DEST); printf("Ready to Receive\n"); blocknum = 1; rbcnt = 0; errorcnt = 0; receiving = TRUE; binary(TRUE); sendbyte(NAK); while (receiving) { do { char1 = recvbyte(6); } while ((char1 != SOH) && (char1 != EOT) && (char1 != TO)); switch (char1) { case TO : if (++errorcnt == ERRMAX) { close(fd); sleep(3); binary(FALSE); receiving = FALSE; } sendbyte(NAK); break; case EOT : sendbyte(ACK); while (recvbyte(3) != TO); close(fd); sleep(3); binary(FALSE); receiving = FALSE; break; case SOH : rcode = getblock(fd,blocknum); switch (rcode) { case 0 : errorcnt = 0; blocknum = ++blocknum & 0xff; rbcnt++; sendbyte(ACK); break; case 1 : if (++errorcnt < ERRMAX) { sendbyte(NAK); break; } default : close(fd); sendbyte(CAN); binary(FALSE); while (recvbyte(3) != TO); receiving = FALSE; break; } break; } } } getblock(fd,blocknum) int fd, blocknum; { int curblock, cmpblock, delay; int recdone, checksum, inchecksum, byte, bufcnt, c; int errflg, errchr; char buff[BLOCKSZ]; curblock = recvbyte(3); if (curblock == TO) return(1); cmpblock = recvbyte(3); if (curblock == TO) return(1); if ((curblock + cmpblock) != 0xff) { while (recvbyte(3) != TO); return(1); } checksum = 0; byte = 0; recdone = FALSE; for (bufcnt=0; bufcnt