(void) write(STDERR_FILENO,
(void) atomicio(write, STDERR_FILENO,
sink(argc, argv)	int argc;	char *argv[];{	static BUF buffer;	struct stat stb;	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 = 0;	char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];	struct utimbuf ut;	int dummy_usec;#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(remout, "", 1);	if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))		targisdir = 1;	for (first = 1;; first = 0) {		cp = buf;		if (read(remin, cp, 1) <= 0)			return;		if (*cp++ == '\n')			SCREWUP("unexpected <newline>");		do {			if (read(remin, &ch, sizeof(ch)) != sizeof(ch))				SCREWUP("lost connection");			*cp++ = ch;		} while (cp < &buf[sizeof(buf) - 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(remout, "", 1);			return;		}		if (ch == '\n')			*--cp = 0;#define getnum(t) (t) = 0; \  while (*cp >= '0' && *cp <= '9') (t) = (t) * 10 + (*cp++ - '0');		cp = buf;		if (*cp == 'T') {			setimes++;			cp++;			getnum(ut.modtime);			if (*cp++ != ' ')				SCREWUP("mtime.sec not delimited");			getnum(dummy_usec);			if (*cp++ != ' ')				SCREWUP("mtime.usec not delimited");			getnum(ut.actime);			if (*cp++ != ' ')				SCREWUP("atime.sec not delimited");			getnum(dummy_usec);			if (*cp++ != '\0')				SCREWUP("atime.usec not delimited");			(void) write(remout, "", 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; *cp >= '0' && *cp <= '9';)			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)				namebuf = xmalloc(need);			(void) sprintf(namebuf, "%s%s%s", targ,				       *targ ? "/" : "", cp);			np = namebuf;		} else			np = targ;		curfile = cp;		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 (utime(np, &ut) < 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 | O_TRUNC, mode)) < 0) {bad:			run_err("%s: %s", np, strerror(errno));			continue;		}		(void) write(remout, "", 1);		if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) {			(void) close(ofd);			continue;		}		cp = bp->buf;		wrerr = NO;		if (showprogress) {			totalbytes = size;			progressmeter(-1);		}		statbytes = 0;		for (count = i = 0; i < size; i += 4096) {			amt = 4096;			if (i + amt > size)				amt = size - i;			count += amt;			do {				j = read(remin, cp, amt);				if (j <= 0) {					run_err("%s", j ? strerror(errno) :						"dropped connection");					exit(1);				}				amt -= j;				cp += j;				statbytes += 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 (showprogress)			progressmeter(1);		if (count != 0 && wrerr == NO &&		    (j = write(ofd, bp->buf, count)) != count) {			wrerr = YES;			wrerrno = j >= 0 ? EIO : errno;		}#if 0		if (ftruncate(ofd, size)) {			run_err("%s: truncate: %s", np, strerror(errno));			wrerr = DISPLAYED;		}#endif		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 (utime(np, &ut) < 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(remout, "", 1);			break;		case DISPLAYED:			break;		}	}screwup:	run_err("protocol error: %s", why);	exit(1);}