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

📄 lrz.c

📁 Debian Linux下的通讯程序
💻 C
📖 第 1 页 / 共 3 页
字号:
 * Wcgetsec fetches a Ward Christensen type sector. * Returns sector number encountered or ERROR if valid sector not received, * or CAN CAN received * or WCEOT if eot sector * time is timeout for first char, set to 4 seconds thereafter ***************** NO ACK IS SENT IF SECTOR IS RECEIVED OK ************** *    (Caller must do that when he is good and ready to get next sector) */wcgetsec(rxbuf, maxtime)char *rxbuf;int maxtime;{	register checksum, wcj, firstch;	register unsigned short oldcrc;	register char *p;	int sectcurr;	for (Lastrx=errors=0; errors<RETRYMAX; errors++) {		if ((firstch=readline(maxtime))==STX) {			Blklen=1024; goto get2;		}		if (firstch==SOH) {			Blklen=128;get2:			sectcurr=readline(1);			if ((sectcurr+(oldcrc=readline(1)))==0377) {				oldcrc=checksum=0;				for (p=rxbuf,wcj=Blklen; --wcj>=0; ) {					if ((firstch=readline(1)) < 0)						goto bilge;					oldcrc=updcrc(firstch, oldcrc);					checksum += (*p++ = firstch);				}				if ((firstch=readline(1)) < 0)					goto bilge;				if (Crcflg) {					oldcrc=updcrc(firstch, oldcrc);					if ((firstch=readline(1)) < 0)						goto bilge;					oldcrc=updcrc(firstch, oldcrc);					if (oldcrc & 0xFFFF)						zperr( "CRC");					else {						Firstsec=FALSE;						return sectcurr;					}				}				else if (((checksum-firstch)&0377)==0) {					Firstsec=FALSE;					return sectcurr;				}				else					zperr( "Checksum");			}			else				zperr("Sector number garbled");		}		/* make sure eot really is eot and not just mixmash */#ifdef NFGVMIN		else if (firstch==EOT && readline(1)==TIMEOUT)			return WCEOT;#else		else if (firstch==EOT && Lleft==0)			return WCEOT;#endif		else if (firstch==CAN) {			if (Lastrx==CAN) {				zperr( "Sender CANcelled");				return ERROR;			} else {				Lastrx=CAN;				continue;			}		}		else if (firstch==TIMEOUT) {			if (Firstsec)				goto humbug;bilge:			zperr( "TIMEOUT");		}		else			zperr( "Got 0%o sector header", firstch);humbug:		Lastrx=0;		while(readline(1)!=TIMEOUT)			;		if (Firstsec) {			sendline(Crcflg?WANTCRC:NAK);			Lleft=0;	/* Do read next time ... */		} else {			maxtime=40; sendline(NAK);			Lleft=0;	/* Do read next time ... */		}	}	/* try to stop the bubble machine. */	canit();	return ERROR;}/* * This version of readline is reasoably well suited for * reading many characters. *  (except, currently, for the Regulus version!) * * timeout is in tenths of seconds */readline(timeout)int timeout;{	register n;#ifndef READLINE_PF	static char *readline_ptr;	/* pointer for removing chars from linbuf */#endif	if (--Lleft >= 0) {		if (Verbose > 8) {			fprintf(stderr, "%02x ", *readline_ptr&0377);		}		return (*readline_ptr++ & 0377);	}	if (!no_timeout)	{		n = timeout/10;		if (n < 2)			n = 3;		if (Verbose > 5)			fprintf(stderr, "Calling read: alarm=%d  Readnum=%d ",			  n, Readnum);		signal(SIGALRM, alrm); alarm(n);	}	else if (Verbose > 5)		fprintf(stderr, "Calling read: Readnum=%d ",		  Readnum);	Lleft=read(iofd, readline_ptr=linbuf, Readnum);	if (!no_timeout)		alarm(0);	if (Verbose > 5) {		fprintf(stderr, "Read returned %d bytes\n", Lleft);	}	if (Lleft < 1)		return TIMEOUT;	--Lleft;	if (Verbose > 8) {		fprintf(stderr, "%02x ", *readline_ptr&0377);	}	return (*readline_ptr++ & 0377);}/* * Purge the modem input queue of all characters */purgeline(){	Lleft = 0;#ifdef TCFLSH	ioctl(iofd, TCFLSH, 0);#else	lseek(iofd, 0L, 2);#endif}/* * Process incoming file information header */procheader(name)char *name;{	register char *openmode, *p, **pp;	int tabs, tab_num;	/* set default parameters and overrides */	openmode = "w";	Thisbinary = (!Rxascii) || Rxbinary;	if (Lzmanag)		zmanag = Lzmanag;	/*	 *  Process ZMODEM remote file management requests	 */	if (!Rxbinary && zconv == ZCNL)	/* Remote ASCII override */		Thisbinary = 0;	if (zconv == ZCBIN)	/* Remote Binary override */		Thisbinary = TRUE;	else if (zmanag == ZMAPND)		openmode = "a";	if (Thisbinary && zconv == ZCBIN && try_resume)		zconv=ZCRESUM;#ifdef ENABLE_TIMESYNC	in_timesync=0;	if (timesync_flag && 0==strcmp(name,"$time$.t"))		in_timesync=1;#endif	/* Check for existing file */	if (zconv != ZCRESUM && !Rxclob && (zmanag&ZMMASK) != ZMCLOB && (fout=fopen(name, "r"))) {#ifdef ENABLE_TIMESYNC	    if (!in_timesync)#endif		fclose(fout);  return ERROR;	}	Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L;	p = name + 1 + strlen(name);	if (*p) {	/* file coming from Unix or DOS system */		sscanf(p, "%ld%lo%o", &Bytesleft, &Modtime, &Filemode);		if (Filemode & UNIXFILE)			++Thisbinary;	} else {		/* File coming from CP/M system */		for (p=name; *p; ++p)		/* change / to _ */			if ( *p == '/')				*p = '_';		if ( *--p == '.')		/* zap trailing period */			*p = 0;	}#ifdef ENABLE_TIMESYNC	if (in_timesync)	{		long t=time(0);		long d=t-Modtime;		if (d<0)			d=0;		if ((Verbose && d>60) || Verbose > 1)			fprintf(stderr,  	"TIMESYNC: here %ld, remote %ld, diff %d seconds\n",			(long) t, (long) Modtime, (long) d);#ifdef HAVE_SETTIMEOFDAY		if (timesync_flag > 1 && d > 10)		{			struct timeval tv;			tv.tv_sec=Modtime;			tv.tv_usec=0;			if (settimeofday(&tv,NULL))				fprintf(stderr, "TIMESYNC: cannot set time: %s\n",				strerror(errno));		}#endif		return ERROR; /* skips file */	}#endif /* ENABLE_TIMESYNC */	if (!Zmodem && MakeLCPathname && !IsAnyLower(name)	  && !(Filemode&UNIXFILE))		uncaps(name);	if (Topipe > 0) {		sprintf(Pathname, "%s %s", Progname+2, name);		if (Verbose)			fprintf(stderr,  "Topipe: %s %s\n",			  Pathname, Thisbinary?"BIN":"ASCII");		if ((fout=popen(Pathname, "w")) == NULL)			return ERROR;	} else {		strcpy(Pathname, name);		if (Verbose)			fprintf(stderr, "\nReceiving: %s\n", name);		timing(1);		checkpath(name);		if (Nflag)			name = "/dev/null";#ifdef OMEN		if (name[0] == '!' || name[0] == '|') {			if ( !(fout = popen(name+1, "w"))) {				return ERROR;			}			Topipe = -1;  return(OK);		}#endif		if (Thisbinary && zconv==ZCRESUM) {			struct stat st;			fout = fopen(name, "r+");			if (fout && 0==fstat(fileno(fout),&st))			{				/* retransfer whole blocks */				rxbytes = st.st_size & ~(1024);				/* Bytesleft == filelength on remote */				if (rxbytes < Bytesleft) {					if (fseek(fout, rxbytes, 0)) {						fclose(fout);						return ZFERR;					}				}				goto buffer_it;			}			rxbytes=0;			if (fout)				fclose(fout);		}#ifdef ENABLE_MKDIR		fout = fopen(name, openmode);		if ( !fout && Restricted < 2)			if (make_dirs(name))				fout = fopen(name, openmode);#else		fout = fopen(name, openmode);#endif		if ( !fout)		{			int e=errno;			fprintf(stderr, "lrz: cannot open %s: %s\n", name,				strerror(e));			return ERROR;		}	}buffer_it:	if (Topipe == 0) {		static char *s=NULL;		if (!s) {			s=malloc(16384);			if (!s) {				fprintf(stderr,"lrz: out of memory\r\n");				exit(1);			}#ifdef SETVBUF_REVERSED			setvbuf(fout,_IOFBF,s,16384);#else			setvbuf(fout,s,_IOFBF,16384);#endif		}	}	return OK;}#ifdef ENABLE_MKDIR/* *  Directory-creating routines from Public Domain TAR by John Gilmore *//* * After a file/link/symlink/dir creation has failed, see if * it's because some required directory was not present, and if * so, create all required dirs. */make_dirs(pathname)register char *pathname;{	register char *p;		/* Points into path */	int madeone = 0;		/* Did we do anything yet? */	int save_errno = errno;		/* Remember caller's errno */	char *strchr();	if (errno != ENOENT)		return 0;		/* Not our problem */	for (p = strchr(pathname, '/'); p != NULL; p = strchr(p+1, '/')) {		/* Avoid mkdir of empty string, if leading or double '/' */		if (p == pathname || p[-1] == '/')			continue;		/* Avoid mkdir where last part of path is '.' */		if (p[-1] == '.' && (p == pathname+1 || p[-2] == '/'))			continue;		*p = 0;				/* Truncate the path there */		if ( !mkdir(pathname, 0777)) {	/* Try to create it as a dir */			vfile("Made directory %s\n", pathname);			madeone++;		/* Remember if we made one */			*p = '/';			continue;		}		*p = '/';		if (errno == EEXIST)		/* Directory already exists */			continue;		/*		 * Some other error in the mkdir.  We return to the caller.		 */		break;	}	errno = save_errno;		/* Restore caller's errno */	return madeone;			/* Tell them to retry if we made one */}#endif /* ENABLE_MKDIR *//* * Putsec writes the n characters of buf to receive file fout. *  If not in binary mode, carriage returns, and all characters *  starting with CPMEOF are discarded. */putsec(buf, n)     char *buf;     register n;{	register char *p;	if (n == 0)		return OK;	if (Thisbinary) {		if (fwrite(buf,n,1,fout)!=1)			return ERROR;	}	else {		if (Eofseen)			return OK;		for (p=buf; --n>=0; ++p ) {			if ( *p == '\r')				continue;			if (*p == CPMEOF) {				Eofseen=TRUE; return OK;			}			putc(*p ,fout);		}	}	return OK;}/* *  Send a character to modem.  Small is beautiful. */sendline(c){	char d;	d = c;	if (Verbose>6)		fprintf(stderr, "Sendline: %x\n", c);	write(1, &d, 1);}flushmo() {}/* make string s lower case */uncaps(s)register char *s;{	for ( ; *s; ++s)		if (isupper(*s))			*s = tolower(*s);}/* * IsAnyLower returns TRUE if string s has lower case letters. */IsAnyLower(s)register char *s;{	for ( ; *s; ++s)		if (islower(*s))			return TRUE;	return FALSE;}/* * Log an error *//*VARARGS1*/zperr(s,p,u)char *s, *p, *u;{	if (Verbose <= 0)		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	};	printf(canistr);	Lleft=0;	/* Do read next time ... */	fflush(stdout);}report(sct)int sct;{	if (Verbose>1)		fprintf(stderr,"Blocks received: %d\r",sct);}/* * 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 == 'l') {		/* lrz -> rz */		++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;}

⌨️ 快捷键说明

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