home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
bbs_mail
/
bsrc_250.arj
/
ZMISC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-15
|
22KB
|
742 lines
/*--------------------------------------------------------------------------*/
/* */
/* */
/* ------------ 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. */
/* */
/* */
/* Zmodem routines used by Zsend and Zreceive */
/* */
/* */
/* 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. */
/* */
/* */
/* This module is based largely on a similar module in OPUS-CBCS V1.03b. */
/* The original work is (C) Copyright 1986, Wynn Wagner III. The original */
/* authors have graciously allowed us to use their code in this work. */
/* */
/*--------------------------------------------------------------------------*/
/* Include this file before any other includes or defines! */
#include "includes.h"
static int Rxtype; /* Type of header received */
static char hex[] = "0123456789abcdef";
/* Send a byte as two hex digits */
#define Z_PUTHEX(i,c) {i=(c);SENDBYTE(hex[((i)&0xF0)>>4]);SENDBYTE(hex[(i)&0xF]);}
/*--------------------------------------------------------------------------*/
/* Private routines */
/*--------------------------------------------------------------------------*/
int _Z_GetBinaryHeader (unsigned char *);
int _Z_32GetBinaryHeader (unsigned char *);
int _Z_GetHexHeader (unsigned char *);
int _Z_GetHex (void);
int _Z_TimedRead (void);
long _Z_PullLongFromHeader (unsigned char *);
#ifdef MILQ
/*
* Dst - Where to put this. Should use a static buffer, if
* a destination is not provided
*
* Src - The filename to be conditioned
*
* TblNm - Name of the file to use for the source of path
* conditioning entries
*
* Mode -
*/
char *ZMdmFlNmCndtn( char *Dst,
char *Src,
char *Tbl,
int Mode ) {
char *p;
char *q;
for ( p = Src, q = Dst; *p; ) {
switch ( *p ) {
case '/':
case '\\':
switch ( UsePaths ) {
case FALSE:
q = Dst;
break;
default:
*q++ = '/';
break;
} /* end of switch ( UsePaths ) */
break;
case ':':
q = Dst;
break;
default:
*q++ = (char) tolower (*p);
break;
} /* end of for ( p = Src ... ) */
p++;
}
*q++ = '\0';
return Dst;
}
#endif
void z_message (char *s)
{
if (fullscreen && un_attended)
{
if (s)
{
sb_move (file_hWnd, 2, 27);
FlLnModeSet( FILE_LN_2, 0 );
sb_puts( GetDlgItem( file_hWnd, FILE_LN_2 + GD_STATUS ), s );
}
#ifndef MILQ
sb_puts (file_hWnd, " ");
#endif
sb_show ();
}
else
{
gotoxy (locate_x + 20, locate_y);
if (s)
{
(void) cputs (s);
}
(void) cputs (" ");
}
}
void z_log (char *s)
{
word x, y;
z_message (s);
x = locate_x;
y = locate_y;
status_line (s); /* also does disk file
* logging */
locate_x = x;
locate_y = y;
}
void show_loc (unsigned long l, unsigned int w)
{
char j[100];
if (fullscreen && un_attended)
{
(void) sprintf (j, "Ofs=%ld Retries=%d ", l, w);
sb_move (file_hWnd, 2, 37);
sb_puts( GetDlgItem( file_hWnd, FILE_LN_2 + GD_SIZE ), j );
sb_show ();
}
else
{
gotoxy (locate_x + 35, locate_y);
(void) printf ("Ofs=%ld Retries=%d ", l, w);
}
}
/*--------------------------------------------------------------------------*/
/* Z GET BYTE */
/* Get a byte from the modem; */
/* return TIMEOUT if no read within timeout tenths, */
/* return RCDO if carrier lost */
/*--------------------------------------------------------------------------*/
int Z_GetByte (int tenths)
{
long timeout;
if (PEEKBYTE () >= 0)
return (MODEM_IN ());
timeout = timerset (tenths * 10);
do
{
if (PEEKBYTE () >= 0)
return MODEM_IN ();
if (!CARRIER)
return RCDO;
if (got_ESC ())
return -1;
time_release ();
}
while (!timeup (timeout));
return TIMEOUT;
}
/*--------------------------------------------------------------------------*/
/* Z PUT STRING */
/* Send a string to the modem, processing for \336 (sleep 1 sec) */
/* and \335 (break signal, ignored) */
/*--------------------------------------------------------------------------*/
void Z_PutString (register unsigned char *s)
{
register unsigned c;
while (*s)
{
switch (c = *s++)
{
case (unsigned int) '\336':
big_pause (2);
case (unsigned int) '\335':
/* Should send a break on this */
break;
default:
SENDBYTE ((unsigned char) c);
} /* switch */
} /* while */
Z_UncorkTransmitter (); /* Make sure all is well */
} /* Z_PutString */
/*--------------------------------------------------------------------------*/
/* Z SEND HEX HEADER */
/* Send ZMODEM HEX header hdr of type type */
/*--------------------------------------------------------------------------*/
void Z_SendHexHeader (unsigned int type, register unsigned char *hdr)
{
register int n;
register int i;
register word crc;
Z_UncorkTransmitter (); /* Get our transmitter going */
#ifdef DEBUG
show_debug_name ("Z_SendHexHeader");
#endif
SENDBYTE (ZPAD);
SENDBYTE (ZPAD);
SENDBYTE (ZDLE);
SENDBYTE (ZHEX);
Z_PUTHEX (i, type);
Crc32t = 0;
crc = Z_UpdateCRC (type, 0);
for (n = 4; --n >= 0;)
{
Z_PUTHEX (i, (*hdr));
crc = Z_UpdateCRC (((unsigned short) (*hdr++)), crc);
}
Z_PUTHEX (i, (crc >> 8));
Z_PUTHEX (i, crc);
/* Make it printable on remote machine */
SENDBYTE ('\r');
SENDBYTE ('\n');
/* Uncork the remote in case a fake XOFF has stopped data flow */
if (type != ZFIN && type != ZACK)
SENDBYTE (021);
if (!CARRIER)
CLEAR_OUTBOUND ();
} /* Z_SendHexHeader */
/*--------------------------------------------------------------------------*/
/* Z UNCORK TRANSMITTER */
/* Wait a reasonable amount of time for transmitter buffer to clear. */
/* When it does, or when time runs out, turn XON/XOFF off then on. */
/* This should release a transmitter stuck by line errors. */
/*--------------------------------------------------------------------------*/
void Z_UncorkTransmitter ()
{
long t;
#ifdef DEBUG
show_debug_name ("Z_UncorkTransmitter");
#endif
if (!OUT_EMPTY () && CARRIER)
{
t = timerset (5 * Rxtimeout); /* Wait for silence */
while (!timeup (t) && !OUT_EMPTY () && CARRIER)
time_release (); /* Give up slice while
* waiting */
}
com_kick ();
}
/*--------------------------------------------------------------------------*/
/* Z GET HEADER */
/* Read a ZMODEM header to hdr, either binary or hex. */
/* On success, set Zmodem to 1 and return type of header. */
/* Otherwise return negative on error */
/*--------------------------------------------------------------------------*/
int Z_GetHeader (byte *hdr)
{
register int c;
register int n;
int cancount;
#ifdef DEBUG
show_debug_name ("Z_GetHeader");
#endif
n = cur_baud.rate_value; /* Max characters before
* start of frame */
cancount = 5;
Again:
if (got_ESC ())
{
send_can ();
z_log (MSG_TXT(M_KBD_MSG));
return ZCAN;
}
Rxframeind = Rxtype = 0;
switch (c = _Z_TimedRead ())
{
case ZPAD:
case ZPAD | 0200:
/*-----------------------------------------------*/
/* This is what we want. */
/*-----------------------------------------------*/
break;
case RCDO:
case TIMEOUT:
goto Done;
case CAN:
GotCan:
if (--cancount <= 0)
{
c = ZCAN;
goto Done;
}
switch (c = Z_GetByte (1))
{
case TIMEOUT:
goto Again;
case ZCRCW:
c = ERROR;
/* fallthrough... */
case RCDO:
goto Done;
case CAN:
if (--cancount <= 0)
{
c = ZCAN;
goto Done;
}
goto Again;
}
/* fallthrough... */
default:
Agn2:
if (--n <= 0)
{
z_log (MSG_TXT(M_FUBAR_MSG));
return ERROR;
}
if (c != CAN)
cancount = 5;
goto Again;
} /* switch */
cancount = 5;
Splat:
switch (c = _Z_TimedRead ())
{
case ZDLE:
/*-----------------------------------------------*/
/* This is what we want. */
/*-----------------------------------------------*/
break;
case ZPAD:
goto Splat;
case RCDO:
case TIMEOUT:
goto Done;
default:
goto Agn2;
} /* switch */
switch (c = _Z_TimedRead ())
{
case ZBIN:
Rxframeind = ZBIN;
Crc32 = 0;
c = _Z_GetBinaryHeader (hdr);
break;
case ZBIN32:
Crc32 = Rxframeind = ZBIN32;
c = _Z_32GetBinaryHeader (hdr);
break;
case ZHEX:
Rxframeind = ZHEX;
Crc32 = 0;
c = _Z_GetHexHeader (hdr);
break;
case CAN:
goto GotCan;
case RCDO:
case TIMEOUT:
goto Done;
default:
goto Agn2;
} /* switch */
Rxpos = _Z_PullLongFromHeader (hdr);
Done:
return c;
} /* Z_GetHeader */
/*--------------------------------------------------------------------------*/
/* Z GET BINARY HEADER */
/* Receive a binary style header (type and position) */
/*--------------------------------------------------------------------------*/
int _Z_GetBinaryHeader (register unsigned char *hdr)
{
register int c;
register unsigned int crc;
register int n;
#ifdef DEBUG
show_debug_name ("Z_GetBinaryHeader");
#endif
if ((c = Z_GetZDL ()) & ~0xFF)
return c;
Rxtype = c;
crc = Z_UpdateCRC (c, 0);
for (n = 4; --n >= 0;)
{
if ((c = Z_GetZDL ()) & ~0xFF)
return c;
crc = Z_UpdateCRC (c, crc);
*hdr++ = (unsigned char) (c & 0xff);
}
if ((c = Z_GetZDL ()) & ~0xFF)
return c;
crc = Z_UpdateCRC (c, crc);
if ((c = Z_GetZDL ()) & ~0xFF)
return c;
crc = Z_UpdateCRC (c, crc);
if (crc & 0xFFFF)
{
z_message (MSG_TXT(M_CRC_MSG));
return ERROR;
}
return Rxtype;
} /* _Z_GetBinaryHeader */
/*--------------------------------------------------------------------------*/
/* Z GET BINARY HEADER with 32 bit CRC */
/* Receive a binary style header (type and position) */
/*--------------------------------------------------------------------------*/
int _Z_32GetBinaryHeader (register unsigned char *hdr)
{
register int c;
register unsigned long crc;
register int n;
#ifdef DEBUG
show_debug_name ("Z_32GetBinaryHeader");
#endif
if ((c = Z_GetZDL ()) & ~0xFF)
return c;
Rxtype = c;
crc = 0xFFFFFFFF;
crc = Z_32UpdateCRC (c, crc);
for (n = 4; --n >= 0;)
{
if ((c = Z_GetZDL ()) & ~0xFF)
return c;
crc = Z_32UpdateCRC (c, crc);
*hdr++ = (unsigned char) (c & 0xff);
}
for (n = 4; --n >= 0;)
{
if ((c = Z_GetZDL ()) & ~0xFF)
return c;
crc = Z_32UpdateCRC (c, crc);
}
if (crc != 0xDEBB20E3)
{
z_message (MSG_TXT(M_CRC_MSG));
return ERROR;
}
return Rxtype;
} /* _Z_32GetBinaryHeader */
/*--------------------------------------------------------------------------*/
/* Z GET HEX HEADER */
/* Receive a hex style header (type and position) */
/*--------------------------------------------------------------------------*/
int _Z_GetHexHeader (register unsigned char *hdr)
{
register int c;
register unsigned int crc;
register int n;
#ifdef DEBUG
show_debug_name ("Z_GetHexHeader");
#endif
if ((c = _Z_GetHex ()) < 0)
return c;
Rxtype = c;
crc = Z_UpdateCRC (c, 0);
for (n = 4; --n >= 0;)
{
if ((c = _Z_GetHex ()) < 0)
return c;
crc = Z_UpdateCRC (c, crc);
*hdr++ = (unsigned char) c;
}
if ((c = _Z_GetHex ()) < 0)
return c;
crc = Z_UpdateCRC (c, crc);
if ((c = _Z_GetHex ()) < 0)
return c;
crc = Z_UpdateCRC (c, crc);
if (crc & 0xFFFF)
{
z_message (MSG_TXT(M_CRC_MSG));
return ERROR;
}
if (Z_GetByte (1) == '\r')
(void) Z_GetByte (1); /* Throw away possible cr/lf */
return Rxtype;
}
/*--------------------------------------------------------------------------*/
/* Z GET HEX */
/* Decode two lower case hex digits into an 8 bit byte value */
/*--------------------------------------------------------------------------*/
int _Z_GetHex ()
{
register int c, n;
#ifdef DEBUG
show_debug_name ("Z_GetHex");
#endif
if ((n = _Z_TimedRead ()) < 0)
return n;
n -= '0';
if (n > 9)
n -= ('a' - ':');
if (n & ~0xF)
return ERROR;
if ((c = _Z_TimedRead ()) < 0)
return c;
c -= '0';
if (c > 9)
c -= ('a' - ':');
if (c & ~0xF)
return ERROR;
return ((n << 4) | c);
}
/*--------------------------------------------------------------------------*/
/* Z GET ZDL */
/* Read a byte, checking for ZMODEM escape encoding */
/* including CAN*5 which represents a quick abort */
/*--------------------------------------------------------------------------*/
int Z_GetZDL ()
{
register int c;
if ((c = Z_GetByte (Rxtimeout)) != ZDLE)
return c;
switch (c = Z_GetByte (Rxtimeout))
{
case CAN:
return ((c = Z_GetByte (Rxtimeout)) < 0) ? c :
((c == CAN) && ((c = Z_GetByte (Rxtimeout)) < 0)) ? c :
((c == CAN) && ((c = Z_GetByte (Rxtimeout)) < 0)) ? c : (GOTCAN);
case ZCRCE:
case ZCRCG:
case ZCRCQ:
case ZCRCW:
return (c | GOTOR);
case ZRUB0:
return 0x7F;
case ZRUB1:
return 0xFF;
default:
return (c < 0) ? c :
((c & 0x60) == 0x40) ? (c ^ 0x40) : ERROR;
} /* switch */
} /* Z_GetZDL */
/*--------------------------------------------------------------------------*/
/* Z TIMED READ */
/* Read a character from the modem line with timeout. */
/* Eat parity, XON and XOFF characters. */
/*--------------------------------------------------------------------------*/
int _Z_TimedRead ()
{
register int c;
#ifdef DEBUG
show_debug_name ("Z_TimedRead");
#endif
for (;;)
{
if ((c = Z_GetByte (Rxtimeout)) < 0)
return c;
switch (c &= 0x7F)
{
case XON:
case XOFF:
continue;
default:
if (!(c & 0x60))
continue;
case '\r':
case '\n':
case ZDLE:
return c;
} /* switch */
} /* for */
} /* _Z_TimedRead */
/*--------------------------------------------------------------------------*/
/* Z LONG TO HEADER */
/* Store long integer pos in Txhdr */
/*--------------------------------------------------------------------------*/
void Z_PutLongIntoHeader (long pos)
{
#ifndef GENERIC
*((long *) Txhdr) = pos;
#else
Txhdr[ZP0] = pos;
Txhdr[ZP1] = pos >> 8;
Txhdr[ZP2] = pos >> 16;
Txhdr[ZP3] = pos >> 24;
#endif
} /* Z_PutLongIntoHeader */
/*--------------------------------------------------------------------------*/
/* Z PULL LONG FROM HEADER */
/* Recover a long integer from a header */
/*--------------------------------------------------------------------------*/
long _Z_PullLongFromHeader (unsigned char *hdr)
{
#ifndef GENERIC
return (*((long *) hdr)); /*PLF Fri 05-05-1989 06:42:41 */
#else
long l;
l = hdr[ZP3];
l = (l << 8) | hdr[ZP2];
l = (l << 8) | hdr[ZP1];
l = (l << 8) | hdr[ZP0];
return l;
#endif
} /* _Z_PullLongFromHeader */
/* END OF FILE: zmisc.c */