progress = oprogress;
recvrequest(cmd, local, remote, lmode, printnames)	const char *cmd, *local, *remote, *lmode;	int printnames;{	FILE *fout, *din = 0;	int (*closefunc) __P((FILE *));	sig_t oldinti, oldintr, oldintp;	int c, d, is_retr, tcrflag, bare_lfs = 0;	static int bufsize;	static char *buf;	off_t hashbytes;	struct stat st;	time_t mtime;	hashbytes = mark;	direction = "received";	bytes = 0;	filesize = -1;	is_retr = strcmp(cmd, "RETR") == 0;	if (is_retr && verbose && printnames) {		if (local && *local != '-')			printf("local: %s ", local);		if (remote)			printf("remote: %s\n", remote);	}	if (proxy && is_retr) {		proxtrans(cmd, local, remote);		return;	}	closefunc = NULL;	oldintr = NULL;	oldintp = NULL;	tcrflag = !crflag && is_retr;	if (setjmp(recvabort)) {		while (cpend) {			(void)getreply(0);		}		if (data >= 0) {			(void)close(data);			data = -1;		}		if (oldintr)			(void)signal(SIGINT, oldintr);		if (oldinti)			(void)signal(SIGINFO, oldinti);		code = -1;		return;	}	oldintr = signal(SIGINT, abortrecv);	oldinti = signal(SIGINFO, psummary);	if (strcmp(local, "-") && *local != '|') {		if (access(local, 2) < 0) {			char *dir = strrchr(local, '/');			if (errno != ENOENT && errno != EACCES) {				warn("local: %s", local);				(void)signal(SIGINT, oldintr);				(void)signal(SIGINFO, oldinti);				code = -1;				return;			}			if (dir != NULL)				*dir = 0;			d = access(dir == local ? "/" : dir ? local : ".", 2);			if (dir != NULL)				*dir = '/';			if (d < 0) {				warn("local: %s", local);				(void)signal(SIGINT, oldintr);				(void)signal(SIGINFO, oldinti);				code = -1;				return;			}			if (!runique && errno == EACCES &&			    chmod(local, 0600) < 0) {				warn("local: %s", local);				(void)signal(SIGINT, oldintr);				(void)signal(SIGINFO, oldinti);				code = -1;				return;			}			if (runique && errno == EACCES &&			   (local = gunique(local)) == NULL) {				(void)signal(SIGINT, oldintr);				(void)signal(SIGINFO, oldinti);				code = -1;				return;			}		}		else if (runique && (local = gunique(local)) == NULL) {			(void)signal(SIGINT, oldintr);			(void)signal(SIGINFO, oldinti);			code = -1;			return;		}	}	if (!is_retr) {		if (curtype != TYPE_A)			changetype(TYPE_A, 0);	} else {		if (curtype != type)			changetype(type, 0);		filesize = remotesize(remote, 0);	}	if (initconn()) {		(void)signal(SIGINT, oldintr);		(void)signal(SIGINFO, oldinti);		code = -1;		return;	}	if (setjmp(recvabort))		goto abort;	if (is_retr && restart_point &&	    command("REST %ld", (long) restart_point) != CONTINUE)		return;	if (remote) {		if (command("%s %s", cmd, remote) != PRELIM) {			(void)signal(SIGINT, oldintr);			(void)signal(SIGINFO, oldinti);			return;		}	} else {		if (command("%s", cmd) != PRELIM) {			(void)signal(SIGINT, oldintr);			(void)signal(SIGINFO, oldinti);			return;		}	}	din = dataconn("r");	if (din == NULL)		goto abort;	if (strcmp(local, "-") == 0)		fout = stdout;	else if (*local == '|') {		oldintp = signal(SIGPIPE, SIG_IGN);		fout = popen(local + 1, "w");		if (fout == NULL) {			warn("%s", local+1);			goto abort;		}		closefunc = pclose;	} else {		fout = fopen(local, lmode);		if (fout == NULL) {			warn("local: %s", local);			goto abort;		}		closefunc = fclose;	}	if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0)		st.st_blksize = BUFSIZ;	if (st.st_blksize > bufsize) {		if (buf)			(void)free(buf);		buf = malloc((unsigned)st.st_blksize);		if (buf == NULL) {			warn("malloc");			bufsize = 0;			goto abort;		}		bufsize = st.st_blksize;	}	progressmeter(-1);	switch (curtype) {	case TYPE_I:	case TYPE_L:		if (restart_point &&		    lseek(fileno(fout), restart_point, SEEK_SET) < 0) {			warn("local: %s", local);			if (closefunc != NULL)				(*closefunc)(fout);			return;		}		errno = d = 0;		while ((c = read(fileno(din), buf, bufsize)) > 0) {			if ((d = write(fileno(fout), buf, c)) != c)				break;			bytes += c;			if (hash && (!progress || filesize < 0)) {				while (bytes >= hashbytes) {					(void)putchar('#');					hashbytes += mark;				}				(void)fflush(stdout);			}		}		if (hash && (!progress || filesize < 0) && bytes > 0) {			if (bytes < mark)				(void)putchar('#');			(void)putchar('\n');			(void)fflush(stdout);		}		if (c < 0) {			if (errno != EPIPE)				warn("netin");			bytes = -1;		}		if (d < c) {			if (d < 0)				warn("local: %s", local);			else				warnx("%s: short write", local);		}		break;	case TYPE_A:		if (restart_point) {			int i, n, ch;			if (fseek(fout, 0L, SEEK_SET) < 0)				goto done;			n = restart_point;			for (i = 0; i++ < n;) {				if ((ch = getc(fout)) == EOF)					goto done;				if (ch == '\n')					i++;			}			if (fseek(fout, 0L, SEEK_CUR) < 0) {done:				warn("local: %s", local);				if (closefunc != NULL)					(*closefunc)(fout);				return;			}		}		while ((c = getc(din)) != EOF) {			if (c == '\n')				bare_lfs++;			while (c == '\r') {				while (hash && (!progress || filesize < 0) &&				    (bytes >= hashbytes)) {					(void)putchar('#');					(void)fflush(stdout);					hashbytes += mark;				}				bytes++;				if ((c = getc(din)) != '\n' || tcrflag) {					if (ferror(fout))						goto break2;					(void)putc('\r', fout);					if (c == '\0') {						bytes++;						goto contin2;					}					if (c == EOF)						goto contin2;				}			}			(void)putc(c, fout);			bytes++;	contin2:	;		}break2:		if (bare_lfs) {			printf("WARNING! %d bare linefeeds received in ASCII mode\n",			    bare_lfs);			puts("File may not have transferred correctly.");		}		if (hash && (!progress || filesize < 0)) {			if (bytes < hashbytes)				(void)putchar('#');			(void)putchar('\n');			(void)fflush(stdout);		}		if (ferror(din)) {			if (errno != EPIPE)				warn("netin");			bytes = -1;		}		if (ferror(fout))			warn("local: %s", local);		break;	}	progressmeter(1);	if (closefunc != NULL)		(*closefunc)(fout);	(void)signal(SIGINT, oldintr);	(void)signal(SIGINFO, oldinti);	if (oldintp)		(void)signal(SIGPIPE, oldintp);	(void)fclose(din);	(void)getreply(0);	if (bytes >= 0 && is_retr) {		if (bytes > 0)			ptransfer(0);		if (preserve && (closefunc == fclose)) {			mtime = remotemodtime(remote, 0);			if (mtime != -1) {				struct utimbuf ut;				ut.actime = time(NULL);				ut.modtime = mtime;				if (utime(local, &ut) == -1)					printf("Can't change modification time on %s to %s",					    local, asctime(localtime(&mtime)));			}		}	}	return;abort:/* abort using RFC959 recommended IP,SYNC sequence */	if (oldintp)		(void)signal(SIGPIPE, oldintp);	(void)signal(SIGINT, SIG_IGN);	if (!cpend) {		code = -1;		(void)signal(SIGINT, oldintr);		(void)signal(SIGINFO, oldinti);		return;	}	abort_remote(din);	code = -1;	if (data >= 0) {		(void)close(data);		data = -1;	}	if (closefunc != NULL && fout != NULL)		(*closefunc)(fout);	if (din)		(void)fclose(din);	if (bytes > 0)		ptransfer(0);	(void)signal(SIGINT, oldintr);	(void)signal(SIGINFO, oldinti);}