You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
753 lines
17 KiB
753 lines
17 KiB
/* mdmx_snd.c -- Routines to handle xmodem sending for HA5G
|
|
*
|
|
* Copyright 1989 by Hilgraeve Inc. -- Monroe, MI
|
|
* All rights reserved
|
|
*
|
|
* $Revision: 9 $
|
|
* $Date: 4/24/02 3:49p $
|
|
*/
|
|
#include <windows.h>
|
|
#include <stdlib.h>
|
|
|
|
#pragma hdrstop
|
|
// #include <setjmp.h>
|
|
|
|
#define BYTE unsigned char
|
|
|
|
#include <tdll\mc.h>
|
|
#include <tdll\stdtyp.h>
|
|
#include <tdll\com.h>
|
|
#include <tdll\assert.h>
|
|
#include <tdll\session.h>
|
|
#include <tdll\load_res.h>
|
|
#include <tdll\xfer_msc.h>
|
|
#include <tdll\file_io.h>
|
|
#include <tdll\htchar.h>
|
|
#include "xfr_srvc.h"
|
|
#include "xfr_todo.h"
|
|
#include "xfr_dsp.h"
|
|
#include "xfer_tsc.h"
|
|
#include "foo.h"
|
|
|
|
#include "cmprs.h"
|
|
|
|
#include "xfer.h"
|
|
#include "xfer.hh"
|
|
|
|
#include "mdmx.h"
|
|
#include "mdmx.hh"
|
|
|
|
#if !defined(STATIC_FUNC)
|
|
#define STATIC_FUNC
|
|
#endif
|
|
|
|
#if !defined(CMPRS_MINSIZE)
|
|
#define CMPRS_MINSIZE 4000L
|
|
#endif
|
|
|
|
/* * * * * * * * * * * * * * * *
|
|
* local function prototypes *
|
|
* * * * * * * * * * * * * * * */
|
|
|
|
STATIC_FUNC int xsend_start(ST_MDMX *xc, BYTE *start_chars, int *start_char);
|
|
|
|
STATIC_FUNC int getresponse(ST_MDMX *xc, int time);
|
|
|
|
STATIC_FUNC void make_file_pckt(ST_MDMX *xc,
|
|
struct s_mdmx_pckt *p,
|
|
char *fname,
|
|
long size);
|
|
|
|
/* * * * * * * *
|
|
* Functions *
|
|
* * * * * * * */
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* mdmx_snd
|
|
*
|
|
* DESCRIPTION:
|
|
* Sends a file using XMODEM or YMODEM protocol. Support 1k packets, batch
|
|
* transfers and 'G' option streaming.
|
|
*
|
|
* ARGUMENTS:
|
|
* attended -- TRUE if user is probably in attendance. Controls the display
|
|
* of some messages.
|
|
*
|
|
* RETURNS:
|
|
* True if transfer completes successfully, FALSE otherwise.
|
|
*/
|
|
int mdmx_snd(HSESSION hSession, int attended, int method, unsigned nfiles, long nbytes)
|
|
{
|
|
ST_MDMX *xc;
|
|
struct s_mdmx_pckt * this_pckt = NULL;
|
|
struct s_mdmx_pckt * next_pckt = NULL;
|
|
struct s_mdmx_pckt * tpckt;
|
|
|
|
/* column values for display box */
|
|
TCHAR sfname[FNAME_LEN];// file name of file being sent
|
|
TCHAR xname[FNAME_LEN]; // transmitted file name
|
|
int still_trying; // controls exit from main transfer loop
|
|
int got_file; // controls when to complete batch op
|
|
int got_response; // controls loop to get valid response
|
|
int tries = 0; // number of retries for each packet
|
|
unsigned total_tries; // number of retries for entire transfer
|
|
int response; // response char. received from other end
|
|
BYTE start_chars[3]; // acceptable start chars. from receiver
|
|
int xstatus = TSC_OK; // winds up with overall status of transfer
|
|
int check_type; // type of error checking in use
|
|
unsigned pcktn; // number of packet currently being sent
|
|
int override = FALSE; // set TRUE if comm. details changed to
|
|
unsigned int uiOldOptions;
|
|
int batch; // TRUE if YMODEM batch transfers used
|
|
int big_pckts; // TRUE if 1K packets are allowed
|
|
int streaming; // TRUE if no packet responses expected
|
|
|
|
if (xfer_set_comport(hSession, TRUE, &uiOldOptions) != TRUE)
|
|
{
|
|
goto done;
|
|
}
|
|
else
|
|
{
|
|
override = TRUE;
|
|
}
|
|
|
|
/* set up options based on method used */
|
|
big_pckts = (method != XF_XMODEM);
|
|
batch = (method == XF_YMODEM || method == XF_YMODEM_G);
|
|
streaming = FALSE; /* will be turned on if receiver starts with 'G' */
|
|
// assert(nfiles == 1 || batch);
|
|
|
|
this_pckt = NULL;
|
|
next_pckt = NULL;
|
|
|
|
xc = malloc(sizeof(ST_MDMX));
|
|
if (xc == NULL)
|
|
{
|
|
goto done;
|
|
}
|
|
memset(xc, 0, sizeof(ST_MDMX));
|
|
|
|
xc->hSession = hSession;
|
|
xc->hCom = sessQueryComHdl(hSession);
|
|
|
|
// RemoteClear(hSession);
|
|
ComRcvBufrClear(xc->hCom);
|
|
|
|
this_pckt = malloc(sizeof(ST_MDMX) +
|
|
(big_pckts ? LARGE_PACKET : SMALL_PACKET) + 2);
|
|
if (this_pckt == NULL)
|
|
{
|
|
goto done;
|
|
}
|
|
memset(this_pckt, 0, sizeof(ST_MDMX) +
|
|
(big_pckts ? LARGE_PACKET : SMALL_PACKET) + 2);
|
|
|
|
next_pckt = malloc(sizeof(ST_MDMX) +
|
|
(big_pckts ? LARGE_PACKET : SMALL_PACKET) + 2);
|
|
if (next_pckt == NULL)
|
|
{
|
|
goto done;
|
|
}
|
|
memset(next_pckt, 0, sizeof(ST_MDMX) +
|
|
(big_pckts ? LARGE_PACKET : SMALL_PACKET) + 2);
|
|
|
|
mdmxXferInit(xc, method); /* Could be smaller but this is easier */
|
|
if (xc->p_crc_tbl == NULL)
|
|
{
|
|
xstatus = TSC_NO_MEM;
|
|
goto done;
|
|
}
|
|
|
|
// hp_report_xtime(0); /* make invalid in case transfer bombs */
|
|
xc->file_bytes = 0L;
|
|
xc->total_bytes = 0L;
|
|
xc->fh = NULL;
|
|
xc->xfertimer = -1L;
|
|
xc->nfiles = nfiles; /* make these available to display routines */
|
|
xc->filen = 0;
|
|
xc->filesize = -1L;
|
|
xc->nbytes = nbytes;
|
|
|
|
mdmxdspTotalsize(xc, nbytes);
|
|
mdmxdspFilecnt(xc, nfiles);
|
|
|
|
xc->mdmx_byte_cnt = 0;
|
|
StrCharCopy(start_chars, (batch ? "CG" : "C\x15")); /* \x15 is NAK */
|
|
check_type = CRC;
|
|
mdmxdspChecktype(xc, (check_type == CRC) ? 0 : 1);
|
|
total_tries = 0;
|
|
mdmxdspErrorcnt(xc, total_tries);
|
|
tries = 0;
|
|
mdmxdspPacketErrorcnt(xc, tries);
|
|
got_file = TRUE;
|
|
while (got_file)
|
|
{
|
|
if ((got_file = xfer_nextfile(hSession, sfname)) == TRUE)
|
|
{
|
|
xc->total_bytes += xc->file_bytes;
|
|
xc->file_bytes = xc->mdmx_byte_cnt = 0L;
|
|
|
|
mdmxdspNewfile(xc,
|
|
xc->filen + 1,
|
|
sfname,
|
|
sfname);
|
|
|
|
++xc->filen;
|
|
|
|
if (xfer_opensendfile(hSession,
|
|
&xc->fh,
|
|
sfname,
|
|
&xc->filesize,
|
|
xname,
|
|
NULL) != 0)
|
|
{
|
|
xstatus = TSC_CANT_OPEN;
|
|
goto done;
|
|
}
|
|
mdmxdspFilesize(xc, xc->filesize);
|
|
}
|
|
else
|
|
{
|
|
// strblank(xname);
|
|
xname[0] = TEXT('\0');
|
|
}
|
|
|
|
pcktn = 0;
|
|
if (batch)
|
|
{
|
|
make_file_pckt(xc, this_pckt, xname, xc->filesize);
|
|
}
|
|
|
|
if ((xstatus = xsend_start(xc, start_chars, &response)) != TSC_OK)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (xc->filen <= 1)
|
|
{
|
|
xc->xfertimer = (long)startinterval(); /* start the clock */
|
|
if (response == NAK)
|
|
{
|
|
check_type = CHECKSUM;
|
|
}
|
|
mdmxdspChecktype(xc, (check_type == CRC) ? 0 : 1);
|
|
if (response == 'G')
|
|
{
|
|
streaming = TRUE;
|
|
mdmxdspChecktype(xc, 2);
|
|
}
|
|
|
|
/* once we've received the first start_char,
|
|
* subsequent ones must match
|
|
*/
|
|
start_chars[0] = (BYTE)response;
|
|
start_chars[1] = '\0';
|
|
}
|
|
|
|
|
|
if (got_file)
|
|
{
|
|
xc->p_getc = xm_getc;
|
|
tries = 0;
|
|
if (!batch &&
|
|
!load_pckt(xc, this_pckt, pcktn = 1, big_pckts, check_type))
|
|
{
|
|
xstatus = TSC_DISK_ERROR;
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
|
|
/* get the first pckt on its way while we prepare the second pckt */
|
|
if ( ComSndBufrSend(xc->hCom,
|
|
&this_pckt->start_char,
|
|
(unsigned)this_pckt->pcktsize,
|
|
SMALL_WAIT) == COM_PORT_NOT_OPEN )
|
|
{
|
|
xstatus = TSC_LOST_CARRIER;
|
|
still_trying = FALSE;
|
|
goto done;
|
|
}
|
|
|
|
mdmxdspPacketnumber(xc, pcktn);
|
|
|
|
/* load next pckt*/
|
|
if (got_file && !load_pckt(xc, next_pckt, ++pcktn, big_pckts, check_type))
|
|
{
|
|
xstatus = TSC_DISK_ERROR;
|
|
goto done;
|
|
}
|
|
|
|
still_trying = TRUE;
|
|
while (still_trying)
|
|
{
|
|
if (streaming)
|
|
{
|
|
/* these things are done in getresponse() if not streaming */
|
|
|
|
if (xfer_carrier_lost(hSession))
|
|
{
|
|
xstatus = TSC_LOST_CARRIER;
|
|
break;
|
|
}
|
|
|
|
if (xfer_user_interrupt(hSession))
|
|
{
|
|
xstatus = TSC_USER_CANNED;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* wait until last packet is out before watching for response */
|
|
ComSndBufrWait(xc->hCom,
|
|
this_pckt->pcktsize >= LARGE_PACKET ? LARGE_WAIT :
|
|
SMALL_WAIT);
|
|
|
|
/* get response from receiver */
|
|
got_response = FALSE;
|
|
while (!got_response)
|
|
{
|
|
response = (streaming && this_pckt->start_char != EOT) ?
|
|
ACK : getresponse(xc, 60);
|
|
|
|
got_response = TRUE;
|
|
|
|
switch(response)
|
|
{
|
|
case ACK:
|
|
if (this_pckt->start_char == EOT)
|
|
{
|
|
/* successful */
|
|
mdmx_progress(xc, FILE_DONE);
|
|
xc->xfertime = (long)interval(xc->xfertimer);
|
|
fio_close(xc->fh);
|
|
|
|
xfer_log_xfer(hSession,
|
|
TRUE,
|
|
sfname,
|
|
NULL,
|
|
TSC_OK);
|
|
|
|
xc->fh = NULL;
|
|
xstatus = TSC_OK;
|
|
still_trying = FALSE;
|
|
}
|
|
else
|
|
{
|
|
xc->file_bytes = this_pckt->byte_count;
|
|
tpckt = this_pckt;
|
|
this_pckt = next_pckt;
|
|
next_pckt = tpckt;
|
|
|
|
/* pcktn will only be <= 1 when batch is on and
|
|
* we've just sent the filename packet (packet 0)
|
|
*/
|
|
if (pcktn <= 1 && (!got_file ||
|
|
(xstatus = xsend_start(xc, start_chars, &response))
|
|
!= TSC_OK))
|
|
{
|
|
still_trying = FALSE;
|
|
break;
|
|
}
|
|
|
|
/* send packet */
|
|
|
|
if ( ComSndBufrSend(xc->hCom,
|
|
&this_pckt->start_char,
|
|
(unsigned)this_pckt->pcktsize,
|
|
SMALL_WAIT) == COM_PORT_NOT_OPEN)
|
|
{
|
|
xstatus = TSC_LOST_CARRIER;
|
|
still_trying = FALSE;
|
|
break;
|
|
}
|
|
|
|
mdmxdspPacketnumber(xc, pcktn);
|
|
|
|
mdmx_progress(xc, 0);
|
|
if (tries != 0)
|
|
{
|
|
mdmxdspPacketErrorcnt(xc, 0);
|
|
|
|
tries = 0;
|
|
}
|
|
if (this_pckt->start_char != EOT)
|
|
{
|
|
if (!load_pckt(xc, next_pckt, ++pcktn, big_pckts, check_type))
|
|
{
|
|
xstatus = TSC_DISK_ERROR;
|
|
still_trying = FALSE;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case NO_RESPONSE:
|
|
mdmxdspLastError(xc, 12);
|
|
still_trying = FALSE;
|
|
break;
|
|
|
|
case ABORTED:
|
|
xstatus = TSC_USER_CANNED;
|
|
still_trying = FALSE;
|
|
break;
|
|
|
|
case CARR_LOST:
|
|
xstatus = TSC_LOST_CARRIER;
|
|
still_trying = FALSE;
|
|
break;
|
|
|
|
case 'C':
|
|
case 'G':
|
|
/* these act as NAKs for packets first packets */
|
|
if (pcktn > 2)
|
|
{
|
|
got_response = FALSE;
|
|
break;
|
|
}
|
|
/* else fall through */
|
|
case NAK:
|
|
if (++tries >= xc->mdmx_tries)
|
|
{
|
|
xstatus = TSC_ERROR_LIMIT;
|
|
goto done;
|
|
}
|
|
else /* send packet */
|
|
{
|
|
if (ComSndBufrSend(xc->hCom,
|
|
&this_pckt->start_char,
|
|
(unsigned)this_pckt->pcktsize,
|
|
SMALL_WAIT) == COM_PORT_NOT_OPEN)
|
|
{
|
|
xstatus = TSC_LOST_CARRIER;
|
|
still_trying = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
if (this_pckt->start_char == EOT && tries == 1)
|
|
{
|
|
break; /* don't print first retransmission on final EOT */
|
|
}
|
|
mdmxdspPacketErrorcnt(xc, tries);
|
|
|
|
mdmxdspErrorcnt(xc, ++total_tries);
|
|
|
|
mdmxdspLastError(xc,
|
|
(response == NAK) ? 13 : 14);
|
|
|
|
break;
|
|
|
|
case CAN:
|
|
if (getresponse(xc, 1) == CAN) /* two consecutive CANs? */
|
|
{
|
|
xstatus = TSC_RMT_CANNED;
|
|
still_trying = FALSE;
|
|
break;
|
|
}
|
|
/* fall through */
|
|
|
|
default:
|
|
got_response = FALSE;
|
|
break;
|
|
}
|
|
|
|
} /* end while (!got_response) */
|
|
|
|
} /* end while(still_trying) */
|
|
|
|
if (!batch || xstatus != TSC_OK)
|
|
{
|
|
break;
|
|
}
|
|
|
|
} /* end while(got_file) */
|
|
|
|
done:
|
|
|
|
mdmx_progress(xc, TRANSFER_DONE);
|
|
|
|
mdmxdspCloseDisplay(xc);
|
|
|
|
// ComSendSetCharDelay(hld_send_cdelay, COMSEND_SETDELAY);
|
|
if (override)
|
|
{
|
|
#if FALSE
|
|
cnfg.bits_per_char = hld_bits_per_char;
|
|
cnfg.parity_type = hld_parity_type;
|
|
(void)(*ComResetPort)();
|
|
#endif
|
|
xfer_restore_comport(hSession, uiOldOptions);
|
|
}
|
|
|
|
if (xc == NULL || this_pckt == NULL || next_pckt == NULL)
|
|
{
|
|
xstatus = TSC_NO_MEM;
|
|
}
|
|
|
|
if (xc != NULL)
|
|
{
|
|
// hp_report_xtime((unsigned)xc->xfertime);
|
|
if (xc->fh)
|
|
{
|
|
fio_close(xc->fh);
|
|
}
|
|
|
|
if (xstatus != TSC_OK)
|
|
{
|
|
if (xstatus != TSC_RMT_CANNED && xstatus != TSC_NO_MEM)
|
|
{
|
|
for (tries = 5 + 1; --tries > 0; )
|
|
{
|
|
ComSendChar(xc->hCom, &xc->stP, CAN);
|
|
}
|
|
ComSendPush(xc->hCom, &xc->stP);
|
|
}
|
|
xfer_log_xfer(hSession,
|
|
TRUE,
|
|
sfname,
|
|
NULL,
|
|
xstatus);
|
|
}
|
|
|
|
#if FALSE
|
|
if (attended && xstatus != TSC_USER_CANNED && xstatus != TSC_NO_MEM)
|
|
{
|
|
menu_bottom_line (BL_ESC, 0L);
|
|
DosBeep(beepfreq, beeplen);
|
|
menu_replybox((int)xc->msgrow, ENTER_RESP, 0, (int)transfer_status_msg((unsigned short)xstatus));
|
|
}
|
|
#endif
|
|
|
|
if (xc->p_crc_tbl != NULL)
|
|
{
|
|
#if defined(DEADWOOD)
|
|
resFreeDataBlock(xc->hSession, xc->p_crc_tbl);
|
|
xc->p_crc_tbl = NULL;
|
|
#else // defined(DEADWOOD
|
|
//
|
|
// We don't need to free xc->p_crc_tbl since it is pointing
|
|
// to a static constant array. REV: 4/10/2002
|
|
//
|
|
xc->p_crc_tbl = NULL;
|
|
#endif // defined(DEADWOOD)
|
|
}
|
|
|
|
free(xc);
|
|
xc = NULL;
|
|
}
|
|
|
|
if (this_pckt)
|
|
{
|
|
free(this_pckt);
|
|
this_pckt = NULL;
|
|
}
|
|
|
|
if (next_pckt)
|
|
{
|
|
free(next_pckt);
|
|
next_pckt = NULL;
|
|
}
|
|
|
|
return((unsigned)xstatus);
|
|
}
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* xsend_start
|
|
*
|
|
* DESCRIPTION:
|
|
* Waits up to one minute for a start request from the receiver at the
|
|
* other end of the line.
|
|
*
|
|
* ARGUMENTS:
|
|
* chktype -- Pointer to a variable to be set to the requested error
|
|
* correction checking method, CRC or Checksum
|
|
*
|
|
* RETURNS:
|
|
* Status code indicating result. Can be one of
|
|
* TSC_USER_CANNED if user interrupted by hitting the ESC key.
|
|
* TSC_NO_RESPONSE if 60 seconds elapses without receiving a start char.
|
|
* TSC_RMT_CANNED if remote sends a control-C
|
|
* TSC_OK if remote sends proper start char.
|
|
*
|
|
*/
|
|
STATIC_FUNC int xsend_start(ST_MDMX *xc, BYTE *start_chars, int *start_char)
|
|
{
|
|
for ( ; ; )
|
|
{
|
|
switch(*start_char = getresponse(xc, 60))
|
|
{
|
|
case ABORTED:
|
|
return(TSC_USER_CANNED);
|
|
|
|
case NO_RESPONSE:
|
|
return(TSC_NO_RESPONSE);
|
|
|
|
case CARR_LOST:
|
|
return(TSC_LOST_CARRIER);
|
|
|
|
case ESC:
|
|
case '\003': /* control-C */
|
|
return(TSC_RMT_CANNED);
|
|
|
|
default:
|
|
if (strchr(start_chars, *start_char))
|
|
{
|
|
return(TSC_OK);
|
|
}
|
|
|
|
/* ignore any other char. */
|
|
break;
|
|
}
|
|
}
|
|
return TSC_OK;
|
|
}
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* getresponse
|
|
*
|
|
* DESCRIPTION:
|
|
* Waits a specified time for a response from the receiver. Can be forced
|
|
* to terminate early if user intervention is detected. No effort is made
|
|
* here to interpret the meaning of a response character. Any character
|
|
* received within the time limit will be returned.
|
|
*
|
|
* ARGUMENTS:
|
|
* time -- Number of seconds to wait for a response character.
|
|
*
|
|
* RETURNS:
|
|
* The response character if one was received or ABORTED or NO_RESPONSE or
|
|
* CARR_LOST.
|
|
*/
|
|
STATIC_FUNC int getresponse(ST_MDMX *xc, int time)
|
|
{
|
|
TCHAR rc = 0;
|
|
long timer;
|
|
|
|
DbgOutStr("getresponse ", 0,0,0,0,0);
|
|
|
|
#if FALSE
|
|
if (kbd_check_flagkey(xc->flagkey, TRUE) > 0)
|
|
{
|
|
kbd_flush();
|
|
return ABORTED;
|
|
}
|
|
#endif
|
|
if (xfer_user_interrupt(xc->hSession))
|
|
{
|
|
DbgOutStr("aborted\r\n", 0,0,0,0,0);
|
|
return ABORTED;
|
|
}
|
|
|
|
// if ((rc = RemoteGet(xc->hSession)) != -1)
|
|
if (mComRcvChar(xc->hCom, &rc) != 0)
|
|
{
|
|
DbgOutStr("returned %d\r\n", rc, 0,0,0,0);
|
|
return(rc & 0x7F);
|
|
}
|
|
|
|
time *= 10;
|
|
timer = (long)startinterval();
|
|
while ((long)interval(timer) < (long)time)
|
|
{
|
|
#if FALSE
|
|
if (kbd_check_flagkey(xc->flagkey, TRUE) > 0)
|
|
{
|
|
kbd_flush();
|
|
return ABORTED;
|
|
}
|
|
#endif
|
|
|
|
if (xfer_carrier_lost(xc->hSession))
|
|
{
|
|
DbgOutStr(" lost\r\n", 0,0,0,0,0);
|
|
return CARR_LOST;
|
|
}
|
|
|
|
if (xfer_user_interrupt(xc->hSession))
|
|
{
|
|
DbgOutStr("aborted\r\n", 0,0,0,0,0);
|
|
return ABORTED;
|
|
}
|
|
|
|
mdmx_progress(xc, 0);
|
|
|
|
if (mComRcvChar(xc->hCom, &rc) != 0)
|
|
{
|
|
DbgOutStr("returned %d\r\n", rc, 0,0,0,0);
|
|
return(rc & 0x7F);
|
|
}
|
|
|
|
xfer_idle(xc->hSession, XFER_IDLE_IO);
|
|
|
|
}
|
|
DbgOutStr(" none\r\n", 0,0,0,0,0);
|
|
return(NO_RESPONSE);
|
|
}
|
|
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* make_file_pckt
|
|
*
|
|
* DESCRIPTION: sets up the initial filename pckt for Ymodem (only)
|
|
*
|
|
* ARGUMENTS:
|
|
* p -- Pointer to the packet structure which receives the filename
|
|
* packet.
|
|
* fname -- The file name as it should be placed in the packet.
|
|
* size -- The size of the file as it should be placed in the packet.
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
STATIC_FUNC void make_file_pckt(ST_MDMX *xc,
|
|
struct s_mdmx_pckt *p,
|
|
char *fname,
|
|
long size)
|
|
{
|
|
BYTE sizestr[20];
|
|
BYTE *ptr;
|
|
BYTE *cp;
|
|
unsigned int crc;
|
|
|
|
p->start_char = SOH; /* set start char to SOH */
|
|
p->pcktnum = 0; /* set pcktnumber to 0 */
|
|
p->npcktnum = 0xff; /* set npcktnumber to 0xff */
|
|
ptr = p->bdata;
|
|
|
|
/* initialize data area with zeros */
|
|
memset(ptr, 0, SMALL_PACKET + 2);
|
|
|
|
if (*fname)
|
|
{
|
|
StrCharCopy(ptr, fname); /* copy filename into buffer*/
|
|
|
|
/* replace all back slashes with slashes */
|
|
//while (strreplace(ptr, FstrBslashBslash(), "/"))
|
|
// ;
|
|
for (cp = ptr; *cp != '\0'; cp += 1)
|
|
if (*cp == '\\') *cp = '/';
|
|
|
|
// StrFmt(sizestr, "%ld", size); /* format the file size */
|
|
wsprintf(sizestr, "%ld", (LONG)size);
|
|
|
|
StrCharCopy(&ptr[StrCharGetByteCount(ptr)+1], sizestr);
|
|
/* add it to buffer */
|
|
}
|
|
|
|
/* calculate CRC value */
|
|
ptr = &p->bdata[SMALL_PACKET]; /* set ptr to char after buffer */
|
|
/* calculate CRC */
|
|
crc = calc_crc(xc, (unsigned)0, p->bdata, SMALL_PACKET+2);
|
|
/* set the CRC */
|
|
*ptr++ = (BYTE)(crc / 0x100);
|
|
*ptr = (BYTE)(crc % 0x100);
|
|
/* set the packetsize */
|
|
p->pcktsize = SMALL_PACKET + 5;
|
|
p->byte_count = xc->mdmx_byte_cnt;
|
|
}
|
|
|
|
|
|
/*********************** end of mdmx_snd.c **************************/
|