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

📄 zmodem.cpp

📁 这是G.723和G.729的音频编解码的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		percentage = (ftell(fp) * 100) / current_file_size;
	}
	else {
		percentage = 100;
	}

	duration = time(NULL) - transfer_start;

	if (duration == 0l) {
		duration = 1l;
	}

	cps = ftell(fp) / duration;

	TRACE("zmtx: sending file \"%s\" %8ld bytes (%3d %%/%5d cps)           \r",
		name,ftell(fp),percentage,cps);
}
*/

/*
 * send from the current position in the file
 * all the way to end of file or until something goes wrong.
 * (ZNAK or ZRPOS received)
 * the name is only used to show progress
 */

int Czmodem::send_from(char * name,FILE * fp)
{
	int n;
	int type = ZCRCG;//ZCRCQ--crc next, frame coninuous, ZACK expected
					 //old---ZCRCG--crc next, frame coninuous, nonstop
	char zdata_frame[] = { ZDATA, 0, 0, 0, 0 };
	int nAAA=0;
	int nNowHaveSendWindowsSize = 0;

	/*
 	 * put the file position in the ZDATA frame
	 */
AGAIN://For test
	zdata_frame[ZP0] =  ftell(fp)        & 0xff;
	zdata_frame[ZP1] = (ftell(fp) >> 8)  & 0xff;
	zdata_frame[ZP2] = (ftell(fp) >> 16) & 0xff;
	zdata_frame[ZP3] = (ftell(fp) >> 24) & 0xff;

	tx_header((unsigned char *)zdata_frame);
	tx_raw(XON);//1999.10.20, Send this header
	tx_raw(XON);//1999.10.20, Send this header
	/*
	 * send the data in the file
	 */

	while (!feof(fp)) {
		if (opt_v) {
			show_progress(name,fp);
		}

		/*
		 * read a block from the file
		 */
		n = fread(tx_data_subpacket,1,subpacket_size,fp);

		if (n == 0) {
			/*
			 * nothing to send ?
			 */
			break;
		}

		/*
		 * at end of file wait for an ACK
		 */
		if (ftell(fp) == current_file_size) {
			type = ZCRCW;
		}

		nNowHaveSendWindowsSize++;
		if(nNowHaveSendWindowsSize > WINDOWSSIZE)
		{
			TRACE("Now type is ZCRCQ!\n");
			type = ZCRCQ;
		}
		tx_data(type,tx_data_subpacket,n);
		
		if(type != ZCRCW)//if type != zcrcw, let multiplex send this data packet
			tx_raw(XON); //else, in tx_data function call tx_raw(XON)
		//顶出一帧数据, 如果不加这一行,最后的数据无法定位, 0xf0....0xf0
		tx_raw(XON);//1999.10.21, by lhf

		//Now we manage the windows, add by lhf
		if(type != ZCRCW && (nNowHaveSendWindowsSize > WINDOWSSIZE))
		{
			TRACE("send data > windows size, waiting for ack, znak, zrpos!\n");

			int typeAck;

			do {
				typeAck = rx_header(10000);

				if (typeAck == ZNAK || typeAck == ZRPOS) {
					return typeAck;
				}
			} while (typeAck != ZACK);

			nNowHaveSendWindowsSize = 0;
			type = ZCRCG;//nonstop
			continue;
		}//end of manage windos

		if (type == ZCRCW) {
			int type;

			do {
				type = rx_header(10000);
				if(nAAA)//For test
				{
					fseek(fp, 0, SEEK_SET);
					goto AGAIN;
				}
				//End of test
				if (type == ZNAK || type == ZRPOS) {
					return type;
				}
			} while (type != ZACK);

			if (ftell(fp) == current_file_size) {
				if (opt_d) {
					TRACE("end of file\n");
				}
				return ZACK;
			}
		}

		/* 
		 * characters from the other side
		 * check out that header
		 */

		while (rx_poll()) {
			int type;
			int c;
			c = rx_raw(0);
			if (c == ZPAD) {
				type = rx_header(1000);
				if (type != TIMEOUT && type != ACK) {
					return type;
				}
			}
		}
	}

	/*
	 * end of file reached.
	 * should receive something... so fake ZACK
	 */

	return ZACK;
}

/*
 * send a file; returns true when session is aborted.
 * (using ZABORT frame)
 */

int
Czmodem::send_file(char * name)

