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

📄 lrz.c

📁 Linux下ztelnet 的rz、sz源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*  lrz - receive files with x/y/zmodem  Copyright (C) until 1988 Chuck Forsberg (Omen Technology INC)  Copyright (C) 1994 Matt Porter, Michael D. Black  Copyright (C) 1996, 1997 Uwe Ohse  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2, or (at your option)  any later version.    This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.  originally written by Chuck Forsberg*/#include "zglobal.h"#define SS_NORMAL 0#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <ctype.h>#include <errno.h>#include <getopt.h>#ifdef HAVE_UTIME_H#include <utime.h>#endif#include "timing.h"#include "long-options.h"#include "xstrtoul.h"#include "error.h"#ifndef STRICT_PROTOTYPESextern time_t time();extern char *strerror();extern char *strstr();#endif#ifndef HAVE_ERRNO_DECLARATIONextern int errno;#endif#define MAX_BLOCK 8192/* * Max value for HOWMANY is 255 if NFGVMIN is not defined. *   A larger value reduces system overhead but may evoke kernel bugs. *   133 corresponds to an XMODEM/CRC sector */#ifndef HOWMANY#ifdef NFGVMIN#define HOWMANY MAX_BLOCK#else#define HOWMANY 255#endif#endifunsigned Baudrate = 2400;FILE *fout;int Lastrx;int Crcflg;int Firstsec;int errors;int Restricted=1;	/* restricted; no /.. or ../ in filenames */int Readnum = HOWMANY;	/* Number of bytes to ask for in read() from modem */int skip_if_not_found;char *Pathname;const char *program_name;		/* the name by which we were called */int Topipe=0;int MakeLCPathname=TRUE;	/* make received pathname lower case */int Verbose=0;int Quiet=0;		/* overrides logic that would otherwise set verbose */int Nflag = 0;		/* Don't really transfer files */int Rxclob=FALSE;	/* Clobber existing file */int Rxbinary=FALSE;	/* receive all files in bin mode */int Rxascii=FALSE;	/* receive files in ascii (translate) mode */int Thisbinary;		/* current file is to be received in bin mode */int try_resume=FALSE;int allow_remote_commands=FALSE;int junk_path=FALSE;int no_timeout=FALSE;enum zm_type_enum protocol;int	under_rsh=FALSE;int zmodem_requested=FALSE;#ifdef SEGMENTSint chinseg = 0;	/* Number of characters received in this data seg */char secbuf[1+(SEGMENTS+1)*MAX_BLOCK];#elsechar secbuf[MAX_BLOCK + 1];#endif#ifdef ENABLE_TIMESYNCint timesync_flag=0;int in_timesync=0;#endifint in_tcpsync=0;int tcpsync_flag=1;int tcp_socket=-1;int tcp_flag=0;char *tcp_server_address=NULL;char tcp_buf[256]="";#if defined(F_GETFD) && defined(F_SETFD) && defined(O_SYNC)static int o_sync = 0;#endifstatic int rzfiles __P ((struct zm_fileinfo *));static int tryz __P ((void));static void checkpath __P ((const char *name));static void chkinvok __P ((const char *s));static void report __P ((int sct));static void uncaps __P ((char *s));static int IsAnyLower __P ((const char *s));static int putsec __P ((struct zm_fileinfo *zi, char *buf, size_t n));static int make_dirs __P ((char *pathname));static int procheader __P ((char *name, struct zm_fileinfo *));static int wcgetsec __P ((size_t *Blklen, char *rxbuf, unsigned int maxtime));static int wcrx __P ((struct zm_fileinfo *));static int wcrxpn __P ((struct zm_fileinfo *, char *rpn));static int wcreceive __P ((int argc, char **argp));static int rzfile __P ((struct zm_fileinfo *));static void usage __P ((int exitcode, const char *what));static void usage1 __P ((int exitcode));static void exec2 __P ((const char *s));static int closeit __P ((struct zm_fileinfo *));static void ackbibi __P ((void));static int sys2 __P ((const char *s));static void zmputs __P ((const char *s));static size_t getfree __P ((void));static long buffersize=32768;static unsigned long min_bps=0;static long min_bps_time=120;char Lzmanag;		/* Local file management request */char zconv;		/* ZMODEM file conversion request */char zmanag;		/* ZMODEM file management request */char ztrans;		/* ZMODEM file transport request */int Zctlesc;		/* Encode control characters */int Zrwindow = 1400;	/* RX window size (controls garbage count) */int tryzhdrtype=ZRINIT;	/* Header type to send corresponding to Last rx close */time_t stop_time;#ifdef ENABLE_SYSLOG#  if defined(ENABLE_SYSLOG_FORCE) || defined(ENABLE_SYSLOG_DEFAULT)int enable_syslog=TRUE;#  elseint enable_syslog=FALSE;#  endif#define DO_SYSLOG_FNAME(message) do { \	if (enable_syslog) { \		const char *shortname; \		if (!zi->fname) \			shortname="no.name"; \		else { \			shortname=strrchr(zi->fname,'/'); \			if (!shortname) \				shortname=zi->fname; \			else \				shortname++; \		} \        lsyslog message ; \	} \} while(0)#define DO_SYSLOG(message) do { \	if (enable_syslog) { \        lsyslog message ; \	} \} while(0)#else#define DO_SYSLOG_FNAME(message) do { } while(0)#define DO_SYSLOG(message) do { } while(0)#endif/* called by signal interrupt or terminate to clean things up */RETSIGTYPEbibi(int n){	if (zmodem_requested)		zmputs(Attn);	canit(STDOUT_FILENO);	io_mode(0,0);	error(128+n,0,_("caught signal %d; exiting"), n);}static struct option const long_options[] ={	{"append", no_argument, NULL, '+'},	{"ascii", no_argument, NULL, 'a'},	{"binary", no_argument, NULL, 'b'},	{"bufsize", required_argument, NULL, 'B'},	{"allow-commands", no_argument, NULL, 'C'},	{"allow-remote-commands", no_argument, NULL, 'C'},	{"escape", no_argument, NULL, 'e'},	{"rename", no_argument, NULL, 'E'},	{"help", no_argument, NULL, 'h'},	{"crc-check", no_argument, NULL, 'H'},	{"junk-path", no_argument, NULL, 'j'},	{"errors", required_argument, NULL, 3},	{"disable-timeouts", no_argument, NULL, 'O'},	{"disable-timeout", no_argument, NULL, 'O'}, /* i can't get it right */	{"min-bps", required_argument, NULL, 'm'},	{"min-bps-time", required_argument, NULL, 'M'},	{"newer", no_argument, NULL, 'n'},	{"newer-or-longer", no_argument, NULL, 'N'},	{"protect", no_argument, NULL, 'p'},	{"resume", no_argument, NULL, 'r'},	{"restricted", no_argument, NULL, 'R'},	{"quiet", no_argument, NULL, 'q'},	{"stop-at", required_argument, NULL, 's'},	{"timesync", no_argument, NULL, 'S'},	{"timeout", required_argument, NULL, 't'},	{"keep-uppercase", no_argument, NULL, 'u'},	{"unrestrict", no_argument, NULL, 'U'},	{"verbose", no_argument, NULL, 'v'},	{"windowsize", required_argument, NULL, 'w'},	{"with-crc", no_argument, NULL, 'c'},	{"xmodem", no_argument, NULL, 'X'},	{"ymodem", no_argument, NULL, 1},	{"zmodem", no_argument, NULL, 'Z'},	{"overwrite", no_argument, NULL, 'y'},	{"null", no_argument, NULL, 'D'},	{"syslog", optional_argument, NULL , 2},	{"delay-startup", required_argument, NULL, 4},	{"o-sync", no_argument, NULL, 5},	{"o_sync", no_argument, NULL, 5},	{"tcp-server", no_argument, NULL, 6},	{"tcp-client", required_argument, NULL, 7},	{NULL,0,NULL,0}};static voidshow_version(void){	printf ("%s (%s) %s\n", program_name, PACKAGE, VERSION);}intmain(int argc, char *argv[]){	register char *cp;	register int npats;	char **patts=NULL; /* keep compiler quiet */	int exitcode=0;	int c;	unsigned int startup_delay=0;	Rxtimeout = 100;	setbuf(stderr, NULL);	if ((cp=getenv("SHELL")) && (strstr(cp, "rsh") || strstr(cp, "rksh")		|| strstr(cp,"rbash") || strstr(cp, "rshell")))		under_rsh=TRUE;	if ((cp=getenv("ZMODEM_RESTRICTED"))!=NULL)		Restricted=2;	/* make temporary and unfinished files */	umask(0077);	from_cu();	chkinvok(argv[0]);	/* if called as [-]rzCOMMAND set flag */#ifdef ENABLE_SYSLOG	openlog(program_name,LOG_PID,ENABLE_SYSLOG);#endif	setlocale (LC_ALL, "");	bindtextdomain (PACKAGE, LOCALEDIR);	textdomain (PACKAGE);    parse_long_options (argc, argv, show_version, usage1);	while ((c = getopt_long (argc, argv, 		"a+bB:cCDeEhm:M:OprRqs:St:uUvw:XZy",		long_options, (int *) 0)) != EOF)	{		unsigned long int tmp;		char *tmpptr;		enum strtol_error s_err;		switch (c)		{		case 0:			break;		case '+': Lzmanag = ZF1_ZMAPND; break;		case 'a': Rxascii=TRUE;  break;		case 'b': Rxbinary=TRUE; break;		case 'B': 			if (strcmp(optarg,"auto")==0) 				buffersize=-1;			else				buffersize=strtol(optarg,NULL,10);			break;		case 'c': Crcflg=TRUE; break;		case 'C': allow_remote_commands=TRUE; break;		case 'D': Nflag = TRUE; break;		case 'E': Lzmanag = ZF1_ZMCHNG; break;		case 'e': Zctlesc = 1; break;		case 'h': usage(0,NULL); break;		case 'H': Lzmanag= ZF1_ZMCRC; break;		case 'j': junk_path=TRUE; break;		case 'm':			s_err = xstrtoul (optarg, &tmpptr, 0, &tmp, "km");			min_bps = tmp;			if (s_err != LONGINT_OK)				STRTOL_FATAL_ERROR (optarg, _("min_bps"), s_err);			break;		case 'M':			s_err = xstrtoul (optarg, NULL, 0, &tmp, NULL);			min_bps_time = tmp;			if (s_err != LONGINT_OK)				STRTOL_FATAL_ERROR (optarg, _("min_bps_time"), s_err);			if (min_bps_time<=1)				usage(2,_("min_bps_time must be > 1"));			break;		case 'N': Lzmanag = ZF1_ZMNEWL;  break;		case 'n': Lzmanag = ZF1_ZMNEW;  break;		case 'O': no_timeout=TRUE; break;		case 'p': Lzmanag = ZF1_ZMPROT;  break;		case 'q': Quiet=TRUE; Verbose=0; break;		case 's':			if (isdigit((unsigned char) (*optarg))) {				struct tm *tm;				time_t t;				int hh,mm;				char *nex;								hh = strtoul (optarg, &nex, 10);				if (hh>23)					usage(2,_("hour to large (0..23)"));				if (*nex!=':')					usage(2, _("unparsable stop time\n"));				nex++;                mm = strtoul (optarg, &nex, 10);				if (mm>59)					usage(2,_("minute to large (0..59)"));								t=time(NULL);				tm=localtime(&t);				tm->tm_hour=hh;				tm->tm_min=hh;				stop_time=mktime(tm);				if (stop_time<t)					stop_time+=86400L; /* one day more */				if (stop_time - t <10)					usage(2,_("stop time to small"));			} else {				s_err = xstrtoul (optarg, NULL, 0, &tmp, NULL);				stop_time = tmp + time(0);				if (s_err != LONGINT_OK)					STRTOL_FATAL_ERROR (optarg, _("stop-at"), s_err);				if (tmp<10)					usage(2,_("stop time to small"));			}			break;		case 'r': 			if (try_resume) 				Lzmanag= ZF1_ZMCRC;			else				try_resume=TRUE;  			break;		case 'R': Restricted++;  break;		case 'S':#ifdef ENABLE_TIMESYNC			timesync_flag++;			if (timesync_flag==2) {#ifdef HAVE_SETTIMEOFDAY				error(0,0,_("don't have settimeofday, will not set time\n"));#endif				if (getuid()!=0)					error(0,0,				_("not running as root (this is good!), can not set time\n"));			}#endif			break;		case 't':			s_err = xstrtoul (optarg, NULL, 0, &tmp, NULL);			Rxtimeout = tmp;			if (s_err != LONGINT_OK)				STRTOL_FATAL_ERROR (optarg, _("timeout"), s_err);			if (Rxtimeout<10 || Rxtimeout>1000)				usage(2,_("timeout out of range 10..1000"));			break;		case 'w':			s_err = xstrtoul (optarg, NULL, 0, &tmp, NULL);			Zrwindow = tmp;			if (s_err != LONGINT_OK)				STRTOL_FATAL_ERROR (optarg, _("window size"), s_err);			break;		case 'u':			MakeLCPathname=FALSE; break;		case 'U':			if (!under_rsh)				Restricted=0;			else  {				DO_SYSLOG((LOG_INFO,"--unrestrict option used under restricted shell"));				error(1,0,	_("security violation: can't do that under restricted shell\n"));			}			break;		case 'v':			++Verbose; break;		case 'X': protocol=ZM_XMODEM; break;		case 1:   protocol=ZM_YMODEM; break;		case 'Z': protocol=ZM_ZMODEM; break;		case 'y':			Rxclob=TRUE; break;		case 2:#ifdef ENABLE_SYSLOG#  ifndef ENABLE_SYSLOG_FORCE			if (optarg && (!strcmp(optarg,"off") || !strcmp(optarg,"no"))) {				if (under_rsh)					error(0,0, _("cannot turnoff syslog"));				else					enable_syslog=FALSE;			}			else				enable_syslog=TRUE;#  else			error(0,0, _("cannot turnoff syslog"));#  endif#endif		case 3:			s_err = xstrtoul (optarg, NULL, 0, &tmp, "km");			bytes_per_error = tmp;			if (s_err != LONGINT_OK)				STRTOL_FATAL_ERROR (optarg, _("bytes_per_error"), s_err);			if (bytes_per_error<100)				usage(2,_("bytes-per-error should be >100"));			break;        case 4:			s_err = xstrtoul (optarg, NULL, 0, &tmp, NULL);			startup_delay = tmp;			if (s_err != LONGINT_OK)				STRTOL_FATAL_ERROR (optarg, _("startup delay"), s_err);			break;		case 5:#if defined(F_GETFD) && defined(F_SETFD) && defined(O_SYNC)			o_sync=1;#else			error(0,0, _("O_SYNC not supported by the kernel"));#endif			break;		case 6:			tcp_flag=2;			break;		case 7:			tcp_flag=3;			tcp_server_address=(char *)strdup(optarg);			if (!tcp_server_address)				error(1,0,_("out of memory"));			break;		default:			usage(2,NULL);		}	}	if (getuid()!=geteuid()) {		error(1,0,		_("this program was never intended to be used setuid\n"));	}	/* initialize zsendline tab */	zsendline_init();#ifdef HAVE_SIGINTERRUPT	siginterrupt(SIGALRM,1);#endif	if (startup_delay)		sleep(startup_delay);	npats = argc - optind;	patts=&argv[optind];	if (npats > 1)		usage(2,_("garbage on commandline"));	if (protocol!=ZM_XMODEM && npats)		usage(2, _("garbage on commandline"));	if (Restricted && allow_remote_commands) {		allow_remote_commands=FALSE;	}	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);	}	io_mode(0,1);	readline_setup(0, HOWMANY, MAX_BLOCK*2);	if (signal(SIGINT, bibi) == SIG_IGN) 		signal(SIGINT, SIG_IGN);	else		signal(SIGINT, bibi);	signal(SIGTERM, bibi);	signal(SIGPIPE, bibi);	if (wcreceive(npats, patts)==ERROR) {		exitcode=0200;		canit(STDOUT_FILENO);	}	io_mode(0,0);	if (exitcode && !zmodem_requested)	/* bellow again with all thy might. */		canit(STDOUT_FILENO);	if (Verbose)	{		fputs("\r\n",stderr);		if (exitcode)			fputs(_("Transfer incomplete\n"),stderr);		else			fputs(_("Transfer complete\n"),stderr);	}	exit(exitcode);}static voidusage1(int exitcode){	usage(exitcode,NULL);}static voidusage(int exitcode, const char *what)

⌨️ 快捷键说明

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