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

📄 rcp.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1983 Regents of the University of California. * All rights reserved.  The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */#ifndef lintchar copyright[] ="@(#) Copyright (c) 1983 Regents of the University of California.\n\ All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)rcp.c 1.1 87/12/21 SMI"; /* from UCB 5.3 6/8/85"*/#endif /* not lint *//* * rcp */#undef _MINIX#define NAMESERVER#include <ctype.h>#include <errno.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <utime.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/wait.h>#include <dirent.h>#include <fcntl.h>#include <pwd.h>#include <signal.h>#include <unistd.h>#include <net/gen/netdb.h>#include <net/netlib.h>#if __STDC__#define PROTO(func, args)	func args#else#define PROTO(func, args)	func ()#endif /* __STDC__ */PROTO (int main, (int argc, char *argv[]));PROTO (void lostconn, (int sig));PROTO (void error, (char *fmt, ...) );PROTO (int response, (void) );PROTO (void source, (int argc, char *argv[]) );PROTO (void sink, (int argc, char *argv[]) );PROTO (void usage, (void) );PROTO (char *colon, (char *cp) );PROTO (int okname, (char *cp0) );PROTO (int susystem, (char *s) );PROTO (void verifydir, (char *cp) );PROTO (void rsource, (char *name, struct stat *statp) );PROTO (struct buffer *allocbuf, (struct buffer *bp, int fd, int blksize) );#define vfork	forkint	rem;int	errs;int	errno;int	iamremote, targetshouldbedirectory;int	iamrecursive;int	myuid;		/* uid of invoker */int	pflag;struct	passwd *pwd;int	userid;int	port;struct buffer {	int	cnt;	char	*buf;};#define	ga()	 	(void) write(rem, "", 1)main(argc, argv)	int argc;	char **argv;{	char *targ, *host, *src;#ifndef NAMESERVER	char *suser, *tuser;#else /* NAMESERVER */	char *suser, *tuser, *thost;#endif /* NAMESERVER */	int i;	char buf[BUFSIZ], cmd[16];	struct servent *sp;	sp = getservbyname("shell", "tcp");	if (sp == NULL) {		fprintf(stderr, "rcp: shell/tcp: unknown service\n");		exit(1);	}	port = sp->s_port;	pwd = getpwuid(userid = getuid());	if (pwd == 0) {		fprintf(stderr, "who are you?\n");		exit(1);	}#ifdef NOT_DEF	/*	 * This is a kludge to allow seteuid to user before touching	 * files and seteuid root before doing rcmd so we can open	 * the socket.	 */	myuid = getuid();	if (setruid(0) < 0) {		perror("setruid root");		exit(1);	}	seteuid(myuid);#endif	for (argc--, argv++; argc > 0 && **argv == '-'; argc--, argv++) {		(*argv)++;		while (**argv) switch (*(*argv)++) {		    case 'r':			iamrecursive++;			break;		    case 'p':		/* preserve mtimes and atimes */			pflag++;			break;		    /* The rest of these are not for users. */		    case 'd':			targetshouldbedirectory = 1;			break;		    case 'f':		/* "from" */			iamremote = 1;			(void) response();			source(--argc, ++argv);			exit(errs);		    case 't':		/* "to" */			iamremote = 1;			sink(--argc, ++argv);			exit(errs);		    default:			usage();			exit(1);		}	}if (iamremote){	close(2);	open("/dev/tty", 2);}	if (argc < 2) {		usage();		exit(1);	}	rem = -1;	if (argc > 2)		targetshouldbedirectory = 1;	(void) sprintf(cmd, "rcp%s%s%s",	    iamrecursive ? " -r" : "", pflag ? " -p" : "", 	    targetshouldbedirectory ? " -d" : "");	(void) signal(SIGPIPE, lostconn);	targ = colon(argv[argc - 1]);	if (targ) {				/* ... to remote */		*targ++ = 0;		if (*targ == 0)			targ = ".";#ifndef NAMESERVER		tuser = strrchr(argv[argc - 1], '.');		if (tuser) {			*tuser++ = 0;			if (!okname(tuser))				exit(1);		} else			tuser = pwd->pw_name;#else /* NAMESERVER */		thost = strchr(argv[argc - 1], '@');		if (thost) {			*thost++ = 0;			tuser = argv[argc - 1];			if (*tuser == '\0')				tuser = pwd->pw_name;			else if (!okname(tuser))				exit(1);		} else {			thost = argv[argc - 1];			tuser = pwd->pw_name;		}#endif /* NAMESERVER */		for (i = 0; i < argc - 1; i++) {			src = colon(argv[i]);			if (src) {		/* remote to remote */				*src++ = 0;				if (*src == 0)					src = ".";#ifndef NAMESERVER				suser = strrchr(argv[i], '.');				if (suser) {					*suser++ = 0;					if (!okname(suser))#else /* NAMESERVER */				host = strchr(argv[i], '@');				if (host) {					*host++ = 0;					suser = argv[i];					if (*suser == '\0')						suser = pwd->pw_name;					else if (!okname(suser))#endif /* NAMESERVER */						continue;#ifndef NAMESERVER		(void) sprintf(buf, "rsh %s -l %s -n %s %s '%s.%s:%s'",					    argv[i], suser, cmd, src,					    argv[argc - 1], tuser, targ);				} else		(void) sprintf(buf, "rsh %s -n %s %s '%s.%s:%s'",					    argv[i], cmd, src,					    argv[argc - 1], tuser, targ);#else /* NAMESERVER */		(void) sprintf(buf, "rsh %s -l %s -n %s %s '%s@%s:%s'",					    host, suser, cmd, src,					    tuser, thost, targ);				} else		(void) sprintf(buf, "rsh %s -n %s %s '%s@%s:%s'",					    argv[i], cmd, src,					    tuser, thost, targ);#endif /* NAMESERVER */				(void) susystem(buf);			} else {		/* local to remote */				if (rem == -1) {					(void) sprintf(buf, "%s -t %s",					    cmd, targ);#ifndef NAMESERVER					host = argv[argc - 1];#else /* NAMESERVER */					host = thost;#endif /* NAMESERVER */#ifdef NOT_DEF					if (seteuid(0) < 0) {						perror("seteuid root");						exit(1);					}#endif					rem = rcmd(&host, port, pwd->pw_name,					    tuser, buf, 0);#ifdef NO_DEF					seteuid(myuid);#endif					if (rem < 0)						exit(1);					if (response() < 0)						exit(1);				}				source(1, argv+i);			}		}	} else {				/* ... to local */		if (targetshouldbedirectory)			verifydir(argv[argc - 1]);		for (i = 0; i < argc - 1; i++) {			src = colon(argv[i]);			if (src == 0) {		/* local to local */				(void) sprintf(buf, "/bin/cp%s%s %s %s",				    iamrecursive ? " -r" : "",				    pflag ? " -p" : "",				    argv[i], argv[argc - 1]);				(void) susystem(buf);			} else {		/* remote to local */				*src++ = 0;				if (*src == 0)					src = ".";#ifndef NAMESERVER				suser = strrchr(argv[i], '.');				if (suser) {					*suser++ = 0;					if (!okname(suser))#else /* NAMESERVER */				host = strchr(argv[i], '@');				if (host) {					*host++ = 0;					suser = argv[i];					if (*suser == '\0')						suser = pwd->pw_name;					else if (!okname(suser))#endif /* NAMESERVER */						continue;#ifndef NAMESERVER				} else#else /* NAMESERVER */				} else {					host = argv[i];#endif /* NAMESERVER */					suser = pwd->pw_name;#ifdef NAMESERVER				}#endif /* NAMESERVER */				(void) sprintf(buf, "%s -f %s", cmd, src);#ifndef NAMESERVER				host = argv[i];#endif /* NAMESERVER */#ifdef NOT_DEF				if (seteuid(0) < 0) {					perror("seteuid root");					exit(1);				}#endif				rem = rcmd(&host, port, pwd->pw_name, suser,				    buf, 0);#ifdef NOT_DEF				seteuid(myuid);#endif				if (rem < 0)					continue;				sink(1, argv+argc-1);				(void) close(rem);				rem = -1;			}		}	}	exit(errs);}voidverifydir(cp)	char *cp;{	struct stat stb;	if (stat(cp, &stb) >= 0) {		if ((stb.st_mode & S_IFMT) == S_IFDIR)			return;		errno = ENOTDIR;	}	error("rcp: %s: %s.\n", cp, strerror(errno));	exit(1);}char *colon(cp)	char *cp;{	while (*cp) {		if (*cp == ':')			return (cp);		if (*cp == '/')			return (0);		cp++;	}	return (0);}intokname(cp0)	char *cp0;{	register char *cp = cp0;	register int c;	do {		c = *cp;		if (c & 0200)			goto bad;		if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-')			goto bad;		cp++;	} while (*cp);	return (1);bad:	fprintf(stderr, "rcp: invalid user name %s\n", cp0);	return (0);}intsusystem(s)	char *s;{	int status, pid, w;	register void PROTO ((*istat), (int) ), PROTO ((*qstat), (int) );	if ((pid = vfork()) == 0) {#ifdef NOT_DEF		(void) setruid(myuid);#endif		execl("/bin/sh", "sh", "-c", s, (char *)0);		_exit(127);	}	istat = signal(SIGINT, SIG_IGN);	qstat = signal(SIGQUIT, SIG_IGN);	while ((w = wait(&status)) != pid && w != -1)		;	if (w == -1)		status = -1;	(void) signal(SIGINT, istat);	(void) signal(SIGQUIT, qstat);	return (status);}voidsource(argc, argv)	int argc;	char **argv;{	char *last, *name;	struct stat stb;	static struct buffer buffer;	struct buffer *bp;	int x, sizerr, f, amt;	off_t i;

⌨️ 快捷键说明

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