📄 zm.c
字号:
c = GCOUNT;
return zRcvFin(c);
}
/* start again from header */
bRxZPAD = bRxZDLE = bRxZHdr = 0;
nCanCount = 5;
break;
}
gfCrc32 = 1; /* for RcvData check */
c = zRcvBinHdr32(pHdrFlag, nRxHdrLen);
bRxZHdr = 1; /* escape from while */
break;
case ZBIN32 :
if(gfUseVHdrs)
{ /* invalid header type */
if(--nGarbageCnt == 0)
{
c = GCOUNT;
return zRcvFin(c);
}
/* start again from header */
bRxZPAD = bRxZDLE = bRxZHdr = 0;
nCanCount = 5;
break;
}
gfCrc32 = 1; /* for RcvData check */
c = zRcvBinHdr32(pHdrFlag, nRxHdrLen);
bRxZHdr = 1; /* escape from while */
break;
case ZVBINR32 :
if((nRxHdrLen = c = zDLERead()) < 0)
return zRcvFin(c);
if(c > ZMAXHLEN)
{ /* invalid header length */
if(--nGarbageCnt == 0)
{
c = GCOUNT;
return zRcvFin(c);
}
/* start again from header */
bRxZPAD = bRxZDLE = bRxZHdr = 0;
nCanCount = 5;
break;
}
gfCrc32 = 2; /* for RcvData check */
c = zRcvBinHdr32(pHdrFlag, nRxHdrLen);
bRxZHdr = 1; /* escape from while */
break;
case ZBINR32 :
if(gfUseVHdrs)
{ /* invalid header type */
if(--nGarbageCnt == 0)
{
c = GCOUNT;
return zRcvFin(c);
}
/* start again from header */
bRxZPAD = bRxZDLE = bRxZHdr = 0;
nCanCount = 5;
break;
}
gfCrc32 = 2; /* for RcvData check */
c = zRcvBinHdr32(pHdrFlag, nRxHdrLen);
bRxZHdr = 1; /* escape from while */
break;
case RCD0 :
case TIMEOUT :
return zRcvFin(c);
case ZVBIN :
if((nRxHdrLen = c = zDLERead()) < 0)
return zRcvFin(c);
if(c > ZMAXHLEN)
{ /* invalid header length */
if(--nGarbageCnt == 0)
{
c = GCOUNT;
return zRcvFin(c);
}
/* start again from header */
bRxZPAD = bRxZDLE = bRxZHdr = 0;
nCanCount = 5;
break;
}
gfCrc32 = 0; /* for RcvData check */
c = zRcvBinHdr(pHdrFlag, nRxHdrLen);
bRxZHdr = 1; /* escape from while */
break;
case ZBIN :
if(gfUseVHdrs)
{ /* invalid header type */
if(--nGarbageCnt == 0)
{
c = GCOUNT;
return zRcvFin(c);
}
/* start again from header */
bRxZPAD = bRxZDLE = bRxZHdr = 0;
nCanCount = 5;
break;
}
gfCrc32 = 0; /* for RcvData check */
c = zRcvBinHdr(pHdrFlag, nRxHdrLen);
bRxZHdr = 1; /* escape from while */
break;
case ZVHEX :
if((nRxHdrLen = c = zGetHex()) < 0)
return zRcvFin(c);
if(c > ZMAXHLEN)
{ /* invalid header length */
if(--nGarbageCnt == 0)
{
c = GCOUNT;
return zRcvFin(c);
}
/* start again from header */
bRxZPAD = bRxZDLE = bRxZHdr = 0;
nCanCount = 5;
break;
}
gfCrc32 = 0; /* for RcvData check */
c = zRcvHexHdr(pHdrFlag, nRxHdrLen);
bRxZHdr = 1; /* escape from while */
break;
case ZHEX :
if(gfUseVHdrs)
{ /* invalid header type */
if(--nGarbageCnt == 0)
{
c = GCOUNT;
return zRcvFin(c);
}
/* start again from header */
bRxZPAD = bRxZDLE = bRxZHdr = 0;
nCanCount = 5;
break;
}
gfCrc32 = 0;
c = zRcvHexHdr(pHdrFlag, nRxHdrLen);
bRxZHdr = 1; /* escape from while */
break;
case CAN :
goto gotcan;
break;
default :
/* invalid header type : start over again */
if(--nGarbageCnt == 0)
{
c = GCOUNT;
return zRcvFin(c);
}
/* start again from header */
bRxZPAD = bRxZDLE = bRxZHdr = 0;
nCanCount = 5;
break;
} /* switch(hdrType) */
} /* while(!bRxHdr) */
/* clear unused pHdrFlag bytes */
for(n=nRxHdrLen; ++n < ZMAXHLEN;)
pHdrFlag[n] = 0;
lRxPos = pHdrFlag[ZP3] & 0377;
lRxPos = (lRxPos << 8) + (pHdrFlag[ZP2] & 0377);
lRxPos = (lRxPos << 8) + (pHdrFlag[ZP1] & 0377);
lRxPos = (lRxPos << 8) + (pHdrFlag[ZP0] & 0377);
/* use variable length headers if we got one */
if(c >= 0 && c <= ZSTDERR && (nRxFrameInd & 040))
gfUseVHdrs = 1;
return c;
}
int zRcvFin(int c)
{
return c;
}
///////////////////////////////////////////////////////////////////////////////
// int zRcvBinHdr(char *pHdrFlag, int nHdrLen)
// Receive a binary style(type 'A')
// ( * ZDLE A TYPE F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2)
//
// NB : TYPE, 4 pos bytes, two bytes of CRC are all ZDLE encoded.
int zRcvBinHdr(char *pHdrFlag, int nHdrLen)
{
int c, n;
unsigned short usCrc;
int nRxHdrType;
/* type */
if((c = zDLERead()) & ~0377)
return c;
nRxHdrType = c;
usCrc = updcrc(c, 0);
/* 4 position/flag bytes */
for(n=nHdrLen; --n>= 0; ++pHdrFlag)
{
if((c = zDLERead()) & ~0377)
return c;
usCrc = updcrc(c, usCrc);
*pHdrFlag = c;
}
/* crc-1 */
if((c = zDLERead()) & ~0377)
return c;
usCrc = updcrc(c, usCrc);
/* crc-2 */
if((c = zDLERead()) & ~0377)
return c;
usCrc = updcrc(c, usCrc);
if(usCrc & 0xFFFF)
{ /* crc error */
return ERROR;
}
return nRxHdrType;
}
///////////////////////////////////////////////////////////////////////////////
// int zRcvBinHdr32(char *pHdrFlag, int nHdrLen)
// Receive a binary style(type 'A') with 32 bit FCS
// ( * ZDLE A TYPE F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2)
//
// NB : TYPE, 4 pos bytes, four bytes of CRC are all ZDLE encoded.
int zRcvBinHdr32(char *pHdrFlag, int nHdrLen)
{
int c, n;
unsigned long ulCrc;
int nRxHdrType;
/* type */
if((c = zDLERead()) & ~0377)
return c;
nRxHdrType = c;
ulCrc = 0xFFFFFFFFl;
ulCrc = UPDC32(c, ulCrc);
/* 4 position/flag bytes */
for(n=nHdrLen; --n>= 0; ++pHdrFlag)
{
if((c = zDLERead()) & ~0377)
return c;
ulCrc = UPDC32(c, ulCrc);
*pHdrFlag = c;
}
/* crc four bytes */
for(n=4; --n >=0; )
{
if((c = zDLERead()) & ~0377)
return c;
ulCrc = UPDC32(c, ulCrc);
}
if(ulCrc != 0xDEBB20E3)
{ /* crc error */
return ERROR;
}
return nRxHdrType;
}
///////////////////////////////////////////////////////////////////////////////
// int zRcvHexHdr(char *pHdrFlag, int nHdrLen)
// Receive a hex style(type 'B')
// ( * * ZDLE B TYPE F3/P0 F2/P1 F1/P2 F0/P3 CRC-1 CRC-2 CR LF XON )
//
// NB : TYPE, four pos bytes, and two bytes of CRC are each sent as two hex digits.
//
int zRcvHexHdr(char *pHdrFlag, int nHdrLen)
{
int c, n;
unsigned short usCrc;
int nRxHdrType; /* Type of header received */
/* type */
if((c = zGetHex()) < 0)
{
return c;
}
nRxHdrType = c;
usCrc = updcrc(c, 0); // for later use crc
/* 4 position/flag bytes */
for(n=nHdrLen; --n>= 0; ++pHdrFlag)
{
if((c = zGetHex()) < 0)
{
return c;
}
usCrc = updcrc(c, usCrc);
*pHdrFlag = c;
}
/* crc-1 */
if((c = zGetHex()) < 0)
{
return c;
}
usCrc = updcrc(c, usCrc);
/* crc-2 */
if((c = zGetHex()) < 0)
{
return c;
}
usCrc = updcrc(c, usCrc);
if(usCrc & 0xFFFF)
{ /* crc error */
return ERROR;
}
/* CR/LF XON */
if((c = ReadLine(RX_TIMEOUT)) < 0)
{
return c;
}
if((c = ReadLine(RX_TIMEOUT)) < 0)
{
return c;
}
return nRxHdrType;
}
///////////////////////////////////////////////////////////////////////////////
// int zDLERead(void)
// Read a byte, checking for ZMODEM escaped(ZDLE) encoding
// including CNA*5 which represents a quick abort.
// return : 32 ~127 = non-escaped character recieved.
// GOTCAN = five successive CAN(030) character.
int zDLERead(void)
{
int c;
int bRcvZDLE = 0;
while(!bRcvZDLE)
{ /* until ZDLE receved or non-escaped characters */
if((c = ReadLine(RX_TIMEOUT)) & 0140) /* non-escpaed character(32 ~127) */
return c;
switch(c)
{
case ZDLE :
bRcvZDLE = 1;
break;
case 023 :
case 0223 :
case 021 :
case 0221 :
break; /* ignores */
default :
if(gzCtlEsc && !(c & 0140)) // if escaped character
break; // ignores
else
return c;
}
}
// process ZDLE sequence and also check CAN*5?
while(1)
{
if((c = ReadLine(RX_TIMEOUT)) < 0)
return c;
if(c == CAN && (c = ReadLine(RX_TIMEOUT)) < 0)
return c;
if(c == CAN && (c = ReadLine(RX_TIMEOUT)) < 0)
return c;
if(c == CAN && (c = ReadLine(RX_TIMEOUT)) < 0)
return c;
switch(c)
{
case CAN :
return GOTCAN;
/* valid ZDLE seequence */
case ZCRCE :
case ZCRCG :
case ZCRCQ :
case ZCRCW :
return (c | GOTOR);
case ZRUB0 : /* translated to 0177 */
return 0177;
case ZRUB1 : /* translated to 0377 */
return 0377;
/* until here valid ZDLE seequence */
case 023 :
case 0223 :
case 021 :
case 0221 :
break; // ignore
default :
if(gzCtlEsc && !(c & 0140))
break; // ignore
if((c & 0140) == 0100)
return (c ^ 0100);
// in this case, error
return ERROR;
}
}
}
///////////////////////////////////////////////////////////////////////////////
// int zGetHex(void)
// Decode two lower case hex digits into an 8-bit byte value
int zGetHex(void)
{
int c;
int n, n2;
if((c = zReadChar()) < 0)
{
return c;
}
n = c - '0';
if(n > 9)
n -= ('a' - ':');
if(n & ~0xF)
{
return ERROR;
}
if((c = zReadChar()) < 0)
{
return c;
}
n2 = c - '0';
if(n2 > 9)
n2 -= ('a' - ':');
if(n2 & ~0xF)
{
return ERROR;
}
// c += (n << 4);
c = n2 + (n << 4);
return c;
}
///////////////////////////////////////////////////////////////////////////////
// int zPutHex(int c)
// Send a byte as two hex digits
int zPutHex(int c)
{
static char digits[] = "0123456789abcdef";
SendLine(digits[(c&0xF0)>>4]);
SendLine(digits[(c)&0xF]);
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// zReadChar(void)
// read a character from the modem line with timeout.
// eat parity, XON and XOFF characters.
int zReadChar(void)
{
int c;
while(1)
{
if((c = ReadLine(RX_TIMEOUT)) < 0)
return c;
c &= 0177; /* eat parity */
switch(c)
{
case XON :
case XOFF :
continue;
default :
if(gzCtlEsc && !(c & 0140))
{
continue;
}
case '\r' :
case '\n' :
case ZDLE :
return c;
}
}
}
///////////////////////////////////////////////////////////////////////////////
// zLongToChar4(char *pChar, long lPos)
// store long integer in char[4]
void zLongToChar4(char *pChar, long lLong)
{
pChar[ZP0] = (lLong & 0377);
pChar[ZP1] = (lLong>>8) & 0377;
pChar[ZP2] = (lLong>>16) & 0377;
pChar[ZP3] = (lLong>>24) & 0377;
return;
}
///////////////////////////////////////////////////////////////////////////////
// zChar4ToLong(char *hdr)
// recover a long integer from char[4]
long zChar4ToLong(char *pChar)
{
register long l;
l = (pChar[ZP3] & 0377);
l = (l << 8) | (pChar[ZP2] & 0377);
l = (l << 8) | (pChar[ZP1] & 0377);
l = (l << 8) | (pChar[ZP0] & 0377);
return l;
}
#endif//zmodem
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -