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

📄 zmdm.c

📁 国产CPU-龙芯(loongson)BIOS源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************//* Project : Unite!       File : zmodem general        Version : 1.02         *//*                                                                            *//* (C) Mattheij Computer Service 1994                                         *//*                                                                            *//* contact us through (in order of preference)                                *//*                                                                            *//*   email:          jacquesm@hacktic.nl                                      *//*   mail:           MCS                                                      *//*                   Prinses Beatrixlaan 535                                  *//*                   2284 AT  RIJSWIJK                                        *//*                   The Netherlands                                          *//*   voice phone:    31+070-3936926                                           *//******************************************************************************//* * zmodem primitives and other code common to zmtx and zmrx */#include <stdio.h>#undef _KERNEL#include <sys/termios.h>#include <errno.h>#define _KERNEL#include <signal.h>#include <unistd.h>#include <string.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"#include <pmon.h>int port_fd;FILE *port_fp;int 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 */extern FILE *logfp;#define XXX_SKIP_CRC 1 /* XXX: Skip CRC check at the moment */void fd_init(FILE *fp){  port_fd = fileno(fp);  port_fp = fp;}/* * read bytes as long as rdchk indicates that * more data is available. */void rx_purge(void){    struct timeval t;    fd_set f;    unsigned char c;    t.tv_sec = 0;    t.tv_usec = 0;    FD_ZERO(&f);    FD_SET(port_fd, &f);    while (select(port_fd, &f, NULL, NULL, &t)) {	read(port_fd, &c, 1);    }}int last_sent = -1;/* * transmit a character. * this is the raw modem interface */void tx_raw(int c){#ifdef DEBUG    if (raw_trace) {	fprintf(logfp, "%02x ", c);    }#endif    last_sent = c & 0x7f;#if 0    putchar(c);#else    {	char tmp;	tmp = c;	write(port_fd, &tmp, 1);    }#endif}/* * transmit a character ZDLE escaped */void tx_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 */void tx(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. */void tx_flush(void){    fflush(port_fp);}/* * transmit a hex header. * these routines use tx_raw because we're sure that all the * characters are not to be escaped. */void tx_nibble(int n){    n &= 0x0f;    if (n < 10) {	n += '0';    } else {	n += 'a' - 10;    }    tx_raw(n);}void tx_hex(int h){    tx_nibble(h >> 4);    tx_nibble(h);}void tx_hex_header(unsigned char *p){    int i;    unsigned short int crc;#ifdef DEBUG    fprintf(logfp, "* tx_hex_header *\n ");#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(logfp, "\n");#endif}/* * Send ZMODEM binary header hdr */void tx_bin32_header(unsigned char *p){    int i;    unsigned long crc;#ifdef DEBUG    fprintf(logfp, "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);}void tx_bin16_header(unsigned char *p){    int i;    unsigned int crc;#ifdef DEBUG    fprintf(logfp, "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 */void tx_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 */void tx_32_data(int sub_frame_type, unsigned char *p, int l){    unsigned long crc;#ifdef DEBUG    fprintf(logfp, "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);}void tx_16_data(int sub_frame_type, unsigned char *p, int l){    unsigned short crc;#ifdef DEBUG    fprintf(logfp, "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 */void tx_data(int sub_frame_type, unsigned char *p, int l){    if (want_fcs_32 && can_fcs_32) {	tx_32_data(sub_frame_type, p, l);    } else {	tx_16_data(sub_frame_type, p, l);    }    if (sub_frame_type == ZCRCW) {	tx_raw(XON);    }    tx_flush();}void tx_pos_header(int type, long pos){    char header[5];    header[0] = type;    header[ZP0] = pos & 0xff;    header[ZP1] = (pos >> 8) & 0xff;    header[ZP2] = (pos >> 16) & 0xff;    header[ZP3] = (pos >> 24) & 0xff;    tx_hex_header(header);}void tx_znak(){#ifdef DEBUG   fprintf(logfp, "tx_znak\n");#endif    tx_pos_header(ZNAK, ack_file_pos);}void tx_zskip(){    tx_pos_header(ZSKIP, 0L);}/* * receive any style header within timeout milliseconds */void alrm(int a){    signal(SIGALRM, SIG_IGN);}int rx_poll(){    struct timeval t;    fd_set f;    t.tv_sec = 0;    t.tv_usec = 0;    FD_ZERO(&f);    FD_SET(port_fd, &f);    if (select(port_fd, &f, NULL, NULL, &t)) {	return 1;    }    return 0;}unsigned char inputbuffer[1024];int n_in_inputbuffer = 0;int inputbuffer_index;/* * rx_raw ; receive a single byte from the line. * reads as many are available and then processes them one at a time * check the data stream for 5 consecutive CAN characters; * and if you see them abort. this saves a lot of clutter in * the rest of the code; even though it is a very strange place * for an exit. (but that was wat session abort was all about.) */int rx_raw(int to){    unsigned char c;    static int n_cans = 0;    if (n_in_inputbuffer == 0) {	/*	 * change the timeout into seconds; minimum is 1	 */#if 0	to /= 1000;	if (to == 0) {	    to++;	}	/* 	 * setup an alarm in case io takes too long	 */	signal(SIGALRM, alrm);		to /= 1000;	  	if (to == 0) {	  to = 2;	}	alarm(to);#endif	n_in_inputbuffer = read(port_fd, inputbuffer, 1); /* was 1024 */#if 0	if (n_in_inputbuffer <= 0) {	    n_in_inputbuffer = 0;	}#endif	/* 	 * cancel the alarm in case it did not go off yet	 */#if 0	signal(SIGALRM, SIG_IGN);#endif	if (n_in_inputbuffer < 0 && (errno != 0 && errno != EINTR)) {	    fprintf(logfp, "zmdm : fatal error reading device\n");	    return(1);	}	if (n_in_inputbuffer == 0) {	    return TIMEOUT;	}	inputbuffer_index = 0;    }    c = inputbuffer[inputbuffer_index++];    n_in_inputbuffer--;    if (c == CAN) {	n_cans++;	if (n_cans == 5) {#if 0	    /*	     * the other side is serious about this. just shut up;	     * clean up and exit.	     */	    cleanup();#endif	    return(CAN);	}    } else {	n_cans = 0;    }    return c;}/* * rx; receive a single byte undoing any escaping at the * sending site. this bit looks like a mess. sorry for that * but there seems to be no other way without incurring a lot * of overhead. at least like this the path for a normal character * is relatively short. */int rx(int to){    int c;    /*     * outer loop for ever so for sure something valid     * will come in; a timeout will occur or a session abort     * will be received.     */    while (TRUE) {	/* 	 * fake do loop so we may continue	 * in case a character should be dropped.	 */	do {	    c = rx_raw(to);	    if (c == TIMEOUT) {		return c;	    }	    switch (c) {	    case ZDLE:		break;	    case 0x11:	    case 0x91:	    case 0x13:	    case 0x93:		continue;		break;	    default:		/*		 * if all control characters should be escaped and		 * this one wasnt then its spurious and should be dropped.		 */		if (escape_all_control_characters && (c & 0x60) == 0) {		    continue;		}		/*		 * normal character; return it.

⌨️ 快捷键说明

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