⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zm.c

📁 Linux下ztelnet 的rz、sz源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  zm.c - zmodem protocol handling lowlevelstuff  Copyright (C) until 1998 Chuck Forsberg (OMEN Technology Inc)  Copyright (C) 1996, 1997 Uwe Ohse  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2, or (at your option)  any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.  originally written by Chuck Forsberg*//* historical comment: -- uwe *   Z M . C *    ZMODEM protocol primitives *    05-09-88  Chuck Forsberg Omen Technology Inc * * Entry point Functions: *	zsbhdr(type, hdr) send binary header *	zshhdr(type, hdr) send hex header *	zgethdr(hdr, eflag) receive header - binary or hex *	zsdata(buf, len, frameend) send data *	zrdata(buf, len, bytes_received) receive data *	stohdr(pos) store position data in Txhdr *	long rclhdr(hdr) recover position offset from header */#include "zglobal.h"#include <stdio.h>unsigned int Rxtimeout = 100;		/* Tenths of seconds to wait for something *//* Globals used by ZMODEM functions */int Rxframeind;		/* ZBIN ZBIN32, or ZHEX type of frame received */int Rxtype;		/* Type of header received */char Rxhdr[4];		/* Received header */char Txhdr[4];		/* Transmitted header */long Txpos;		/* Transmitted file position */int Txfcs32;		/* TRUE means send binary frames with 32 bit FCS */int Crc32t;		/* Display flag indicating 32 bit CRC being sent */int Crc32;		/* Display flag indicating 32 bit CRC being received */int Znulls;		/* Number of nulls to send at beginning of ZDATA hdr */char Attn[ZATTNLEN+1];	/* Attention string rx sends to tx on err */static char lastsent;	/* Last char we sent */int turbo_escape;int bytes_per_error=0;static const char *frametypes[] = {	"Carrier Lost",		/* -3 */	"TIMEOUT",		/* -2 */	"ERROR",		/* -1 */#define FTOFFSET 3	"ZRQINIT",	"ZRINIT",	"ZSINIT",	"ZACK",	"ZFILE",	"ZSKIP",	"ZNAK",	"ZABORT",	"ZFIN",	"ZRPOS",	"ZDATA",	"ZEOF",	"ZFERR",	"ZCRC",	"ZCHALLENGE",	"ZCOMPL",	"ZCAN",	"ZFREECNT",	"ZCOMMAND",	"ZSTDERR",	"xxxxx"#define FRTYPES 22	/* Total number of frame types in this array */			/*  not including psuedo negative entries */};#define badcrc _("Bad CRC")/* static char *badcrc = "Bad CRC"; */static inline int noxrd7 __P ((void));static inline int zdlread __P ((void));static int zdlread2 __P ((int)) LRZSZ_ATTRIB_REGPARM(1);static inline int zgeth1 __P ((void));static void zputhex __P ((int c, char *pos));static inline int zgethex __P ((void));static int zrbhdr __P ((char *hdr));static int zrbhdr32 __P ((char *hdr));static int zrhhdr __P ((char *hdr));static char zsendline_tab[256];static int zrdat32 __P ((char *buf, int length, size_t *));static void zsbh32 __P ((char *hdr, int type));extern int zmodem_requested;#define sendline(c) putchar((c) & 0377)#define xsendline(c) putchar(c)/* * Read a character from the modem line with timeout. *  Eat parity, XON and XOFF characters. */static inline intnoxrd7(void){	register int c;	for (;;) {		if ((c = READLINE_PF(Rxtimeout)) < 0)			return c;		switch (c &= 0177) {		case XON:		case XOFF:			continue;		default:			if (Zctlesc && !(c & 0140))				continue;		case '\r':		case '\n':		case ZDLE:			return c;		}	}}static inline intzgeth1(void){	register int c, n;	if ((c = noxrd7()) < 0)		return c;	n = c - '0';	if (n > 9)		n -= ('a' - ':');	if (n & ~0xF)		return ERROR;	if ((c = noxrd7()) < 0)		return c;	c -= '0';	if (c > 9)		c -= ('a' - ':');	if (c & ~0xF)		return ERROR;	c += (n<<4);	return c;}/* Decode two lower case hex digits into an 8 bit byte value */static inline intzgethex(void){	register int c;	c = zgeth1();	VPRINTF(9,("zgethex: %02X", c));	return c;}/* * Read a byte, checking for ZMODEM escape encoding *  including CAN*5 which represents a quick abort */static inline intzdlread(void){	int c;	/* Quick check for non control characters */	if ((c = READLINE_PF(Rxtimeout)) & 0140)		return c;	return zdlread2(c);}/* no, i don't like gotos. -- uwe */static intzdlread2(int c){	goto jump_over; /* bad style */again:	/* Quick check for non control characters */	if ((c = READLINE_PF(Rxtimeout)) & 0140)		return c;jump_over:	switch (c) {	case ZDLE:		break;	case XON:	case (XON|0200):	case XOFF:	case (XOFF|0200):		goto again;	default:		if (Zctlesc && !(c & 0140)) {			goto again;		}		return c;	}again2:	if ((c = READLINE_PF(Rxtimeout)) < 0)		return c;	if (c == CAN && (c = READLINE_PF(Rxtimeout)) < 0)		return c;	if (c == CAN && (c = READLINE_PF(Rxtimeout)) < 0)		return c;	if (c == CAN && (c = READLINE_PF(Rxtimeout)) < 0)		return c;	switch (c) {	case CAN:		return GOTCAN;	case ZCRCE:	case ZCRCG:	case ZCRCQ:	case ZCRCW:		return (c | GOTOR);	case ZRUB0:		return 0177;	case ZRUB1:		return 0377;	case XON:	case (XON|0200):	case XOFF:	case (XOFF|0200):		goto again2;	default:		if (Zctlesc && ! (c & 0140)) {			goto again2;		}		if ((c & 0140) ==  0100)			return (c ^ 0100);		break;	}	VPRINTF(2,(_("Bad escape sequence %x"), c));	return ERROR;}/* * Send character c with ZMODEM escape sequence encoding. *  Escape XON, XOFF. Escape CR following @ (Telenet net escape) */inline void zsendline(int c){	switch(zsendline_tab[(unsigned) (c&=0377)])	{	case 0: 		xsendline(lastsent = c); 		break;	case 1:		xsendline(ZDLE);		c ^= 0100;		xsendline(lastsent = c);		break;	case 2:		if ((lastsent & 0177) != '@') {			xsendline(lastsent = c);		} else {			xsendline(ZDLE);			c ^= 0100;			xsendline(lastsent = c);		}		break;	}}static inline void zsendline_s(const char *s, size_t count) {	const char *end=s+count;	while(s!=end) {		int last_esc=0;		const char *t=s;		while (t!=end) {			last_esc=zsendline_tab[(unsigned) ((*t) & 0377)];			if (last_esc) 				break;			t++;		}		if (t!=s) {			fwrite(s,(size_t)(t-s),1,stdout);			lastsent=t[-1];			s=t;		}		if (last_esc) {			int c=*s;			switch(last_esc) {			case 0: 				xsendline(lastsent = c); 				break;			case 1:				xsendline(ZDLE);				c ^= 0100;				xsendline(lastsent = c);				break;			case 2:				if ((lastsent & 0177) != '@') {					xsendline(lastsent = c);				} else {					xsendline(ZDLE);					c ^= 0100;					xsendline(lastsent = c);				}				break;			}			s++;		}	}}/* Send ZMODEM binary header hdr of type type */void zsbhdr(int type, char *hdr){	register int n;	register unsigned short crc;	VPRINTF(3,("zsbhdr: %s %lx", frametypes[type+FTOFFSET], rclhdr(hdr)));	if (type == ZDATA)		for (n = Znulls; --n >=0; )			xsendline(0);	xsendline(ZPAD); xsendline(ZDLE);	Crc32t=Txfcs32;	if (Crc32t)		zsbh32(hdr, type);	else {		xsendline(ZBIN); zsendline(type); crc = updcrc(type, 0);		for (n=4; --n >= 0; ++hdr) {			zsendline(*hdr);			crc = updcrc((0377& *hdr), crc);		}		crc = updcrc(0,updcrc(0,crc));		zsendline(crc>>8);		zsendline(crc);	}	if (type != ZDATA)		flushmo();}/* Send ZMODEM binary header hdr of type type */static voidzsbh32(char *hdr, int type){	register int n;	register unsigned long crc;	xsendline(ZBIN32);  zsendline(type);	crc = 0xFFFFFFFFL; crc = UPDC32(type, crc);	for (n=4; --n >= 0; ++hdr) {		crc = UPDC32((0377 & *hdr), crc);		zsendline(*hdr);	}	crc = ~crc;	for (n=4; --n >= 0;) {		zsendline((int)crc);		crc >>= 8;	}}/* Send ZMODEM HEX header hdr of type type */void zshhdr(int type, char *hdr){	register int n;	register unsigned short crc;	char s[30];	size_t len;	VPRINTF(3,("zshhdr: %s %lx", frametypes[(type & 0x7f)+FTOFFSET], rclhdr(hdr)));	s[0]=ZPAD;	s[1]=ZPAD;	s[2]=ZDLE;	s[3]=ZHEX;	zputhex(type & 0x7f ,s+4);	len=6;	Crc32t = 0;	crc = updcrc((type & 0x7f), 0);	for (n=4; --n >= 0; ++hdr) {		zputhex(*hdr,s+len); 		len += 2;		crc = updcrc((0377 & *hdr), crc);	}	crc = updcrc(0,updcrc(0,crc));	zputhex(crc>>8,s+len); 	zputhex(crc,s+len+2);	len+=4;	/* Make it printable on remote machine */	s[len++]=015;	s[len++]=0212;	/*	 * Uncork the remote in case a fake XOFF has stopped data flow	 */	if (type != ZFIN && type != ZACK)	{		s[len++]=021;	}	flushmo();	write(1,s,len);}/* * Send binary array buf of length length, with ending ZDLE sequence frameend */static const char *Zendnames[] = { "ZCRCE", "ZCRCG", "ZCRCQ", "ZCRCW"};void zsdata(const char *buf, size_t length, int frameend){	register unsigned short crc;	VPRINTF(3,("zsdata: %lu %s", (unsigned long) length, 		Zendnames[(frameend-ZCRCE)&3]));	crc = 0;	do {		zsendline(*buf); crc = updcrc((0377 & *buf), crc);		buf++;	} while (--length>0);	xsendline(ZDLE); xsendline(frameend);	crc = updcrc(frameend, crc);	crc = updcrc(0,updcrc(0,crc));	zsendline(crc>>8); zsendline(crc);	if (frameend == ZCRCW) {		xsendline(XON);  flushmo();	}}voidzsda32(const char *buf, size_t length, int frameend){	int c;	unsigned long crc;	int i;	VPRINTF(3,("zsdat32: %d %s", length, Zendnames[(frameend-ZCRCE)&3]));	crc = 0xFFFFFFFFL;	zsendline_s(buf,length);	for (; length; length--) {		c = *buf & 0377;		crc = UPDC32(c, crc);		buf++;	}	xsendline(ZDLE); xsendline(frameend);	crc = UPDC32(frameend, crc);	crc = ~crc;	for (i=4; --i >= 0;) {		c=(int) crc;		if (c & 0140)			xsendline(lastsent = c);		else			zsendline(c);		crc >>= 8;	}	if (frameend == ZCRCW) {		xsendline(XON);  flushmo();	}}#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ <= 4)#  undef DEBUG_BLOCKSIZE#endif#ifdef DEBUG_BLOCKSIZEstruct debug_blocksize {	int size;	long count;};struct debug_blocksize blocksizes[]={	{32,0},	{64,0},

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -