📄 zmutil.c
字号:
#ifndef lintstatic const char rcsid[] = "$Id: zmutil.c,v 1.1.1.1 2001/03/08 00:01:48 efalk Exp $" ;#endif/* * Copyright (c) 1995 by Edward A. Falk *//********** * * * @@@@@ @ @ @ @ @@@@@ @@@ @ * @ @@ @@ @ @ @ @ @ * @ @ @ @ @ @ @ @ @ * @ @ @ @ @ @ @ @ @ * @@@@@ @ @ @ @@@ @ @@@ @@@@@ * * ZMUTIL - utilties used by zmodem protocol. * * Routines provided here: * * * int ZXmitHdrHex(type, data, info) * int type ; * u_char data[4] ; * ZModem *info ; * * transmit zmodem header in hex. * * * int ZXmitHdrBin(type, data, info) * int type ; * u_char data[4] ; * ZModem *info ; * * transmit zmodem header in binary. * * * int ZXmitHdrBin32(type, data, info) * int type ; * u_char data[4] ; * ZModem *info ; * * transmit zmodem header in binary with 32-bit crc. * * * int ZXmitHdr(type, format, data, info) * int type, format ; * u_char data[4] ; * ZModem *info ; * * transmit zmodem header * * * int ZXmitData(format, data, len, term, info) * int format, len ; * u_char term ; * u_char *data ; * ZModem *info ; * * transmit buffer of data. * * * u_long FileCrc(name) * char *name ; * * compute 32-bit crc for a file, returns 0 on not found * * * u_char *ZEnc4(n) * u_long n ; * * convert u_long to 4 bytes. * * u_long ZDec4(buf) * u_char buf[4] ; * * convert 4 bytes to u_long * * * * Edward A. Falk * * January, 1995 * * * **********/#include <stdio.h>#include <stdarg.h>#include <string.h>#include <ctype.h>#include <time.h>#include <sys/time.h>#include "zmodem.h"#include "crctab.h"static char hexChars[] = "0123456789abcdef" ;extern char *hdrnames[] ; FILE *zmodemlogfile = NULL ; /* put a number as two hex digits */static u_char *putHex( u_char *ptr, u_char c ){ *ptr++ = hexChars[(c>>4)&0xf] ; *ptr++ = hexChars[c&0xf] ; return ptr ;} /* put a number with ZDLE escape if needed */u_char *putZdle( register u_char *ptr, register u_char c, register ZModem *info ){register u_char c2 = c & 0177 ; if( c == ZDLE || c2 == 020 || c2 == 021 || c2 == 023 || c2 == 0177 || (c2 == 015 && info->atSign) ||#ifdef COMMENT c2 == 035 || (c2 == '~' && info->lastCR) ||#endif /* COMMENT */ c2 == 035 || (c2 < 040 && info->escCtrl) ) { *ptr++ = ZDLE ; if( c == 0177 ) *ptr = ZRUB0 ; else if( c == 0377 ) *ptr = ZRUB1 ; else *ptr = c^0100 ; } else *ptr = c ; info->atSign = c2 == '@' ; info->lastCR = c2 == '\r' ; return ++ptr ;}intZXmitHdrHex( int type, u_char data[4], ZModem *info ){ u_char buffer[128] ;register u_char *ptr = buffer ;register u_int crc ; int i ; zmodemlog("sending %s: %2.2x %2.2x %2.2x %2.2x = %lx\n", hdrnames[type], data[0], data[1], data[2], data[3], ZDec4(data)) ; *ptr++ = ZPAD ; *ptr++ = ZPAD ; *ptr++ = ZDLE ; *ptr++ = ZHEX ; ptr = putHex(ptr, type) ; crc = updcrc(type, 0) ; for( i=4; --i >= 0; ++data ) { ptr = putHex(ptr, *data) ; crc = updcrc(*data, crc) ; } crc = updcrc(0,crc) ; crc = updcrc(0,crc) ; ptr = putHex(ptr, (crc>>8)&0xff) ; ptr = putHex(ptr, crc&0xff) ; *ptr++ = '\r' ; *ptr++ = '\n' ; if( type != ZACK && type != ZFIN ) *ptr++ = XON ; return ZXmitStr(buffer, ptr-buffer, info) ;}intZXmitHdrBin( int type, u_char data[4], register ZModem *info ){ u_char buffer[128] ;register u_char *ptr = buffer ;register u_int crc ; int len ; zmodemlog("sending %s: %2.2x %2.2x %2.2x %2.2x = %lx\n", hdrnames[type], data[0], data[1], data[2], data[3], ZDec4(data)) ; *ptr++ = ZPAD ; *ptr++ = ZDLE ; *ptr++ = ZBIN ; ptr = putZdle(ptr, type, info) ; crc = updcrc(type, 0) ; for( len=4; --len >= 0; ++data ) { ptr = putZdle(ptr, *data, info) ; crc = updcrc(*data, crc) ; } crc = updcrc(0,crc) ; crc = updcrc(0,crc) ; ptr = putZdle(ptr, (crc>>8)&0xff, info) ; ptr = putZdle(ptr, crc&0xff, info) ; len = ptr-buffer ; return ZXmitStr(buffer, len, info) ;}intZXmitHdrBin32( int type, u_char data[4], ZModem *info ){ u_char buffer[128] ;register u_char *ptr = buffer ;register u_long crc ; int len ; zmodemlog("sending %s: %2.2x %2.2x %2.2x %2.2x = %lx\n", hdrnames[type], data[0], data[1], data[2], data[3], ZDec4(data)) ; *ptr++ = ZPAD ; *ptr++ = ZDLE ; *ptr++ = ZBIN32 ; ptr = putZdle(ptr, type, info) ; crc = UPDC32(type, 0xffffffffL) ; for( len=4; --len >= 0; ++data ) { ptr = putZdle(ptr, *data, info) ; crc = UPDC32(*data, crc) ; } crc = ~crc ; for(len=4; --len >= 0; crc >>= 8) ptr = putZdle(ptr, crc&0xff, info) ; len = ptr-buffer ; return ZXmitStr(buffer, len, info) ;}intZXmitHdr( int type, int format, u_char data[4], ZModem *info){ if( format == ZBIN && info->crc32 ) format = ZBIN32 ; switch( format ) { case ZHEX: return ZXmitHdrHex(type, data, info) ; case ZBIN: return ZXmitHdrBin(type, data, info) ; case ZBIN32: return ZXmitHdrBin32(type, data, info) ; default: return 0 ; }} /* TODO: if input is not a file, need to keep old data * for possible retransmission */intZXmitData( int format, int len, u_char term, u_char *data, ZModem *info){register u_char *ptr = info->buffer ;register u_int crc ; if( format == ZBIN && info->crc32 ) format = ZBIN32 ; zmodemlog("ZXmiteData: fmt=%c, len=%d, term=%c\n", format, len, term) ; crc = (format == ZBIN) ? 0 : 0xffffffff ; while( --len >= 0 ) { if( format == ZBIN ) crc = updcrc(*data, crc) ; else crc = UPDC32(*data, crc) ; ptr = putZdle(ptr, *data++, info) ; } *ptr++ = ZDLE ; if( format == ZBIN ) crc = updcrc(term, crc) ; else crc = UPDC32(term, crc) ; *ptr++ = term ; if( format == ZBIN ) { crc = updcrc(0,crc) ; crc = updcrc(0,crc) ; ptr = putZdle(ptr, (crc>>8)&0xff, info) ; ptr = putZdle(ptr, crc&0xff, info) ; } else { crc = ~crc ; for(len=4; --len >= 0; crc >>= 8) ptr = putZdle(ptr, crc&0xff, info) ; } return ZXmitStr(info->buffer, ptr-info->buffer, info) ;} /* compute 32-bit crc for a file, returns 0 on not found */u_longFileCrc( char *name ){ u_long crc ; FILE *ifile = fopen(name, "r") ; int i ; if( ifile == NULL ) /* shouldn't happen, since we did access(2) */ return 0 ; crc = 0xffffffff ; while( (i=fgetc(ifile)) != EOF ) crc = UPDC32(i, crc) ; fclose(ifile) ; return ~crc ;}u_char *ZEnc4( u_long n ){static u_char buf[4] ; buf[0] = n&0xff ; n >>= 8 ; buf[1] = n&0xff ; n >>= 8 ; buf[2] = n&0xff ; n >>= 8 ; buf[3] = n&0xff ; return buf ;}u_longZDec4( u_char buf[4] ){ return buf[0] | (buf[1]<<8) | (buf[2]<<16) | (buf[3]<<24) ;}char *sname2(ZMState state){ static char *names[] = { "RStart", "RSinitWait", "RFileName", "RCrc", "RFile", "RData", "RDataErr", "RFinish", "TStart", "TInit", "FileWait", "CrcWait", "Sending", "SendWait", "SendDone", "SendEof", "TFinish", "CommandData", "CommandWait", "StderrData", "Done", "YTStart", "YTFile", "YTDataWait", "YTData", "YTEOF", "YTFin", "YRStart", "YRDataWait", "YRData", "YREOF"} ; return names[(int)state] ;}char *sname(ZModem *info){ return sname2(info->state) ;}#ifdef DEBUGvoidzmodemlog(const char *fmt, ... ){ va_list ap; struct timeval tv ; struct tm *tm ;static int do_ts = 1 ; if( zmodemlogfile == NULL ) return ; if( do_ts ) { gettimeofday(&tv, NULL) ; tm = localtime(&tv.tv_sec) ; fprintf(zmodemlogfile, "%2.2d:%2.2d:%2.2d.%2.2ld: ", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec/10000) ; } do_ts = strchr(fmt, '\n') != NULL ; va_start(ap, fmt) ; vfprintf(zmodemlogfile, fmt, ap) ; va_end(ap) ;}#endif /* DEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -