strcpy(new, tempname);
strlcpy(new, tempname, sizeof new);
recvf(cmd, type)	char *cmd;	int type;{	char *cp = cmd;	int f = -1, mode, opts = 0, wrerr, olderrno;	off_t i, size;	time_t mtime;	struct stat stb;	struct timeval tvp[2];	char *owner, *group;	char new[BUFSIZ];	extern char *tempname;	while (*cp >= '0' && *cp <= '7')		opts = (opts << 3) | (*cp++ - '0');	if (*cp++ != ' ') {		error("recvf: options not delimited\n");		return;	}	mode = 0;	while (*cp >= '0' && *cp <= '7')		mode = (mode << 3) | (*cp++ - '0');	if (*cp++ != ' ') {		error("recvf: mode not delimited\n");		return;	}	size = 0;	while (isdigit(*cp))		size = size * 10 + (*cp++ - '0');	if (*cp++ != ' ') {		error("recvf: size not delimited\n");		return;	}	mtime = 0;	while (isdigit(*cp))		mtime = mtime * 10 + (*cp++ - '0');	if (*cp++ != ' ') {		error("recvf: mtime not delimited\n");		return;	}	owner = cp;	while (*cp && *cp != ' ')		cp++;	if (*cp != ' ') {		error("recvf: owner name not delimited\n");		return;	}	*cp++ = '\0';	group = cp;	while (*cp && *cp != ' ')		cp++;	if (*cp != ' ') {		error("recvf: group name not delimited\n");		return;	}	*cp++ = '\0';	if (type == S_IFDIR) {		if (catname >= sizeof(stp)) {			error("%s:%s: too many directory levels\n",				host, target);			return;		}		stp[catname] = tp;		if (catname++) {			*tp++ = '/';			while (*tp++ = *cp++)				;			tp--;		}		if (opts & VERIFY) {			ack();			return;		}		if (lstat(target, &stb) == 0) {			if (ISDIR(stb.st_mode)) {				if ((stb.st_mode & 07777) == mode) {					ack();					return;				}				buf[0] = '\0';				(void) snprintf(buf + 1, sizeof(buf) - 1,					"%s: Warning: remote mode %o != local mode %o\n",					target, stb.st_mode & 07777, mode);				(void) write(rem, buf, strlen(buf + 1) + 1);				return;			}			errno = ENOTDIR;		} else if (errno == ENOENT && (mkdir(target, mode) == 0 ||		    chkparent(target) == 0 && mkdir(target, mode) == 0)) {			if (fchog(-1, target, owner, group, mode) == 0)				ack();			return;		}		error("%s:%s: %s\n", host, target, strerror(errno));		tp = stp[--catname];		*tp = '\0';		return;	}	if (catname)		(void) snprintf(tp, sizeof(target) - (tp - target), "/%s", cp);	cp = strrchr(target, '/');	if (cp == NULL)		strcpy(new, tempname);	else if (cp == target)		(void) snprintf(new, sizeof(new), "/%s", tempname);	else {		*cp = '\0';		(void) snprintf(new, sizeof(new), "%s/%s", target, tempname);		*cp = '/';	}	if (type == S_IFLNK) {		int j;		ack();		cp = buf;		for (i = 0; i < size; i += j) {			if ((j = read(rem, cp, size - i)) <= 0)				cleanup(0);			cp += j;		}		*cp = '\0';		if (response() < 0) {			err();			return;		}		if (symlink(buf, new) < 0) {			if (errno != ENOENT || chkparent(new) < 0 ||			    symlink(buf, new) < 0)				goto badnew1;		}		mode &= 0777;		if (opts & COMPARE) {			char tbuf[BUFSIZ];			if ((i = readlink(target, tbuf, BUFSIZ)) >= 0 &&			    i == size && strncmp(buf, tbuf, size) == 0) {				(void) unlink(new);				ack();				return;			}			if (opts & VERIFY)				goto differ;		}		goto fixup;	}	if ((f = creat(new, mode)) < 0) {		if (errno != ENOENT || chkparent(new) < 0 ||		    (f = creat(new, mode)) < 0)			goto badnew1;	}	ack();	wrerr = 0;	for (i = 0; i < size; i += BUFSIZ) {		int amt = BUFSIZ;		cp = buf;		if (i + amt > size)			amt = size - i;		do {			int j = read(rem, cp, amt);			if (j <= 0) {				(void) close(f);				(void) unlink(new);				cleanup(0);			}			amt -= j;			cp += j;		} while (amt > 0);		amt = BUFSIZ;		if (i + amt > size)			amt = size - i;		if (wrerr == 0 && write(f, buf, amt) != amt) {			olderrno = errno;			wrerr++;		}	}	if (response() < 0) {		err();		goto badnew2;	}	if (wrerr)		goto badnew1;	if (opts & COMPARE) {		FILE *f1, *f2;		int c;		if ((f1 = fopen(target, "r")) == NULL)			goto badtarget;		if ((f2 = fopen(new, "r")) == NULL) {badnew1:		error("%s:%s: %s\n", host, new, strerror(errno));			goto badnew2;		}		while ((c = getc(f1)) == getc(f2))			if (c == EOF) {				(void) fclose(f1);				(void) fclose(f2);				ack();				goto badnew2;			}		(void) fclose(f1);		(void) fclose(f2);		if (opts & VERIFY) {differ:			buf[0] = '\0';			(void) snprintf(buf + 1, sizeof(buf) - 1,				"need to update: %s\n",target);			(void) write(rem, buf, strlen(buf + 1) + 1);			goto badnew2;		}	}	/*	 * Set last modified time	 */	tvp[0].tv_sec = time(0);	tvp[0].tv_usec = 0;	tvp[1].tv_sec = mtime;	tvp[1].tv_usec = 0;	if (utimes(new, tvp) < 0)		note("%s: utimes failed %s: %s\n", host, new, strerror(errno));	if (fchog(f, new, owner, group, mode) < 0) {badnew2:			if (f >= 0)			(void) close(f);		(void) unlink(new);		return;	}	(void) close(f);fixup:	if (rename(new, target) < 0) {badtarget:	error("%s:%s: %s\n", host, target, strerror(errno));		(void) unlink(new);		return;	}	if (opts & COMPARE) {		buf[0] = '\0';		(void) snprintf(buf + 1, sizeof(buf) - 1,			"updated %s\n", target);		(void) write(rem, buf, strlen(buf + 1) + 1);	} else		ack();}