home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*/
- /* */
- /* */
- /* ------------ Bit-Bucket Software <no-Inc> */
- /* \ 10001101 / Writers and Distributors of */
- /* \ 011110 / No-Cost<no-tm> Software. */
- /* \ 1011 / */
- /* ------ */
- /* */
- /* Copyright (C) 1987, 1988, 1989 by Robert Hartman and Vincent Perriello */
- /* */
- /* */
- /* GENERAL PURPOSE FILE TRANSMITTER (Xmodem/YModem/Sealink) */
- /* */
- /* */
- /* For complete details of the licensing restrictions, please refer */
- /* to the License agreement, which is published in its entirety in */
- /* the MAKEFILE and BT.C, and also contained in the file LICENSE.210. */
- /* */
- /* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */
- /* BINKLEYTERM LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */
- /* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */
- /* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT THE AUTHORS */
- /* AT THE ADDRESSES LISTED BELOW. IN NO EVENT SHOULD YOU PROCEED TO */
- /* USE THIS FILE WITHOUT HAVING ACCEPTED THE TERMS OF THE */
- /* BINKLEYTERM LICENSING AGREEMENT, OR SUCH OTHER AGREEMENT AS YOU */
- /* ARE ABLE TO REACH WITH THE AUTHORS. */
- /* */
- /* */
- /* The Authors can be reached at the following addresses: */
- /* */
- /* Robert C. Hartman Vincent E. Perriello */
- /* Spark Software VEP Software */
- /* 427-3 Amherst Street 111 Carroll Street */
- /* CS2032, Suite 232 Naugatuck, CT 06770 */
- /* Nashua, NH 03061 */
- /* */
- /* FidoNet 1:132/101 FidoNet 1:141/491 */
- /* Data (603) 888-8179 Data (203) 729-7569 */
- /* */
- /* Please feel free to contact us at any time to share your comments */
- /* about our software and/or licensing policies. */
- /* */
- /* */
- /* This module is based largely on a similar module in OPUS-CBCS V1.03b. */
- /* The original work is (C) Copyright 1987, Wynn Wagner III. The original */
- /* author has graciously allowed us to use his code in this work. */
- /* */
- /*--------------------------------------------------------------------------*/
-
- #include <sys\types.h>
- #include <sys\stat.h>
- #include <sys\timeb.h>
- #include <errno.h>
- #include <stdio.h>
- #include <time.h>
- #include <stdlib.h>
- #include <string.h>
- #include <io.h>
- #include <conio.h>
- #include <dos.h>
-
- #ifdef __TURBOC__
- #include <alloc.h>
- #include <mem.h>
- #else
- #include <malloc.h>
- #include <memory.h>
- #endif
-
-
- #include "com.h"
- #include "xfer.h"
- #include "sbuf.h"
- #include "sched.h"
- #include "externs.h"
- #include "prototyp.h"
- #include "find.h" /*PLF Fri 05-05-1989 23:23:05 */
-
- static int send_ackless;
- static int ackless_ok;
- static char *NOACKS_msg = "SEAlink Overdrive Disengaged";
-
- /*--------------------------------------------------------------------------*/
- /* MULTI-PURPOSE FILE TRANSFER */
- /*--------------------------------------------------------------------------*/
- int send_file (fname, protocol)
- char *fname, protocol;
- {
- register int i, j;
- register byte *b;
- static FSCAN *dh = NULL; /*PLF Fri 05-05-1989 23:15:36 */
- struct zero_block *header;
- int in_char;
- int in_char1;
- long ackblock;
- long blknum;
- long last_block;
- long temp;
- unsigned int errs;
- int real_errs;
- int sliding;
- int base;
- int head;
- int block_size;
- char *buffer;
- int do_chksum;
- FILE *fp;
- char *message;
- long block_timer, timerset ();
- int win_size;
- int full_window;
- int may_be_seadog;
- int ackerr;
- struct stat st_stat;
- char junkbuff[80];
-
- if (protocol == 'F')
- {
- protocol = 'S';
- may_be_seadog = 1;
- }
- else may_be_seadog = 0;
- fp = NULL;
- sliding = 0;
- ackblock = -1;
- do_chksum = errs = 0;
- ackerr = 0;
- real_errs = 0;
-
-
- /*
- * The following window size works out to be between 3.5 and 4.5 seconds
- * of data at any valid baud rate. This gives us a set time that the
- * other end will wait before NAK'ing a block if it waits to flush its
- * buffer before NAK'ing. If it does not wait, then it does not matter
- * very much except to make sure we only have a set amount of run-ahead
- * that will fit in a 4K buffer
- */
- full_window = cur_baud / 400;
-
- if (small_window && full_window > 6)
- full_window = 6;
-
- XON_DISABLE ();
-
- /*--------------------------------------------------------------------*/
- /* Prepare file */
- /*--------------------------------------------------------------------*/
- if ((!fname) || (!fname[0])) /* No file? Just send an
- * EOT. */
- {
-
- CLEAR_INBOUND ();
-
- for (i = 0; i < 5; i++)
- {
- switch (in_char = TIMED_READ (5))
- {
-
- case 'C':
- case NAK:
- case CAN:
- SENDBYTE (EOT);
- break;
-
- case TSYNC:
- return TSYNC;
-
- default:
- if (in_char < ' ')
- return 0;
-
- } /* switch */
- }
- return 0;
- }
-
- strlwr (fname); /* ww/870225 */
- CLEAR_IOERR ();
- if(!dh) dh = opendir(); /*PLF Fri 05-05-1989 23:16:37 */
- if(!findfirst(fname, _A_NORMAL, dh)) /*PLF Fri 05-05-1989 23:17:09 */
- fp = fopen (fname, read_binary);
- else errno = ENOENT;
-
- if (got_error (OPEN_msg, fname))
- {
- send_can ();
- return 0;
- }
- if (isatty (fileno (fp)))
- {
- errno = 1;
- got_error (DEVICE_msg, fname);
- fclose (fp);
- return (NULL);
- }
-
- /*--------------------------------------------------------------------*/
- /* Prepare buffer */
- /*--------------------------------------------------------------------*/
- buffer = Txbuf;
- header = (struct zero_block *) buffer;
- if (!buffer)
- {
- message = MEMOVFL_msg;
- goto fubar;
- }
-
- /*--------------------------------------------------------------------*/
- /* Prepare method */
- /*--------------------------------------------------------------------*/
- block_size = 128;
- head = SOH;
- switch (protocol)
- {
- case 'Y':
- base = 1;
- block_size = 1024;
- head = STX;
- break;
- case 'X':
- base = 1;
- break;
- case 'S':
- base = 0;
- break;
- case 'T':
- base = 0;
- head = SYN;
- break;
- case 'M':
- base = 1;
- break;
- default:
- status_line ("!Protocol?");
- return 0;
- }
- blknum = base;
-
- last_block = (long) ((dh->size + ((long) block_size - 1L)) / (long) block_size); /*PLF Fri 05-05-1989 23:17:40 */
-
- sprintf (junkbuff, "Send %s (%ld %c-blks)", fname, last_block, protocol);
- if (un_attended && fullscreen)
- {
- clear_filetransfer ();
- sb_move (filewin, 1, 2);
- sb_puts (filewin, junkbuff);
- sb_show ();
- }
- else
- {
- cprintf ("\r\n");
- cprintf ("%s", junkbuff);
- set_xy (NULL);
- locate_x += 2;
- }
-
-
- /*--------------------------------------------------------------------*/
- /* Wait for signal to begin */
- /*--------------------------------------------------------------------*/
- do
- {
- i = TIMED_READ (5);
- switch (i)
- {
- case NAK:
- /*--------------------------------------------*/
- /* NAK */
- /*--------------------------------------------*/
- do_chksum = 1;
- /* fallthrough */
-
- case 'C':
- /*--------------------------------------------*/
- /* CRC RESPONSE */
- /*--------------------------------------------*/
- {
- int send_tmp;
-
- if (((send_tmp = TIMED_READ (1)) >= 0)
- && (TIMED_READ (1) == ((~send_tmp) & 0xff)))
- {
- if (send_tmp <= 1)
- sliding = 1;
- else
- {
- /* Not a normal SEAlink startup */
- /* Lets end the transmission and */
- /* try again. Nasty, but it helps */
- SENDBYTE (EOT);
- continue;
- }
- }
- if (may_be_seadog)
- {
- sliding = 1;
- }
- errs = 0;
- CLEAR_INBOUND ();
- throughput (0, 0L);
- goto sendloop;
- }
-
- case CAN:
- /*--------------------------------------------*/
- /* CANCEL */
- /*--------------------------------------------*/
- message = CAN_msg;
- goto fubar;
-
- default:
- /*--------------------------------------------*/
- /* OTHER RESPONSES (debris) */
- /*--------------------------------------------*/
- if (got_ESC ())
- {
- message = KBD_msg;
- goto fubar;
- }
- else if ((errs++) > 15)
- {
- message = TIME_msg;
- goto fubar;
- }
- block_timer = timerset (50);
- while (!timeup (block_timer))
- time_release ();
- CLEAR_INBOUND ();
-
- } /* switch */
- } /* wait for signal to begin */
- while (CARRIER);
-
- message = CARRIER_msg;
- goto fubar;
-
-
- /*--------------------------------------------------------------------*/
- /* Transfer */
- /*--------------------------------------------------------------------*/
- sendloop:
- while (CARRIER)
- {
- message = NULL;
- win_size = (blknum < 2) ? 2 : (send_ackless ? 220 : full_window);
-
- if (got_ESC ())
- {
- message = KBD_msg;
- goto fubar;
- }
-
- if (blknum <= last_block)
- {
- /*--------------------------------------------------------*/
- /* DATA */
- /*--------------------------------------------------------*/
- memset (buffer, 0, block_size);
- if (blknum)
- {
- errno = 0;
- fseek (fp, ((long) (blknum - 1) * (long) block_size), 0);
- if (got_error (READ_msg, fname))
- {
- message = SEEK_msg;
- goto fubar;
- }
-
- errno = 0;
- fread (buffer, block_size, 1, fp);
- if (got_error (READ_msg, fname))
- {
- message = READ_msg;
- goto fubar;
- }
- }
- else
- {
- block_size = 128;
- header->size = dh->size; /*PLF Fri 05-05-1989 23:17:47 */
- stat (fname, &st_stat);
- tzset ();
- header->time = st_stat.st_atime - timezone;
-
- stcgfn (header->name, dh->name); /*PLF Fri 05-05-1989 23:17:55 */
-
- if (protocol == 'T')
- {
- for (i = 0; i < HEADER_NAMESIZE; i++)
- if (!(header->name[i]))
- header->name[i] = ' ';
- header->time = findtime(dh); /*PLF Fri 05-05-1989 23:18:02 */
- }
-
- strcpy (header->moi, xfer_id);
- if ((cur_baud >= 9600) && (sliding))
- {
- header->noacks = 1;
- send_ackless = 1;
- }
- else
- {
- header->noacks = 0;
- send_ackless = 0;
- }
-
- if (no_overdrive)
- {
- header->noacks = 0;
- send_ackless = 0;
- }
-
- ackless_ok = 0;
- }
-
- /*--------------------------------------------------------*/
- /* HEAD */
- /*--------------------------------------------------------*/
- SENDBYTE ((unsigned char) head);
- SENDBYTE ((unsigned char) (blknum & 0xff));
- SENDBYTE ((unsigned char) (~(blknum & 0xff)));
-
- /*--------------------------------------------------------*/
- /* SEND */
- /*--------------------------------------------------------*/
- b = buffer;
- SENDCHARS (b, block_size, 1);
-
- /*--------------------------------------------------------*/
- /* CHECK */
- /*--------------------------------------------------------*/
- if ((do_chksum) || (head == SYN))
- {
- unsigned char chksum = '\0';
-
- for (b = buffer, i = 0; i < block_size; i++, b++)
- chksum += (*b);
- SENDBYTE (chksum);
- }
- else
- {
- word crc;
-
- for (b = buffer, crc = i = 0; i < block_size; i++, b++)
- crc = xcrc (crc, (byte) (*b));
-
- SENDBYTE ((unsigned char) (crc >> 8));
- SENDBYTE ((unsigned char) (crc & 0xff));
- }
- } /* if not finished */
-
- /*
- * Only wait 30 seconds for a response For non-sliding this number is
- * updated, for sliding we have a problem since the output buffer may
- * still have stuff in it. We need to make sure we reset this when
- * output is done in the sliding case. What we actually do is reset it
- * if the output has not yet completed. We only check it in the case
- * of debris, then recycle, so this should be a reasonable way of
- * doing things in the sliding case.
- */
- block_timer = timerset (3000);
-
- slide_reply:
-
- /*
- * If we are not sliding, force the output and purge the input. This is
- * simply good Xmodem practice. It is also necessary to make sure that
- * the other end has received all of the data before starting the block
- * reply timeout.
- */
- if (!sliding)
- {
- while (!OUT_EMPTY ())
- time_release ();
- block_timer = timerset (3000);
- }
-
- /*--------------------------------------------------------------*/
- /* REPLY: Slide */
- /* Don't wait, unless other end has something to say */
- /* or we're at/beyond the window. */
- /*--------------------------------------------------------------*/
- else if ((blknum < (ackblock + win_size)) && /* in window */
- (blknum < last_block) && /* have more to send */
- (PEEKBYTE () < 0) /* other end is quiet */
- )
- {
- if ((send_ackless) && (blknum > 0))
- {
- ackblock = blknum;
-
- if (blknum >= last_block)
- {
- if (ackless_ok)
- {
- if (fullscreen && un_attended)
- {
- sb_move (filewin, 2, 2);
- sb_puts (filewin, ultoa (((unsigned long) (last_block)), e_input, 10));
- sb_putc (filewin, '*');
- sb_show ();
- }
- else
- {
- gotoxy (locate_x, locate_y);
- cputs (ultoa (((unsigned long) (last_block)), e_input, 10));
- /*PLF bdos (9, (unsigned int) "*$", 0); */
- putch('*'); /*PLF Fri 05-05-1989 06:57:35 */
- }
- goto done;
- }
-
- blknum = last_block + 1;
- goto sendloop;
- }
-
- ++blknum;
-
- if (!(blknum & 0x001F)) /* Update SLO display every
- * 32 */
- {
- if (fullscreen && un_attended)
- {
- sb_move (filewin, 2, 2);
- sb_puts (filewin, ultoa (((unsigned long) (blknum)), e_input, 10));
- sb_putc (filewin, '*');
- sb_show ();
- }
- else
- {
- gotoxy (locate_x, locate_y);
- cputs (ultoa (((unsigned long) (blknum)), e_input, 10));
- /*PLF bdos (9, (unsigned int) "*$", 0); */
- putch('*'); /*PLF Fri 05-05-1989 06:57:35 */
- }
- }
- }
- else
- {
- blknum++;
- }
- goto sendloop;
- }
-
- if (PEEKBYTE () < 0)
- {
- if (send_ackless)
- {
- ackblock = blknum;
-
- if (blknum >= last_block)
- {
- if (ackless_ok)
- {
- if (fullscreen && un_attended)
- {
- sb_move (filewin, 2, 2);
- sb_puts (filewin, ultoa (((unsigned long) (last_block)), e_input, 10));
- sb_putc (filewin, '*');
- sb_show ();
- }
- else
- {
- gotoxy (locate_x, locate_y);
- cputs (ultoa (((unsigned long) (last_block)), e_input, 10));
- /*PLF bdos (9, (unsigned int) "*$", 0); */
- putch('*'); /*PLF Fri 05-05-1989 06:57:35 */
- }
- goto done;
- }
-
- blknum = last_block + 1;
- goto sendloop;
- }
-
- ++blknum;
-
- if ((blknum % 20) == 0)
- {
- if (fullscreen && un_attended)
- {
- sb_move (filewin, 2, 2);
- sb_puts (filewin, ultoa (((unsigned long) (blknum)), e_input, 10));
- sb_putc (filewin, '*');
- sb_show ();
- }
- else
- {
- gotoxy (locate_x, locate_y);
- cputs (ultoa (((unsigned long) (blknum)), e_input, 10));
- /*PLF bdos (9, (unsigned int) "*$", 0); */
- putch('*'); /*PLF Fri 05-05-1989 06:57:35 */
- }
- }
-
- goto sendloop;
- }
- }
-
- reply:
- /*--------------------------------------------------------------*/
- /* REPLY: Wait state */
- /* No sliding, or slid too far. Wait for a reply. */
- /* If we got here we are either not sliding, or we are sliding */
- /* and have received an input character, or we are sliding and */
- /* have slid too far. In the first case the following loop */
- /* will not do anything because the output is empty, in the */
- /* second case we also will not do anything since we have an */
- /* input character ready, in the final case we want to execute */
- /* the loop since we are in a wait state. The loop will go on */
- /* until the output is empty (in the worst case), and since we */
- /* we have disabled flow control here (right???) we will never */
- /* have to worry about the loop not terminating. Now, we just */
- /* sit and loop as long as there is output to do and no input. */
- /* Just to make wwIII happy do a time_release() so that his */
- /* DDos system will be more efficient! */
- /*--------------------------------------------------------------*/
-
- while ((!OUT_EMPTY ()) &&
- (PEEKBYTE () < 0))
- time_release (); /* ... time slice routine
- * for multi-taskers */
-
- /*--------------------------------------------------------------*/
- /* If we got here we either sent all the output, or got input. */
- /* In the first case we should get a response within 15 seconds */
- /* In the second case we should get an immediate response. */
- /* Either way, nothing in 30 seconds is a timeout */
- /*--------------------------------------------------------------*/
- if ((in_char = TIMED_READ (30)) < 0)
- {
- message = TIME_msg;
- goto fubar;
- }
-
- if (in_char == 'C')
- {
- do_chksum = 0;
- in_char = NAK;
- }
-
- /*--------------------------------------------------------------*/
- /* CAN */
- /*--------------------------------------------------------------*/
- if (in_char == CAN)
- {
- message = CAN_msg;
- goto fubar;
- }
-
- /*--------------------------------------------------------------*/
- /* REPLY: Take action based on slide-response */
- /*--------------------------------------------------------------*/
- if ((in_char > 0) && (sliding))
- {
- if (++ackerr >= 10)
- {
- if (send_ackless)
- {
- send_ackless = 0;
- message = NOACKS_msg;
- }
- }
-
- if ((in_char == ACK) || (in_char == NAK))
- {
- if ((i = TIMED_READ (2)) < 0)
- {
- sliding = 0;
- if (send_ackless)
- {
- send_ackless = 0;
- message = NOACKS_msg;
- }
- }
- else
- {
- if ((j = TIMED_READ (2)) < 0)
- {
- sliding = 0;
- if (send_ackless)
- {
- send_ackless = 0;
- message = NOACKS_msg;
- }
- }
- else if (i == (j ^ 0xff))
- {
- temp = blknum - ((blknum - i) & 0xff);
- if ((temp <= blknum) && (temp > (blknum - win_size - 10)))
- {
- if (in_char == ACK)
- {
- if ((head == SYN) && (blknum))
- head = SOH; /* ZapTeLink */
-
- if (send_ackless)
- {
- ackless_ok = 1;
- goto slide_reply;
- }
- else
- {
- ackblock = temp;
- }
-
- blknum++;
-
- if (ackblock >= last_block)
- {
- goto done;
- }
- errs = 0;
- }
- else
- {
- blknum = temp;
- /* CLEAR_INBOUND(); */
- CLEAR_OUTBOUND ();
- errs++;
- real_errs++;
- }
- }
- }
- else
- {
- message = "SLIDE CMPL ERR";
- }
- }
- }
- else
- {
- /*--------------------------------------------------*/
- /* If we got debris, just ignore it and go on if we */
- /* have not yet had a timeout. If we timed out, */
- /* then just go to the fubar label and abort */
- /*--------------------------------------------------*/
-
- if (fullscreen && un_attended)
- {
- sb_move (filewin, 2, 12);
- sb_puts (filewin, " Debris");
- sb_show ();
- }
- else
- {
- gotoxy (locate_x + 10, locate_y);
- cprintf (" Debris [%Xh]", in_char);
- }
-
- /*--------------------------------------------------*/
- /* The error is timeout with the output buffer */
- /* empty (we can't penalize someone for a timeout */
- /* if we haven't yet sent them all they need!!! */
- /*--------------------------------------------------*/
-
- if (timeup (block_timer) && OUT_EMPTY ())
- {
- message = TIME_msg;
- goto fubar;
- }
-
- /*--------------------------------------------------*/
- /* Ok, we either have a timeout or the buffer still */
- /* has stuff in it. If it still has stuff, reset */
- /* the timeout variable before trying again */
- /*--------------------------------------------------*/
-
- else if (!OUT_EMPTY ())
- block_timer = timerset (3000);
-
- goto slide_reply;
- }
- }
-
- /*--------------------------------------------------------------*/
- /* REPLY: Take action based on regular response */
- /*--------------------------------------------------------------*/
- if (!sliding)
- {
- if (in_char == ACK)
- {
- /*--------------------------------------------------*/
- /* On block 10, throw in an extra pause to give the */
- /* other end a change to fall into a slide if it */
- /* feels it's something it needs to do. */
- /*--------------------------------------------------*/
- if (blknum == 10)
- timer (3); /* approx. 3/10s second */
-
- /*--------------------------------------------------*/
- /* Smell the other system vis-a-vis a slide. */
- /*--------------------------------------------------*/
- if (PEEKBYTE () > 0)
- {
- int send_tmp;
-
- if (((send_tmp = TIMED_READ (1)) >= 0)
- && (TIMED_READ (1) == ((~send_tmp) & 0xff)))
- {
- sliding = 1;
- ackblock = send_tmp;
- }
- }
-
- message = NULL;
- if (blknum >= last_block)
- goto done;
- blknum++;
-
- if ((head == SYN) && (blknum))
- head = SOH; /* ZapTeLink */
-
- errs = 0;
- }
- else if (in_char == NAK)
- {
- errs++;
- real_errs++;
- timer (5);
- CLEAR_OUTBOUND ();
- message = NAK_msg;
- }
- else if (CARRIER)
- {
- /* Did we time out yet? */
- if (!timeup (block_timer))
- goto reply;
- else
- {
- message = TIME_msg;
- goto fubar;
- }
- }
- else
- {
- message = CARRIER_msg;
- goto fubar;
- }
- }
-
- if (errs > 10)
- {
- message = FUBAR_msg;
- goto fubar;
- }
-
- temp = (blknum <= last_block) ? blknum : last_block;
- if (fullscreen && un_attended)
- {
- sb_move (filewin, 2, 2);
- sb_puts (filewin, ultoa (((unsigned long) (temp)), e_input, 10));
- sb_show ();
- }
- else
- {
- gotoxy (locate_x, locate_y);
- cputs (ultoa (((unsigned long) (temp)), e_input, 10));
- }
-
- if ((sliding) && (ackblock > 0))
- {
- if (send_ackless)
- {
- if (fullscreen && un_attended)
- {
- sb_putc (filewin, '*');
- sb_show ();
- }
- else
- {
- /*PLF bdos (9, (unsigned int) "*$", 0); */
- putch('*'); /*PLF Fri 05-05-1989 06:57:35 */
- }
- }
- else
- {
- if (fullscreen && un_attended)
- {
- sb_puts (filewin, " : ");
- sb_puts (filewin, ultoa (((unsigned long) (ackblock)), e_input, 10));
- sb_show ();
- }
- else
- {
- /*PLF bdos (9, (unsigned int) " : $", 0); */
- cputs(" : $"); /*PLF Fri 05-05-1989 07:37:42 */
- cputs (ultoa (((unsigned long) (ackblock)), e_input, 10));
- }
- }
- }
-
- if (message)
- {
- if (fullscreen && un_attended)
- {
- sb_putc (filewin, ' ');
- sb_puts (filewin, message);
- sb_puts (filewin, " ");
- sb_show ();
- }
- else
- {
- putch (' ');
- cputs (message);
- cputs (" ");
- }
- }
- } /* while */
-
- message = CARRIER_msg;
-
- fubar:
-
- CLEAR_OUTBOUND ();
- send_can ();
-
- status_line ("!%s not sent: %s", fname, message);
-
- if (fp)
- fclose (fp);
-
- return 0;
-
- done:
- while (!OUT_EMPTY ())
- time_release ();
-
- CLEAR_INBOUND ();
- SENDBYTE (EOT);
-
- ackerr = 1;
- blknum = last_block + 1;
-
- for (i = 0; i < 5; i++)
- {
- if (!CARRIER)
- {
- ackerr = 1;
- goto gohome;
- }
-
- switch (TIMED_READ (5))
- {
- case 'C':
- case NAK:
- case CAN:
- if (sliding && ((in_char = TIMED_READ (1)) >= 0))
- {
- in_char1 = TIMED_READ (1);
- if (in_char == (in_char1 ^ 0xff))
- {
- blknum -= ((blknum - in_char) & 0xff);
- CLEAR_INBOUND ();
- if (blknum <= last_block)
- goto sendloop;
- }
- }
- CLEAR_INBOUND ();
- SENDBYTE (EOT);
- break;
-
- case TSYNC:
- ackerr = TSYNC;
- goto gohome;
-
- case ACK:
- if (sliding && ((in_char = TIMED_READ (1)) >= 0))
- {
- in_char1 = TIMED_READ (1);
- }
- ackerr = 1;
- goto gohome;
-
- } /* switch */
- }
-
- gohome:
-
- if (fp)
- fclose (fp);
-
- if (locate_y > 1 && !(fullscreen && un_attended))
- gotoxy (2, locate_y - 1);
- throughput (1, dh->size); /*PLF Fri 05-05-1989 23:18:08 */
-
- if (real_errs > 4)
- status_line ("+Corrected %d errors in %ld blocks", real_errs, last_block);
- status_line ("+Sent-S %s", fname);
-
- update_files (1);
- closedir(dh); dh=NULL; /*PLF Fri 05-05-1989 23:18:25 */
- return ackerr;
- }
-
- /* END OF FILE: F_Send.C */