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

📄 lsz.c

📁 Linux下ztelnet 的rz、sz源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		usage(2,_("need at least one file to send"));	if (command_mode && Restricted) {		printf(_("Can't send command in restricted mode\n"));		exit(1);	}	if (Fromcu && !Quiet) {		if (Verbose == 0)			Verbose = 2;	}	vfile("%s %s\n", program_name, VERSION);	if (tcp_flag==2) {		char buf[256];#ifdef MAXHOSTNAMELEN		char hn[MAXHOSTNAMELEN];#else		char hn[256];#endif		char *p,*q;		int d;		/* tell receiver to receive via tcp */		d=tcp_server(buf);		p=strchr(buf+1,'<');		p++;		q=strchr(p,'>');		*q=0;		if (gethostname(hn,sizeof(hn))==-1) {			error(1,0, _("hostname too long\n"));		}		fprintf(stdout,"connect with lrz --tcp-client \"%s:%s\"\n",hn,p);		fflush(stdout);		/* ok, now that this file is sent we can switch to tcp */		tcp_socket=tcp_accept(d);		dup2(tcp_socket,0);		dup2(tcp_socket,1);	}	if (tcp_flag==3) {		char buf[256];		char *p;		p=strchr(tcp_server_address,':');		if (!p)			error(1,0, _("illegal server address\n"));		*p++=0;		sprintf(buf,"[%s] <%s>\n",tcp_server_address,p);		fprintf(stdout,"connecting to %s\n",buf);		fflush(stdout);		/* we need to switch to tcp mode */		tcp_socket=tcp_connect(buf);		dup2(tcp_socket,0);		dup2(tcp_socket,1);	}	{		/* we write max_blocklen (data) + 18 (ZModem protocol overhead)		 * + escape overhead (about 4 %), so buffer has to be		 * somewhat larger than max_blklen 		 */		char *s=malloc(max_blklen+1024);		if (!s)		{			zperr(_("out of memory"));			exit(1);		}#ifdef SETVBUF_REVERSED		setvbuf(stdout,_IOFBF,s,max_blklen+1024);#else		setvbuf(stdout,s,_IOFBF,max_blklen+1024);#endif	}	blklen=start_blklen;	for (i=optind,stdin_files=0;i<argc;i++) {		if (0==strcmp(argv[i],"-"))			stdin_files++;	}	if (stdin_files>1) {		usage(1,_("can read only one file from stdin"));	} else if (stdin_files==1) {		io_mode_fd=1;	}	io_mode(io_mode_fd,1);	readline_setup(io_mode_fd, 128, 256);	if (signal(SIGINT, bibi) == SIG_IGN)		signal(SIGINT, SIG_IGN);	else {		signal(SIGINT, bibi); 		play_with_sigint=1;	}	signal(SIGTERM, bibi);	signal(SIGPIPE, bibi);	signal(SIGHUP, bibi);	if ( protocol!=ZM_XMODEM) {		if (protocol==ZM_ZMODEM) {			printf("rz\r");			fflush(stdout);		}		countem(npats, patts);		if (protocol == ZM_ZMODEM) {			/* throw away any input already received. This doesn't harm			 * as we invite the receiver to send it's data again, and			 * might be useful if the receiver has already died or			 * if there is dirt left if the line 			 */#ifdef HAVE_SELECT			struct timeval t;			unsigned char throwaway;			fd_set f;#endif			purgeline(io_mode_fd);				#ifdef HAVE_SELECT			t.tv_sec = 0;			t.tv_usec = 0;							FD_ZERO(&f);			FD_SET(io_mode_fd,&f);							while (select(1,&f,NULL,NULL,&t)) {				if (0==read(io_mode_fd,&throwaway,1)) /* EOF ... */					break;			}#endif			purgeline(io_mode_fd);			stohdr(0L);			if (command_mode)				Txhdr[ZF0] = ZCOMMAND;			zshhdr(ZRQINIT, Txhdr);			zrqinits_sent++;#if defined(ENABLE_TIMESYNC)			if (Rxflags2 != ZF1_TIMESYNC)				/* disable timesync if there are any flags we don't know.				 * dsz/gsz seems to use some other flags! */				enable_timesync=FALSE;			if (Rxflags2 & ZF1_TIMESYNC && enable_timesync) {				Totalleft+=6; /* TIMESYNC never needs more */				Filesleft++;			}#endif			if (tcp_flag==1) {				Totalleft+=256; /* tcp never needs more */				Filesleft++;			}		}	}	fflush(stdout);	if (Cmdstr) {		if (getzrxinit()) {			Exitcode=0200; canit(STDOUT_FILENO);		}		else if (zsendcmd(Cmdstr, strlen(Cmdstr)+1)) {			Exitcode=0200; canit(STDOUT_FILENO);		}	} else if (wcsend(npats, patts)==ERROR) {		Exitcode=0200;		canit(STDOUT_FILENO);	}	fflush(stdout);	io_mode(io_mode_fd,0);	if (Exitcode)		dm=Exitcode;	else if (errcnt)		dm=1;	else		dm=0;	if (Verbose)	{		fputs("\r\n",stderr);		if (dm)			fputs(_("Transfer incomplete\n"),stderr);		else			fputs(_("Transfer complete\n"),stderr);	}	exit(dm);	/*NOTREACHED*/}static int send_pseudo(const char *name, const char *data){	char *tmp;	const char *p;	int ret=0; /* ok */	size_t plen;	int fd;	int lfd;		p = getenv ("TMPDIR");	if (!p)		p = getenv ("TMP");	if (!p)		p = "/tmp";	tmp=malloc(PATH_MAX+1);	if (!tmp)		error(1,0,_("out of memory"));		plen=strlen(p);	memcpy(tmp,p,plen);		tmp[plen++]='/';	lfd=0;	do {		if (lfd++==10) {			free(tmp);			vstringf (_ ("send_pseudo %s: cannot open tmpfile %s: %s"),					 name, tmp, strerror (errno));			vstring ("\r\n");			return 1;		}		sprintf(tmp+plen,"%s.%lu.%d",name,(unsigned long) getpid(),lfd);		fd=open(tmp,O_WRONLY|O_CREAT|O_EXCL,0700);		/* is O_EXCL guaranted to not follow symlinks? 		 * I don`t know ... so be careful		 */		if (fd!=-1) {			struct stat st;			if (0!=lstat(tmp,&st)) {				vstringf (_ ("send_pseudo %s: cannot lstat tmpfile %s: %s"),						 name, tmp, strerror (errno));				vstring ("\r\n");				unlink(tmp);				close(fd);				fd=-1;			} else {				if (S_ISLNK(st.st_mode)) {					vstringf (_ ("send_pseudo %s: avoiding symlink trap"),name);					vstring ("\r\n");					unlink(tmp);					close(fd);					fd=-1;				}			}		}	} while (fd==-1);	if (write(fd,data,strlen(data))!=(signed long) strlen(data)		|| close(fd)!=0) {		vstringf (_ ("send_pseudo %s: cannot write to tmpfile %s: %s"),				 name, tmp, strerror (errno));		vstring ("\r\n");		free(tmp);		return 1;	}	if (wcs (tmp,name) == ERROR) {		if (Verbose)			vstringf (_ ("send_pseudo %s: failed"),name);		else {			if (Verbose)				vstringf (_ ("send_pseudo %s: ok"),name);			Filcnt--;		}		vstring ("\r\n");		ret=1;	}	unlink (tmp);	free(tmp);	return ret;}static intwcsend (int argc, char *argp[]){	int n;	Crcflg = FALSE;	firstsec = TRUE;	bytcnt = (size_t) -1;	if (tcp_flag==1) {		char buf[256];		int d;		/* tell receiver to receive via tcp */		d=tcp_server(buf);		if (send_pseudo("/$tcp$.t",buf)) {			error(1,0,_("tcp protocol init failed\n"));		}		/* ok, now that this file is sent we can switch to tcp */		tcp_socket=tcp_accept(d);		dup2(tcp_socket,0);		dup2(tcp_socket,1);	}	for (n = 0; n < argc; ++n) {		Totsecs = 0;		if (wcs (argp[n],NULL) == ERROR)			return ERROR;	}#if defined(ENABLE_TIMESYNC)	if (Rxflags2 & ZF1_TIMESYNC && enable_timesync) {		/* implement Peter Mandrellas extension */		char buf[60];		time_t t = time (NULL);		struct tm *tm = localtime (&t);		/* sets timezone */		strftime (buf, sizeof (buf) - 1, "%H:%M:%S", tm);		if (Verbose) {			vstring ("\r\n");			vstringf (_("Answering TIMESYNC at %s"),buf);		}#if defined(HAVE_TIMEZONE_VAR)		sprintf(buf+strlen(buf),"%ld\r\n", timezone / 60);		if (Verbose)			vstringf (" (%s %ld)\r\n", _ ("timezone"), timezone / 60);#else		if (Verbose)			vstringf (" (%s)\r\n", _ ("timezone unknown"));#endif		send_pseudo("/$time$.t",buf);	}#endif	Totsecs = 0;	if (Filcnt == 0) {			/* bitch if we couldn't open ANY files */#if 0	/* i *really* do not like this */		if (protocol != ZM_XMODEM) {			const char *Cmdstr;		/* Pointer to the command string */			command_mode = TRUE;			Cmdstr = "echo \"lsz: Can't open any requested files\"";			if (getnak ()) {				Exitcode = 0200;				canit(STDOUT_FILENO);			}			if (!zmodem_requested)				canit(STDOUT_FILENO);			else if (zsendcmd (Cmdstr, 1 + strlen (Cmdstr))) {				Exitcode = 0200;				canit(STDOUT_FILENO);			}			Exitcode = 1;			return OK;		}#endif		canit(STDOUT_FILENO);		vstring ("\r\n");		vstringf (_ ("Can't open any requested files."));		vstring ("\r\n");		return ERROR;	}	if (zmodem_requested)		saybibi ();	else if (protocol != ZM_XMODEM) {		struct zm_fileinfo zi;		char *pa;		pa=alloca(PATH_MAX+1);		*pa='\0';		zi.fname = pa;		zi.modtime = 0;		zi.mode = 0;		zi.bytes_total = 0;		zi.bytes_sent = 0;		zi.bytes_received = 0;		zi.bytes_skipped = 0;		wctxpn (&zi);	}	return OK;}static intwcs(const char *oname, const char *remotename){#if !defined(S_ISDIR)	int c;#endif	struct stat f;	char *name;	struct zm_fileinfo zi;#ifdef HAVE_MMAP	int dont_mmap_this=0;#endif#ifdef ENABLE_SYSLOG	const char *shortname;	shortname=strrchr(oname,'/');	if (shortname)		shortname++;	else		shortname=oname;#endif	if (Restricted) {		/* restrict pathnames to current tree or uucppublic */		if ( strstr(oname, "../")#ifdef PUBDIR		 || (oname[0]== '/' && strncmp(oname, MK_STRING(PUBDIR),		 	strlen(MK_STRING(PUBDIR))))#endif		) {			canit(STDOUT_FILENO);			vchar('\r');			error(1,0,				_("security violation: not allowed to upload from %s"),oname);		}	}		if (0==strcmp(oname,"-")) {		char *p=getenv("ONAME");		name=alloca(PATH_MAX+1);		if (p) {			strcpy(name, p);		} else {			sprintf(name, "s%lu.lsz", (unsigned long) getpid());		}		input_f=stdin;#ifdef HAVE_MMAP		dont_mmap_this=1;#endif	} else if ((input_f=fopen(oname, "r"))==NULL) {		int e=errno;		error(0,e, _("cannot open %s"),oname);		++errcnt;		return OK;	/* pass over it, there may be others */	} else {		name=alloca(PATH_MAX+1);		strcpy(name, oname);	}#ifdef HAVE_MMAP	if (!use_mmap || dont_mmap_this)#endif	{		static char *s=NULL;		static size_t last_length=0;		struct stat st;		if (fstat(fileno(input_f),&st)==-1)			st.st_size=1024*1024;		if (buffersize==(size_t) -1 && s) {			if ((size_t) st.st_size > last_length) {				free(s);				s=NULL;				last_length=0;			}		}		if (!s && buffersize) {			last_length=16384;			if (buffersize==(size_t) -1) {				if (st.st_size>0)					last_length=st.st_size;			} else				last_length=buffersize;			/* buffer whole pages */			last_length=(last_length+4095)&0xfffff000;			s=malloc(last_length);			if (!s) {				zpfatal(_("out of memory"));				exit(1);			}		}		if (s) {#ifdef SETVBUF_REVERSED			setvbuf(input_f,_IOFBF,s,last_length);#else			setvbuf(input_f,s,_IOFBF,last_length);#endif		}	}	vpos = 0;	/* Check for directory or block special files */	fstat(fileno(input_f), &f);#if defined(S_ISDIR)	if (S_ISDIR(f.st_mode) || S_ISBLK(f.st_mode)) {#else	c = f.st_mode & S_IFMT;	if (c == S_IFDIR || c == S_IFBLK) {#endif		error(0,0, _("is not a file: %s"),name);		fclose(input_f);		return OK;	}	if (remotename) {		/* disqualify const */		union {			const char *c;			char *s;		} cheat;		cheat.c=remotename;		zi.fname=cheat.s;	} else		zi.fname=name;	zi.modtime=f.st_mtime;	zi.mode=f.st_mode;#if defined(S_ISFIFO)	zi.bytes_total= (S_ISFIFO(f.st_mode)) ? DEFBYTL : f.st_size;#else	zi.bytes_total= c == S_IFIFO ? DEFBYTL : f.st_size;#endif	zi.bytes_sent=0;	zi.bytes_received=0;	zi.bytes_skipped=0;	zi.eof_seen=0;	timing(1,NULL);	++Filcnt;	switch (wctxpn(&zi)) {	case ERROR:#ifdef ENABLE_SYSLOG		if (enable_syslog)			lsyslog(LOG_INFO, _("%s/%s: error occured"),protname(),shortname);#endif		return ERROR;	case ZSKIP:		error(0,0, _("skipped: %s"),name);#ifdef ENABLE_SYSLOG		if (enable_syslog)			lsyslog(LOG_INFO, _("%s/%s: skipped"),protname(),shortname);#endif		return OK;	}	if (!zmodem_requested && wctx(&zi)==ERROR)	{#ifdef ENABLE_SYSLOG		if (enable_syslog)			lsyslog(LOG_INFO, _("%s/%s: error occured"),protname(),shortname);#endif		return ERROR;	}	if (Unlinkafter)		unlink(oname);	if (Verbose > 1#ifdef ENABLE_SYSLOG		|| enable_syslog#endif		) {		long bps;		double d=timing(0,NULL);		if (d==0) /* can happen if timing() uses time() */			d=0.5;		bps=zi.bytes_sent/d;		vchar('\r');		if (Verbose > 1) 			vstringf(_("Bytes Sent:%7ld   BPS:%-8ld                        \n"),				(long) zi.bytes_sent,bps);#ifdef ENABLE_SYSLOG		if (enable_syslog)			lsyslog(LOG_INFO, "%s/%s: %ld Bytes, %ld BPS",shortname,				protname(), (long) zi.bytes_sent,bps);#endif	}	return 0;}/* * generate and transmit pathname block consisting of *  pathname (null terminated), *  file length, mode time and file mode in octal *  as provided by the Unix fstat call. *  N.B.: modifies the passed name, may extend it! */static intwctxpn(struct zm_fileinfo *zi){	register char *p, *q;	char *name2;	struct stat f;	name2=alloca(PATH_MAX+1);	if (protocol==ZM_XMODEM) {		if (Verbose && *zi->fname && fstat(fileno(input_f), &f)!= -1) {			vstringf(_("Sending %s, %ld blocks: "),			  zi->fname, (long) (f.st_size>>7));		}		vstringf(_("Give your local XMODEM receive command now."));		vstring("\r\n");		return OK;	}	if (!zmodem_requested)		if (getnak()) {			vfile("getnak failed");			DO_SYSLOG((LOG_INFO, "%s/%s: getnak failed",					   shortname,protname()));			return ERROR;		}	q = (char *) 0;	if (Dottoslash) {		/* change . to . */		for (p=zi->fname; *p; ++p) {			if (*p == '/')				q = p;			else if (*p == '.')				*(q=p) = '/';		}		if (q && strlen(++q) > 8) {	/* If name>8 chars */			q += 8;			/*   make it .ext */			strcpy(name2, q);	/* save excess of name */			*q = '.';			strcpy(++q, name2);	/* add it back */		}	}	for (p=zi->fname, q=txbuf ; *p; )		if ((*q++ = *p++) == '/' && !Fullname)			q = txbuf;	*q++ = 0;	p=q;	while (q < (txbuf + MAX_BLOCK))		*q++ = 0;	/* note that we may lose some information here in case mode_t is wider than an 	 * int. But i believe sending %lo instead of %o _could_ break compatability	 */	if (!Ascii && (input_f!=stdin) && *zi->fname && fstat(fileno(input_f), &f)!= -1)		sprintf(p, "%lu %lo %o 0 %d %ld", (long) f.st_size, f.st_mtime,		  (unsigned int)((no_unixmode) ? 0 : f.st_mode), 		  Filesleft, Totalleft);	if (Verbose)		vstringf(_("Sending: %s\n"),txbuf);	Totalleft -= f.st_size;	if (--Filesleft <= 0)		Totalleft = 0;	if (Totalleft < 0)		Totalleft = 0;	/* force 1k blocks if name won't fit in 128 byte block */

⌨️ 快捷键说明

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