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

📄 rcp.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	char buf[BUFSIZ];	for (x = 0; x < argc; x++) {		name = argv[x];		if ((f = open(name, 0)) < 0) {			error("rcp: %s: %s\n", name, strerror(errno));			continue;		}		if (fstat(f, &stb) < 0)			goto notreg;		switch (stb.st_mode&S_IFMT) {		case S_IFREG:			break;		case S_IFDIR:			if (iamrecursive) {				(void) close(f);				rsource(name, &stb);				continue;			}			/* fall into ... */		default:notreg:			(void) close(f);			error("rcp: %s: not a plain file\n", name);			continue;		}		last = strrchr(name, '/');		if (last == 0)			last = name;		else			last++;		if (pflag) {			/*			 * Make it compatible with possible future			 * versions expecting microseconds.			 */			(void) sprintf(buf, "T%ld 0 %ld 0\n",			    stb.st_mtime, stb.st_atime);			(void) write(rem, buf, strlen(buf));			if (response() < 0) {				(void) close(f);				continue;			}		}		(void) sprintf(buf, "C%04o %ld %s\n",		    stb.st_mode&07777, stb.st_size, last);		(void) write(rem, buf, strlen(buf));		if (response() < 0) {			(void) close(f);			continue;		}		if ((bp = allocbuf(&buffer, f, BUFSIZ)) == 0) {			(void) close(f);			continue;		}		sizerr = 0;		for (i = 0; i < stb.st_size; i += bp->cnt) {			amt = bp->cnt;			if (i + amt > stb.st_size)				amt = stb.st_size - i;			if (sizerr == 0 && read(f, bp->buf, amt) != amt)				sizerr = 1;			(void) write(rem, bp->buf, amt);		}		(void) close(f);		if (sizerr == 0)			ga();		else			error("rcp: %s: file changed size\n", name);		(void) response();	}}voidrsource(name, statp)	char *name;	struct stat *statp;{	DIR *d = opendir(name);	char *last;	struct dirent *dp;	char buf[BUFSIZ];	char *bufv[1];	if (d == 0) {		error("rcp: %s: %s\n", name, strerror(errno));		return;	}	last = strrchr(name, '/');	if (last == 0)		last = name;	else		last++;	if (pflag) {		(void) sprintf(buf, "T%ld 0 %ld 0\n",		    statp->st_mtime, statp->st_atime);		(void) write(rem, buf, strlen(buf));		if (response() < 0) {			closedir(d);			return;		}	}	(void) sprintf(buf, "D%04o %d %s\n", statp->st_mode&07777, 0, last);	(void) write(rem, buf, strlen(buf));	if (response() < 0) {		closedir(d);		return;	}	while (dp = readdir(d)) {		if (dp->d_ino == 0)			continue;		if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))			continue;		if (strlen(name) + 1 + strlen(dp->d_name) >= BUFSIZ - 1) {			error("%s/%s: Name too long.\n", name, dp->d_name);			continue;		}		(void) sprintf(buf, "%s/%s", name, dp->d_name);		bufv[0] = buf;		source(1, bufv);	}	closedir(d);	(void) write(rem, "E\n", 2);	(void) response();}intresponse(){	char resp, c, rbuf[BUFSIZ], *cp = rbuf;	if (read(rem, &resp, 1) != 1)		lostconn(0);	switch (resp) {	case 0:				/* ok */		return (0);	default:		*cp++ = resp;		/* fall into... */	case 1:				/* error, followed by err msg */	case 2:				/* fatal error, "" */		do {			if (read(rem, &c, 1) != 1)				lostconn(0);			*cp++ = c;		} while (cp < &rbuf[BUFSIZ] && c != '\n');		if (iamremote == 0)			(void) write(2, rbuf, cp - rbuf);		errs++;		if (resp == 1)			return (-1);		exit(1);	}	/*NOTREACHED*/}voidlostconn(sig)int sig;{	if (iamremote == 0)		fprintf(stderr, "rcp: lost connection\n");	exit(1);}voidsink(argc, argv)	int argc;	char **argv;{	off_t i, j, size;	char *targ, *whopp, *cp;	int of, mode, wrerr, exists, first, count, amt;	struct buffer *bp;	static struct buffer buffer;	struct stat stb;	int targisdir = 0;	int mask = umask(0);	char *myargv[1];	char cmdbuf[BUFSIZ], nambuf[BUFSIZ];	int setimes = 0;	struct utimbuf utimbuf;#define atime	utimbuf.actime#define mtime	utimbuf.modtime	time_t dummy;#define	SCREWUP(str)	{ whopp = str; goto screwup; }#ifdef NOT_DEF	seteuid(pwd->pw_uid);#endif	if (!pflag)		(void) umask(mask);	if (argc != 1) {		error("rcp: ambiguous target\n");		exit(1);	}	targ = *argv;	if (targetshouldbedirectory)		verifydir(targ);	ga();	if (stat(targ, &stb) == 0 && (stb.st_mode & S_IFMT) == S_IFDIR)		targisdir = 1;	for (first = 1; ; first = 0) {		cp = cmdbuf;		if (read(rem, cp, 1) <= 0)			return;		if (*cp++ == '\n')			SCREWUP("unexpected '\\n'");		do {			if (read(rem, cp, 1) != 1)				SCREWUP("lost connection");		} while (*cp++ != '\n');		*cp = 0;		if (cmdbuf[0] == '\01' || cmdbuf[0] == '\02') {			if (iamremote == 0)				(void) write(2, cmdbuf+1, strlen(cmdbuf+1));			if (cmdbuf[0] == '\02')				exit(1);			errs++;			continue;		}		*--cp = 0;		cp = cmdbuf;		if (*cp == 'E') {			ga();			return;		}#define getnum(t) (t) = 0; while (isdigit(*cp)) (t) = (t) * 10 + (*cp++ - '0');		if (*cp == 'T') {			setimes++;			cp++;			getnum(mtime);			if (*cp++ != ' ')				SCREWUP("mtime.sec not delimited");			getnum(dummy);			if (*cp++ != ' ')				SCREWUP("mtime.usec not delimited");			getnum(atime);			if (*cp++ != ' ')				SCREWUP("atime.sec not delimited");			getnum(dummy);			if (*cp++ != '\0')				SCREWUP("atime.usec not delimited");			ga();			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) {				error("%s\n", cp);				exit(1);			}			SCREWUP("expected control record");		}		cp++;		mode = 0;		for (; cp < cmdbuf+5; cp++) {			if (*cp < '0' || *cp > '7')				SCREWUP("bad mode");			mode = (mode << 3) | (*cp - '0');		}		if (*cp++ != ' ')			SCREWUP("mode not delimited");		size = 0;		while (isdigit(*cp))			size = size * 10 + (*cp++ - '0');		if (*cp++ != ' ')			SCREWUP("size not delimited");		if (targisdir)			(void) sprintf(nambuf, "%s%s%s", targ,			    *targ ? "/" : "", cp);		else			(void) strcpy(nambuf, targ);		exists = stat(nambuf, &stb) == 0;		if (cmdbuf[0] == 'D') {			if (exists) {				if ((stb.st_mode&S_IFMT) != S_IFDIR) {					errno = ENOTDIR;					goto bad;				}				if (pflag)					(void) chmod(nambuf, mode);			} else if (mkdir(nambuf, mode) < 0)				goto bad;			myargv[0] = nambuf;			sink(1, myargv);			if (setimes) {				setimes = 0;				if (utime(nambuf, &utimbuf) < 0)					error("rcp: can't set times on %s: %s\n",					    nambuf, strerror(errno));			}			continue;		}		if ((of = creat(nambuf, mode)) < 0) {	bad:			error("rcp: %s: %s\n", nambuf, strerror(errno));			continue;		}		if (exists && pflag)			(void) chmod(nambuf, mode);		ga();		if ((bp = allocbuf(&buffer, of, BUFSIZ)) == 0) {			(void) close(of);			continue;		}		cp = bp->buf;		count = 0;		wrerr = 0;		for (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)					exit(1);				amt -= j;				cp += j;			} while (amt > 0);			if (count == bp->cnt) {				if (wrerr == 0 &&				    write(of, bp->buf, count) != count)					wrerr++;				count = 0;				cp = bp->buf;			}		}		if (count != 0 && wrerr == 0 &&		    write(of, bp->buf, count) != count)			wrerr++;		(void) close(of);		(void) response();		if (setimes) {			setimes = 0;			if (utime(nambuf, &utimbuf) < 0)				error("rcp: can't set times on %s: %s\n",				    nambuf, strerror(errno));		}				   		if (wrerr)			error("rcp: %s: %s\n", nambuf, strerror(errno));		else			ga();	}screwup:	error("rcp: protocol screwup: %s\n", whopp);	exit(1);}struct buffer *allocbuf(bp, fd, blksize)	struct buffer *bp;	int fd, blksize;{	struct stat stb;	int size;	if (fstat(fd, &stb) < 0) {		error("rcp: fstat: %s\n", strerror(errno));		return ((struct buffer *)0);	}	size= 0;#if NOT_DEF	size = roundup(stb.st_blksize, blksize);#endif	if (size == 0)		size = blksize;	if (bp->cnt < size) {		if (bp->buf != 0)			free(bp->buf);		bp->buf = (char *)malloc((unsigned) size);		if (bp->buf == 0) {			error("rcp: malloc: out of memory\n");			return ((struct buffer *)0);		}	}	bp->cnt = size;	return (bp);}/*VARARGS1*/#if __STDC__voiderror (char *fmt, ...)#elseerror(fmt)char *fmt;#endif{	char buf[BUFSIZ], *cp = buf;	va_list ap;	va_start(ap, fmt);	errs++;	*cp++ = 1;	(void) vsprintf(cp, fmt, ap);	va_end(ap);	(void) write(rem, buf, strlen(buf));	if (iamremote == 0)		(void) write(2, buf+1, strlen(buf+1));}voidusage(){	fprintf(stderr, "Usage: rcp [-p] f1 f2; or: rcp [-rp] f1 ... fn d2\n");}

⌨️ 快捷键说明

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