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.
802 lines
18 KiB
802 lines
18 KiB
/* File: C:\WACKER\xfer\krm_snd.c (Created: 28-Jan-1994)
|
|
* created from HAWIN source code
|
|
* krm_snd.c -- Routines for handling file transmission using KERMIT
|
|
* file transfer protocol.
|
|
*
|
|
* Copyright 1989,1990,1991,1994 by Hilgraeve Inc. -- Monroe, MI
|
|
* All rights reserved
|
|
*
|
|
* $Revision: 5 $
|
|
* $Date: 7/11/02 11:10a $
|
|
*/
|
|
// #define DEBUGSTR 1
|
|
|
|
#include <windows.h>
|
|
#pragma hdrstop
|
|
|
|
#include <time.h>
|
|
#include <stdlib.h>
|
|
#include <sys\types.h>
|
|
#include <sys\utime.h>
|
|
|
|
#include <term\res.h>
|
|
#include <tdll\stdtyp.h>
|
|
#include <tdll\mc.h>
|
|
#include <tdll\assert.h>
|
|
#include <tdll\load_res.h>
|
|
#include <tdll\xfer_msc.h>
|
|
#include <tdll\globals.h>
|
|
#include <tdll\file_io.h>
|
|
#include <tdll\session.h>
|
|
#include <tdll\htchar.h>
|
|
#include <tdll\com.h>
|
|
|
|
#if !defined(BYTE)
|
|
#define BYTE unsigned char
|
|
#endif
|
|
|
|
#include "cmprs.h"
|
|
#include "itime.h"
|
|
#include "xfr_dsp.h"
|
|
#include "xfr_todo.h"
|
|
#include "xfr_srvc.h"
|
|
|
|
#include "xfer.h"
|
|
#include "xfer.hh"
|
|
#include "xfer_tsc.h"
|
|
|
|
#include "krm.h"
|
|
#include "krm.hh"
|
|
|
|
// unsigned total_retries;
|
|
// metachar (NEAR *p_kgetc)(void);
|
|
// long kbytes_sent = 0L;
|
|
// KPCKT FAR * this_kpckt;
|
|
// KPCKT FAR * next_kpckt;
|
|
|
|
/* local funtion prototypes */
|
|
void build_attributes(ST_KRM *kc,
|
|
unsigned char *bufr,
|
|
long size,
|
|
unsigned long ul_time);
|
|
|
|
int ksend_init(ST_KRM *kc);
|
|
int ksend_break(ST_KRM *kc);
|
|
int ksend_file(ST_KRM *kc, long fsize);
|
|
|
|
int wldindexx(const char *string,
|
|
const char FAR *substr,
|
|
char wildcard,
|
|
int ic);
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* krm_snd
|
|
*
|
|
* DESCRIPTION:
|
|
* send a file or files using kermit protocol
|
|
*
|
|
* This routine also handles logging of kermit sending operations to the
|
|
* optional log file.
|
|
*
|
|
* ARGUMENTS:
|
|
* attended -- TRUE if transfer is run manually, FALSE if run under automation
|
|
* such as in host or hyperpilot
|
|
* nfile -- number of files to be sent
|
|
* nbytes -- total number of bytes to be sent in all files
|
|
*
|
|
* RETURNS:
|
|
* Returns TRUE if all files are sent successfully or if all cancellations
|
|
* were user-requested, 'graceful' ones. Returns FALSE if an error occurs
|
|
* at either end of transfer or if user forces an immediate exit.
|
|
*/
|
|
int krm_snd(HSESSION hS, int attended, int nfiles, long nbytes)
|
|
{
|
|
ST_KRM *kc;
|
|
int result;
|
|
long sndsize;
|
|
unsigned long filetime;
|
|
long ttime;
|
|
|
|
kc = malloc(sizeof(ST_KRM));
|
|
if (kc == NULL)
|
|
{
|
|
xferMsgClose(hS);
|
|
return TSC_NO_MEM;
|
|
}
|
|
memset(kc, 0, sizeof(ST_KRM));
|
|
|
|
kc->hSession = hS;
|
|
kc->hCom = sessQueryComHdl(hS);
|
|
|
|
kc->kbytes_sent = 0L;
|
|
|
|
kc->this_kpckt = NULL;
|
|
kc->next_kpckt = NULL;
|
|
|
|
if (kc != NULL)
|
|
kc->this_kpckt = malloc(sizeof(KPCKT));
|
|
if (kc->this_kpckt != NULL)
|
|
kc->next_kpckt = malloc(sizeof(KPCKT));
|
|
if (kc->next_kpckt == NULL)
|
|
{
|
|
if (kc->this_kpckt != NULL)
|
|
{
|
|
free(kc->this_kpckt);
|
|
kc->this_kpckt = NULL;
|
|
}
|
|
if (kc != NULL)
|
|
{
|
|
free(kc);
|
|
kc = NULL;
|
|
}
|
|
xferMsgClose(hS);
|
|
return TSC_NO_MEM;
|
|
}
|
|
|
|
krmGetParameters(kc);
|
|
|
|
kc->KrmProgress = ks_progress;
|
|
|
|
kc->total_retries = 0;
|
|
|
|
xferMsgFilecnt(kc->hSession, nfiles);
|
|
xferMsgTotalsize(kc->hSession, nbytes);
|
|
|
|
kc->nbytes = nbytes;
|
|
kc->file_cnt = nfiles;
|
|
kc->files_done = 0;
|
|
kc->its_maxl = 80;
|
|
kc->its_timeout = 15;
|
|
kc->its_npad = 0;
|
|
kc->its_padc = '\0';
|
|
kc->its_eol = kc->k_eol;
|
|
kc->its_chkt = 1;
|
|
kc->its_qctl = K_QCTL;
|
|
kc->its_qbin = '\0';
|
|
kc->its_rept = '\0';
|
|
kc->its_capat = FALSE;
|
|
|
|
kc->ksequence = 0;
|
|
kc->packetnum = 1;
|
|
kc->abort_code = KA_OK;
|
|
kc->xfertime = -1L;
|
|
|
|
if (!ksend_init(kc))
|
|
{
|
|
int kret;
|
|
|
|
kret = kresult_code[kc->abort_code];
|
|
|
|
free(kc->this_kpckt);
|
|
kc->this_kpckt = NULL;
|
|
free(kc->next_kpckt);
|
|
kc->next_kpckt = NULL;
|
|
free(kc);
|
|
kc = NULL;
|
|
|
|
xferMsgClose(hS);
|
|
return(kret);
|
|
}
|
|
|
|
/* don't show init errors once transfer has started */
|
|
kc->total_dsp = kc->total_thru = 0L; /* new transfer starting */
|
|
|
|
while(xfer_nextfile(kc->hSession, kc->our_fname))
|
|
{
|
|
// xfer_idle(kc->hSession, XFER_IDLE_IO);
|
|
|
|
if (kc->abort_code == KA_LABORT1) /* TODO: figure this out */
|
|
kc->abort_code = KA_LABORTALL;
|
|
|
|
if (kc->abort_code >= KA_LABORTALL)
|
|
break;
|
|
|
|
kc->abort_code = KA_OK;
|
|
|
|
result = xfer_opensendfile(kc->hSession,
|
|
&kc->fhdl,
|
|
kc->our_fname,
|
|
&sndsize,
|
|
kc->their_fname,
|
|
&filetime);
|
|
if (result != 0)
|
|
{
|
|
kc->abort_code = KA_CANT_OPEN;
|
|
break;
|
|
}
|
|
|
|
if (kc->its_capat)
|
|
build_attributes(kc, kc->next_kpckt->pdata, sndsize, filetime);
|
|
|
|
ksend_file(kc, sndsize);
|
|
|
|
++kc->files_done;
|
|
if (kc->fhdl)
|
|
{
|
|
fio_close(kc->fhdl);
|
|
kc->fhdl = NULL;
|
|
}
|
|
|
|
/* log transfer status here based on kc->abort_code */
|
|
|
|
xfer_log_xfer(kc->hSession,
|
|
TRUE,
|
|
kc->our_fname,
|
|
NULL,
|
|
kresult_code[kc->abort_code]);
|
|
}
|
|
|
|
if (kc->abort_code < KA_IMMEDIATE)
|
|
ksend_break(kc);
|
|
ks_progress(kc, TRANSFER_DONE);
|
|
ttime = ((long)interval(kc->xfertime) / 10L);
|
|
|
|
result = kresult_code[kc->abort_code];
|
|
|
|
xferMsgClose(kc->hSession);
|
|
|
|
free(kc->this_kpckt);
|
|
kc->this_kpckt = NULL;
|
|
free(kc->next_kpckt);
|
|
kc->next_kpckt = NULL;
|
|
free(kc);
|
|
kc = NULL;
|
|
|
|
xferMsgClose(hS);
|
|
return(result);
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* build_attributes
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
void build_attributes(ST_KRM *kc,
|
|
unsigned char *bufr,
|
|
long size,
|
|
unsigned long ul_time)
|
|
{
|
|
char str[15];
|
|
int sl;
|
|
struct tm *pt;
|
|
|
|
/* add file size in K */
|
|
wsprintf((LPSTR)str,
|
|
(LPSTR)"%d",
|
|
(int)(FULL_HUNKS(size, 1024)));
|
|
|
|
wsprintf((LPSTR)bufr,
|
|
(LPSTR)"!%c%s",
|
|
tochar(sl = (int)StrCharGetByteCount(str)),
|
|
(LPSTR)str);
|
|
|
|
bufr += (sl + 2);
|
|
|
|
/* add file size in bytes */
|
|
wsprintf((LPSTR)str,
|
|
(LPSTR)"%ld",
|
|
(ULONG)size);
|
|
|
|
wsprintf((LPSTR)bufr,
|
|
(LPSTR)"1%c%s",
|
|
tochar(sl = (int)StrCharGetByteCount(str)),
|
|
(LPSTR)str);
|
|
|
|
bufr += (sl + 2);
|
|
|
|
/* add file date and time */
|
|
ul_time += itimeGetBasetime(); /* Adjust to C7 and later */
|
|
pt = localtime((time_t*)&ul_time);
|
|
assert(pt);
|
|
|
|
if (pt)
|
|
{
|
|
/*
|
|
* Dimwitted thing sometimes returns 0
|
|
*/
|
|
wsprintf((LPSTR)bufr,
|
|
(LPSTR)"#%c%04d%02d%02d %02d:%02d:%02d",
|
|
tochar(17),
|
|
pt->tm_year + 1900,
|
|
pt->tm_mon + 1,
|
|
pt->tm_mday,
|
|
pt->tm_hour,
|
|
pt->tm_min,
|
|
pt->tm_sec);
|
|
|
|
bufr += 19;
|
|
}
|
|
|
|
/* system of origin */
|
|
StrCharCat(bufr, ".\"U8");
|
|
bufr += 4;
|
|
}
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* ksend_init
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
int ksend_init(ST_KRM *kc)
|
|
{
|
|
unsigned plen; /* length of outgoing packet data */
|
|
char rpacket[MAXPCKT]; /* space to receive response packet */
|
|
int rlen, rseq; /* length and sequence of response packet */
|
|
int tries = 0;
|
|
|
|
/* set init parameters as sender */
|
|
plen = (unsigned)buildparams(kc, TRUE, kc->this_kpckt->pdata);
|
|
xferMsgPacketnumber(kc->hSession, kc->packetnum);
|
|
|
|
while (tries < kc->k_retries)
|
|
{
|
|
// xfer_idle(kc->hSession, XFER_IDLE_IO);
|
|
|
|
xferMsgPacketErrcnt(kc->hSession, tries);
|
|
|
|
ksend_packet(kc, 'S', plen, kc->ksequence, kc->this_kpckt);
|
|
|
|
switch (krec_packet(kc, &rlen, &rseq, rpacket))
|
|
{
|
|
case 'Y':
|
|
if (rseq == kc->ksequence)
|
|
{
|
|
kc->xfertime = (long)startinterval();
|
|
getparams(kc, TRUE, rpacket);
|
|
kc->ksequence = (kc->ksequence + 1) % 64;
|
|
++kc->packetnum;
|
|
return(TRUE);
|
|
}
|
|
|
|
/* fall through */
|
|
|
|
case 'N':
|
|
xferMsgLasterror(kc->hSession, KE_NAK);
|
|
++tries;
|
|
break;
|
|
|
|
case 'T':
|
|
xferMsgLasterror(kc->hSession, KE_TIMEOUT);
|
|
++tries;
|
|
break;
|
|
|
|
case BAD_PACKET:
|
|
if (xfer_user_interrupt(kc->hSession))
|
|
{
|
|
kc->abort_code = KA_IMMEDIATE;
|
|
return (FALSE);
|
|
}
|
|
|
|
if (xfer_carrier_lost(kc->hSession))
|
|
{
|
|
kc->abort_code = KA_LOST_CARRIER;
|
|
return (FALSE);
|
|
}
|
|
|
|
xferMsgLasterror(kc->hSession, KE_BAD_PACKET);
|
|
++tries;
|
|
break;
|
|
|
|
case 'E':
|
|
/* received error packet, abort transfer */
|
|
xferMsgLasterror(kc->hSession, KE_RMTERR);
|
|
strncpy(kc->xtra_err, rpacket, (unsigned)65);
|
|
kc->abort_code = KA_RMTERR;
|
|
return(FALSE);
|
|
/*lint -unreachable*/
|
|
break;
|
|
|
|
default:
|
|
/* unexpected packet type */
|
|
kc->abort_code = KA_BAD_FORMAT;
|
|
return(FALSE);
|
|
/*lint -unreachable*/
|
|
break;
|
|
}
|
|
}
|
|
/* error count has been exceeded */
|
|
kc->abort_code = KA_ERRLIMIT;
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* ksend_break
|
|
*
|
|
* DESCRIPTION:
|
|
* Send 'B' packet to indicate end of transaction
|
|
*
|
|
* ARGUMENTS:
|
|
* none
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
int ksend_break(ST_KRM *kc)
|
|
{
|
|
char rpacket[MAXPCKT]; /* space to receive response packet */
|
|
int rlen, rseq; /* length and sequence of response packet */
|
|
int tries = 0;
|
|
|
|
while (tries < kc->k_retries)
|
|
{
|
|
// xfer_idle(kc->hSession, XFER_IDLE_IO);
|
|
|
|
ksend_packet(kc, 'B', 0, kc->ksequence, kc->this_kpckt);
|
|
switch (krec_packet(kc, &rlen, &rseq, rpacket))
|
|
{
|
|
case 'Y':
|
|
if (rseq == kc->ksequence)
|
|
{
|
|
kc->ksequence = (kc->ksequence + 1) % 64;
|
|
++kc->packetnum;
|
|
return(TRUE);
|
|
}
|
|
|
|
/* fall through */
|
|
|
|
case 'N':
|
|
case 'T':
|
|
case BAD_PACKET:
|
|
if (xfer_user_interrupt(kc->hSession))
|
|
{
|
|
kc->abort_code = KA_IMMEDIATE;
|
|
return FALSE;
|
|
}
|
|
|
|
if (xfer_carrier_lost(kc->hSession))
|
|
{
|
|
kc->abort_code = KA_LOST_CARRIER;
|
|
return FALSE;
|
|
}
|
|
|
|
++tries;
|
|
break;
|
|
|
|
case 'E':
|
|
/* received error packet, abort transfer */
|
|
StrCharCopyN(kc->xtra_err, rpacket, MAXLINE);
|
|
kc->abort_code = KA_RMTERR;
|
|
return(FALSE);
|
|
/*lint -unreachable*/
|
|
break;
|
|
|
|
default:
|
|
/* unexpected packet type */
|
|
kc->abort_code = KA_BAD_FORMAT;
|
|
return(FALSE);
|
|
/*lint -unreachable*/
|
|
break;
|
|
}
|
|
}
|
|
/* error count has been exceeded */
|
|
kc->abort_code = KA_ERRLIMIT;
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* ksend_file
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* ARGUMENTS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
int ksend_file(ST_KRM *kc, long fsize)
|
|
{
|
|
int tries = 0;
|
|
int file_sent = FALSE;
|
|
int packet_sent = FALSE;
|
|
int kbd_abort = KA_OK;
|
|
char rtype;
|
|
int rlen, rseq;
|
|
char rpacket[MAXPCKT];
|
|
int sendattr;
|
|
KPCKT *tmp;
|
|
|
|
DbgOutStr("ksend_file %s\r\n", (LPSTR)kc->our_fname, 0,0,0,0);
|
|
|
|
xferMsgNewfile(kc->hSession,
|
|
kc->files_done + 1,
|
|
kc->our_fname,
|
|
kc->our_fname);
|
|
|
|
xferMsgFilesize(kc->hSession, fsize);
|
|
|
|
xferMsgPacketErrcnt(kc->hSession, 0);
|
|
|
|
xferMsgPacketnumber(kc->hSession, 0);
|
|
|
|
kc->p_kgetc = ks_getc;
|
|
kc->kbytes_sent = 0;
|
|
|
|
/* prepare file-header packet in this_kpckt */
|
|
kc->this_kpckt->ptype = 'F';
|
|
StrCharCopyN(kc->this_kpckt->pdata, kc->their_fname, MAXPCKT);
|
|
kc->this_kpckt->datalen = (int)StrCharGetByteCount(kc->this_kpckt->pdata);
|
|
sendattr = kc->its_capat &&
|
|
(size_t)StrCharGetByteCount(kc->next_kpckt->pdata) <= (size_t)(kc->its_maxl - 5);
|
|
|
|
while (!file_sent && kc->abort_code == KA_OK) /* for each packet */
|
|
{
|
|
// xfer_idle(kc->hSession, XFER_IDLE_IO);
|
|
|
|
tries = 0;
|
|
packet_sent = FALSE;
|
|
while (!packet_sent && tries++ < kc->k_retries && kc->abort_code == KA_OK)
|
|
{
|
|
// xfer_idle(kc->hSession, XFER_IDLE_IO);
|
|
|
|
if (kbd_abort != KA_OK && tries == 1)
|
|
{
|
|
kc->this_kpckt->ptype = 'Z';
|
|
kc->this_kpckt->datalen = 1;
|
|
StrCharCopyN(kc->this_kpckt->pdata, "D", MAXPCKT);
|
|
}
|
|
|
|
DbgOutStr("Calling ksend_packet %d %c (0x%x)",
|
|
tries, kc->this_kpckt->ptype, kc->this_kpckt->ptype, 0,0);
|
|
|
|
ksend_packet(kc, kc->this_kpckt->ptype,
|
|
(unsigned)kc->this_kpckt->datalen,
|
|
kc->ksequence, kc->this_kpckt);
|
|
|
|
if (xfer_carrier_lost(kc->hSession))
|
|
{
|
|
kc->abort_code = KA_LOST_CARRIER;
|
|
break;
|
|
}
|
|
|
|
if (tries == 1) /* first try for this packet */
|
|
{
|
|
xferMsgPacketnumber(kc->hSession, kc->packetnum);
|
|
|
|
if (fsize > 0)
|
|
ks_progress(kc, 0);
|
|
|
|
/* get next packet ready while first is being sent */
|
|
if (sendattr) /* data alreay prepared in next_kpckt */
|
|
{
|
|
kc->next_kpckt->datalen = (int)StrCharGetByteCount(kc->next_kpckt->pdata);
|
|
kc->next_kpckt->ptype = 'A';
|
|
sendattr = FALSE;
|
|
}
|
|
else if ((kc->next_kpckt->datalen =
|
|
kload_packet(kc, kc->next_kpckt->pdata)) == ERROR)
|
|
{
|
|
kc->next_kpckt->ptype = 'E';
|
|
kc->next_kpckt->datalen = (int)StrCharGetByteCount(kc->xtra_err);
|
|
StrCharCopyN(kc->next_kpckt->pdata, kc->xtra_err, MAXPCKT);
|
|
}
|
|
else
|
|
kc->next_kpckt->ptype = (char)(kc->next_kpckt->datalen ? 'D':'Z');
|
|
|
|
DbgOutStr(" next packet %c (0x%x)\r\n",
|
|
kc->next_kpckt->ptype, kc->next_kpckt->ptype, 0,0,0);
|
|
|
|
} /* end of if (tries == 1) */
|
|
else
|
|
{
|
|
xferMsgPacketErrcnt(kc->hSession, tries - 1);
|
|
xferMsgErrorcnt(kc->hSession, ++kc->total_retries);
|
|
|
|
DbgOutStr(" retry\r\n", 0,0,0,0,0);
|
|
}
|
|
|
|
rtype = (char)krec_packet(kc, &rlen, &rseq, rpacket);
|
|
if (rtype == 'N' && (--rseq < 0 ? 63 : rseq) == kc->ksequence)
|
|
rtype = 'Y';
|
|
|
|
DbgOutStr("called krec_packet %c (0x%x)\r\n", rtype, rtype, 0,0,0);
|
|
|
|
switch(rtype)
|
|
{
|
|
case 'Y':
|
|
if (rseq == kc->ksequence)
|
|
{
|
|
packet_sent = TRUE;
|
|
kc->ksequence = (kc->ksequence + 1) % 64;
|
|
++kc->packetnum;
|
|
if (kc->this_kpckt->ptype == 'A')/* response to attr pckt */
|
|
{
|
|
/* If receiver responded to an attribute packet with
|
|
* an 'N' in the data field, do not transfer the file.
|
|
*/
|
|
|
|
if (rlen > 0 && *rpacket == 'N')
|
|
kbd_abort = KA_RABORT1;
|
|
}
|
|
if (kc->this_kpckt->ptype == 'Z')/* have we sent last one?*/
|
|
{
|
|
file_sent = TRUE;
|
|
kc->abort_code = kbd_abort;
|
|
kbd_abort = KA_OK;
|
|
}
|
|
if (rlen == 1)
|
|
{
|
|
if (*rpacket == 'X')
|
|
kbd_abort = KA_RABORT1;
|
|
else if (*rpacket == 'Z')
|
|
kbd_abort = KA_RABORTALL;
|
|
}
|
|
tmp = kc->this_kpckt;
|
|
kc->this_kpckt = kc->next_kpckt;
|
|
kc->next_kpckt = tmp;
|
|
}
|
|
else
|
|
xferMsgLasterror(kc->hSession, KE_SEQUENCE);
|
|
break;
|
|
|
|
case 'N':
|
|
xferMsgLasterror(kc->hSession, KE_NAK);
|
|
break;
|
|
|
|
case BAD_PACKET:
|
|
xferMsgLasterror(kc->hSession, KE_BAD_PACKET);
|
|
break;
|
|
|
|
case 'T':
|
|
xferMsgLasterror(kc->hSession, KE_TIMEOUT);
|
|
break;
|
|
|
|
case 'E':
|
|
xferMsgLasterror(kc->hSession, KE_RMTERR);
|
|
StrCharCopyN(kc->xtra_err, rpacket, MAXLINE);
|
|
kc->abort_code = KA_RMTERR;
|
|
return(FALSE);
|
|
/*lint -unreachable*/
|
|
break;
|
|
|
|
default:
|
|
xferMsgLasterror(kc->hSession, KE_WRONG);
|
|
kc->abort_code = KA_BAD_FORMAT;
|
|
return(FALSE);
|
|
/*lint -unreachable*/
|
|
break;
|
|
}
|
|
|
|
if (xfer_user_interrupt(kc->hSession))
|
|
{
|
|
if (kbd_abort == KA_OK) /* first time */
|
|
{
|
|
kbd_abort = KA_LABORT1;
|
|
}
|
|
else
|
|
kc->abort_code = KA_IMMEDIATE;
|
|
}
|
|
|
|
if (xfer_carrier_lost(kc->hSession))
|
|
kc->abort_code = KA_LOST_CARRIER;
|
|
} /* end while (!packet_sent && etc.) */
|
|
|
|
xferMsgPacketErrcnt(kc->hSession, tries = 0);
|
|
|
|
if (kc->abort_code == KA_OK && !packet_sent) /* error count exceeded */
|
|
kc->abort_code = KA_ERRLIMIT;
|
|
} /* end while (!file_sent etc.) */
|
|
|
|
xferMsgPacketnumber(kc->hSession, kc->packetnum);
|
|
|
|
ks_progress(kc, FILE_DONE);
|
|
kc->total_dsp += fsize;
|
|
kc->total_thru += kc->kbytes_sent;
|
|
kc->kbytes_sent = 0;
|
|
return(file_sent);
|
|
} /* end ksend_file() */
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
|
* ks_progress
|
|
*
|
|
* DESCRIPTION:
|
|
* Displays transfer progress indicators for Kermit Send
|
|
*
|
|
* ARGUMENTS:
|
|
* final -- TRUE if final display for a file.
|
|
*
|
|
* RETURNS:
|
|
* nothing
|
|
*/
|
|
void ks_progress(ST_KRM *kc, int status)
|
|
{
|
|
long ttime, stime;
|
|
long bytes_sent;
|
|
long cps;
|
|
long krm_stime = -1;
|
|
long krm_ttime = -1;
|
|
long krm_cps = -1;
|
|
long krm_file_so_far = -1;
|
|
long krm_total_so_far = -1;
|
|
|
|
if (kc->xfertime == -1L)
|
|
return;
|
|
ttime = (long)interval(kc->xfertime);
|
|
|
|
if ((stime = ttime / 10L) != kc->displayed_time ||
|
|
bittest(status, FILE_DONE | TRANSFER_DONE))
|
|
{
|
|
/* Display elapsed time */
|
|
krm_stime = stime;
|
|
|
|
/* Display amount transferred */
|
|
bytes_sent = kc->total_dsp + kc->kbytes_sent;
|
|
|
|
krm_file_so_far = kc->kbytes_sent;
|
|
krm_total_so_far = bytes_sent;
|
|
|
|
/* Display throughput and est. time to completion */
|
|
if ((stime > 2 ||
|
|
ttime > 0 && bittest(status, FILE_DONE | TRANSFER_DONE)) &&
|
|
(cps = ((kc->total_thru + kc->kbytes_sent) * 10L) / ttime) > 0)
|
|
{
|
|
krm_cps = cps;
|
|
|
|
if ((kc->nbytes > 0))
|
|
{
|
|
ttime = ((kc->nbytes - bytes_sent) / cps) +
|
|
kc->file_cnt - kc->files_done;
|
|
krm_ttime = ttime;
|
|
}
|
|
}
|
|
kc->displayed_time = stime;
|
|
}
|
|
|
|
xferMsgProgress(kc->hSession,
|
|
krm_stime,
|
|
krm_ttime,
|
|
krm_cps,
|
|
krm_file_so_far,
|
|
krm_total_so_far);
|
|
}
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
|
|
|
#define toupper(x) ((x)-'a'+'A')
|
|
|
|
int wldindexx(const char *string,
|
|
const char *substr,
|
|
char wildcard,
|
|
int ic)
|
|
/* ic - ignore case */
|
|
{
|
|
short index, limit;
|
|
const char *s;
|
|
const char *ss;
|
|
|
|
if (*substr == '\0')
|
|
return(0);
|
|
index = 0;
|
|
limit = (short)StrCharGetByteCount(string) - (short)StrCharGetByteCount(substr);
|
|
while (index <= limit)
|
|
{
|
|
s = &string[index];
|
|
ss = substr;
|
|
while (*ss == wildcard || *s == *ss || (ic && isascii(*s)
|
|
&& isascii(*ss) && toupper(*s) == toupper(*ss)))
|
|
{
|
|
++s;
|
|
if (*++ss == '\0')
|
|
return(index);
|
|
}
|
|
++index;
|
|
}
|
|
return(-1);
|
|
}
|
|
|
|
/********************* end of krm_snd.c ********************/
|