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

📄 rz.c

📁 ZMODEM协议的实现
💻 C
📖 第 1 页 / 共 3 页
字号:
		return;	fprintf(stderr, "Retry %d: ", errors);	fprintf(stderr, s, p, u);	fprintf(stderr, "\n");}/* send cancel string to get the other end to shut up */canit(){	static char canistr[] = {	 24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0	};#ifdef vax11c	raw_wbuf(strlen(canistr), canistr);	purgeline();#else	printf(canistr);	Lleft=0;	/* Do read next time ... */	fflush(stdout);#endif}report(sct)int sct;{	if (Verbose>1)		fprintf(stderr,"%03d%c",sct,sct%10? ' ' : '\r');}/* * If called as [-][dir/../]vrzCOMMAND set Verbose to 1 * If called as [-][dir/../]rzCOMMAND set the pipe flag * If called as rb use YMODEM protocol */chkinvok(s)char *s;{	register char *p;	p = s;	while (*p == '-')		s = ++p;	while (*p)		if (*p++ == '/')			s = p;	if (*s == 'v') {		Verbose=1; ++s;	}	Progname = s;	if (s[0]=='r' && s[1]=='z')		Batch = TRUE;	if (s[0]=='r' && s[1]=='b')		Batch = Nozmodem = TRUE;	if (s[2] && s[0]=='r' && s[1]=='b')		Topipe = 1;	if (s[2] && s[0]=='r' && s[1]=='z')		Topipe = 1;}/* * Totalitarian Communist pathname processing */checkpath(name)char *name;{	if (Restricted) {		if (fopen(name, "r") != NULL) {			canit();			fprintf(stderr, "\r\nrz: %s exists\n", name);			bibi(-1);		}		/* restrict pathnames to current tree or uucppublic */		if ( substr(name, "../")		 || (name[0]== '/' && strncmp(name, PUBDIR, strlen(PUBDIR))) ) {			canit();			fprintf(stderr,"\r\nrz:\tSecurity Violation\r\n");			bibi(-1);		}	}}/* * Initialize for Zmodem receive attempt, try to activate Zmodem sender *  Handles ZSINIT frame *  Return ZFILE if Zmodem filename received, -1 on error, *   ZCOMPL if transaction finished,  else 0 */tryz(){	register c, n;	register cmdzack1flg;	if (Nozmodem)		/* Check for "rb" program name */		return 0;	for (n=Zmodem?15:5; --n>=0; ) {		/* Set buffer length (0) and capability flags */#ifdef SEGMENTS		stohdr(SEGMENTS*1024L);#else		stohdr(0L);#endif#ifdef CANBREAK		Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO|CANBRK;#else		Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO;#endif		if (Zctlesc)			Txhdr[ZF0] |= TESCCTL;		Txhdr[ZF0] |= CANRLE;		Txhdr[ZF1] = CANVHDR;		/* tryzhdrtype may == ZRINIT */		zshhdr(4,tryzhdrtype, Txhdr);		if (tryzhdrtype == ZSKIP)	/* Don't skip too far */			tryzhdrtype = ZRINIT;	/* CAF 8-21-87 */again:		switch (zgethdr(Rxhdr, 0)) {		case ZRQINIT:			if (Rxhdr[ZF3] & 0x80)				Usevhdrs = 1;	/* we can var header */			continue;		case ZEOF:			continue;		case TIMEOUT:			continue;		case ZFILE:			zconv = Rxhdr[ZF0];			zmanag = Rxhdr[ZF1];			ztrans = Rxhdr[ZF2];			if (Rxhdr[ZF3] & ZCANVHDR)				Usevhdrs = TRUE;			tryzhdrtype = ZRINIT;			c = zrdata(secbuf, 1024);			mode(3);			if (c == GOTCRCW)				return ZFILE;			zshhdr(4,ZNAK, Txhdr);			goto again;		case ZSINIT:			Zctlesc = TESCCTL & Rxhdr[ZF0];			if (zrdata(Attn, ZATTNLEN) == GOTCRCW) {				stohdr(1L);				zshhdr(4,ZACK, Txhdr);				goto again;			}			zshhdr(4,ZNAK, Txhdr);			goto again;		case ZFREECNT:			stohdr(getfree());			zshhdr(4,ZACK, Txhdr);			goto again;		case ZCOMMAND:#ifdef vax11c			return ERROR;#else			cmdzack1flg = Rxhdr[ZF0];			if (zrdata(secbuf, 1024) == GOTCRCW) {				if (cmdzack1flg & ZCACK1)					stohdr(0L);				else					stohdr((long)sys2(secbuf));				purgeline();	/* dump impatient questions */				do {					zshhdr(4,ZCOMPL, Txhdr);				}				while (++errors<20 && zgethdr(Rxhdr,1) != ZFIN);				ackbibi();				if (cmdzack1flg & ZCACK1)					exec2(secbuf);				return ZCOMPL;			}			zshhdr(4,ZNAK, Txhdr); goto again;#endif		case ZCOMPL:			goto again;		default:			continue;		case ZFIN:			ackbibi(); return ZCOMPL;		case ZCAN:			return ERROR;		}	}	return 0;}/* * Receive 1 or more files with ZMODEM protocol */rzfiles(){	register c;	for (;;) {		switch (c = rzfile()) {		case ZEOF:		case ZSKIP:			switch (tryz()) {			case ZCOMPL:				return OK;			default:				return ERROR;			case ZFILE:				break;			}			continue;		default:			return c;		case ERROR:			return ERROR;		}	}}/* * Receive a file with ZMODEM protocol *  Assumes file name frame is in secbuf */rzfile(){	register c, n;	long rxbytes;	Eofseen=FALSE;	if (procheader(secbuf) == ERROR) {		return (tryzhdrtype = ZSKIP);	}	n = 20; rxbytes = 0l;	for (;;) {#ifdef SEGMENTS		chinseg = 0;#endif		stohdr(rxbytes);		zshhdr(4,ZRPOS, Txhdr);nxthdr:		switch (c = zgethdr(Rxhdr, 0)) {		default:			vfile("rzfile: zgethdr returned %d", c);			return ERROR;		case ZNAK:		case TIMEOUT:#ifdef SEGMENTS			putsec(secbuf, chinseg);			chinseg = 0;#endif			if ( --n < 0) {				vfile("rzfile: zgethdr returned %d", c);				return ERROR;			}		case ZFILE:			zrdata(secbuf, 1024);			continue;		case ZEOF:#ifdef SEGMENTS			putsec(secbuf, chinseg);			chinseg = 0;#endif			if (rclhdr(Rxhdr) != rxbytes) {				/*				 * Ignore eof if it's at wrong place - force				 *  a timeout because the eof might have gone				 *  out before we sent our zrpos.				 */				errors = 0;  goto nxthdr;			}			if (closeit()) {				tryzhdrtype = ZFERR;				vfile("rzfile: closeit returned <> 0");				return ERROR;			}			vfile("rzfile: normal EOF");			return c;		case ERROR:	/* Too much garbage in header search error */#ifdef SEGMENTS			putsec(secbuf, chinseg);			chinseg = 0;#endif			if ( --n < 0) {				vfile("rzfile: zgethdr returned %d", c);				return ERROR;			}			zmputs(Attn);			continue;		case ZSKIP:#ifdef SEGMENTS			putsec(secbuf, chinseg);			chinseg = 0;#endif			Modtime = 1;			closeit();			vfile("rzfile: Sender SKIPPED file");			return c;		case ZDATA:			if (rclhdr(Rxhdr) != rxbytes) {				if ( --n < 0) {					return ERROR;				}#ifdef SEGMENTS				putsec(secbuf, chinseg);				chinseg = 0;#endif				zmputs(Attn);  continue;			}moredata:			if (Verbose>1)				fprintf(stderr, "\r%7ld ZMODEM%s    ",				  rxbytes, Crc32r?" CRC-32":"");#ifdef SEGMENTS			if (chinseg >= (1024 * SEGMENTS)) {				putsec(secbuf, chinseg);				chinseg = 0;			}			switch (c = zrdata(secbuf+chinseg, 1024))#else			switch (c = zrdata(secbuf, 1024))#endif			{			case ZCAN:#ifdef SEGMENTS				putsec(secbuf, chinseg);				chinseg = 0;#endif				vfile("rzfile: zgethdr returned %d", c);				return ERROR;			case ERROR:	/* CRC error */#ifdef SEGMENTS				putsec(secbuf, chinseg);				chinseg = 0;#endif				if ( --n < 0) {					vfile("rzfile: zgethdr returned %d", c);					return ERROR;				}				zmputs(Attn);				continue;			case TIMEOUT:#ifdef SEGMENTS				putsec(secbuf, chinseg);				chinseg = 0;#endif				if ( --n < 0) {					vfile("rzfile: zgethdr returned %d", c);					return ERROR;				}				continue;			case GOTCRCW:				n = 20;#ifdef SEGMENTS				chinseg += Rxcount;				putsec(secbuf, chinseg);				chinseg = 0;#else				putsec(secbuf, Rxcount);#endif				rxbytes += Rxcount;				stohdr(rxbytes);				zshhdr(4,ZACK, Txhdr);				sendline(XON);				goto nxthdr;			case GOTCRCQ:				n = 20;#ifdef SEGMENTS				chinseg += Rxcount;#else				putsec(secbuf, Rxcount);#endif				rxbytes += Rxcount;				stohdr(rxbytes);				zshhdr(4,ZACK, Txhdr);				goto moredata;			case GOTCRCG:				n = 20;#ifdef SEGMENTS				chinseg += Rxcount;#else				putsec(secbuf, Rxcount);#endif				rxbytes += Rxcount;				goto moredata;			case GOTCRCE:				n = 20;#ifdef SEGMENTS				chinseg += Rxcount;#else				putsec(secbuf, Rxcount);#endif				rxbytes += Rxcount;				goto nxthdr;			}		}	}}/* * Send a string to the modem, processing for \336 (sleep 1 sec) *   and \335 (break signal) */zmputs(s)char *s;{	register c;	while (*s) {		switch (c = *s++) {		case '\336':			sleep(1); continue;		case '\335':			sendbrk(); continue;		default:			sendline(c);		}	}}/* * Close the receive dataset, return OK or ERROR */closeit(){	time_t time();#ifndef vax11c	if (Topipe) {		if (pclose(fout)) {			return ERROR;		}		return OK;	}#endif	if (fclose(fout)==ERROR) {		fprintf(stderr, "file close ERROR\n");		return ERROR;	}#ifndef vax11c	if (Modtime) {		timep[0] = time(NULL);		timep[1] = Modtime;		utime(Pathname, timep);	}#endif	if ((Filemode&S_IFMT) == S_IFREG)		chmod(Pathname, (07777 & Filemode));	return OK;}/* * Ack a ZFIN packet, let byegones be byegones */ackbibi(){	register n;	vfile("ackbibi:");	Readnum = 1;	stohdr(0L);	for (n=3; --n>=0; ) {		purgeline();		zshhdr(4,ZFIN, Txhdr);		switch (readline(100)) {		case 'O':			readline(1);	/* Discard 2nd 'O' */			vfile("ackbibi complete");			return;		case RCDO:			return;		case TIMEOUT:		default:			break;		}	}}/* * Local console output simulation */bttyout(c){	if (Verbose || Fromcu)		putc(c, stderr);}#ifndef vax11c/* * Strip leading ! if present, do shell escape.  */sys2(s)register char *s;{	if (*s == '!')		++s;	return system(s);}/* * Strip leading ! if present, do exec. */exec2(s)register char *s;{	if (*s == '!')		++s;	mode(0);	execl("/bin/sh", "sh", "-c", s);}#endif/* End of rz.c */

⌨️ 快捷键说明

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