usr.bin/ftp/ftp.c
/*
 * Need to start a listen on the data channel before we send the command,
 * otherwise the server's connect may fail.
 */
Need to start a listen on the data channel before we send the command,
otherwise the server's connect may fail.
Need to start a listen on the data channel before we send the command otherwise the server ' s connect may fail .
int
initconn()
{
	char *p, *a;
	int result, len, tmpno = 0;
	int on = 1;
	int a0, a1, a2, a3, p0, p1;
	if (passivemode) {
		data = socket(AF_INET, SOCK_STREAM, 0);
		if (data < 0) {
			perror("ftp: socket");
			return(1);
		}
		if ((options & SO_DEBUG) &&
		    setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
			       sizeof (on)) < 0)
			perror("ftp: setsockopt (ignored)");
		if (command("PASV") != COMPLETE) {
			printf("Passive mode refused.\n");
			goto bad;
		}
		if (sscanf(pasv,"%d,%d,%d,%d,%d,%d",
			   &a0, &a1, &a2, &a3, &p0, &p1) != 6) {
			printf("Passive mode address scan failure. "
			       "Shouldn't happen!\n");
			goto bad;
		}
		bzero(&data_addr, sizeof(data_addr));
		data_addr.sin_family = AF_INET;
		a = (char *)&data_addr.sin_addr.s_addr;
		a[0] = a0 & 0xff;
		a[1] = a1 & 0xff;
		a[2] = a2 & 0xff;
		a[3] = a3 & 0xff;
		p = (char *)&data_addr.sin_port;
		p[0] = p0 & 0xff;
		p[1] = p1 & 0xff;
		if (connect(data, (struct sockaddr *)&data_addr,
			    sizeof(data_addr)) < 0) {
			perror("ftp: connect");
			goto bad;
		}
#ifdef IP_TOS
		on = IPTOS_THROUGHPUT;
		if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on,
			       sizeof(int)) < 0)
			perror("ftp: setsockopt TOS (ignored)");
#endif
		return(0);
	}
noport:
	data_addr = myctladdr;
	if (sendport)
		data_addr.sin_port = 0;	 
	if (data != -1)
		(void) close(data);
	data = socket(AF_INET, SOCK_STREAM, 0);
	if (data < 0) {
		warn("socket");
		if (tmpno)
			sendport = 1;
		return (1);
	}
	if (!sendport)
		if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
			warn("setsockopt (reuse address)");
			goto bad;
		}
	if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {
		warn("bind");
		goto bad;
	}
	if (options & SO_DEBUG &&
	    setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
		warn("setsockopt (ignored)");
	len = sizeof (data_addr);
	if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {
		warn("getsockname");
		goto bad;
	}
	if (listen(data, 1) < 0)
		warn("listen");
	if (sendport) {
		a = (char *)&data_addr.sin_addr;
		p = (char *)&data_addr.sin_port;
#define	UC(b)	(((int)b)&0xff)
		result =
		    command("PORT %d,%d,%d,%d,%d,%d",
		      UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
		      UC(p[0]), UC(p[1]));
		if (result == ERROR && sendport == -1) {
			sendport = 0;
			tmpno = 1;
			goto noport;
		}
		return (result != COMPLETE);
	}
	if (tmpno)
		sendport = 1;
#ifdef IP_TOS
	on = IPTOS_THROUGHPUT;
	if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
		warn("setsockopt TOS (ignored)");
#endif
	return (0);
bad:
	(void) close(data), data = -1;
	if (tmpno)
		sendport = 1;
	return (1);
}
int initconn ( ) { char * p , * a ; int result , len , tmpno = 0 ; int on = 1 ; int a0 , a1 , a2 , a3 , p0 , p1 ; if ( passivemode ) { data = socket ( AF_INET , SOCK_STREAM , 0 ) ; if ( data < 0 ) { perror ( " " ) ; return ( 1 ) ; } if ( ( options & SO_DEBUG ) && setsockopt ( data , SOL_SOCKET , SO_DEBUG , ( char * ) & on , sizeof ( on ) ) < 0 ) perror ( " " ) ; if ( command ( " " ) != COMPLETE ) { printf ( " \n " ) ; goto bad ; } if ( sscanf ( pasv , " " , & a0 , & a1 , & a2 , & a3 , & p0 , & p1 ) != 6 ) { printf ( " " " \n " ) ; goto bad ; } bzero ( & data_addr , sizeof ( data_addr ) ) ; data_addr . sin_family = AF_INET ; a = ( char * ) & data_addr . sin_addr . s_addr ; a [ 0 ] = a0 & 0xff ; a [ 1 ] = a1 & 0xff ; a [ 2 ] = a2 & 0xff ; a [ 3 ] = a3 & 0xff ; p = ( char * ) & data_addr . sin_port ; p [ 0 ] = p0 & 0xff ; p [ 1 ] = p1 & 0xff ; if ( connect ( data , ( struct sockaddr * ) & data_addr , sizeof ( data_addr ) ) < 0 ) { perror ( " " ) ; goto bad ; } #ifdef IP_TOS on = IPTOS_THROUGHPUT ; if ( setsockopt ( data , IPPROTO_IP , IP_TOS , ( char * ) & on , sizeof ( int ) ) < 0 ) perror ( " " ) ; #endif return ( 0 ) ; } noport : data_addr = myctladdr ; if ( sendport ) data_addr . sin_port = 0 ; if ( data != -1 ) ( void ) close ( data ) ; data = socket ( AF_INET , SOCK_STREAM , 0 ) ; if ( data < 0 ) { warn ( " " ) ; if ( tmpno ) sendport = 1 ; return ( 1 ) ; } if ( ! sendport ) if ( setsockopt ( data , SOL_SOCKET , SO_REUSEADDR , ( char * ) & on , sizeof ( on ) ) < 0 ) { warn ( " " ) ; goto bad ; } if ( bind ( data , ( struct sockaddr * ) & data_addr , sizeof ( data_addr ) ) < 0 ) { warn ( " " ) ; goto bad ; } if ( options & SO_DEBUG && setsockopt ( data , SOL_SOCKET , SO_DEBUG , ( char * ) & on , sizeof ( on ) ) < 0 ) warn ( " " ) ; len = sizeof ( data_addr ) ; if ( getsockname ( data , ( struct sockaddr * ) & data_addr , & len ) < 0 ) { warn ( " " ) ; goto bad ; } if ( listen ( data , 1 ) < 0 ) warn ( " " ) ; if ( sendport ) { a = ( char * ) & data_addr . sin_addr ; p = ( char * ) & data_addr . sin_port ; #define UC ( b ) 	(((int)b)&0xff) result = command ( " " , UC ( a [ 0 ] ) , UC ( a [ 1 ] ) , UC ( a [ 2 ] ) , UC ( a [ 3 ] ) , UC ( p [ 0 ] ) , UC ( p [ 1 ] ) ) ; if ( result == ERROR && sendport == -1 ) { sendport = 0 ; tmpno = 1 ; goto noport ; } return ( result != COMPLETE ) ; } if ( tmpno ) sendport = 1 ; #ifdef IP_TOS on = IPTOS_THROUGHPUT ; if ( setsockopt ( data , IPPROTO_IP , IP_TOS , ( char * ) & on , sizeof ( int ) ) < 0 ) warn ( " " ) ; #endif return ( 0 ) ; bad : ( void ) close ( data ) , data = -1 ; if ( tmpno ) sendport = 1 ; return ( 1 ) ; }
Need to start a listen on the data channel before we send the command,
 otherwise the server's connect may fail.
Need to start a listen on the data channel before we send the command otherwise the server ' s connect may fail .
/*
		 * What we've got at this point is a string of comma
		 * separated one-byte unsigned integer values.
		 * The first four are the an IP address. The fifth is
		 * the MSB of the port number, the sixth is the LSB.
		 * From that we'll prepare a sockaddr_in.
		 */ /* let system pick one */