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

📄 rcp.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
			}		}		if (close(fd) && !haderr)			haderr = errno;		if (!haderr)			(void)write(rem, "", 1);		else			run_err("%s: %s", name, strerror(haderr));		(void)response();	}}voidrsource(name, statp)	char *name;	struct stat *statp;{	DIR *dirp;	struct dirent *dp;	char *last, *vect[1], path[MAXPATHLEN];	if (!(dirp = opendir(name))) {		run_err("%s: %s", name, strerror(errno));		return;	}	last = strrchr(name, '/');	if (last == 0)		last = name;	else		last++;	if (pflag) {		(void)snprintf(path, sizeof(path), "T%ld 0 %ld 0\n",		    statp->st_mtimespec.ts_sec, statp->st_atimespec.ts_sec);		(void)write(rem, path, strlen(path));		if (response() < 0) {			closedir(dirp);			return;		}	}	(void)snprintf(path, sizeof(path),	    "D%04o %d %s\n", statp->st_mode & MODEMASK, 0, last);	(void)write(rem, path, strlen(path));	if (response() < 0) {		closedir(dirp);		return;	}	while (dp = readdir(dirp)) {		if (dp->d_ino == 0)			continue;		if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))			continue;		if (strlen(name) + 1 + strlen(dp->d_name) >= MAXPATHLEN - 1) {			run_err("%s/%s: name too long", name, dp->d_name);			continue;		}		(void)snprintf(path, sizeof(path), "%s/%s", name, dp->d_name);		vect[0] = path;		source(1, vect);	}	(void)closedir(dirp);	(void)write(rem, "E\n", 2);	(void)response();}voidsink(argc, argv)	int argc;	char *argv[];{	static BUF buffer;	struct stat stb;	struct timeval tv[2];	enum { YES, NO, DISPLAYED } wrerr;	BUF *bp;	off_t i, j;	int amt, count, exists, first, mask, mode, ofd, omode;	int setimes, size, targisdir, wrerrno;	char ch, *cp, *np, *targ, *why, *vect[1], buf[BUFSIZ];#define	atime	tv[0]#define	mtime	tv[1]#define	SCREWUP(str)	{ why = str; goto screwup; }	setimes = targisdir = 0;	mask = umask(0);	if (!pflag)		(void)umask(mask);	if (argc != 1) {		run_err("ambiguous target");		exit(1);	}	targ = *argv;	if (targetshouldbedirectory)		verifydir(targ);	(void)write(rem, "", 1);	if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))		targisdir = 1;	for (first = 1;; first = 0) {		cp = buf;		if (read(rem, cp, 1) <= 0)			return;		if (*cp++ == '\n')			SCREWUP("unexpected <newline>");		do {			if (read(rem, &ch, sizeof(ch)) != sizeof(ch))				SCREWUP("lost connection");			*cp++ = ch;		} while (cp < &buf[BUFSIZ - 1] && ch != '\n');		*cp = 0;		if (buf[0] == '\01' || buf[0] == '\02') {			if (iamremote == 0)				(void)write(STDERR_FILENO,				    buf + 1, strlen(buf + 1));			if (buf[0] == '\02')				exit(1);			++errs;			continue;		}		if (buf[0] == 'E') {			(void)write(rem, "", 1);			return;		}		if (ch == '\n')			*--cp = 0;#define getnum(t) (t) = 0; while (isdigit(*cp)) (t) = (t) * 10 + (*cp++ - '0');		cp = buf;		if (*cp == 'T') {			setimes++;			cp++;			getnum(mtime.tv_sec);			if (*cp++ != ' ')				SCREWUP("mtime.sec not delimited");			getnum(mtime.tv_usec);			if (*cp++ != ' ')				SCREWUP("mtime.usec not delimited");			getnum(atime.tv_sec);			if (*cp++ != ' ')				SCREWUP("atime.sec not delimited");			getnum(atime.tv_usec);			if (*cp++ != '\0')				SCREWUP("atime.usec not delimited");			(void)write(rem, "", 1);			continue;		}		if (*cp != 'C' && *cp != 'D') {			/*			 * Check for the case "rcp remote:foo\* local:bar".			 * In this case, the line "No match." can be returned			 * by the shell before the rcp command on the remote is			 * executed so the ^Aerror_message convention isn't			 * followed.			 */			if (first) {				run_err("%s", cp);				exit(1);			}			SCREWUP("expected control record");		}		mode = 0;		for (++cp; cp < buf + 5; cp++) {			if (*cp < '0' || *cp > '7')				SCREWUP("bad mode");			mode = (mode << 3) | (*cp - '0');		}		if (*cp++ != ' ')			SCREWUP("mode not delimited");		for (size = 0; isdigit(*cp);)			size = size * 10 + (*cp++ - '0');		if (*cp++ != ' ')			SCREWUP("size not delimited");		if (targisdir) {			static char *namebuf;			static int cursize;			size_t need;			need = strlen(targ) + strlen(cp) + 250;			if (need > cursize) {				if (!(namebuf = malloc(need)))					run_err("%s", strerror(errno));			}			(void)snprintf(namebuf, need, "%s%s%s", targ,			    *targ ? "/" : "", cp);			np = namebuf;		} else			np = targ;		exists = stat(np, &stb) == 0;		if (buf[0] == 'D') {			int mod_flag = pflag;			if (exists) {				if (!S_ISDIR(stb.st_mode)) {					errno = ENOTDIR;					goto bad;				}				if (pflag)					(void)chmod(np, mode);			} else {				/* Handle copying from a read-only directory */				mod_flag = 1;				if (mkdir(np, mode | S_IRWXU) < 0)					goto bad;			}			vect[0] = np;			sink(1, vect);			if (setimes) {				setimes = 0;				if (utimes(np, tv) < 0)				    run_err("%s: set times: %s",					np, strerror(errno));			}			if (mod_flag)				(void)chmod(np, mode);			continue;		}		omode = mode;		mode |= S_IWRITE;		if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) {bad:			run_err("%s: %s", np, strerror(errno));			continue;		}		(void)write(rem, "", 1);		if ((bp = allocbuf(&buffer, ofd, BUFSIZ)) == NULL) {			(void)close(ofd);			continue;		}		cp = bp->buf;		wrerr = NO;		for (count = i = 0; i < size; i += BUFSIZ) {			amt = BUFSIZ;			if (i + amt > size)				amt = size - i;			count += amt;			do {				j = read(rem, cp, amt);				if (j <= 0) {					run_err("%s", j ? strerror(errno) :					    "dropped connection");					exit(1);				}				amt -= j;				cp += j;			} while (amt > 0);			if (count == bp->cnt) {				/* Keep reading so we stay sync'd up. */				if (wrerr == NO) {					j = write(ofd, bp->buf, count);					if (j != count) {						wrerr = YES;						wrerrno = j >= 0 ? EIO : errno; 					}				}				count = 0;				cp = bp->buf;			}		}		if (count != 0 && wrerr == NO &&		    (j = write(ofd, bp->buf, count)) != count) {			wrerr = YES;			wrerrno = j >= 0 ? EIO : errno; 		}		if (ftruncate(ofd, size)) {			run_err("%s: truncate: %s", np, strerror(errno));			wrerr = DISPLAYED;		}		if (pflag) {			if (exists || omode != mode)				if (fchmod(ofd, omode))					run_err("%s: set mode: %s",					    np, strerror(errno));		} else {			if (!exists && omode != mode)				if (fchmod(ofd, omode & ~mask))					run_err("%s: set mode: %s",					    np, strerror(errno));		}		(void)close(ofd);		(void)response();		if (setimes && wrerr == NO) {			setimes = 0;			if (utimes(np, tv) < 0) {				run_err("%s: set times: %s",				    np, strerror(errno));				wrerr = DISPLAYED;			}		}		switch(wrerr) {		case YES:			run_err("%s: %s", np, strerror(wrerrno));			break;		case NO:			(void)write(rem, "", 1);			break;		case DISPLAYED:			break;		}	}screwup:	run_err("protocol error: %s", why);	exit(1);}#ifdef KERBEROSintkerberos(host, bp, locuser, user)	char **host, *bp, *locuser, *user;{	struct servent *sp;again:	if (use_kerberos) {		rem = KSUCCESS;		errno = 0;		if (dest_realm == NULL)			dest_realm = krb_realmofhost(*host);		rem = #ifdef CRYPT		    doencrypt ? 			krcmd_mutual(host,			    port, user, bp, 0, dest_realm, &cred, schedule) :#endif			krcmd(host, port, user, bp, 0, dest_realm);		if (rem < 0) {			use_kerberos = 0;			if ((sp = getservbyname("shell", "tcp")) == NULL)				errx(1, "unknown service shell/tcp");			if (errno == ECONNREFUSED)			    oldw("remote host doesn't support Kerberos");			else if (errno == ENOENT)			    oldw("can't provide Kerberos authentication data");			port = sp->s_port;			goto again;		}	} else {#ifdef CRYPT		if (doencrypt)			errx(1,			   "the -x option requires Kerberos authentication");#endif		rem = rcmd(host, port, locuser, user, bp, 0);	}	return (rem);}#endif /* KERBEROS */intresponse(){	char ch, *cp, resp, rbuf[BUFSIZ];	if (read(rem, &resp, sizeof(resp)) != sizeof(resp))		lostconn(0);	cp = rbuf;	switch(resp) {	case 0:				/* ok */		return (0);	default:		*cp++ = resp;		/* FALLTHROUGH */	case 1:				/* error, followed by error msg */	case 2:				/* fatal error, "" */		do {			if (read(rem, &ch, sizeof(ch)) != sizeof(ch))				lostconn(0);			*cp++ = ch;		} while (cp < &rbuf[BUFSIZ] && ch != '\n');		if (!iamremote)			(void)write(STDERR_FILENO, rbuf, cp - rbuf);		++errs;		if (resp == 1)			return (-1);		exit(1);	}	/* NOTREACHED */}voidusage(){#ifdef KERBEROS#ifdef CRYPT	(void)fprintf(stderr, "%s\n\t%s\n",	    "usage: rcp [-Kpx] [-k realm] f1 f2",	    "or: rcp [-Kprx] [-k realm] f1 ... fn directory");#else	(void)fprintf(stderr, "%s\n\t%s\n",	    "usage: rcp [-Kp] [-k realm] f1 f2",	    "or: rcp [-Kpr] [-k realm] f1 ... fn directory");#endif#else	(void)fprintf(stderr,	    "usage: rcp [-p] f1 f2; or: rcp [-pr] f1 ... fn directory\n");#endif	exit(1);}#if __STDC__#include <stdarg.h>#else#include <varargs.h>#endif#ifdef KERBEROSvoid#if __STDC__oldw(const char *fmt, ...)#elseoldw(fmt, va_alist)	char *fmt;        va_dcl#endif{	va_list ap;#if __STDC__	va_start(ap, fmt);#else	va_start(ap);#endif	(void)fprintf(stderr, "rcp: ");	(void)vfprintf(stderr, fmt, ap);	(void)fprintf(stderr, ", using standard rcp\n");	va_end(ap);}#endifvoid#if __STDC__run_err(const char *fmt, ...)#elserun_err(fmt, va_alist)	char *fmt;        va_dcl#endif{	static FILE *fp;	va_list ap;#if __STDC__	va_start(ap, fmt);#else	va_start(ap);#endif	++errs;	if (fp == NULL && !(fp = fdopen(rem, "w")))		return;	(void)fprintf(fp, "%c", 0x01);	(void)fprintf(fp, "rcp: ");	(void)vfprintf(fp, fmt, ap);	(void)fprintf(fp, "\n");	(void)fflush(fp);	if (!iamremote)		vwarnx(fmt, ap);	va_end(ap);}

⌨️ 快捷键说明

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