{
	long pos;
	long size;
	struct stat s;
	FILE * fp;
	unsigned char * p;
	char zfile_frame[] = { ZFILE, 0, 0, 0, 0 };
	char zeof_frame[] = { ZEOF, 0, 0, 0, 0 };
	//int wait_for_header;
	int type;
	char * n;

	if (opt_v) {
		TRACE("zmtx: sending file \"%s\"\r",name);
	}

	/*
	 * before doing a lot of unnecessary work check if the file exists
	 */

	fp = fopen(name,"rb");

	if (fp == NULL) {
		if (opt_v) {
			TRACE("zmtx: can't open file %s\n",name);
		}
		return FALSE;
	}

	fstat(fileno(fp),&s);
	size = s.st_size;
	current_file_size = size;

	/*
	 * the file exists. now build the ZFILE frame
	 */

	/*
	 * set conversion option
	 * (not used; always binary)
	 */

	zfile_frame[ZF0] = ZF0_ZCBIN;

	/*
	 * management option
	 */

	if (management_protect) {
		zfile_frame[ZF1] = ZF1_ZMPROT;		
		if (opt_d) {
			TRACE("zmtx: protecting destination\n");
		}
	}

	if (management_clobber) {
		zfile_frame[ZF1] = ZF1_ZMCLOB;
		if (opt_d) {
			TRACE("zmtx: overwriting destination\n");
		}
	}

	if (management_newer) {
		zfile_frame[ZF1] = ZF1_ZMNEW;
		if (opt_d) {
			TRACE("zmtx: overwriting destination if newer\n");
		}
	}

	/*
	 * transport options
	 * (just plain normal transfer)
	 */

	zfile_frame[ZF2] = ZF2_ZTNOR;

	/*
	 * extended options
	 */

	zfile_frame[ZF3] = 0;

	/*
 	 * now build the data subpacket with the file name and lots of other
	 * useful information.
	 */

	/*
	 * first enter the name and a 0
	 */

	p = tx_data_subpacket;

	/*
	 * strip the path name from the filename
	 */

	n = strrchr(name,'/');
	if (n == NULL) {
		n = name;
	}
	else {
		n++;
	}

	strcpy((char*)p,n);

	p += strlen((char*)p) + 1;

	/*
	 * next the file size
	 */

	sprintf((char*)p,"%ld ",size);

	p += strlen((char*)p);

	/*
 	 * modification date
	 */

	sprintf((char*)p,"%lo ",s.st_mtime);

	p += strlen((char*)p);

	/*
	 * file mode
	 */

	sprintf((char*)p,"0 ");

	p += strlen((char*)p);

	/*
	 * serial number (??)
	 */

	sprintf((char*)p,"0 ");

	p += strlen((char*)p);

	/*
	 * number of files remaining
	 */

	sprintf((char*)p,"%d ",n_files_remaining);

	p += strlen((char*)p);

	/*
	 * file type
	 */

	sprintf((char*)p,"0");

	p += strlen((char*)p) + 1;

	do {
		/*
	 	 * send the header and the data
	 	 */

		tx_header((unsigned char*)zfile_frame);
		tx_data(ZCRCW,tx_data_subpacket,p - tx_data_subpacket);
		tx_raw(XON);//1999.10.21, add by lhf, for cdemultiplex can locate on frame zack
		::Sleep(500);
	
		/*
		 * wait for anything but an ZACK packet
		 */

		do {
			type = rx_header(10000);
		} while (type == ZACK);

		if (opt_d) {
			TRACE("type : %d\n",type);
		}

		if (type == ZSKIP) {
			fclose(fp);
			if (opt_v) {
				TRACE("zmtx: skipped file \"%s\"                       \n",name);
			}
			return TRUE;
		}

	} while (type != ZRPOS);

	transfer_start = time(NULL);

	do {
		/*
		 * fetch pos from the ZRPOS header
		 */

		if (type == ZRPOS) {
			pos = rxd_header[ZP0] | (rxd_header[ZP1] << 8) | (rxd_header[ZP2] << 16) | (rxd_header[ZP3] << 24);
		}

		/*
 		 * seek to the right place in the file
		 */
		fseek(fp,pos,0);

		/*
		 * and start sending
		 */

		type = send_from(n,fp);

		if (type == ZFERR || type == ZABORT) {
 			fclose(fp);
			return TRUE;
		}

	} while (type == ZRPOS || type == ZNAK);

	/*
	 * file sent. send end of file frame
	 * and wait for zrinit. if it doesnt come then try again
	 */

	zeof_frame[ZP0] =  s.st_size        & 0xff;
	zeof_frame[ZP1] = (s.st_size >> 8)  & 0xff;
	zeof_frame[ZP2] = (s.st_size >> 16) & 0xff;
	zeof_frame[ZP3] = (s.st_size >> 24) & 0xff;

	do {
		tx_hex_header((unsigned char*)zeof_frame);
		type = rx_header(10000);
	} while (type != ZRINIT);

	/*
	 * and close the input file
	 */

	if (opt_v) {
		TRACE("zmtx: sent file \"%s\"                                    \n",name);
	}

	fclose(fp);

	return FALSE;
}

