📄 zmtx-new.c
字号:
//X/* Project : Unite! File : zmodem general Version : 1.02 *///X/* *///X/* (C) Mattheij Computer Service 1994 *///X/* *///X/* contact us through (in order of preference) *///X/* *///X/* email: jacquesm@hacktic.nl *///X/* mail: MCS *///X/* Prinses Beatrixlaan 535 *///X/* 2284 AT RIJSWIJK *///X/* The Netherlands *///X/* voice phone: 31+070-3936926 *///X/******************************************************************************///X//X/*//X * zmodem primitives and other code common to zmtx and zmrx//X *///X#include <stdio.h>#include <termios.h>#include <signal.h>#ifdef UNITE#include <sys/select.h>#endif#ifdef SUNOS4#include <sys/types.h>#endif#include <sys/time.h>#include "zmodem.h"#define ZMDM#include "zmdm.h"#include "crctab.h"#if 0#define DEBUG#endifint receive_32_bit_data;int raw_trace;int want_fcs_32 = TRUE;long ack_file_pos; /* file position used in acknowledgement of correctly */ /* received data subpackets *//* * routines to make the io channel raw and restore it * to its normal state. */struct termios old_termios;voidfd_init(){ struct termios t; tcgetattr(0,&old_termios); tcgetattr(0,&t); t.c_iflag = 0; t.c_oflag = 0; t.c_lflag = 0; t.c_cflag |= CS8; tcsetattr(0,TCSANOW,&t);}voidfd_exit(){ tcsetattr(0,TCSANOW,&old_termios);}/* * read bytes as long as rdchk indicates that * more data is available. */voidrx_purge(void){ struct timeval t; fd_set f; unsigned char c; t.tv_sec = 0; t.tv_usec = 0; FD_ZERO(&f); FD_SET(0,&f); while (select(1,&f,NULL,NULL,&t)) { read(0,&c,1); }}int last_sent = -1;/* * transmit a character. * this is the raw modem interface */voidtx_raw(int c){#ifdef DEBUG if (raw_trace) { fprintf(stderr,"%02x ",c); }#endif last_sent = c & 0x7f; putchar(c);}/* * transmit a character ZDLE escaped */voidtx_esc(int c){ tx_raw(ZDLE); /* * exclusive or; not an or so ZDLE becomes ZDLEE */ tx_raw(c ^ 0x40);}/* * transmit a character; ZDLE escaping if appropriate */voidtx(unsigned char c){ switch (c) { case ZDLE: tx_esc(c); return; break; case 0x8d: case 0x0d: if (escape_all_control_characters && last_sent == '@') { tx_esc(c); return; } break; case 0x10: case 0x90: case 0x11: case 0x91: case 0x13: case 0x93: tx_esc(c); return; break; default: if (escape_all_control_characters && (c & 0x60) == 0) { tx_esc(c); return; } break; } /* * anything that ends here is so normal we might as well transmit it. */ tx_raw((int) c);}/* * send the bytes accumulated in the output buffer. */voidtx_flush(void){ fflush(stdout);}/* * transmit a hex header. * these routines use tx_raw because we're sure that all the * characters are not to be escaped. */voidtx_nibble(int n){ n &= 0x0f; if (n < 10) { n += '0'; } else { n += 'a' - 10; } tx_raw(n);}voidtx_hex(int h){ tx_nibble(h >> 4); tx_nibble(h);}voidtx_hex_header(unsigned char * p){ int i; unsigned short int crc;#ifdef DEBUG fprintf(stderr,"tx_hheader : ");#endif tx_raw(ZPAD); tx_raw(ZPAD); tx_raw(ZDLE); if (use_variable_headers) { tx_raw(ZVHEX); tx_hex(HDRLEN); } else { tx_raw(ZHEX); } /* * initialise the crc */ crc = 0; /* * transmit the header */ for (i=0;i<HDRLEN;i++) { tx_hex(*p); crc = UPDCRC16(*p, crc); p++; } /* * update the crc as though it were zero */ crc = UPDCRC16(0,crc); crc = UPDCRC16(0,crc); /* * transmit the crc */ tx_hex(crc >> 8); tx_hex(crc); /* * end of line sequence */ tx_raw(0x0d); tx_raw(0x0a); tx_raw(XON); tx_flush();#ifdef DEBUG fprintf(stderr,"\n");#endif}/* * Send ZMODEM binary header hdr */voidtx_bin32_header(unsigned char * p){ int i; unsigned long crc;#ifdef DEBUG fprintf(stderr,"tx binary header 32 bits crc\n"); raw_trace = 1;#endif tx_raw(ZPAD); tx_raw(ZPAD); tx_raw(ZDLE); if (use_variable_headers) { tx_raw(ZVBIN32); tx(HDRLEN); } else { tx_raw(ZBIN32); } crc = 0xffffffffL; for (i=0;i<HDRLEN;i++) { crc = UPDCRC32(*p,crc); tx(*p++); } crc = ~crc; tx(crc); tx(crc >> 8); tx(crc >> 16); tx(crc >> 24);}voidtx_bin16_header(unsigned char * p){ int i; unsigned int crc;#ifdef DEBUG fprintf(stderr,"tx binary header 16 bits crc\n");#endif tx_raw(ZPAD); tx_raw(ZPAD); tx_raw(ZDLE); if (use_variable_headers) { tx_raw(ZVBIN); tx(HDRLEN); } else { tx_raw(ZBIN); } crc = 0; for (i=0;i<HDRLEN;i++) { crc = UPDCRC16(*p,crc); tx(*p++); } crc = UPDCRC16(0,crc); crc = UPDCRC16(0,crc); tx(crc >> 8); tx(crc);}/* * transmit a header using either hex 16 bit crc or binary 32 bit crc * depending on the receivers capabilities * we dont bother with variable length headers. I dont really see their * advantage and they would clutter the code unneccesarily */voidtx_header(unsigned char * p){ if (can_fcs_32) { if (want_fcs_32) { tx_bin32_header(p); } else { tx_bin16_header(p); } } else { tx_hex_header(p); }}/* * data subpacket transmission */voidtx_32_data(int sub_frame_type,unsigned char * p,int l){ int c; unsigned long crc;#ifdef DEBUG fprintf(stderr,"tx_32_data\n");#endif crc = 0xffffffffl; while (l > 0) { crc = UPDCRC32(*p,crc); tx(*p++); l--; } crc = UPDCRC32(sub_frame_type, crc); tx_raw(ZDLE); tx_raw(sub_frame_type); crc = ~crc; tx((int) (crc ) & 0xff); tx((int) (crc >> 8 ) & 0xff); tx((int) (crc >> 16) & 0xff); tx((int) (crc >> 24) & 0xff);}voidtx_16_data(int sub_frame_type,unsigned char * p,int l){ unsigned short crc;#ifdef DEBUG fprintf(stderr,"tx_16_data\n");#endif crc = 0; while (l > 0) { crc = UPDCRC16(*p,crc); tx(*p++); l--; } crc = UPDCRC16(sub_frame_type,crc); tx_raw(ZDLE); tx_raw(sub_frame_type); crc = UPDCRC16(0,crc); crc = UPDCRC16(0,crc); tx(crc >> 8); tx(crc);}/* * send a data subpacket using crc 16 or crc 32 as desired by the receiver */voidtx_data(int sub_frame_type,unsigned char * p, int l){ if (want_fcs_32 && can_fcs_32) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -