(void) seteuid((uid_t)pw->pw_uid);
getdatasock(char *mode){	int on = 1, s, t, tries;	if (data >= 0)		return (fdopen(data, mode));	sigprocmask (SIG_BLOCK, &allsigs, NULL);	s = socket(ctrl_addr.su_family, SOCK_STREAM, 0);	if (s < 0)		goto bad;	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,	    (char *) &on, sizeof(on)) < 0)		goto bad;	/* anchor socket to avoid multi-homing problems */	data_source = ctrl_addr;	data_source.su_port = htons(20); /* ftp-data port */	(void) seteuid(0);	for (tries = 1; ; tries++) {		if (bind(s, (struct sockaddr *)&data_source,		    data_source.su_len) >= 0)			break;		if (errno != EADDRINUSE || tries > 10) {			(void) seteuid(pw->pw_uid);			goto bad;		}		sleep(tries);	}	(void) seteuid((uid_t)pw->pw_uid);	sigprocmask (SIG_UNBLOCK, &allsigs, NULL);#ifdef IP_TOS	if (ctrl_addr.su_family == AF_INET) {		on = IPTOS_THROUGHPUT;		if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&on,		    sizeof(int)) < 0)			syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");	}#endif#ifdef TCP_NOPUSH	/*	 * Turn off push flag to keep sender TCP from sending short packets	 * at the boundaries of each write().  Should probably do a SO_SNDBUF	 * to set the send buffer size as well, but that may not be desirable	 * in heavy-load situations.	 */	on = 1;	if (setsockopt(s, IPPROTO_TCP, TCP_NOPUSH, (char *)&on, sizeof(on)) < 0)		syslog(LOG_WARNING, "setsockopt (TCP_NOPUSH): %m");#endif#ifdef SO_SNDBUF	on = 65536;	if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&on, sizeof(on)) < 0)		syslog(LOG_WARNING, "setsockopt (SO_SNDBUF): %m");#endif	return (fdopen(s, mode));bad:	/* Return the real value of errno (close may change it) */	t = errno;	sigprocmask (SIG_UNBLOCK, &allsigs, NULL);	(void) close(s);	errno = t;	return (NULL);}