home *** CD-ROM | disk | FTP | other *** search
- /* Create xrb - xmodem_request_block */
-
- /* Xmodem, and associated routines for z-term */
- /* Nik Conwell 4/20/87 */
-
- #include "term.h" /* Defines */
- #include "term.common"
-
- /* Send a character to the serial port */
-
- void sendchar(ch,zt)
- char ch;
- struct Z_Term *zt;
- {
- zt->rs_out = ch;
- DoIO(zt->write_request);
- }
-
-
-
-
-
- int readchar(ch,zt)
- char *ch;
- struct Z_Term *zt;
-
- {
-
- set_timer(zt->timeout_time,zt); /* set up the timer */
- dowait: zt->wakeupmask = Wait(SERIAL_INPUT |
- W1_INTUITION_MESSAGE |
- TIMER_MESSAGE);
- if (zt->wakeupmask & SERIAL_INPUT)
- {
- WaitIO(zt->read_request);
- *ch = zt->rs_in;
- BeginIO(zt->read_request);
- } /* end if */
- if (zt->wakeupmask & W1_INTUITION_MESSAGE)
- {
- zt->message = (struct IntuiMessage *) GetMsg(zt->w1->UserPort);
- zt->class = zt->message->Class;
- zt->code = zt->message->Code;
- ReplyMsg(zt->message);
- if ((zt->class == MENUPICK) && (zt->code != MENUNULL))
- {
- zt->menunum = MENUNUM(zt->code);
- zt->menuitem = ITEMNUM(zt->code);
- if ((zt->menunum == MENU_FILESTUFF) &&
- (zt->menuitem == MENU_FILESTUFF_ABORT_XMODEM))
- {
- con_put_str("\nUser Cancelled Transfer.\n",zt);
- return(USER_ABORT);
- }
- } /* end if the user is playing with the menu */
- goto dowait;
- } /* end if we woke up because of intuition */
- if (zt->wakeupmask & TIMER_MESSAGE)
- {
- con_put_str("\nTimeout waiting for character.\n",zt);
- return(TIMEOUT);
- }
- return(NULL);
- }
-
-
-
-
-
-
- int xmodem_read_file(zt)
- struct Z_Term *zt;
-
- {
- int sectnum, errors, errorflag;
- unsigned int checksum, i, j, bufptr;
- unsigned char sectcurr, sectcomp, sentchecksum1, sentchecksum2;
- unsigned char ourchecksum1, ourchecksum2, firstchar;
- int xfer_current_blocksize, xfer_current_error_detect_alg;
- int fd;
- char numb[10];
- char bufr[BUFSIZE];
- int temp;
-
- firstchar = NULL;
- sectcurr = NULL;
- sectcomp = NULL;
- sentchecksum1 = NULL;
- sentchecksum2 = NULL;
- xfer_current_blocksize = zt->xfer_blocksize; /* copy blocksize */
- xfer_current_error_detect_alg = zt->xfer_error_detect_alg; /* copy spec alg */
- if ((fd = creat(zt->filename, 0)) < 0)
- {
- con_put_str("\nCannot Open ",zt);
- con_put_str(zt->filename,zt);
- con_put_str(" . File exists.\n",zt);
- goto xmodem_read_file_exit;
- }
- else
- {
- con_put_str("\nReceiving ",zt);
- con_put_str(zt->filename,zt);
- con_put_str(" using ",zt);
- if (zt->xfer_blocksize == XMODEM_128_BLOCK)
- {
- con_put_str("128",zt);
- }
- if (zt->xfer_blocksize == XMODEM_1024_BLOCK)
- {
- con_put_str("1024",zt);
- }
- con_put_str(" byte blocks, with ",zt);
- if (zt->xfer_error_detect_alg == XMODEM_CHECKSUM)
- {
- con_put_str("checksum",zt);
- }
- if (zt->xfer_error_detect_alg == XMODEM_CRC16)
- {
- con_put_str("crc-16",zt);
- }
- con_put_str(" error detection algorithm.\n",zt);
- }
- zt->timeout_time = 3;
- sectnum = errors = bufptr = 0;
- do /* Loop until SOH or STX is received */
- {
- if (xfer_current_error_detect_alg == XMODEM_CHECKSUM)
- {
- sendchar((char) NAK,zt); /* NAK specifies checksum recv */
- }
- if (xfer_current_error_detect_alg == XMODEM_CRC16)
- {
- sendchar((char) CCHAR,zt); /* C specifies crc16 recv */
- }
-
- zt->st = readchar(&firstchar,zt);
-
- if (zt->st == USER_ABORT)
- {
- goto xmodem_read_file_exit;
- }
- if ((zt->st == TIMEOUT) && (xfer_current_error_detect_alg == XMODEM_CHECKSUM))
- {
- con_put_str("\nSender not responding to initial NAK.\n",zt);
- goto xmodem_read_file_exit; /* if checksum, getout */
- }
- if ((zt->st == TIMEOUT) && (xfer_current_error_detect_alg == XMODEM_CRC16))
- {
- xfer_current_error_detect_alg = XMODEM_CHECKSUM;
- con_put_str("\nSender not responding to CRC option.\n",zt);
- con_put_str("\nXferring using checksum algorithm.\n",zt);
- }
- if ((firstchar != SOH) && (firstchar != STX)) /* if !SOH, tell what it is */
- {
- con_put_str("\nSender not sending SOH or STX.\n",zt);
- temp = (int) firstchar;
- stci_d(numb,temp,10);
- con_put_str(numb,zt);
- con_put_str(" ascii received instead.\n",zt);
- }
- }
- while ((firstchar != SOH) && (firstchar != STX));
- zt->timeout_time = 10; /* 10 second timeout period */
- while ((firstchar != EOT) && (errors < ERRORMAX))
- {
- errorflag = FALSE;
- if ((firstchar == SOH) || (firstchar == STX))
- {
- if ((firstchar == SOH) && (xfer_current_blocksize == XMODEM_1024_BLOCK))
- {
- xfer_current_blocksize = XMODEM_128_BLOCK;
- con_put_str("\nSender specified 128 byte block.\n",zt);
- con_put_str("Temporarily switched block size.\n",zt);
- }
- if ((firstchar == STX) && (xfer_current_blocksize == XMODEM_128_BLOCK))
- {
- xfer_current_blocksize = XMODEM_1024_BLOCK;
- con_put_str("\nSender specified 1024 byte block.\n",zt);
- con_put_str("Temporarily switched block size.\n",zt);
- }
- con_put_str("Receiving Block ",zt);
- stci_d(numb,sectnum,10);
- con_put_str(numb,zt);
- con_put_str("...",zt);
-
- zt->st = readchar(§curr,zt);
- if (zt->st == USER_ABORT)
- {
- goto xmodem_read_file_exit;
- }
- if (zt->st == TIMEOUT)
- {
- con_put_str("\nTimeout occured while waiting for sectcurr.\n",zt);
- goto xmodem_read_file_exit;
- }
-
- zt->st = readchar(§comp,zt);
- if (zt->st == USER_ABORT)
- {
- goto xmodem_read_file_exit;
- }
- if (zt->st == TIMEOUT)
- {
- con_put_str("\nTimeout occured while waiting for sector complement.\n",zt);
- goto xmodem_read_file_exit;
- }
- if ((sectcurr + sectcomp) == 255) /* must be compliment */
- {
- if (sectcurr == (sectnum + 1 & 0xff)) /* must be same sector */
- {
- checksum = 0;
- for (j = bufptr; j < (bufptr + xfer_current_blocksize); j++)
- {
- zt->st = readchar((char *) &bufr[j],zt);
- if (zt->st == USER_ABORT)
- {
- goto xmodem_read_file_exit;
- }
- if (zt->st == TIMEOUT)
- {
- con_put_str("\nTimeout occurred waiting for data in block.\n",zt);
- goto xmodem_read_file_exit;
- }
- if (xfer_current_error_detect_alg == XMODEM_CHECKSUM) /* calc checksum */
- {
- checksum = (checksum + bufr[j]) & 0xff;
- }
- if (xfer_current_error_detect_alg == XMODEM_CRC16)
- {
- checksum = checksum ^ (int) bufr[j] << 8; /* calc crc16 */
- for (i = 0;i < 8; ++i)
- {
- if (checksum & 0x8000)
- {
- checksum = checksum << 1 ^ 0x1021;
- }
- else
- {
- checksum = checksum << 1;
- }
- } /* end for */
- checksum = checksum & 0xffff;
- } /* end if error detect alg == XMODEM_CRC16 */
- } /* end for */
- if (zt->xfer_error_detect_alg == XMODEM_CHECKSUM)
- {
- zt->st = readchar(&sentchecksum1,zt);
- if (zt->st == USER_ABORT)
- {
- goto xmodem_read_file_exit;
- }
- ourchecksum1 = checksum;
- }
- if (xfer_current_error_detect_alg == XMODEM_CRC16)
- {
- zt->st = readchar(&sentchecksum1,zt);
- if (zt->st == USER_ABORT)
- {
- goto xmodem_read_file_exit;
- }
-
- zt->st = readchar(&sentchecksum2,zt);
- if (zt->st == USER_ABORT)
- {
- goto xmodem_read_file_exit;
- }
- ourchecksum1 = checksum >> 8;
- ourchecksum2 = checksum;
- }
- if (((xfer_current_error_detect_alg == XMODEM_CHECKSUM) &&
- (ourchecksum1 == sentchecksum1)) ||
- ((xfer_current_error_detect_alg == XMODEM_CRC16) &&
- (ourchecksum1 == sentchecksum1) &&
- (ourchecksum2 == sentchecksum2)))
- {
- errors = 0;
- sectnum++;
- bufptr += xfer_current_blocksize;
- con_put_str("ok\n",zt);
- if (bufptr == BUFSIZE)
- {
- bufptr = 0;
- if (write(fd, bufr, BUFSIZE) == EOF)
- {
- con_put_str("\nError Writing File\n",zt);
- goto xmodem_read_file_exit;
- } /* end if */
- } /* end if */
- sendchar((char) ACK,zt);
- } /* end if */
- else /* checksum not what we computed!!! */
- {
- errorflag = TRUE;
- if (zt->st == TIMEOUT)
- {
- goto xmodem_read_file_exit;
- }
- con_put_str("\nCalculated checksum != received checksum.\n",zt);
- con_put_str("\nCalculated checksum1 = ",zt);
- stci_d(numb,(int) ourchecksum1,10);
- con_put_str(numb,zt);
- con_put_str(". Received checksum1 = ",zt);
- stci_d(numb,(int) sentchecksum1,10);
- con_put_str(numb,zt);
- con_put_str(".\n",zt);
- if (xfer_current_error_detect_alg == XMODEM_CRC16)
- {
- con_put_str("\nCalculated checksum2 = ",zt);
- stci_d(numb,(int) ourchecksum2,10);
- con_put_str(numb,zt);
- con_put_str(". Received checksum2 = ",zt);
- stci_d(numb,(int) sentchecksum2,10);
- con_put_str(numb,zt);
- con_put_str(".\n",zt);
- } /* end if */
- } /* end else */
- } /* end if sectcurr == (sectnum + 1 & 0xff) */
- else
- {
- if (sectcurr == (sectnum & 0xff))
- {
- con_put_str("\nReceived Duplicate Sector\n",zt);
- sendchar((char) ACK,zt);
- } /* end if sectcurr == (sectnum & 0xff) */
- else
- { /* didn't receive expected sector number */
- errorflag = TRUE;
- con_put_str("\nExpecting to receive sector ",zt);
- stci_d(numb,(int) sectcurr,10);
- con_put_str(numb,zt);
- con_put_str(".\nBut received sector ",zt);
- stci_d(numb,(int) sectcurr,10);
- con_put_str(numb,zt);
- con_put_str(" instead.\n",zt);
- }
- } /* end else */
- } /* end if sectcurr + sectcomp == 255 */
- else
- {
- con_put_str("\nSector number, and compliment are not that.\n",zt);
- con_put_str("\nSector number sent = ",zt);
- stci_d(numb,(int) sectcurr,10);
- con_put_str(numb,zt);
- con_put_str(" ascii.\n",zt);
- con_put_str("\nSector complement sent = ",zt);
- stci_d(numb,(int) sectcomp,10);
- con_put_str(numb,zt);
- con_put_str(" ascii.\n",zt);
- errorflag=TRUE;
- } /* end else */
- } /* end if firstchar == SOH || STX */
- else
- {
- con_put_str("\nOOPS!! We didn't receive SOH or STX!!\n",zt);
- }
- if (errorflag == TRUE)
- {
- errors++;
- con_put_str("\nError\n",zt);
- sendchar((char) NAK,zt);
- } /* end if errorflag == true */
- /* Read the SOH ^ STX */
- zt->st = readchar(&firstchar,zt);
- if (zt->st == USER_ABORT)
- {
- goto xmodem_read_file_exit;
- }
-
- } /* end while */
-
- write(fd,bufr,bufptr);
- close(fd);
-
- if ((firstchar == EOT) && (errors < ERRORMAX))
- {
- sendchar((char) ACK,zt);
- return(TRUE);
- }
- goto xmodem_read_file_exit_do;
- xmodem_read_file_exit:
- write(fd,bufr,bufptr);
- close(fd);
- xmodem_read_file_exit_do:
- return(FALSE);
- }
-
-
-
-
-
- int xmodem_send_file(zt)
-
- struct Z_Term *zt;
-
- {
- int sectnum, bytes_to_send, size, attempts, j;
- unsigned char sectsend, c;
- unsigned int checksum, bufptr;
- struct FileLock *lock1, *Lock();
- struct FileInfoBlock *infoblock1 = 0;
- LONG filesize;
- int xfer_current_error_detect_alg;
- int i;
- unsigned char outchecksum1;
- int sync_lost_count;
- int xfer_total_blocks;
- int timeout_time, fd;
- char bufr[BUFSIZE];
- char numb[10];
- int temp;
-
- xfer_current_error_detect_alg = NULL; /* nullify alg */
- timeout_time = 10; /* 10 sec timeout period */
- if ((lock1 = Lock(zt->filename,ACCESS_READ)) != NULL) /* get shared lock */
- {
- infoblock1 = (struct FileInfoBlock *)
- AllocMem(sizeof(*infoblock1),MEMF_PUBLIC|MEMF_CLEAR);
- Examine(lock1,infoblock1);
- filesize = infoblock1->fib_Size;
- UnLock(lock1);
- FreeMem(infoblock1,sizeof(*infoblock1));
- con_put_str("\nSending ",zt);
- con_put_str(zt->filename,zt);
- con_put_str(".\n",zt);
- con_put_str("File is ",zt);
- stci_d(numb,(int) filesize,10);
- con_put_str(numb,zt);
- con_put_str(" bytes long.\n",zt);
- con_put_str("Current blocksize is ",zt);
- stci_d(numb,zt->xfer_blocksize,10);
- con_put_str(numb,zt);
- con_put_str(" bytes.\nCurrent error detection algorithm is ",zt);
- if (zt->xfer_error_detect_alg == XMODEM_CHECKSUM)
- {
- con_put_str("checksum",zt);
- }
- if (zt->xfer_error_detect_alg == XMODEM_CRC16)
- {
- con_put_str("crc-16",zt);
- }
- xfer_total_blocks = (filesize / zt->xfer_blocksize);
- xfer_total_blocks += 1;
- con_put_str(".\nTotal blocks to send is ",zt);
- stci_d(numb,xfer_total_blocks,10);
- con_put_str(numb,zt);
- con_put_str(".",zt);
- if ((fd = open(zt->filename, 1)) == NULL)
- {
- con_put_str("\nError opening send file.\n",zt);
- goto xmodem_send_file_exit;
- }
- con_put_str("\nSending File\n",zt);
- } /* end if lock1 != NULL */
- else
- {
- con_put_str("\nCould not open ",zt);
- con_put_str(zt->filename,zt);
- con_put_str(" for input.\n",zt);
- goto xmodem_send_file_exit;
- }
-
- attempts = 0;
- sectnum = 1;
- sectsend = 1;
-
- /* wait for sync char */
-
- sync_lost_count = 1;
-
-
-
- do
- {
- zt->st = readchar(&c,zt);
- if (zt->st == USER_ABORT)
- {
- goto xmodem_send_file_exit;
- }
-
- if ((c != NAK) && (c != CCHAR))
- {
- con_put_str("Not receiving C or NAK.\nAscii ",zt);
- temp = (int) c;
- stci_d(numb,temp,10);
- con_put_str(numb,zt);
- con_put_str(" received instead.\n",zt);
- }
- }
- while (((c != NAK) && (c != CCHAR)) && (sync_lost_count++ < ERRORMAX));
-
- if (sync_lost_count >= (ERRORMAX))
- {
- con_put_str("\nCouldn't sync up.\n",zt);
- con_put_str("\nReceiver not sending NAKs or C's.\n",zt);
- goto xmodem_send_file_exit;
- }
-
- if (c == NAK)
- {
- xfer_current_error_detect_alg = XMODEM_CHECKSUM;
- }
- if (c == CCHAR)
- {
- xfer_current_error_detect_alg = XMODEM_CRC16;
- }
- if (xfer_current_error_detect_alg == NULL)
- {
- con_put_str("\nERROR!! Receiver specified unknown error detect alg.\n",zt);
- temp = (int) c;
- stci_d(numb,temp,10);
- con_put_str("\nAscii ",zt);
- con_put_str(numb,zt);
- con_put_str(" was received.\n",zt);
- goto xmodem_send_file_exit;
- }
- if (xfer_current_error_detect_alg != zt->xfer_error_detect_alg)
- {
- con_put_str("\nReceiver specified error detection algorithm to be ",zt);
- if (xfer_current_error_detect_alg == XMODEM_CHECKSUM)
- {
- con_put_str("checksum",zt);
- }
- if (xfer_current_error_detect_alg == XMODEM_CRC16)
- {
- con_put_str("crc-16",zt);
- }
- con_put_str(" instead of ",zt);
- if (zt->xfer_error_detect_alg == XMODEM_CHECKSUM)
- {
- con_put_str("checksum.\n",zt);
- }
- if (zt->xfer_error_detect_alg == XMODEM_CRC16)
- {
- con_put_str("crc-16.\n",zt);
- }
- } /* end if current_error_detect_alg != error_detect_alg */
-
- while ((bytes_to_send = read(fd, bufr, BUFSIZE)) && (attempts != RETRYMAX))
- {
- if (bytes_to_send == EOF)
- {
- con_put_str("\nError Reading File\n",zt);
- goto xmodem_send_file_exit;
- }
-
- bufptr = 0;
- while ((bytes_to_send > 0) && (attempts != RETRYMAX))
- {
- attempts = 0;
- do
- {
- if (zt->xfer_blocksize == XMODEM_128_BLOCK)
- {
- sendchar((char) SOH,zt);
- }
- if (zt->xfer_blocksize == XMODEM_1024_BLOCK)
- {
- sendchar((char) STX,zt);
- }
- sendchar((char) sectsend,zt);
- sendchar((char) ~sectsend,zt);
-
- checksum = 0;
- size = zt->xfer_blocksize
- <= bytes_to_send ? zt->xfer_blocksize : bytes_to_send;
- bytes_to_send -= size;
- for (j = bufptr; j < (bufptr + zt->xfer_blocksize); j++)
- {
- if (j < (bufptr + size))
- {
- sendchar((char) bufr[j],zt);
- if (xfer_current_error_detect_alg == XMODEM_CHECKSUM)
- {
- checksum += bufr[j];
- }
- if (xfer_current_error_detect_alg == XMODEM_CRC16)
- {
- checksum = checksum ^ (int) bufr[j] << 8;
- for (i = 0;i < 8; ++i)
- {
- if (checksum & 0x8000)
- {
- checksum = checksum << 1 ^ 0x1021;
- }
- else
- {
- checksum = checksum << 1;
- }
- } /* end for */
- checksum = checksum & 0xffff;
- } /* end if */
- }
- else
- {
- sendchar((char) NULL,zt);
- }
- } /* end for */
- if (xfer_current_error_detect_alg == XMODEM_CHECKSUM)
- {
- sendchar((char) checksum & 0xff,zt);
- }
- if (xfer_current_error_detect_alg == XMODEM_CRC16)
- {
- outchecksum1 = (checksum >> 8);
- sen