hfaxd/InetFaxServer.c++
/*
 * InetFaxServer::passiveCmd() is called when the fax client sends the 'PASV'
 * or 'EPSV' command to the hfaxd server over the existing control channel.
 * This function implements RFC 2428 (http://tools.ietf.org/html/rfc2428).
 * A properly behaving client will not send 'PASV' or 'EPSV' mutliple times.
 */
:passiveCmd() is called when the fax client sends the 'PASV'
or 'EPSV' command to the hfaxd server over the existing control channel.
This function implements RFC 2428 .
A properly behaving client will not send 'PASV' or 'EPSV' mutliple times.
: passiveCmd () is called when the fax client sends the ' PASV ' or ' EPSV ' command to the hfaxd server over the existing control channel . This function implements RFC 2428 . A properly behaving client will not send ' PASV ' or ' EPSV ' mutliple times .
void
InetFaxServer::passiveCmd(void)
{
    bool extended_mode = (tokenBody[0] == 'E');		
    if (pdata != -1) {
       reply(500, "PASV/EPSV connection already exists");
       return;
    }
 (MUST use 'EPSV' for IPV6)
    if (!extended_mode && (Socket::family(ctrl_addr) != AF_INET)) {
	reply(500, "Cannot use PASV with IPv6 connections");
	return;
    }
    if (debug) logDebug("Opening socket for '%s' mode for address family %d",
	extended_mode ? "EPSV" : "PASV",
	Socket::family(pasv_addr));
    pasv_addr = ctrl_addr;
    Socket::port(pasv_addr) = 0;
    pdata = setupPassiveDataSocket(pasv_addr);
    if (pdata < 0) {
	perror_reply(425, "Cannot setup extended passive connection", errno);
	return;
    }
    if (extended_mode) {
	    reply(229, "Entering Extended Passive Mode (|||%u|)",
		    ntohs(Socket::port(pasv_addr)));
    } else {
	const u_char* a = (const u_char*) &pasv_addr.in.sin_addr;
	const u_char* p = (const u_char*) &pasv_addr.in.sin_port;
	reply(227, "Entering passive mode (%d,%d,%d,%d,%d,%d)", UC(a[0]),
	      UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
    }
}
void InetFaxServer :: passiveCmd ( void ) { bool extended_mode = ( tokenBody [ 0 ] == ' ' ) ; if ( pdata != -1 ) { reply ( 500 , " " ) ; return ; } if ( ! extended_mode && ( Socket :: family ( ctrl_addr ) != AF_INET ) ) { reply ( 500 , " " ) ; return ; } if ( debug ) logDebug ( " " , extended_mode ? " " : " " , Socket :: family ( pasv_addr ) ) ; pasv_addr = ctrl_addr ; Socket :: port ( pasv_addr ) = 0 ; pdata = setupPassiveDataSocket ( pasv_addr ) ; if ( pdata < 0 ) { perror_reply ( 425 , " " , errno ) ; return ; } if ( extended_mode ) { reply ( 229 , " " , ntohs ( Socket :: port ( pasv_addr ) ) ) ; } else { const u_char * a = ( const u_char * ) & pasv_addr . in . sin_addr ; const u_char * p = ( const u_char * ) & pasv_addr . in . sin_port ; reply ( 227 , " " , UC ( a [ 0 ] ) , UC ( a [ 1 ] ) , UC ( a [ 2 ] ) , UC ( a [ 3 ] ) , UC ( p [ 0 ] ) , UC ( p [ 1 ] ) ) ; } }
InetFaxServer::passiveCmd() is called when the fax client sends the 'PASV'
 or 'EPSV' command to the hfaxd server over the existing control channel.
InetFaxServer :: passiveCmd () is called when the fax client sends the ' PASV ' or ' EPSV ' command to the hfaxd server over the existing control channel .
// For brevity. // Sanity checking // Maybe we should close the socket instead, and open a new one? // Sanity checking (MUST use 'EPSV' for IPV6) // Create socket (common to both modes). // NOTE: setupPassiveDataSocket() will choose the proper address family. // Send response via control channel, per RFC 2428. // NOTE: The affirmative response codes are DIFFERENT between EPSV and PASV.