home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
pub
/
win100
/
winkpr.w
< prev
next >
Wrap
Text File
|
2020-01-01
|
25KB
|
1,174 lines
/*
* Windows Kermit
*
* Written by William S. Hall
* 3665 Benton Street, #66
* Santa Clara, CA 95051
*
* protocol module
*/
#define NOKANJI
#define NOATOM
#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <stdio.h>
#include <limits.h>
#include <sys\types.h>
#include <sys\stat.h>
#define EXTERN
#include "winasc.h"
#include "winkpr.h"
#include "winkpf.h"
extern cid;
/* local functions */
static BOOL NEAR paritycheck(void);
static int NEAR wart(void);
static void NEAR ShowTransactionError(HWND, int);
static void NEAR scmd(char cmd);
static void NEAR ttoi(BYTE *buf, int len);
static int NEAR input(void);
static void NEAR errpkt(HWND hWnd, int id);
static int NEAR opent(HWND);
static int NEAR sinit(void);
static void NEAR sipkt(char c);
static int NEAR sfile(void);
static void NEAR seof(char *s);
static int NEAR sdata(void);
static void NEAR ack(int len, BYTE *s);
static int NEAR nxtpkt(void);
static int NEAR canned(char *buf);
static int NEAR gnfile(void);
static void NEAR seot(void);
static void NEAR rinit(void);
static void NEAR resetc(void);
static void NEAR resend(void);
static int NEAR rcvfil(void);
static void NEAR reot(void);
static int NEAR reof(void);
static void NEAR srinit(void);
static void NEAR spar(BYTE *data, int len);
static int NEAR rpar(BYTE *data);
static void NEAR spack(BYTE type, int num, int len, BYTE *data);
static int NEAR bufill(BYTE buffer[]);
static int NEAR encodebuf(BYTE outbuf[], BYTE inbuf[], int *inbufsize);
static int NEAR bufemp(BYTE *buffer, int len, int dest);
static HANDLE NEAR GetSendFileName(char *name);
static HANDLE NEAR GetReceiveFileName(HWND hWnd, BYTE *packet);
static void NEAR ShowErrorPacket(HWND hWnd, char *errstr);
static int NEAR getpacket(BYTE *str, int len);
static int NEAR input(void);
static void NEAR UpdateXferBox(void);
/* timer function */
void FAR PASCAL krmDoTimeout(HWND hWnd,unsigned message,short event,DWORD time)
{
KillTimer(hWnd, event);
if (Kermit.bell)
MessageBeep(0);
rcvpkt.state = PS_SYNCH;
Kermit.inpacket = FALSE;
switch(event) {
case KRM_WAITSEND:
Kermit.waitsend = FALSE;
break;
default:
Kermit.timeout = TRUE;
break;
}
}
/* local variables */
static int lclcount;
static BYTE *lclbuf;
static HWND lclhWnd;
/* dispatch a string from the comm port. return when used up */
void krmKermitDispatch(HWND hWnd, BYTE *buf, int count)
{
if (Kermit.waitsend)
return;
lclcount = count;
lclbuf = buf;
lclhWnd = hWnd;
wart();
if (Kermit.sstate < 0)
SendMessage(lclhWnd, WM_COMMAND, IDM_CANCELPROTOCOL, (LONG)krmState);
}
/* protocol stuff */
#define RESUME return(0)
#define wart() static int NEAR wart()
static int vstate = 0;
static char vcmd = 0;
%states get rfile rdata
%states ssinit ssfile ssdata sseof sseot
%states ipkt rgen
%%
s { /* send */
tinit(lclhWnd, krmState);
if (sinit())
BEGIN ssinit;
else {
Kermit.sstate = KRM_NO_SEND_FILE;
RESUME;
}
}
v { /* receive */
tinit(lclhWnd, krmState);
BEGIN get;
}
r { /* get */
tinit(lclhWnd, krmState);
vstate = get;
vcmd = 0;
sipkt('I');
BEGIN ipkt;
}
c { /* host */
tinit(lclhWnd, krmState);
vstate = rgen;
vcmd = 'C';
sipkt('I');
BEGIN ipkt;
}
g { /* generic */
tinit(lclhWnd, krmState);
vstate = rgen;
vcmd = 'G';
sipkt('I');
BEGIN ipkt;
}
<rgen,get>S { /* got send_init */
rinit();
/* note : set block check type */
resetc();
BEGIN rfile;
}
<ipkt>Y { /* got ack for I-packet */
spar(rcvpkt.data, rcvpkt.len);
if (vcmd) {
scmd(vcmd);
vcmd = 0;
}
if (vstate == get)
srinit();
BEGIN vstate;
}
<ipkt>E { /* got E for I-packet, ignore */
if (vcmd)
scmd(vcmd);
vcmd = 0;
if (vstate == get)
srinit();
BEGIN vstate;
}
<rgen>Y { /* got reply in ACK data */
bufemp(rcvpkt.data, rcvpkt.len, 2);
Kermit.sstate = KRM_COMPLETE;
RESUME;
}
<rgen,rfile>F { /* got file header */
if (rcvfil()) {
ack(strlen(Kermit.filename), Kermit.filename);
BEGIN rdata;
}
else {
Kermit.sstate = KRM_FILE_OPEN_ERROR;
errpkt(lclhWnd, Kermit.sstate);
RESUME;
}
}
<rgen,rfile>X {
if (opent(lclhWnd)) {
ack(0,"");
BEGIN rdata;
}
else {
Kermit.sstate = KRM_TERM_OPEN_ERROR;
errpkt(lclhWnd, Kermit.sstate);
RESUME;
}
}
<rfile>B { /* got eot */
ack(0,"");
reot();
Kermit.sstate = KRM_COMPLETE;
RESUME;
}
<rdata>D { /* got data */
if (Kermit.fileabort)
ack(1, "X");
else if (Kermit.batchabort)
ack(1, "Z");
else
ack(0,"");
if (bufemp(rcvpkt.data, rcvpkt.len, Kermit.displayfile) < 0) {
Kermit.sstate = KRM_FILE_WRITE_ERROR;
errpkt(lclhWnd, Kermit.sstate);
RESUME;
}
}
<rdata>Z { /* got end of file */
if (reof() < 0) {
Kermit.sstate = KRM_FILE_CLOSE_ERROR;
errpkt(lclhWnd, Kermit.sstate);
RESUME;
} else {
ack(0,"");
BEGIN rfile;
}
}
<ssinit>Y { /* got ack to send init */
spar(rcvpkt.data, rcvpkt.len);
/* note : set block check type */
if (sfile()) {
resetc();
BEGIN ssfile;
} else {
Kermit.sstate = KRM_FILE_OPEN_ERROR;
errpkt(lclhWnd, Kermit.sstate);
RESUME;
}
}
<ssfile>Y { /* got ack to F */
if (sdata() <= 0) {
clsif();
seof("");
BEGIN sseof;
}
else
BEGIN ssdata;
}
<ssdata>Y {
if (canned(rcvpkt.data)) {
clsif();
seof("D");
BEGIN sseof;
}
else if (sdata() <= 0) {
clsif();
seof("");
BEGIN sseof;
}
}
<sseof>Y { /* got ack to EOF */
if (gnfile() > 0) {
if (sfile())
BEGIN ssdata;
else {
Kermit.sstate = KRM_FILE_OPEN_ERROR;
errpkt(lclhWnd, Kermit.sstate);
RESUME;
}
} else { /* no next file */
seot();
BEGIN sseot;
}
}
<sseot>Y { /* got ack to EOT */
Kermit.sstate = KRM_COMPLETE;
RESUME;
}
p { /* partial packet */
if (Kermit.numtry >= Kermit.maxtry)
Kermit.sstate = KRM_RETRY_LIMIT;
RESUME;
}
E { /* error packet */
bufemp(rcvpkt.data, rcvpkt.len, 2);
clsif(); /* close input files */
clsof(TRUE); /* discard any output files */
Kermit.sstate = KRM_ERROR_PKT;
RESUME;
}
$ { /* user abort */
Kermit.sstate = KRM_USERCNX;
errpkt(lclhWnd,Kermit.sstate);
RESUME;
}
. {
Kermit.sstate = KRM_UNKNOWN_PACKET;
errpkt(lclhWnd, Kermit.sstate);
RESUME;
}
%%
/* following are all support routines */
static void NEAR errpkt(HWND hWnd, int id)
{
char szError[80];
HANDLE hInstance = (HANDLE)GetWindowWord(hWnd, GWW_HINSTANCE);
int *len, datalen;
*len = LoadString(hInstance, id, (LPSTR)szError, sizeof(szError));
datalen = encodebuf(sndpkt.data,szError,len);
spack('E', Kermit.pktnum, datalen, sndpkt.data);
clsif(); clsof(1);
}
static void NEAR sipkt(char c)
{
BYTE buf[KRM_MAXPACKETSIZE];
FlushComm(cid,1);
lclcount = 0;
spack(c,Kermit.pktnum,rpar(buf),buf);
}
static int NEAR sinit()
{
if ((Kermit.pNextFile = strtok(Kermit.pfilelist," ,")) != NULL) {
sipkt('S');
return(TRUE);
}
return(FALSE);
}
static int NEAR sfile()
{
int *len;
register int datalen;
BYTE buf[20];
Kermit.hInFile = GetSendFileName(Kermit.pNextFile);
if (Kermit.hInFile == -1)
return(0);
strcpy(buf, Kermit.filename);
*len = strlen(Kermit.filename);
datalen = encodebuf(sndpkt.data, buf, len);
nxtpkt();
spack('F',Kermit.pktnum, datalen, sndpkt.data);
return(1);
}
static int NEAR sdata()
{
register int len;
if (rcvpkt.len) {
bufemp(rcvpkt.data, rcvpkt.len, 2);
SetDlgItemText(hWndXfer, IDD_SAVENAME,(LPSTR)rcvpkt.data);
}
if (Kermit.fileabort || Kermit.batchabort)
return(-1);
if ((len = bufill(sndpkt.data)) > 0) {
nxtpkt();
spack('D', Kermit.pktnum, len, sndpkt.data);
}
if (len < 0)
ShowTransactionError(lclhWnd, KRM_FILE_READ_ERROR);
return(len);
}
static void NEAR seof(char *s)
{
nxtpkt();
if ((s != NULL) && (*s != NUL))
spack('Z', Kermit.pktnum, 1, s);
else
spack('Z', Kermit.pktnum, 0, "");
}
static void NEAR ack(int len, BYTE *s)
{
spack('Y', Kermit.pktnum, len, s);
nxtpkt();
}
static int NEAR nxtpkt()
{
Kermit.pktcount += 1;
return(Kermit.pktnum = (Kermit.pktnum + 1) & 63);
}
void clsif() {
if (Kermit.hInFile) {
Kermit.hInFile = (HANDLE)close(Kermit.hInFile);
Kermit.hInFile = NULL;
}
Kermit.fileabort = FALSE;
}
static int NEAR canned(char *buf)
{
if (*buf == 'X')
Kermit.fileabort = TRUE;
if (*buf == 'Z')
Kermit.batchabort = TRUE;
return((Kermit.fileabort || Kermit.batchabort) ? 1 : 0);
}
static int NEAR gnfile()
{
/* don't do this if displaying on terminal */
if (Kermit.batchabort || (Kermit.pNextFile = strtok(NULL, " ,")) == NULL)
return(0);
return(1);
}
static void NEAR seot() {
nxtpkt();
spack('B', Kermit.pktnum,0, "");
Kermit.fileabort = Kermit.batchabort = FALSE;
}
static void NEAR rinit() {
BYTE buf[100];
spar(rcvpkt.data, rcvpkt.len);
ack(rpar(buf), buf);
}
static int NEAR rcvfil() {
bufemp(rcvpkt.data, rcvpkt.len, 2);
if ((Kermit.hOutFile =
GetReceiveFileName(lclhWnd,rcvpkt.data)) == -1)
return(0);
return(1);
}
static int NEAR reof() {
register int x;
if (Kermit.fileabort == FALSE)
Kermit.fileabort = rcvpkt.len ? (rcvpkt.data[0] == 'D') : FALSE;
x = clsof(Kermit.fileabort | Kermit.batchabort);
if (Kermit.fileabort || Kermit.batchabort)
Kermit.fileabort = FALSE;
return(x);
}
int clsof(int disp) {
if (Kermit.displayfile)
return(1);
if (Kermit.hOutFile) {
if ((Kermit.hOutFile = (HANDLE)close(Kermit.hOutFile)) != NULL)
return(-1);
if (disp && Kermit.filediscard)
unlink(myofstruct.szPathName);
return(1);
}
}
static void NEAR reot() {
Kermit.fileabort = Kermit.batchabort = FALSE;
}
static void NEAR resetc() {
/* add appropriate code */
}
static void NEAR resend() {
Kermit.numtry += 1;
Kermit.retrycount += 1;
if (sndpkt.len)
ttoi(sndpkt.pktbuf, sndpkt.len);
else
spack('N', Kermit.pktnum, 0, "");
if (IsWindow(hWndXfer))
UpdateXferBox();
}
static void NEAR srinit() {
int *len;
*len = strlen(Kermit.pfilelist);
spack('R', Kermit.pktnum,
encodebuf(sndpkt.data,Kermit.pfilelist,len), sndpkt.data);
}
static void NEAR scmd(char cmd) {
int *len;
register int datalen;
switch (krmState) {
case IDM_KRM_FINISH:
datalen = 1;
sndpkt.data[0] = 'F';
break;
case IDM_KRM_BYE:
case IDM_KRM_LOGOUT:
datalen = 1;
sndpkt.data[0] = 'L';
break;
case IDM_KRM_REMOTEHOST:
*len = strlen(Kermit.pfilelist);
datalen = encodebuf(sndpkt.data, Kermit.pfilelist,len);
break;
default:
*len = strlen(Kermit.pRemoteCommand);
datalen = encodebuf(sndpkt.data, Kermit.pRemoteCommand,len);
break;
}
spack(cmd,Kermit.pktnum,datalen,sndpkt.data);
}
static int NEAR opent(HWND hWnd) {
BYTE crstring[3];
if (krmInitMainDisplay(hWnd, Kermit.DispCharWidth, Kermit.DispCharHeight)) {
bufemp(rcvpkt.data, rcvpkt.len, 2);
krmMainStringDisplay(hWnd, rcvpkt.data, rcvpkt.len);
crstring[0] = CR;
crstring[1] = LF;
krmMainStringDisplay(hWnd, crstring,2);
Kermit.displayfile = 1;
return(TRUE);
}
return FALSE;
}
static BOOL NEAR paritycheck() {
DCB commdata;
GetCommState(cid, (DCB FAR *)&commdata);
if ((commdata.Parity == NOPARITY) && (commdata.ByteSize == 8))
return FALSE;
return TRUE;
}
static int NEAR rpar(BYTE *data) {
register int i = 0;
data[i++] = (BYTE)tochar(local.maxpacketsize);
data[i++] = (BYTE)tochar(local.timeout);
data[i++] = (BYTE)tochar(local.padcount);
data[i++] = ctl(local.padchar);
data[i++] = (BYTE)tochar(local.eol);
data[i++] = local.quote;
switch (Kermit.rqf) {
case -1 :
case 1 :
if (paritycheck())
Kermit.ebq = local.binquote = '&';
break;
case 0 :
case 2 :
break;
}
data[i++] = local.binquote;
/* fixup: get these fields straight */
data[i++] = (BYTE)(local.chksumtype + '0');
data[i++] = local.rptprefix;
return(i);
}
static void NEAR spar(BYTE *data, int len) {
register int i = 0;
register int intval;
char charval;
intval = (i < len) ? unchar(data[i++]) : KRM_DEFPACKETSIZE;
remote.maxpacketsize = (intval < KRM_MINPACKETSIZE)
? KRM_DEFPACKETSIZE : intval;
intval = (i < len) ? unchar(data[i++]) : KRM_DEFTIMEOUT;
remote.timeout = ((intval < 0) || (intval > 65)) ? KRM_DEFTIMEOUT : intval;
Kermit.mstimeout = 1000 * remote.timeout;
remote.padcount = KRM_DEFPADCOUNT;
remote.padchar = KRM_DEFPADCHAR;
if (i < len) {
remote.padcount = unchar(data[i++]);
if (i < len)
if ((((charval = ctl(data[i++])) >= 0) && (charval < SP))
|| (charval == DEL))
remote.padchar = charval;
}
intval = (i < len) ? unchar(data[i++]) : KRM_DEFEOL;
remote.eol = ((intval > SOH) || (intval < SP)) ? intval : KRM_DEFEOL;
charval = (i < len) ? data[i++] : KRM_DEFQUOTE;
remote.quote = ((charval > SP) && (charval < '?')) ||
((charval > '_') && (charval < DEL)) ?
charval : KRM_DEFQUOTE;
charval = remote.binquote = (i < len) ? data[i++] : 0;
if (charval == 'Y')
Kermit.rqf = 1;
else if ((charval > 32 && charval < '?') ||
(charval > '_' && charval < DEL))
Kermit.rqf = 2;
else
Kermit.rqf = 0;
switch (Kermit.rqf) {
case 0 :
Kermit.ebqflg = FALSE;
break;
case 1 :
if (paritycheck()) {
Kermit.ebqflg = TRUE;
Kermit.ebq = '&';
}
break;
case 2:
if (Kermit.ebqflg = (Kermit.ebq == local.binquote ||
local.binquote == 'Y'))
Kermit.ebq = charval;
break;
}
/* fixup the following code */
intval = 1;
if (i < len) {
intval = data[i++] - '0';
if ((intval < 1) || (intval > 3))
intval = 1;
}
remote.chksumtype = intval;
if (i < len) {
remote.rptprefix = charval = data[i++];
Kermit.rptflg = ((charval > 32 && charval < '?') ||
(charval > '_' && charval < DEL));
}
else
Kermit.rptflg = FALSE;
Kermit.maxsenddatalen = remote.maxpacketsize - 2 - Kermit.chksumtype;
}
static void NEAR spack(BYTE type, int num, int len, BYTE *data) {
WORD chksum = 0;
register int i, k;
sndpkt.len = 0;
sndpkt.data[len] = NUL;
if (k = remote.padcount) {
memset(sndpkt.pktbuf, remote.padchar, k);
ttoi(sndpkt.pktbuf, k);
}
k = 0;
sndpkt.pktbuf[k++] = sndpkt.mark;
chksum += sndpkt.pktbuf[k++] = (BYTE)tochar(len + 3);
chksum += sndpkt.pktbuf[k++] = (BYTE)tochar(num);
chksum += sndpkt.pktbuf[k++] = type;
for (i = 0; i < len; i++)
chksum += sndpkt.pktbuf[k++] = data[i];
chksum = (((chksum & 0300) >> 6) + chksum) & 077;
sndpkt.pktbuf[k++] = (BYTE)tochar(chksum);
sndpkt.pktbuf[k++] = (BYTE)remote.eol;
sndpkt.pktbuf[k] = NUL;
ttoi(sndpkt.pktbuf,k);
sndpkt.len = k;
}
static void NEAR ttoi(BYTE *buf, int len)
{
COMSTAT mycomstat;
register int inque;
do {
GetCommError(cid, (COMSTAT FAR *)&mycomstat);
inque = mycomstat.cbOutQue;
} while(inque);
WriteComm(cid, (LPSTR)buf, len);
}
static int NEAR bufill(BYTE buffer[]) {
register int numloaded, numread;
BYTE buf[KRM_MAXPACKETSIZE];
int numrem;
if ((numread = read(Kermit.hInFile,buf,Kermit.maxsenddatalen)) <= 0) {
numloaded = numread;
if (numread == 0)
Kermit.percentage = 100;
} else {
numrem = numread;
numloaded = encodebuf(buffer, buf, &numrem);
lseek(Kermit.hInFile, (LONG)(-numrem), SEEK_CUR);
if (Kermit.filesize) {
Kermit.bytesmoved += numread - numrem;
Kermit.percentage = (int)(Kermit.bytesmoved *100 / Kermit.filesize);
}
}
return(numloaded);
}
static int NEAR encodebuf(BYTE outbuf[], BYTE inbuf[], int *inbufsize) {
register int i,j;
BYTE t, t7;
int maxbufsize = Kermit.maxsenddatalen - 3; /* char + prefix */
char quote = remote.quote;
char binquote = Kermit.ebq;
if (Kermit.ebqflg) {
for (i = 0, j = 0 ; j < *inbufsize ; ) {
t = inbuf[j++];
if (t & 0x80)
outbuf[i++] = binquote;
if (((t7 = t & 0x7f) < SP) || (t7 == DEL)) {
outbuf[i++] = quote;
t7 = ctl(t7);
}
else if ((t7 == quote) || (t7 == binquote))
outbuf[i++] = quote;
outbuf[i++] = t7;
if (i > maxbufsize)
break;
}
}
else {
for (i = 0, j = 0 ; j < *inbufsize ; ) {
t = inbuf[j++];
if ((t7 = t & 0x7f) < SP || t7 == DEL || t7 == quote) {
outbuf[i++] = quote;
if (t7 != quote)
t = ctl(t);
}
outbuf[i++] = t;
if (i > maxbufsize)
break;
}
}
*inbufsize -= j;
return(i);
}
static int NEAR bufemp(BYTE *buffer, int len, int dest) {
register int i,j;
int result;
BYTE t, t7, wbuf[100];
BYTE bitset;
char quote = local.quote;
char binquote = Kermit.ebq;
if (Kermit.ebqflg) {
for (i = 0, j = 0; i < len; i++) {
t = buffer[i];
if (t == binquote) {
t = buffer[++i];
bitset = 0x80;
}
else
bitset = 0;
if (t == quote) {
t = buffer[++i];
if (((t7 = t & 0x7f) != quote) && (t7 != binquote))
t = ctl(t);
}
wbuf[j++] = t | bitset;
}
}
else {
for (i = 0, j = 0; i < len; i++) {
t = buffer[i];
if (t == quote) {
t = buffer[++i];
if ((t & 0x7f) != quote)
t = ctl(t);
}
wbuf[j++] = t;
}
}
wbuf[j] = NUL;
switch (dest) {
case 2 :
strcpy(rcvpkt.data, wbuf);
rcvpkt.len = j;
return (TRUE);
case 1 :
krmMainStringDisplay(lclhWnd, wbuf, j);
return (TRUE);
default:
if ((result = write(Kermit.hOutFile, wbuf, j)) >= 0)
Kermit.bytesmoved += result;
if ((result < j) || (result == -1))
return(-1);
else
return(result);
}
}
static HANDLE NEAR GetSendFileName(char *name) {
HANDLE hfile;
struct stat buf;
hfile = OpenFile((LPSTR)name, (OFSTRUCT FAR *)&myofstruct,OF_READ);
if (hfile != -1) {
Kermit.filename = (strrchr(myofstruct.szPathName,'\\') + 1);
SetDlgItemText(hWndXfer, IDD_FILENAME,(LPSTR)Kermit.filename);
fstat(hfile, &buf);
Kermit.filesize = buf.st_size;
}
Kermit.bytesmoved = 0;
Kermit.percentage = 0;
return hfile;
}
static HANDLE NEAR GetReceiveFileName(HWND hWnd, BYTE *packet)
{
HANDLE hInstance = (HANDLE)GetWindowWord(hWnd, GWW_HINSTANCE);
register int i, j;
char filename[13];
char ext[5];
int numresult;
char *ptrresult;
BOOL gotextension;
HANDLE hfile;
char tempname[9], genstring[20];
int filecount;
Kermit.newname_flag = FALSE;
memset(filename, NUL, 13);
ext[0] = NUL;
SetDlgItemText(hWndXfer, IDD_FILENAME,(LPSTR)packet);
ptrresult = strtok(packet, "."); /* look for any extension */
numresult = strlen(ptrresult); /* find out how long */
numresult = numresult < 8 ? numresult : 8;
strncpy(filename,ptrresult,numresult); /* load up name */
gotextension = FALSE;
ptrresult = strtok(NULL, "."); /* get extension */
if (ptrresult != NULL) {
strcpy(ext,".");
strncat(ext, ptrresult,3);
ext[4] = NUL;
strcat(filename, ext);
gotextension = TRUE;
}
if (Kermit.filewarning) {
for (filecount = 0; filecount < INT_MAX; filecount++) {
if ((hfile = OpenFile((LPSTR)filename,
(OFSTRUCT FAR *)&myofstruct,OF_EXIST)) == -1)
break;
ptrresult = strtok(filename, ".");
strcpy(tempname, ptrresult);
numresult = strlen(ptrresult);
for (i = numresult; i < 8; i++)
tempname[i] = '0';
numresult = strlen(itoa(filecount + 1, genstring,10));
for (i = 8 - numresult, j = 0; i < 8; i++,j++)
tempname[i] = genstring[j];
tempname[8] = NUL;
strcpy(filename, tempname);
if (gotextension)
strcat(filename,ext);
}
if (filecount > 0)
Kermit.newname_flag = TRUE;
}
hfile = OpenFile((LPSTR)filename,(OFSTRUCT FAR *)&myofstruct,OF_CREATE);
if (hfile != -1) {
Kermit.filename = (strrchr(myofstruct.szPathName,'\\') + 1);
SetDlgItemText(hWndXfer, IDD_SAVENAME,(LPSTR)Kermit.filename);
}
Kermit.bytesmoved = 0;
return (hfile);
}
static int NEAR input() {
int type, rsn, seq;
int startcount;
if (Kermit.sstate > 0) {
type = Kermit.sstate;
Kermit.sstate = 0;
return(type);
}
if (Kermit.protocolabort)
return('$');
again:
if (!Kermit.inpacket) {
if (IsWindow(hWndXfer))
UpdateXferBox();
if (Kermit.timer)
SetTimer(lclhWnd, KRM_WAITPACKET, Kermit.mstimeout, Kermit.fpTimer);
Kermit.inpacket = TRUE;
}
startcount = lclcount;
lclcount = getpacket(lclbuf, lclcount);
lclbuf += startcount - lclcount;
if (rcvpkt.state == PS_DONE) {
rcvpkt.state = PS_SYNCH;
Kermit.inpacket = FALSE;
if (Kermit.timer) {
KillTimer(lclhWnd, KRM_WAITPACKET);
Kermit.timeout = FALSE;
}
type = rcvpkt.type;
rsn = rcvpkt.num;
seq = Kermit.pktnum;
if (type == sndpkt.pktbuf[3])
goto again;
if ((rsn != seq) || (type == 'N') || (type == 'Q')) {
if ((type == 'N') && (rsn == (seq + 1) & 63)) {
Kermit.numtry = 0;
return ('Y');
}
else {
resend();
goto again;
}
}
Kermit.numtry = 0;
return (type);
}
else {
if (Kermit.timeout) {
Kermit.timeout = FALSE;
resend();
}
return('p');
}
}
/* get a packet, complete or partial */
static int NEAR getpacket(BYTE *str, int len) {
register BYTE t;
register int i;
while (len) {
switch (rcvpkt.state) {
case PS_SYNCH:
while (len) {
if (*str != rcvpkt.mark) {
str++;
len--;
}
else
break;
}
if (len) {
str++;
len--;
rcvpkt.state = PS_LEN;
rcvpkt.cchksum = 0;
rcvpkt.data_count = 0;
rcvpkt.data[0] = NUL;
}
break;
case PS_LEN:
if ((t = *str) == rcvpkt.mark)
rcvpkt.state = PS_SYNCH;
else {
rcvpkt.state = PS_NUM;
rcvpkt.len = unchar(t) - 2 - Kermit.chksumtype;
rcvpkt.cchksum += t;
str++;
len--;
}
break;
case PS_NUM:
if ((t = *str) == rcvpkt.mark)
rcvpkt.state = PS_SYNCH;
else {
rcvpkt.state = PS_TYPE;
rcvpkt.num = unchar(t);
rcvpkt.cchksum += t;
str++;
len--;
}
break;
case PS_TYPE:
if ((t = *str) == rcvpkt.mark)
rcvpkt.state = PS_SYNCH;
else {
if (rcvpkt.len)
rcvpkt.state = PS_DATA;
else
rcvpkt.state = PS_CHK;
rcvpkt.type = t;
rcvpkt.cchksum += t;
str++;
len--;
}
break;
case PS_DATA:
for (i = rcvpkt.data_count; i < rcvpkt.len; i++) {
if ((t = *str) == rcvpkt.mark)
break;
else {
rcvpkt.data[i] = t;
rcvpkt.cchksum += t;
rcvpkt.data_count += 1;
str++;
len--;
if (len <= 0)
break;
}
}
if (t == rcvpkt.mark)
rcvpkt.state = PS_SYNCH;
else if (rcvpkt.data_count == rcvpkt.len) {
rcvpkt.data[rcvpkt.len] = NUL;
rcvpkt.state = PS_CHK;
}
break;
case PS_CHK:
if ((t = *str) == rcvpkt.mark)
rcvpkt.state = PS_SYNCH;
else {
rcvpkt.rchksum = unchar(t);
str++;
len--;
rcvpkt.cchksum = (((rcvpkt.cchksum & 0xC0) >> 6)
+ rcvpkt.cchksum) & 0x3f;
if (rcvpkt.cchksum != rcvpkt.rchksum)
rcvpkt.type = 'Q';
rcvpkt.state = PS_DONE;
}
break;
case PS_DONE:
if ((t = *str) == (BYTE)local.eol) {
str++;
len--;
}
return len;
} /* switch */
} /* while */
return len;
}
static void NEAR ShowTransactionError(HWND hWnd, int id)
{
char szMessage[80];
char szCaption[40];
HANDLE hInstance = (HANDLE)GetWindowWord(hWnd, GWW_HINSTANCE);
LoadString(hInstance, IDS_KRM_KERMIT, (LPSTR)szCaption, sizeof(szCaption));
LoadString(hInstance, id, (LPSTR)szMessage, sizeof(szMessage));
if (Kermit.bell)
MessageBeep(MB_OK | MB_ICONASTERISK);
MessageBox(hWnd,(LPSTR)szMessage,(LPSTR)szCaption, MB_OK | MB_ICONASTERISK);
}
static void NEAR UpdateXferBox()
{
char str[20];
static int prevcount;
if (IsIconic(lclhWnd))
InvalidateRect(lclhWnd, (LPRECT)NULL, FALSE);
else {
SetDlgItemText(hWndXfer,IDD_BYTESMOVED,ltoa(Kermit.bytesmoved,str,10));
SetDlgItemInt(hWndXfer,IDD_PACKETS,Kermit.pktcount,0);
if (krmState == IDM_KRM_SEND)
SetDlgItemInt(hWndXfer,IDD_PERCENTAGE,Kermit.percentage,0);
if (prevcount != Kermit.retrycount) {
SetDlgItemInt(hWndXfer,IDD_RETRIES,Kermit.retrycount,0);
prevcount = Kermit.retrycount;
}
}
}