Exemplo n.º 1
0
Arquivo: ftplib.c Projeto: cjpl/midas
int ftp_data(FTP_CON * con, const char *command, const char *file)
/* open data socket */
{
   struct sockaddr_in data, from;
   struct hostent *host;
   char host_name[256];
   int listen_socket, data_socket;
   unsigned int len = sizeof(data), fromlen = sizeof(from);
   int one = 1, status;
   char *a, *b;

   memset(&data, 0, sizeof(data));
   memset(&from, 0, sizeof(from));

   if (gethostname(host_name, sizeof(host_name)) == -1)
      return FTP_NET_ERROR;

   if ((host = (struct hostent *) gethostbyname(host_name)) == 0)
      return FTP_NET_ERROR;

   if ((listen_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
      return FTP_NET_ERROR;

   if (setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR,
                  (char *) &one, sizeof(one)) < 0) {
      closesocket(listen_socket);
      return FTP_NET_ERROR;
   }

   data.sin_family = AF_INET;
   data.sin_port = htons(0);
   data.sin_addr.s_addr = *(unsigned long *) *(host->h_addr_list);

   if (bind(listen_socket, (struct sockaddr *) &data, sizeof(data)) == -1) {
      closesocket(listen_socket);
      return FTP_NET_ERROR;
   }

#ifdef OS_WINNT
   if (getsockname(listen_socket, (struct sockaddr *) &data, (int *)&len) < 0) {
#else
   if (getsockname(listen_socket, (struct sockaddr *) &data, &len) < 0) {
#endif
      closesocket(listen_socket);
      return FTP_NET_ERROR;
   }

   if (listen(listen_socket, 1) != 0) {
      closesocket(listen_socket);
      return FTP_NET_ERROR;
   }

   a = (char *) &data.sin_addr;
   b = (char *) &data.sin_port;

   status = ftp_port(con, FTP_CUT(a[0]), FTP_CUT(a[1]), FTP_CUT(a[2]),
                     FTP_CUT(a[3]), FTP_CUT(b[0]), FTP_CUT(b[1]));
   if (status != FTP_SUCCESS)
      return FTP_NET_ERROR;

   status = ftp_command(con, command, file, 200, 120, 150, 125, 250, EOF);
   if (status >= 0)
      return status;

#ifdef OS_WINNT
   data_socket = accept(listen_socket, (struct sockaddr *) &from, (int *)&fromlen);
#else
   data_socket = accept(listen_socket, (struct sockaddr *) &from, &fromlen);
#endif

   if (data_socket == -1) {
      closesocket(listen_socket);
      return FTP_NET_ERROR;
   }

   closesocket(listen_socket);

   con->data = data_socket;

   return status;
}

/*------------------------------------------------------------------*/

int ftp_close(FTP_CON * con)
/* close data connection */
{
   char str[256];

   closesocket(con->data);

   return ftp_get_message(con, str);
}
Exemplo n.º 2
0
//
//	Open data connection
//	Returns -1 upon failure; a socket descriptor upon success.
//
static int opendataconn( struct opusftp_globals *ogp, struct ftp_info *info )
{
int            ts;					// Temporary socket
LONG           len = sizeof(struct sockaddr_in);	// Length of socket address
int            reply;					// Reply from FTP commands
int            bad_pasv = FALSE;			// Passive unavailable?

// PASV known not to work on this site?
if	(info->fi_flags & FTP_NO_PASV)
	bad_pasv = TRUE;

// PASV option not enabled?
if	(!(info->fi_flags & FTP_PASSIVE))
	bad_pasv = TRUE;

// Create temporary socket
if	((ts = socket( AF_INET, SOCK_STREAM, 0 )) >= 0)
	{
	// Passive mode?  Try it first.
	if	(!bad_pasv)
		{
		// Send PASV command to FTP server
		int pasvreply;

		pasvreply=ftp_pasv( info );

		switch	(pasvreply)
			{
			case  227: // correct reply
				if	(pasv_to_address( &info->fi_addr, info->fi_iobuf ))
					{
					if	(connect( ts, (struct sockaddr *)&info->fi_addr, sizeof(info->fi_addr) ) >= 0)
						return(ts);
					}

				bad_pasv = TRUE;
				break;

			case 421: // sockect closed by timeout

				CloseSocket( ts );
				return(-1);

			default:
				D(bug( "Pasv failed returns %ld\n",pasvreply));
				bad_pasv = TRUE;
			}
		}

	// Sendport mode - Passive may have just failed above

	if	(bad_pasv || (info->fi_flags & FTP_NO_PASV))
		{
		getsockname( info->fi_cs, (struct sockaddr*)&info->fi_addr, &len );

		// Set port to zero so the system will pick one
		info->fi_addr.sin_port = 0;

		if	(bind( ts, (struct sockaddr *)&info->fi_addr, sizeof(info->fi_addr) ) >= 0)
			{
			// The system will now fill in the port number it picked
			if	(getsockname( ts, (struct sockaddr*)&info->fi_addr, &len ) >= 0)
				{
				if	(listen( ts, 1 ) >= 0)
					{
					// Can TIMEOUT
					//reply = ftp_port( info, 0, (char *)&info->fi_addr.sin_addr, (char *)&info->fi_addr.sin_port );
					reply = ftp_port( info, 0, &info->fi_addr );

					if	(reply/100 == COMPLETE)
						return(ts);
					}
				else
					{
					D(bug( "** listen fail\n" ));
					info->fi_errno = FTPERR_LISTEN_FAIL;
					}
				}
			else
				{
				D(bug( "** getsockname fail\n" ));
				info->fi_errno = FTPERR_GETSOCKNAME_FAIL;
				}
			}
		else
			{
			D(bug( "** bind fail\n" ));
			info->fi_errno = FTPERR_BIND_FAIL;
			}
		}

	CloseSocket( ts );
	}
else
	info->fi_errno = FTPERR_SOCKET_FAIL;

return (-1) ;
}