home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*/
- /* */
- /* */
- /* ------------ Bit-Bucket Software, Co. */
- /* \ 10001101 / Writers and Distributors of */
- /* \ 011110 / Freely Available<tm> Software. */
- /* \ 1011 / */
- /* ------ */
- /* */
- /* (C) Copyright 1987-91, Bit Bucket Software Co., a Delaware Corporation. */
- /* */
- /* */
- /* This module was written by Bob Hartman */
- /* */
- /* */
- /* BinkleyTerm Xmodem Receiver State Machine */
- /* */
- /* */
- /* 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.250. */
- /* */
- /* 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 BIT BUCKET */
- /* SOFTWARE CO. AT ONE OF 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 BIT BUCKET SOFTWARE, CO. */
- /* */
- /* */
- /* You can contact Bit Bucket Software Co. at any one of the following */
- /* addresses: */
- /* */
- /* Bit Bucket Software Co. FidoNet 1:104/501, 1:343/491 */
- /* P.O. Box 460398 AlterNet 7:491/0 */
- /* Aurora, CO 80046 BBS-Net 86:2030/1 */
- /* Internet f491.n343.z1.fidonet.org */
- /* */
- /* Please feel free to contact us at any time to share your comments about */
- /* our software and/or licensing policies. */
- /* */
- /*--------------------------------------------------------------------------*/
-
- /* Include this file before any other includes or defines! */
-
- #include "includes.h"
-
- void Find_Char (int);
- int Header_in_data (unsigned char *);
- void Send_ACK (XMARGSP);
- void Send_NAK (XMARGSP);
- long Open_Xmodem_File (XMARGSP);
-
- int XRInit (XMARGSP, int);
- int XREnd (XMARGSP, int);
- int XRRecInit (XMARGSP);
- int XRBrecInit (XMARGSP);
- int XRRecStart (XMARGSP);
- int XRWaitFirst (XMARGSP);
- int XRWaitBlock (XMARGSP);
- int XRRestart (XMARGSP);
- int XRSetOvrdr (XMARGSP);
-
- STATES Xmodem_Receiver[] = {
- { "XRInit", XRInit },
- { "XREnd", XREnd },
- { "XR0", XRRecInit },
- { "XR0B", XRBrecInit },
- { "XR1", XRRecStart },
- { "XR2", XRWaitFirst },
- { "XR3", XRWaitBlock },
- { "XR4", XRRestart },
- { "XR5", XRSetOvrdr }
- };
-
- long Open_Xmodem_File (XMARGSP args)
- {
- char *s1, *s2;
-
- if (args->file_pointer == NULL)
- {
- args->temp_name = calloc (1, 80);
-
- if (args->path != NULL)
- (void) strcpy (args->temp_name, args->path);
-
- s1 = &(args->temp_name[strlen (args->temp_name)]);
- (void) strcpy (s1, "BTXXXXXX");
- s2 = mktemp (args->temp_name);
- if ((s2 == NULL) || ((args->file_pointer = fopen (s2, "wb")) == NULL))
- {
- status_line (MSG_TXT(M_TEMP_NOT_OPEN), s2);
- return (-1L);
- }
- }
-
- throughput (0, 0L);
- return (0L);
- }
-
- long Set_Up_Restart (XMARGSP args)
- {
- char foo[100];
- char foo1[50];
- struct stat st;
-
- args->sub_results = 0;
-
- /* Look for file in directory */
- if (args->path != NULL)
- (void) strcpy (foo, args->path);
-
- if ((args->received_name != NULL) &&
- (strlen (args->received_name) > 0) &&
- args->options.Resync)
- {
- (void) strcat (foo, args->received_name);
-
- if (stat (foo, &st) == 0)
- {
- if ((st.st_size == args->filelen) && (st.st_atime == (time_t)(args->save_filetime.oneword.timedate)))
- {
- if ((args->file_pointer = fopen (foo, "rb+")) != NULL)
- {
- throughput (0, 0L);
- (void) fseek (args->file_pointer, 0L, SEEK_END);
- args->sub_results = DID_RESYNC;
- args->temp_name = calloc (1, 80);
- (void) strcpy (args->temp_name, foo);
- args->prev_bytes = args->filelen;
- status_line (MSG_TXT(M_ALREADY_HAVE), foo);
- status_line (MSG_TXT(M_SYNCHRONIZING_EOF));
- return (args->total_blocks + 1L);
- }
- }
- }
-
- /* Look for file in .Z file */
- if (dexists (Abortlog_name))
- {
- (void) sprintf (Resume_info, "%ld %lo", args->filelen, args->save_filetime.oneword.timedate);
- if (check_failed (Abortlog_name, args->received_name, Resume_info, foo1))
- {
- foo[0] = '\0';
- /* Here it looks like it was a failed WaZOO session */
- if (args->path != NULL)
- (void) strcpy (foo, args->path);
- (void) strcat (foo, foo1);
-
- if ((args->file_pointer = fopen (foo, "rb+")) != NULL)
- {
- (void) stat (foo, &st);
- throughput (0, 0L);
- args->temp_name = calloc(1, 80);
- (void) strcpy (args->temp_name, foo);
- args->prev_bytes = (st.st_size / 128L) * 128L;
- (void) fseek (args->file_pointer, args->prev_bytes, SEEK_SET);
- status_line (MSG_TXT(M_SYNCHRONIZING_OFFSET), args->prev_bytes);
- return (args->prev_bytes / 128L + 1L);
- }
- }
- }
- }
-
- return (Open_Xmodem_File (args));
- }
-
- void Finish_Xmodem_Receive (XMARGSP args)
- {
- struct stat st;
- char new_name[80];
- struct utimbuf times;
- int i, j, k;
-
- /* Set the file's time and date stamp */
- if ((args->save_header == SOH) || (args->save_header == SYN))
- {
- (void) fclose (args->file_pointer);
- times.modtime = times.UT_ACTIME = (time_t) args->save_filetime.oneword.timedate;
- (void) utime (args->temp_name, (UTIMBUF *)×);
- }
- else
- {
- (void) strcpy (args->received_name, "");
- (void) fclose (args->file_pointer);
- }
-
- if (args->result == SUCCESS)
- {
- /* Get the file information */
- (void) stat (args->temp_name, &st);
-
- throughput (1, (unsigned long) (st.st_size - args->prev_bytes));
-
- update_files (0);
-
- if (args->sub_results & DID_RESYNC)
- {
- status_line ("%s: %s", MSG_TXT(M_FILE_RECEIVED), args->temp_name);
- }
- else
- {
- new_name[0] = '\0';
- if (args->path != NULL)
- (void) strcpy (new_name, args->path);
- if ((args->filename == NULL) || (strlen (args->filename) == 0))
- {
- if (strlen (args->received_name) > 0)
- (void) strcat (new_name, args->received_name);
- else
- (void) strcat (new_name, "BAD_FILE.000");
- }
- else
- {
- (void) strcat (new_name, args->filename);
- }
-
- i = (int) strlen (args->temp_name) - 1;
- j = (int) strlen (new_name) - 1;
-
- if (args->temp_name[i] == '.')
- args->temp_name[i] = '\0';
- if (new_name[j] == '.')
- {
- new_name[j] = '\0';
- --j;
- }
-
- i = 0;
- k = is_arcmail (new_name, j);
- status_line ("%s: %s", MSG_TXT(M_FILE_RECEIVED), new_name);
- if ((!overwrite) || k)
- {
- while (rename (args->temp_name, new_name))
- {
- if (isdigit (new_name[j]))
- new_name[j]++;
- else new_name[j] = '0';
- if (!isdigit (new_name[j]))
- {
- return;
- }
- i = 1;
- }
- CLEAR_IOERR ();
- }
- else
- {
- (void) unlink (new_name);
- while (rename (args->temp_name, new_name))
- {
- if (!i)
- {
- status_line (MSG_TXT(M_ORIGINAL_NAME_BAD), new_name);
- }
- if (isdigit (new_name[j]))
- new_name[j]++;
- else new_name[j] = '0';
- if (!isdigit (new_name[j]))
- {
- return;
- }
- i = 1;
- }
- CLEAR_IOERR ();
- }
- if (i)
- {
- if (locate_y && !(fullscreen && un_attended))
- gotoxy (2, locate_y - 1);
- status_line (MSG_TXT(M_RENAME_MSG), new_name);
- }
- }
-
- remove_abort (Abortlog_name, args->received_name);
- }
- else
- {
- if ((args->received_name != NULL) && (strlen (args->received_name) > 0) && (args->save_header != 0))
- {
- (void) sprintf (Resume_info, "%ld %lo", args->filelen, args->save_filetime.oneword.timedate);
- add_abort (Abortlog_name, args->received_name, args->temp_name, args->path, Resume_info);
- }
- else
- {
- /* File aborted, so remove all traces of it */
- if (args->temp_name != NULL)
- (void) unlink (args->temp_name);
- }
- }
-
- if (args->temp_name != NULL) {
- free (args->temp_name);
- }
- }
-
- void Get_Telink_Info (XMARGSP args)
- {
- char *p1;
- char junkbuff[100];
- TLDATAP t;
- unsigned int i, j;
- struct tm tmstruc;
- time_t curr_time;
-
- /* Figure out how many blocks we will get */
- t = (TLDATAP) &(args->header);
- args->total_blocks = (t->filelength + 127)/ 128;
- t->nullbyte = '\0';
- p1 = strchr (t->filename, ' ');
- if (p1 != NULL)
- *p1 = '\0';
- (void) strcpy (args->received_name, t->filename);
- args->save_header = args->header;
- if (args->save_header == SYN)
- {
- i = t->filetime.twowords.time;
- j = t->filetime.twowords.date;
-
- curr_time = time (NULL);
- tmstruc = *localtime (&curr_time); /* Structure assignment */
-
- tmstruc.tm_year = (j >> 9) + 70;
- tmstruc.tm_mon = (j >> 5) & 0x0f;
- tmstruc.tm_mday = j & 0x1f;
-
- tmstruc.tm_hour = i >> 11;
- tmstruc.tm_min = (i >> 5) & 0x3f;
- tmstruc.tm_sec = i & 0x1f;
-
- args->save_filetime.oneword.timedate = mktime (&tmstruc);
- }
- else
- {
- args->save_filetime.oneword.timedate = t->filetime.oneword.timedate;
- }
- args->filelen = t->filelength;
- (void) sprintf (junkbuff, MSG_TXT(M_RECEIVE_MSG),
- args->total_blocks, t->filename, t->sendingprog, t->filelength);
-
- (void) strncpy (args->sending_program, t->sendingprog, 15);
- if (un_attended && fullscreen)
- {
- clear_filetransfer ();
- sb_move (file_hWnd, 1, 2);
- FlLnModeSet (FILE_LN_2, 1);
- sb_puts( GetDlgItem (file_hWnd, FILE_LN_1), junkbuff );
- elapse_time ();
- sb_show ();
- }
- else
- {
- status_line ("+%s", junkbuff);
- (void) printf ("\n");
- locate_y = wherey ();
- locate_x = wherex ();
- }
- }
-
- int Read_Block (XMARGSP args)
- {
- unsigned char *p; /* Pointers to XMODEM data */
- int i; /* Counter */
- int j; /* Counter start */
- unsigned char c; /* character being processed */
- int in_char;
- char junkbuff[128];
- long head_timer;
-
- struct _pkthdr *packet; /* FTS-0001 packet type */
- struct _pkthdr45 *pkt0045; /* FSC-0045 packet type */
- struct _pkthdr39 *pkt0039; /* FSC-0039 packet type */
-
- unsigned int cwtest; /* Used to verify FSC-0039 type */
-
- if (got_ESC ())
- {
- status_line (MSG_TXT(M_KBD_MSG));
- return (KBD_ERR);
- }
-
- /* Set up to point into the XMODEM data structure */
- p = (unsigned char *) &(args->header);
-
- /* Get the first character that is waiting */
- *p = (unsigned char) TIMED_READ (8);
-
- head_timer = timerset (6000);
- j = 1;
- while (!timeup (head_timer))
- {
- /* Now key off of the header character */
- switch (*p)
- {
- case EOT: /* End of file */
- /* Is this a valid EOT */
- if (args->total_blocks <= args->WriteBLK)
- {
- return (EOT_BLOCK);
- }
- else
- {
- status_line (MSG_TXT(M_UNEXPECTED_EOF), args->total_blocks);
- return (BAD_BLOCK);
- }
-
- case SYN: /* Telink block */
- /* For Telink, read all of the data except the checksum */
- for (i = 1; i < sizeof (TLDATA) - 2; i++)
- {
- /* If we go more than 5 second, then we have a short block */
- if ((in_char = TIMED_READ (5)) < 0)
- {
- return (BAD_BLOCK);
- }
- *(++p) = (unsigned char) (in_char & 0xff);
- }
-
- /* if the block number or its complement are wrong, return error */
- if ((args->block_num != 0) || (args->block_num_comp != 0xff))
- {
- return (BAD_BLOCK);
- }
-
- /* Now calculate the checksum - Telink block always checksum mode */
- Data_Check ((XMDATAP) &(args->header), CHECKSUM);
-
- /* See if we can receive the checksum byte */
- if ((in_char = TIMED_READ (10)) < 0)
- {
- Xmodem_Error (MSG_TXT(M_TIMEOUT), 0L);
- return (BAD_BLOCK);
- }
-
- /* Was it right */
- c = (unsigned char) (in_char & 0xff);
- if (c != args->data_check[0])
- {
- Xmodem_Error (MSG_TXT(M_CHECKSUM), 0L);
- return (BAD_BLOCK);
- }
- /* Everything looks good, it must be a legal TELINK block */
-
- Get_Telink_Info (args);
- return (TELINK_BLOCK);
-
- case SOH: /* Normal data block */
- args->datalen = 128;
- /* Read in all of the data for an XMODEM block except the checksum */
- p += (j - 1);
- for (i = j; i < sizeof (XMDATA) - 2; i++)
- {
- /* If we go more than 5 seconds, then it is a short block */
- if ((in_char = TIMED_READ (5)) < 0)
- {
- return (BAD_BLOCK);
- }
- *(++p) = (unsigned char) (in_char & 0xff);
- }
-
- /* The block number is 0 to 255 inclusive */
- c = (unsigned char) (args->blocknum & 0xff);
-
- /* Properly calculate the CRC or checksum */
- Data_Check ((XMDATAP) &(args->header), args->options.do_CRC ? CRC : CHECKSUM);
-
- /* Can we get the checksum byte */
- if ((in_char = TIMED_READ (10)) < 0)
- {
- Xmodem_Error (MSG_TXT(M_TIMEOUT), args->WriteBLK);
- return (BAD_BLOCK);
- }
-
- /* Is it the right value */
- c = (unsigned char) (in_char & 0xff);
- if (c != args->data_check[0])
- {
- status_line (">Xmodem Receive: Bad %s", (args->options.do_CRC)?"CRC":"checksum");
- Xmodem_Error (MSG_TXT(M_CRC_MSG), args->WriteBLK);
- if (args->options.do_CRC)
- (void) TIMED_READ (5);
- return (BAD_BLOCK);
- }
-
- /* If we are in CRC mode, do the second byte */
- if (args->options.do_CRC)
- {
- /* Can we get the character */
- if ((in_char = TIMED_READ (10)) < 0)
- {
- status_line (">Xmodem Receive: Timeout waiting for CRC byte 2");
- Xmodem_Error (MSG_TXT(M_TIMEOUT), args->WriteBLK);
- return (BAD_BLOCK);
- }
- /* Is it right */
- c = (unsigned char) (in_char & 0xff);
- if (c != args->data_check[1])
- {
- Xmodem_Error (MSG_TXT(M_CRC_MSG), args->WriteBLK);
- return (BAD_BLOCK);
- }
- }
-
- /* Do we have a valid data block */
- if (args->block_num_comp != (unsigned char)((~(args->block_num)) & 0xff))
- {
- if (!(args->options.SEAlink))
- {
- Xmodem_Error (MSG_TXT(M_JUNK_BLOCK), args->WriteBLK);
- return (BAD_BLOCK);
- }
-
- p = (unsigned char *) &(args->header);
- j = Header_in_data (p);
- if (j)
- {
- continue;
- }
-
- j = 1;
- Find_Char (SOH);
- *p = (unsigned char) TIMED_READ (0);
- }
-
- if ((args->WriteBLK == 1) && (args->header == SOH) && (args->block_num == 0))
- {
- Get_Telink_Info (args);
- return (SEALINK_BLOCK);
- }
-
- if (first_block)
- {
- packet = (struct _pkthdr *) args->data;
- pkt0045 = (struct _pkthdr45 *) packet;
- pkt0039 = (struct _pkthdr39 *) packet;
-
- if (!remote_capabilities)
- {
- remote_addr.Net = packet->orig_net;
- remote_addr.Node = packet->orig_node;
- if (packet->rate == 2)
- {
- /* This is a FSC-0045 (type 2.2) packet! */
- remote_addr.Zone = packet->orig_zone;
- remote_addr.Point = (unsigned) pkt0045->orig_point;
-
- strncpy (junkbuff, (char *)(pkt0045->orig_domain), 8);
- junkbuff[8] = '\0';
- remote_addr.Domain = find_domain (junkbuff);
- }
- else
- {
- remote_addr.Domain = NULL;
- cwtest = (((pkt0039->CapValid) & 0x7f00) >> 8) +
- (((pkt0039->CapValid) & 0x007f) << 8);
- if (cwtest == (unsigned int)((pkt0039->CapWord) & 0x7f7f))
- {
- /* This is a FSC-0039 packet! */
- remote_addr.Zone = pkt0039->orig_zone;
- remote_addr.Point = pkt0039->orig_point;
- }
- else
- {
- remote_addr.Zone = packet->orig_zone;
- remote_addr.Point = 0;
- }
- }
- /*
- * Here we have extracted the Zone, Net, Node, Point and Domain from the
- * packet -- regardless of type. Now see if we need to map to a fake net
- * or to mung the address because it's someone else's point.
- */
- if ((remote_addr.Point > 0) &&
- (pvtnet >= 0) &&
- ((remote_addr.Zone == alias[assumed].Zone) || (remote_addr.Zone == 0)) &&
- (remote_addr.Net == boss_addr.Net) &&
- (remote_addr.Node == boss_addr.Node))
- {
- remote_addr.Net = pvtnet;
- remote_addr.Node = remote_addr.Point;
- remote_addr.Point = 0;
- }
- else if ((pvtnet >= 0) && (remote_addr.Point > 0))
- {
- remote_addr.Point = 0;
- remote_addr.Node = -1;
- }
- }
-
- if (who_is_he)
- {
- if (!remote_addr.Zone && !remote_addr.Net && !remote_addr.Node)
- {
- LOWER_DTR (); /* Bad trip, cut it off */
- timer (2); /* Wait two secs */
- return(CARRIER_ERR); /* Get out of here! */
- }
-
- if (nodefind (&remote_addr, 1))
- {
- if (!remote_addr.Zone)
- remote_addr.Zone = found_zone;
-
- (void) sprintf (junkbuff, "%s: %s (%s)",
- MSG_TXT(M_REMOTE_SYSTEM),
- newnodedes.SystemName,
- Full_Addr_Str (&remote_addr));
- }
- else
- {
- (void) sprintf (junkbuff, "%s: %s (%s)",
- MSG_TXT(M_REMOTE_SYSTEM),
- MSG_TXT(M_UNKNOWN_MAILER),
- Full_Addr_Str (&remote_addr));
- }
-
- last_type (2, &remote_addr);
- status_line (junkbuff);
- }
- if (args->sending_program[0] != '\0')
- {
- status_line ("%s %s", MSG_TXT(M_REMOTE_USES), args->sending_program);
- }
- else
- {
- log_product (packet->product, 0, packet->serial);
- }
- who_is_he = 0;
- first_block = 0;
- }
-
- if (args->WriteBLK == args->total_blocks)
- {
- args->datalen = (int) (args->filelen - ((args->WriteBLK - 1) * 128));
- }
-
- /* If we got this far, it is a valid data block */
- args->recblock = args->block_num;
- return (XMODEM_BLOCK);
-
- default: /* Bad block */
- if ((args->blocknum <= 1) || (PEEKBYTE () < 0))
- return (BAD_BLOCK);
-
- /* Garbage header, return bad */
- *p = (unsigned char) TIMED_READ (0);
- }
- }
- return (BAD_BLOCK);
- }
-
- int XRInit (XMARGSP args, int start_state)
- {
- char *HoldName;
-
- args->tries = 0;
- args->goodfile = 1;
- XON_DISABLE ();
- HoldName = HoldAreaNameMunge(&called_addr);
- (void) sprintf (Abortlog_name, "%s%s.Z\0",
- HoldName, Hex_Addr_Str (&remote_addr));
- args->sending_program[0] = '\0';
- return (start_state);
- }
-
- int XREnd (XMARGSP args, int cur_state)
- {
- args->result = cur_state;
- Finish_Xmodem_Receive (args);
- return (cur_state);
- }
-
- int XRRecInit (XMARGSP args)
- {
- args->options.SEAlink = 0;
- args->options.SLO = 0;
- args->options.Resync = 0;
- args->options.MacFlow = 0;
- args->options.do_CRC = 1;
- args->blocknum = 0;
- args->WriteBLK = 1;
- args->curr_byte = 0L;
- args->tries = 0;
- return (XR1);
- }
-
- int XRBrecInit (XMARGSP args)
- {
- args->options.SEAlink = 0;
- args->options.SLO = 0;
- args->options.Resync = 0;
- args->options.MacFlow = 0;
- args->options.do_CRC = 1;
- args->blocknum = 0;
- args->WriteBLK = 1;
- args->curr_byte = 0L;
- args->tries = 0;
- return (XR2);
- }
-
- int XRRecStart (XMARGSP args)
- {
- Send_NAK (args);
- return (XR2);
- }
-
- int XRWaitFirst (XMARGSP args)
- {
- long XR2Timer;
-
- XR2Timer = timerset (800);
- if (args->tries >= 10)
- {
- args->goodfile = 0;
- return (TIME_ERR);
- }
- if (args->tries == 5)
- {
- args->options.do_CRC = 0;
- ++(args->tries);
- return (XR1);
- }
-
- while (CARRIER)
- {
- switch (Read_Block (args))
- {
- case EOT_BLOCK:
- args->WriteBLK = 0;
- Send_ACK (args);
- return (SUCCESS_EOT);
-
- case TELINK_BLOCK:
- if (Open_Xmodem_File (args) == -1L)
- return (OPEN_ERR);
- Send_ACK (args);
- args->tries = 0;
- return (XR3);
-
- case SEALINK_BLOCK:
- args->options.SEAlink = no_sealink ? 0 : 1;
- if (args->options.SEAlink && !no_resync)
- args->options.Resync = (((SEADATAP) (&(args->header)))->Resync) != 0;
- return (XR4);
-
- case XMODEM_BLOCK:
- if (args->recblock == 1)
- {
- if (Open_Xmodem_File (args) == -1L)
- return (OPEN_ERR);
- (void) fwrite (args->data, sizeof (unsigned char), args->datalen, args->file_pointer);
- ++(args->WriteBLK);
- args->curr_byte = 128L;
- ++(args->blocknum);
- Send_ACK (args);
- args->tries = 0;
- return (XR3);
- }
-
- /* Fallthrough on wrong block */
-
- case BAD_BLOCK:
- ++(args->tries);
- return (XR1);
-
- case CARRIER_ERR:
- case KBD_ERR:
- return (CARRIER_ERR);
- }
-
- if (timeup (XR2Timer))
- {
- ++(args->tries);
- return (XR1);
- }
- }
-
- return (CARRIER_ERR);
- }
-
- int XRWaitBlock (XMARGSP args)
- {
- int blocknum_copy;
-
- if (args->tries >= 10)
- {
- args->goodfile = 0;
- return (TIME_ERR);
- }
-
- while (CARRIER)
- {
- switch (Read_Block (args))
- {
- case EOT_BLOCK:
- args->options.SLO = 0;
- Send_ACK (args);
- return (SUCCESS);
-
- case XMODEM_BLOCK:
-
- blocknum_copy = (int)args->blocknum & 0xff;
-
- if (args->recblock == ((blocknum_copy - 1) & 0xff))
- {
- --(args->blocknum);
- Send_ACK (args);
- return (XR3);
- }
-
- if (args->recblock == blocknum_copy)
- {
- (void) fwrite (args->data, sizeof (unsigned char), args->datalen, args->file_pointer);
- ++(args->WriteBLK);
- args->curr_byte += 128L;
- Send_ACK (args);
- args->tries = 0;
- return (XR3);
- }
-
- if (args->recblock < blocknum_copy)
- {
- args->recblock += 256;
- }
-
- if ((args->recblock > blocknum_copy) && (args->recblock <= ((blocknum_copy + 127) & 0xff)))
- {
- if (args->tries != 0)
- {
- /* We have sent at least one nak, now only send them
- every so often to allow buffers to drain */
- if ((args->recblock - blocknum_copy) % 16)
- return (XR3);
-
- /* If it is a multiple of 16, then check that it is
- higher than 32 */
- if ((args->recblock - blocknum_copy) / 16 < 2)
- return (XR3);
- }
- }
-
- /* fallthrough on bad block */
-
- case BAD_BLOCK:
- Send_NAK (args);
- ++(args->tries);
- return (XR3);
-
- case CARRIER_ERR:
- case KBD_ERR:
- return (CARRIER_ERR);
- }
- }
-
- return (CARRIER_ERR);
- }
-
- int XRRestart (XMARGSP args)
- {
- long c;
-
- c = Set_Up_Restart (args);
- if (c == -1L)
- return (OPEN_ERR);
-
- if ((!c) || (!(args->options.Resync)))
- {
- Send_ACK (args);
- args->tries = 0;
- }
- else
- {
- args->WriteBLK = c;
- args->curr_byte = (c - 1) * 128L;
- args->blocknum = (unsigned char) ((args->WriteBLK) & 0xff);
- Send_NAK (args);
- }
-
- return (XR5);
- }
-
- int XRSetOvrdr (XMARGSP args)
- {
- if (!no_overdrive)
- args->options.SLO = (((SEADATAP) (&(args->header)))->SLO) != 0;
-
- if (args->options.SLO)
- show_block ((long) (args->WriteBLK - 1), " *Overdrive*", args);
-
- return (XR3);
- }
-
- int Xmodem_Receive_File (char *path, char *filename)
- {
- XMARGS xmfile;
- int res;
-
- locate_y = wherey ();
- locate_x = wherex ();
- (void) memset (&xmfile, 0, sizeof (XMARGS));
- xmfile.path = path;
- xmfile.filename = filename;
- xmfile.total_blocks = -1L;
- xmfile.sent_ACK = 0;
- res = state_machine (Xmodem_Receiver, &xmfile, XR0);
- return (res);
- }
-
- int Batch_Xmodem_Receive_File (char *path, char *filename)
- {
- XMARGS xmfile;
- int res;
-
- locate_y = wherey ();
- locate_x = wherex ();
- (void) memset (&xmfile, 0, sizeof (XMARGS));
- xmfile.path = path;
- xmfile.filename = filename;
- xmfile.total_blocks = -1L;
- xmfile.sent_ACK = 0;
- res = state_machine (Xmodem_Receiver, &xmfile, XR0B);
- return (res);
- }
-
- int SAInit (XMARGSP, int);
- int SAEnd (XMARGSP, int);
- int SAClearLine (XMARGSP);
- int SASendACK (XMARGSP);
- int SASEAlink (XMARGSP);
- int SAIncBlk (XMARGSP);
-
- STATES ACK_States[] = {
- { "SAInit", SAInit },
- { "SAEnd", SAEnd },
- { "SA0", SAClearLine },
- { "SA1", SASendACK },
- { "SA2", SASEAlink },
- { "SA3", SAIncBlk }
- };
-
- int SAInit (XMARGSP args, int start_state)
- {
- happy_compiler = args->tries; /* Makes the compiler happy! */
- return (start_state);
- }
-
- int SAEnd (XMARGSP args, int cur_state)
- {
- happy_compiler = args->tries; /* Makes the compiler happy! */
- return (cur_state);
- }
-
- int SAClearLine (XMARGSP args)
- {
- long SA0Timer;
-
- SA0Timer = timerset (3000);
- if (args->options.SLO)
- return (SA3);
-
- if (args->options.SEAlink)
- return (SA1);
-
- while (CARRIER && !timeup (SA0Timer))
- {
- if (PEEKBYTE () >= 0)
- {
- (void) TIMED_READ (0);
- time_release ();
- continue;
- }
-
- return (SA1);
- }
-
- return (TIME_ERR);
- }
-
- int SASendACK (XMARGSP args)
- {
- SENDBYTE (ACK);
- args->sent_ACK = 1;
- return (SA2);
- }
-
- int SASEAlink (XMARGSP args)
- {
- if (!(args->options.SEAlink))
- return (SA3);
-
- SENDBYTE (args->blocknum);
- SENDBYTE ((unsigned char)~(args->blocknum));
- return (SA3);
- }
-
- void show_block (long b, char *c, XMARGSP args)
- {
- char j[100];
- int i;
- long k;
-
- if (fullscreen && un_attended)
- {
- elapse_time();
-
- sb_move (file_hWnd, 2, 2);
- sb_puts( GetDlgItem (file_hWnd, FILE_LN_2 + GD_STATUS),
- ultoa (((unsigned long) b), e_input, 10));
- if (c)
- sb_puts( GetDlgItem (file_hWnd, FILE_LN_2 + GD_STATUS), c );
-
- k = args->filelen - args->curr_byte;
- if (k < 0L)
- k = 0L;
-
- i = (int) ((k * 10 / cur_baud.rate_value * 100 /
- ((args->save_header == SOH) ? 94 : 70) + 59) / 60);
- (void) sprintf (j, "%3d min", i);
-
- sb_move (file_hWnd, 2, 69);
- sb_puts( GetDlgItem (file_hWnd, FILE_LN_2 + GD_STATUS), j );
- sb_show ();
- }
- else
- {
- gotoxy (locate_x, locate_y);
- (void) printf ("%s", ultoa (((unsigned long) b), e_input, 10));
- if (c)
- (void) printf ("%s", c);
- }
- }
-
- int SAIncBlk (XMARGSP args)
- {
- ++(args->blocknum);
- if ((args->options.SLO) &&
- (((args->WriteBLK > 0) && (!((args->WriteBLK - 1) & 0x001F)) && (args->WriteBLK < args->total_blocks)) ||
- (args->WriteBLK >= args->total_blocks)))
- {
- show_block ((long) (args->WriteBLK - 1), " *Overdrive*", args);
- }
- else if ((!(args->options.SLO)) && (args->WriteBLK > 0))
- {
- show_block ((long) (args->WriteBLK - 1), NULL, args);
- }
-
- return (SUCCESS);
- }
-
- void Send_ACK (XMARGSP args)
- {
- (void) state_machine (ACK_States, args, SA0);
- }
-
- void Send_Resync_Packet (XMARGSP);
-
- int SNInit (XMARGSP, int);
- int SNEnd (XMARGSP, int);
- int SNClearLine (XMARGSP);
- int SNSendNAK (XMARGSP);
- int SNSEAlink (XMARGSP);
- int SNAckResync (XMARGSP);
-
- STATES NAK_States[] = {
- { "SNInit", SNInit },
- { "SNEnd", SNEnd },
- { "SN0", SNClearLine },
- { "SN1", SNSendNAK },
- { "SN2", SNSEAlink },
- { "SN3", SNAckResync }
- };
-
- int SNInit (XMARGSP args, int start_state)
- {
- happy_compiler = args->tries; /* Makes the compiler happy! */
- return (start_state);
- }
-
- int SNEnd (XMARGSP args, int cur_state)
- {
- happy_compiler = args->tries; /* Makes the compiler happy! */
- return (cur_state);
- }
-
- int SNClearLine (XMARGSP args)
- {
- long SN0Timer;
-
- SN0Timer = timerset (3000);
- if (args->options.Resync)
- {
- Send_Resync_Packet (args);
- return (SN3);
- }
-
- if (args->options.SEAlink)
- return (SN1);
-
- while (CARRIER && !timeup (SN0Timer))
- {
- if (PEEKBYTE () >= 0)
- {
- (void) TIMED_READ (0);
- time_release ();
- continue;
- }
-
- return (SN1);
- }
-
- return (TIME_ERR);
- }
-
- int SNSendNAK (XMARGSP args)
- {
- if (args->options.do_CRC && (args->sent_ACK == 0))
- SENDBYTE (WANTCRC);
- else
- SENDBYTE (NAK);
- return (SN2);
- }
-
- int SNSEAlink (XMARGSP args)
- {
- if (!(args->options.SEAlink))
- return (SUCCESS);
-
- SENDBYTE (args->blocknum);
- SENDBYTE ((unsigned char)~(args->blocknum));
- return (SUCCESS);
- }
-
- int SNAckResync (XMARGSP args)
- {
- long SN3Timer;
- int c;
-
- SN3Timer = timerset (3000);
-
- while (CARRIER && !timeup (SN3Timer))
- {
- if ((unsigned int)(c = TIMED_READ (10)) == 0xffff)
- {
- Send_Resync_Packet (args);
- continue;
- }
-
- if (c == ACK)
- {
- big_pause (1);
- c = PEEKBYTE();
- if ((c == SOH) || (c == EOT))
- return (SUCCESS);
- }
- }
-
- if (!CARRIER)
- return (CARRIER_ERR);
- else
- return (TIME_ERR);
- }
-
- void Send_NAK (XMARGSP args)
- {
- (void) state_machine (NAK_States, args, SN0);
- }
-
- void Send_Resync_Packet (XMARGSP args)
- {
- unsigned char resyncit[30];
- unsigned int nak_crc;
-
- SENDBYTE (SYN);
- (void) sprintf ((char *) resyncit, "%ld", args->WriteBLK);
- SENDCHARS ((char *) resyncit, strlen ((char *) resyncit), 1);
- nak_crc = crc_block ((unsigned char *) resyncit, (int) strlen ((char *) resyncit));
- SENDBYTE (ETX);
- SENDBYTE ((unsigned char) (nak_crc & 0xff));
- CLEAR_INBOUND ();
- SENDBYTE ((unsigned char) (nak_crc >> 8));
- }
-
- void Xmodem_Error (char *s, long block_number)
- {
- char j[50];
- char k[50];
-
- (void) sprintf (j, "%s %s %ld", s, MSG_TXT(M_ON_BLOCK), block_number);
- (void) sprintf (k, "%-49.49s", j);
-
- status_line (">Xmodem Error: %s", k);
- if (fullscreen && un_attended)
- {
- sb_move (file_hWnd, 2, 20);
- sb_puts( GetDlgItem (file_hWnd, FILE_LN_2 + GD_SIZE), k );
- sb_show ();
- }
- else
- {
- gotoxy (locate_x + 20, locate_y);
- (void) cputs (k);
- }
- }
-
- void Find_Char (int c)
- {
- long t1;
- long t2;
-
- t1 = timerset (3000);
- t2 = timerset (100);
- while (!timeup (t1) && !timeup (t2))
- {
- if (!CARRIER)
- break;
-
- if (PEEKBYTE () == (c & 0xff))
- break;
- else if (PEEKBYTE () >= 0)
- {
- (void) TIMED_READ (0);
- t2 = timerset (100);
- }
- }
- }
-
- int Header_in_data (unsigned char *p)
- {
- int i;
- int j;
- char *p1;
-
- p1 = (char *) p;
- ++p1;
- j = sizeof (XMDATA) - 2;
- for (i = 1; i < j; i++, p1++)
- {
- if (*p1 == SOH)
- {
- (void) memcpy (p, p1, (unsigned int) (j - i));
- return (j - i);
- }
- }
-
- return (0);
- }
-