/*
void
cleanup(void)

{
	fd_exit();
}

void
usage(void)

{
	TRACE("zmtx %s (C) Mattheij Computer Service 1994\n",VERSION);
	TRACE("usage : zmtx options files\n");
	TRACE("	-lline      line to use for io\n");
	TRACE("	-n    		transfer if source is newer\n");
	TRACE("	-o    	    overwrite if exists\n");
	TRACE("	-p          protect (don't overwrite if exists)\n");
	TRACE("\n");
	TRACE("	-d          debug output\n");
	TRACE("	-v          verbose output\n");
	TRACE("	(only one of -n -c or -p may be specified)\n");

	cleanup();

	exit(1);
}
*/

void Czmodem::SendFile(char* FileName, char* Option)
{
	int i;
	char * s;
	int nCount = 0;

	if(Option != NULL)
	{
		s = Option;
		while(s[nCount] != '\0')
		{
			switch (toupper(s[nCount])) {
				OPT_BOOL('D',opt_d);
				OPT_BOOL('V',opt_v);

				OPT_BOOL('N',management_newer);
				OPT_BOOL('O',management_clobber);
				OPT_BOOL('P',management_protect);
				OPT_STRING('L',line);
				default:
					TRACE("zmtx: bad option %c\n",*s);
					usage();
			}
			nCount++;
		}
	}
#ifdef _DEBUG
	opt_d = TRUE;
#endif

	if (opt_d) {
		opt_v = TRUE;
	}

	if ((management_newer + management_clobber + management_protect) > 1 || FileName == NULL) {
		usage();
	}

	if (line != NULL) {	
		if (freopen(line,"r",stdin) == NULL) {
			TRACE("zmtx can't open line for input %s\n",line);
			::ExitThread(2);//return;//exit(2);
		}
		if (freopen(line,"w",stdout) == NULL) {
			TRACE("zmtx can't open line for output %s\n",line);
			::ExitThread(2);//return;//exit(2);
		}
	}

	//* set the io device to transparent

	fd_init();	

	// * clear the input queue from any possible garbage
	// * this also clears a possible ZRINIT from an already started
	// * zmodem receiver. this doesn't harm because we reinvite to
	// * receive again below and it may be that the receiver whose
	// * ZRINIT we are about to wipe has already died.

	rx_purge();

	//* establish contact with the receiver

	if (opt_v) {
		TRACE("zmtx: establishing contact with receiver\n");
	}

	i = 0;
	do {
		unsigned char zrqinit_header[] = { ZRQINIT, 0, 0, 0, 0 };
		i++;
		if (i > 10) {
			TRACE("zmtx: can't establish contact with receiver\n");
			cleanup();
			::ExitThread(3);//return;//exit(3);
		}

		//1999.10.18 tx_raw('z');
		//1999.10.18 tx_raw('m');
		//1999.10.18 tx_raw(13);
		tx_hex_header(zrqinit_header);
		tx_raw(XON);//1999.10.21, add by lhf, for cdemultiplex can locate on frame zack
		::Sleep(500);
	} while (rx_header(7000) != ZRINIT);

	if (opt_v) {
		TRACE("zmtx: contact established\n");
		TRACE("zmtx: starting file transfer\n");
	}

	//* decode receiver capability flags
	//* forget about encryption and compression.

	can_full_duplex					= (rxd_header[ZF0] & ZF0_CANFDX)  != 0;
	can_overlap_io					= (rxd_header[ZF0] & ZF0_CANOVIO) != 0;
	can_break						= (rxd_header[ZF0] & ZF0_CANBRK)  != 0;
	can_fcs_32						= (rxd_header[ZF0] & ZF0_CANFC32) != 0;
	escape_all_control_characters	= (rxd_header[ZF0] & ZF0_ESCCTL)  != 0;
	escape_8th_bit					= (rxd_header[ZF0] & ZF0_ESC8)    != 0;

	use_variable_headers			= (rxd_header[ZF1] & ZF1_CANVHDR) != 0;

	if (opt_d) {
		TRACE("receiver %s full duplex\n"          ,can_full_duplex               ? "can"      : "can't");
		TRACE("receiver %s overlap io\n"           ,can_overlap_io                ? "can"      : "can't");
		TRACE("receiver %s break\n"                ,can_break                     ? "can"      : "can't");
		TRACE("receiver %s fcs 32\n"               ,can_fcs_32                    ? "can"      : "can't");
		TRACE("receiver %s escaped control chars\n",escape_all_control_characters ? "requests" : "doesn't request");
		TRACE("receiver %s escaped 8th bit\n"      ,escape_8th_bit                ? "re

⌨️ 快捷键说明

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