Beispiel #1
0
int
ftp_retr(int fd, off_t offset)
{
	char	buf[MAX_LINE];
	off_t	file_sz;
	int	data_sock, ret;

	if (ftp_size(ctrl_sock, file, &file_sz) != P_OK) {
		warnx("failed to get size of file %s", file);
		return -1;
	}

	if ((data_sock = ftp_pasv(ctrl_sock)) == -1)
		return -1;

	if (ftp_command(ctrl_sock, "RETR %s\r\n", file) != P_PRE)
		return -1;

	ret = retr_file(data_sock, fd, file_sz, offset);
	if (ftp_readline(ctrl_sock, buf, sizeof buf) != P_OK) {
		warnx("error retrieving file %s", file);
		return -1;
	}

	ftp_command(ctrl_sock, "QUIT\r\n");
	return ret;
}
Beispiel #2
0
int
ftp_get(off_t offset, struct url *url)
{
	char	*dir;
	int	 ret;

	log_info("Using binary mode to transfer files.\n");
	if (ftp_command(ctrl_sock, "TYPE I\r\n") != P_OK) {
		fprintf(stderr, "Failed to set mode to binary\n");
		return -1;
	}

	if (url->path)
		file = strrchr(url->path, '/');

	if (file == NULL || file == url->path)
		dir = NULL;
	else {
		dir = url->path;
		*file++ = '\0';
	}

	if (dir && ftp_command(ctrl_sock, "CWD %s\r\n", dir) != P_OK)
		return -1;

	ret = 200;
	if (offset && ftp_command(ctrl_sock, "REST %lld\r\n", offset) == P_OK)
		ret = 206;

	return ret;
}
Beispiel #3
0
int ftp_move(FTP_CON * con, const char *oldname, const char *newname)
/* move/rename file */
{
   int status;

   status = ftp_command(con, "RNFR %s", oldname, 200, 350, EOF);

   if (status < 0)
      return ftp_command(con, "RNTO %s", newname, 200, 250, EOF);
   else
      return status;
}
Beispiel #4
0
static time_t
ftp_modtime(FTP ftp, char *path)
{
    int status;
    Str tmp;
    char *p;
    struct tm tm;
    time_t t, lt, gt;

    tmp = ftp_command(ftp, "MDTM", path, &status);
    if (status != 213)
        return -1;
    for (p = tmp->ptr + 4; *p && *p == ' '; p++) ;
    memset(&tm, 0, sizeof(struct tm));
    if (sscanf(p, "%04d%02d%02d%02d%02d%02d",
               &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
               &tm.tm_hour, &tm.tm_min, &tm.tm_sec) < 6)
        return -1;
    tm.tm_year -= 1900;
    tm.tm_mon--;
    t = mktime(&tm);
    lt = mktime(localtime(&t));
    gt = mktime(gmtime(&t));
    return t + (lt - gt);
}
Beispiel #5
0
int
ftp_connect(struct url *url)
{
	char	buf[MAX_LINE];
	int	r = -1;

	if (url->port[0] == '\0')
		(void)strlcpy(url->port, "21", sizeof url->port);

	if ((ctrl_sock = tcp_connect(url->host, url->port)) == -1)
		return -1;

	if (proxy && proxy_connect(ctrl_sock, url) == -1)
		goto error;

	/* greeting */
	if ((r = ftp_readline(ctrl_sock, buf, sizeof buf)) != P_OK)
		goto error;

	log_info("Connected to %s\n", url->host);
	if ((r = ftp_auth(NULL, NULL)) != P_OK)
		goto error;

	return ctrl_sock;
error:
	if (r == -1 && errno != EINTR)
		warnx("Can't connect or login to host `%s'", url->host);

	ftp_command(ctrl_sock, "QUIT\r\n");
	if (close(ctrl_sock) == -1 && errno != EINTR)
		err(1, "ftp_connect: close");

	return -1;
}
Beispiel #6
0
int conn_setup( conn_t *conn )
{
	if( conn->ftp->fd <= 0 && conn->http->fd <= 0 )
		if( !conn_init( conn ) )
			return( 0 );
	
	if( conn->proto == PROTO_FTP && !conn->proxy )
	{
		if( !ftp_data( conn->ftp ) )	/* Set up data connnection	*/
			return( 0 );
		conn->fd = conn->ftp->data_fd;
		
		if( conn->currentbyte )
		{
			ftp_command( conn->ftp, "REST %lld", conn->currentbyte );
			if( ftp_wait( conn->ftp ) / 100 != 3 &&
			    conn->ftp->status / 100 != 2 )
				return( 0 );
		}
	}
	else
	{
		char s[MAX_STRING];
		int i;

		snprintf( s, MAX_STRING, "%s%s", conn->dir, conn->file );
		conn->http->firstbyte = conn->currentbyte;
		conn->http->lastbyte = conn->lastbyte;
		http_get( conn->http, s );
		http_addheader( conn->http, "User-Agent: %s", conn->conf->user_agent );
		for( i = 0; i < conn->conf->add_header_count; i++)
			http_addheader( conn->http, "%s", conn->conf->add_header[i] );
	}
	return( 1 );
}
Beispiel #7
0
int conn_setup( conn_t *conn )
{
	if( conn->ftp->fd <= 0 && conn->http->fd <= 0 )
		if( !conn_init( conn ) )
			return( 0 );
	
	if( conn->proto == PROTO_FTP && !conn->proxy )
	{
		if( !ftp_data( conn->ftp ) )	/* Set up data connnection	*/
			return( 0 );
		conn->fd = conn->ftp->data_fd;
		
		if( conn->currentbyte )
		{
			ftp_command( conn->ftp, "REST %i", conn->currentbyte );
			if( ftp_wait( conn->ftp ) / 100 != 3 &&
			    conn->ftp->status / 100 != 2 )
				return( 0 );
		}
	}
	else
	{
		char s[MAX_STRING];
		
		snprintf( s, MAX_STRING, "%s%s", conn->dir, conn->file );
		conn->http->firstbyte = conn->currentbyte;
		conn->http->lastbyte = conn->lastbyte;
		http_get( conn->http, s );
	}
	return( 1 );
}
Beispiel #8
0
static void
closeFTPdata(FILE * f)
{
    int status;
    if (f) {
        fclose(f);
        if (f == current_ftp.data)
            current_ftp.data = NULL;
    }
    ftp_command(&current_ftp, NULL, NULL, &status);
    /* status == 226 */
}
Beispiel #9
0
int ftp_connect( ftp_t *conn, char *host, int port, char *user, char *pass )
{
#if WIN32
	conn->data_fd = INVALID_SOCKET;
#else
	conn->data_fd = -1;
#endif
	conn->message = malloc( MAX_STRING );
	
	if( ( conn->fd = tcp_connect( host, port, conn->local_if ) ) == -1 )
	{
		sprintf( conn->message, _("Unable to connect to server %s:%i\n"), host, port );
		return( 0 );
	}
	
	if( ftp_wait( conn ) / 100 != 2 )
		return( 0 );
	
	ftp_command( conn, "USER %s", user );
	if( ftp_wait( conn ) / 100 != 2 )
	{
		if( conn->status / 100 == 3 )
		{
			ftp_command( conn, "PASS %s", pass );
			if( ftp_wait( conn ) / 100 != 2 )
				return( 0 );
		}		
		else
		{
			return( 0 );
		}
	}
	
	/* ASCII mode sucks. Just use Binary.. */
	ftp_command( conn, "TYPE I" );
	if( ftp_wait( conn ) / 100 != 2 )
		return( 0 );
	
	return( 1 );
}
Beispiel #10
0
/* Change current working directory					*/
int ftp_cwd( ftp_t *conn, char *cwd )
{
	/* Necessary at all? */
	if( strncmp( conn->cwd, cwd, MAX_STRING ) == 0 )
		return( 1 );

	ftp_command( conn, "CWD %s", cwd );
	if( ftp_wait( conn ) / 100 != 2 )
		return( 0 );

	strncpy( conn->cwd, cwd, MAX_STRING );

	return( 1 );
}
Beispiel #11
0
static int
ftp_auth(const char *user, const char *pass)
{
	int	code, ret;
	char	hn[HOST_NAME_MAX+1];
	char	addr[LOGIN_NAME_MAX+HOST_NAME_MAX+3];

	code = ftp_command(ctrl_sock, "USER %s\r\n", user ? user : "******");
	if (code != P_OK && code != P_INTER)
		return code;

	if (pass == NULL) {
		if (gethostname(hn, sizeof hn) == -1)
			err(1, "ftp_auth: gethostname");

		ret = snprintf(addr, sizeof addr, "%s@%s",getlogin(), hn);
		if (ret == -1 || ret > sizeof addr)
			errx(1, "addr too long");
	}

	code = ftp_command(ctrl_sock, "PASS %s\r\n", pass ? pass : addr);
	return code;
}
Beispiel #12
0
static int
ftp_quit(FTP ftp)
{
    /*
     * int status;
     * ftp_command(ftp, "QUIT", NULL, &status);
     * ftp_close(ftp);
     * if (status != 221)
     * return -1;
     */
    ftp_command(ftp, "QUIT", NULL, NULL);
    ftp_close(ftp);
    return 0;
}
Beispiel #13
0
int conn_setup(conn_t *conn)
{
#if WIN32
	if (INVALID_SOCKET == conn->ftp->fd && INVALID_SOCKET == conn->http->fd)
#else
	if (conn->ftp->fd <= 0 && conn->http->fd <= 0) 
#endif
	{
		if (!conn_init(conn)) 
		{
			return 0;
		}
	}
	
	if (conn->proto == PROTO_FTP && !conn->proxy)
	{
		/* Set up data connnection	*/
		if(!ftp_data(conn->ftp)) 
		{	
			return 0;
		}
		conn->fd = conn->ftp->data_fd;
		
		if (conn->currentbyte)
		{
			ftp_command(conn->ftp, "REST %lld", conn->currentbyte);
			if (ftp_wait(conn->ftp) / 100 != 3 && conn->ftp->status / 100 != 2) 
			{
				return 0;
			}
		}
	}
	else
	{
		char s[MAX_STRING];
		int i;

		snprintf(s, MAX_STRING, "%s%s", conn->dir, conn->file);
		conn->http->firstbyte = conn->currentbyte;
		conn->http->lastbyte = conn->lastbyte;
		http_get(conn->http, s);
		http_addheader(conn->http, "User-Agent: %s", conn->conf->user_agent);
		for (i = 0; i < conn->conf->add_header_count; i++) 
		{
			http_addheader(conn->http, "%s", conn->conf->add_header[i]);
		}
	}
	return 1;
}
Beispiel #14
0
int conn_exec( conn_t *conn )
{
	if( conn->proto == PROTO_FTP && !conn->proxy )
	{
		if( !ftp_command( conn->ftp, "RETR %s", conn->file ) )
			return( 0 );
		return( ftp_wait( conn->ftp ) / 100 == 1 );
	}
	else
	{
		if( !http_exec( conn->http ) )
			return( 0 );
		return( conn->http->status / 100 == 2 );
	}
}
Beispiel #15
0
/* Change current working directory					*/
int ftp_cwd( ftp_t *conn, char *cwd )
{
	/* Necessary at all? */
	if( strncmp( conn->cwd, cwd, MAX_STRING ) == 0 )
		return( 1 );
	
	ftp_command( conn, "CWD %s", cwd );
	if( ftp_wait( conn ) / 100 != 2 )
	{
		fprintf( stderr, _("Can't change directory to %s\n"), cwd );
		return( 0 );
	}
	
	strncpy( conn->cwd, cwd, MAX_STRING );
	
	return( 1 );
}
Beispiel #16
0
/* Open a data connection. Only Passive mode supported yet, easier..	*/
int ftp_data( ftp_t *conn )
{
	int i, info[6];
	char host[MAX_STRING];
	
	/* Already done?						*/
	if( conn->data_fd > 0 )
		return( 0 );
	
/*	if( conn->ftp_mode == FTP_PASSIVE )
	{
*/		ftp_command( conn, "PASV" );
		if( ftp_wait( conn ) / 100 != 2 )
			return( 0 );
		*host = 0;
		for( i = 0; conn->message[i]; i ++ )
		{
			if( sscanf( &conn->message[i], "%i,%i,%i,%i,%i,%i",
			            &info[0], &info[1], &info[2], &info[3],
			            &info[4], &info[5] ) == 6 )
			{
				sprintf( host, "%i.%i.%i.%i",
				         info[0], info[1], info[2], info[3] );
				break;
			}
		}
		if( !*host )
		{
			sprintf( conn->message, _("Error opening passive data connection.\n") );
			return( 0 );
		}
		if( ( conn->data_fd = tcp_connect( host,
			info[4] * 256 + info[5], conn->local_if ) ) == -1 )
		{
			sprintf( conn->message, _("Error opening passive data connection.\n") );
			return( 0 );
		}
		
		return( 1 );
/*	}
	else
	{
		sprintf( conn->message, _("Active FTP not implemented yet.\n" ) );
		return( 0 );
	} */
}
Beispiel #17
0
/* Get file size. Should work with all reasonable servers now		*/
long long int ftp_size( ftp_t *conn, char *file, int maxredir )
{
	long long int i, j, size = MAX_STRING;
	char *reply, *s, fn[MAX_STRING];
	
	/* Try the SIZE command first, if possible			*/
	if( !strchr( file, '*' ) && !strchr( file, '?' ) )
	{
		ftp_command( conn, "SIZE %s", file );
		if( ftp_wait( conn ) / 100 == 2 )
		{
			sscanf( conn->message, "%*i %lld", &i );
			return( i );
		}
		else if( conn->status / 10 != 50 )
		{
			sprintf( conn->message, _("File not found.\n") );
			return( -1 );
		}
	}
	
	if( maxredir == 0 )
	{
		sprintf( conn->message, _("Too many redirects.\n") );
		return( -1 );
	}
	
	if( !ftp_data( conn ) )
		return( -1 );
	
	ftp_command( conn, "LIST %s", file );
	if( ftp_wait( conn ) / 100 != 1 )
		return( -1 );
	
	/* Read reply from the server.					*/
	reply = malloc( size );
	memset( reply, 0, size );
	*reply = '\n';
	i = 1;
	while( ( j = read( conn->data_fd, reply + i, size - i - 3 ) ) > 0 )
	{
		i += j;
		reply[i] = 0;
		if( size - i <= 10 )
		{
			size *= 2;
			reply = realloc( reply, size );
			memset( reply + size / 2, 0, size / 2 );
		}
	}
	close( conn->data_fd );
	conn->data_fd = -1;
	
	if( ftp_wait( conn ) / 100 != 2 )
	{
		free( reply );
		return( -1 );
	}
	
#ifdef DEBUG
    fprintf(stderr, "%s", reply);
#endif
	
	/* Count the number of probably legal matches: Files&Links only	*/
	j = 0;
	for( i = 1; reply[i] && reply[i+1]; i ++ )
		if( reply[i] == '-' || reply[i] == 'l' )
			j ++;
		else
			while( reply[i] != '\n' && reply[i] )
				i ++;
	
	/* No match or more than one match				*/
	if( j != 1 )
	{
		if( j == 0 )
			sprintf( conn->message, _("File not found.\n") );
		else
			sprintf( conn->message, _("Multiple matches for this URL.\n") );
		free( reply );
		return( -1 );
	}

	/* Symlink handling						*/
	if( ( s = strstr( reply, "\nl" ) ) != NULL )
	{
		/* Get the real filename */
		sscanf( s, "%*s %*i %*s %*s %*i %*s %*i %*s %100s", fn );
		strcpy( file, fn );
		
		/* Get size of the file linked to			*/
		strncpy( fn, strstr( s, "->" ) + 3, MAX_STRING );
		free( reply );
		if( ( reply = strchr( fn, '\r' ) ) != NULL )
			*reply = 0;
		if( ( reply = strchr( fn, '\n' ) ) != NULL )
			*reply = 0;
		return( ftp_size( conn, fn, maxredir - 1 ) );
	}
	/* Normal file, so read the size! And read filename because of
	   possible wildcards.						*/
	else
	{
		s = strstr( reply, "\n-" );
		i = sscanf( s, "%*s %*i %*s %*s %lld %*s %*i %*s %100s", &size, fn );
		if( i < 2 )
		{
			i = sscanf( s, "%*s %*i %lld %*i %*s %*i %*i %100s", &size, fn );
			if( i < 2 )
			{
				return( -2 );
			}
		}
		strcpy( file, fn );
		
		free( reply );
		return( size );
	}
}
Beispiel #18
0
/* Get file size and other information					*/
int conn_info( conn_t *conn )
{
	/* It's all a bit messed up.. But it works.			*/
	if( conn->proto == PROTO_FTP && !conn->proxy )
	{
		ftp_command( conn->ftp, "REST %lld", 1 );
		if( ftp_wait( conn->ftp ) / 100 == 3 ||
		    conn->ftp->status / 100 == 2 )
		{
			conn->supported = 1;
			ftp_command( conn->ftp, "REST %lld", 0 );
			ftp_wait( conn->ftp );
		}
		else
		{
			conn->supported = 0;
		}
		
		if( !ftp_cwd( conn->ftp, conn->dir ) )
			return( 0 );
		conn->size = ftp_size( conn->ftp, conn->file, MAX_REDIR );
		if( conn->size < 0 )
			conn->supported = 0;
		if( conn->size == -1 )
			return( 0 );
		else if( conn->size == -2 )
			conn->size = INT_MAX;
	}
	else
	{
		char s[MAX_STRING], *t;
		long long int i = 0;
		
		do
		{
			conn->currentbyte = 1;
			if( !conn_setup( conn ) )
				return( 0 );
			conn_exec( conn );
			conn_disconnect( conn );
			/* Code 3xx == redirect				*/
			if( conn->http->status / 100 != 3 )
				break;
			if( ( t = http_header( conn->http, "location:" ) ) == NULL )
				return( 0 );
			sscanf( t, "%1023s", s );  // Warning: truncating to MAX_STRING
			if( strstr( s, "://" ) == NULL)
			{
				sprintf( conn->http->headers, "%s%s",
					conn_url( conn ), s );
				strncpy( s, conn->http->headers, MAX_STRING );
			}
			else if( s[0] == '/' )
			{
				sprintf( conn->http->headers, "http://%s:%i%s",
					conn->host, conn->port, s );
				strncpy( s, conn->http->headers, MAX_STRING );
			}
			conn_set( conn, s );
			i ++;
		}
		while( conn->http->status / 100 == 3 && i < MAX_REDIR );
		
		if( i == MAX_REDIR )
		{
			sprintf( conn->message, _("Too many redirects.\n") );
			return( 0 );
		}
		
		conn->size = http_size( conn->http );
		if( conn->http->status == 206 && conn->size >= 0 )
		{
			conn->supported = 1;
			conn->size ++;
		}
		else if( conn->http->status == 200 || conn->http->status == 206 )
		{
			conn->supported = 0;
			conn->size = INT_MAX;
		}
		else
		{
			t = strchr( conn->message, '\n' );
			if( t == NULL )
				sprintf( conn->message, _("Unknown HTTP error.\n") );
			else
				*t = 0;
			return( 0 );
		}
	}
	
	return( 1 );
}
Beispiel #19
0
int ftp_open_connection(const char * host, const char * name, const char * password, const char * proxy)
{
	int sock;
	struct in_addr serverAddress;
	union {
		struct sockaddr_in in;
		struct sockaddr sa;
	} destPort;
	int rc;
	int port = 21;
	std::string proxyname;

	if (!strcmp(name, "")) {
		name = "anonymous";
		password = "******";
	}

	if (strcmp(proxy, "")) {
		proxyname.append(name).append("@").append(host);
		name = proxyname.c_str();
		host = proxy;
	}

	if ((rc = get_host_address(host, &serverAddress))) return rc;

	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
	if (sock < 0) {
		return FTPERR_FAILED_CONNECT;
	}

	destPort.in.sin_family = AF_INET;
	destPort.in.sin_port = htons(port);
	destPort.in.sin_addr = serverAddress;

	if (connect(sock, &destPort.sa, sizeof(destPort.in))) {
		close(sock);
		return FTPERR_FAILED_CONNECT;
	}

	/* ftpCheckResponse() assumes the socket is nonblocking */
	if (fcntl(sock, F_SETFL, O_NONBLOCK)) {
		close(sock);
		return FTPERR_FAILED_CONNECT;
	}

	if ((rc = ftp_check_response(sock, NULL))) {
		return rc;     
	}

	if ((rc = ftp_command(sock, "USER", name))) {
		close(sock);
		return rc;
	}

	if ((rc = ftp_command(sock, "PASS", password))) {
		close(sock);
		return rc;
	}

	if ((rc = ftp_command(sock, "TYPE", "I"))) {
		close(sock);
		return rc;
	}

	return sock;
}
Beispiel #20
0
InputStream
openFTPStream(ParsedURL *pu, URLFile *uf)
{
    Str tmp;
    int status;
    char *user = NULL;
    char *pass = NULL;
    Str uname = NULL;
    Str pwd = NULL;
    int add_auth_cookie_flag = FALSE;
    char *realpathname = NULL;

    if (!pu->host)
        return NULL;

    if (pu->user == NULL && pu->pass == NULL) {
        if (find_auth_user_passwd(pu, NULL, &uname, &pwd, 0)) {
            if (uname)
                user = uname->ptr;
            if (pwd)
                pass = pwd->ptr;
        }
    }
    if (user)
        /* do nothing */ ;
    else if (pu->user)
        user = pu->user;
    else
        user = "******";

    if (current_ftp.host) {
        if (!strcmp(current_ftp.host, pu->host) &&
                current_ftp.port == pu->port && !strcmp(current_ftp.user, user)) {
            ftp_command(&current_ftp, "NOOP", NULL, &status);
            if (status != 200)
                ftp_close(&current_ftp);
            else
                goto ftp_read;
        }
        else
            ftp_quit(&current_ftp);
    }

    if (pass)
        /* do nothing */ ;
    else if (pu->pass)
        pass = pu->pass;
    else if (pu->user) {
        pwd = NULL;
        find_auth_user_passwd(pu, NULL, &uname, &pwd, 0);
        if (pwd == NULL) {
            if (fmInitialized) {
                term_raw();
                pwd = Strnew_charp(inputLine("Password: "******"Password: "******"Password: "******"anonymous");
#else
        tmp = Strnew_charp("anonymous");
#endif /* __MINGW32_VERSION */
        Strcat_char(tmp, '@');
        pass = tmp->ptr;
    }

    if (!current_ftp.host) {
        current_ftp.host = allocStr(pu->host, -1);
        current_ftp.port = pu->port;
        current_ftp.user = allocStr(user, -1);
        current_ftp.pass = allocStr(pass, -1);
        if (!ftp_login(&current_ftp))
            return NULL;
    }
    if (add_auth_cookie_flag)
        add_auth_user_passwd(pu, NULL, uname, pwd, 0);

ftp_read:
    ftp_command(&current_ftp, "TYPE", "I", &status);
    if (ftp_pasv(&current_ftp) < 0) {
        ftp_quit(&current_ftp);
        return NULL;
    }
    if (pu->file == NULL || *pu->file == '\0' ||
            pu->file[strlen(pu->file) - 1] == '/')
        goto ftp_dir;

    realpathname = file_unquote(pu->file);
    if (*realpathname == '/' && *(realpathname + 1) == '~')
        realpathname++;
    /* Get file */
    uf->modtime = ftp_modtime(&current_ftp, realpathname);
    ftp_command(&current_ftp, "RETR", realpathname, &status);
    if (status == 125 || status == 150)
        return newFileStream(current_ftp.data, (void (*)())closeFTPdata);

ftp_dir:
    pu->scheme = SCM_FTPDIR;
    return NULL;
}
Beispiel #21
0
static int
ftp_pasv(FTP ftp)
{
    int status;
    int n1, n2, n3, n4, p1, p2;
    int data;
    char *p;
    Str tmp;
    int family;
#ifdef INET6
    struct sockaddr_storage sockaddr;
    int port;
    socklen_t sockaddrlen;
    unsigned char d1, d2, d3, d4;
    char abuf[INET6_ADDRSTRLEN];
#endif

#ifdef INET6
    sockaddrlen = sizeof(sockaddr);
    if (getpeername(fileno(ftp->wf),
                    (struct sockaddr *)&sockaddr, &sockaddrlen) < 0)
        return -1;
#ifdef HAVE_OLD_SS_FAMILY
    family = sockaddr.__ss_family;
#else
    family = sockaddr.ss_family;
#endif
#else
    family = AF_INET;
#endif
    switch (family) {
#ifdef INET6
    case AF_INET6:
        tmp = ftp_command(ftp, "EPSV", NULL, &status);
        if (status != 229)
            return -1;
        for (p = tmp->ptr + 4; *p && *p != '('; p++) ;
        if (*p == '\0')
            return -1;
        if (sscanf(++p, "%c%c%c%d%c", &d1, &d2, &d3, &port, &d4) != 5
                || d1 != d2 || d1 != d3 || d1 != d4)
            return -1;
        if (getnameinfo((struct sockaddr *)&sockaddr, sockaddrlen,
                        abuf, sizeof(abuf), NULL, 0, NI_NUMERICHOST) != 0)
            return -1;
        data = openSocket(abuf, "", port);
        break;
#endif
    case AF_INET:
        tmp = ftp_command(ftp, "PASV", NULL, &status);
        if (status != 227)
            return -1;
        for (p = tmp->ptr + 4; *p && !IS_DIGIT(*p); p++) ;
        if (*p == '\0')
            return -1;
        sscanf(p, "%d,%d,%d,%d,%d,%d", &n1, &n2, &n3, &n4, &p1, &p2);
        tmp = Sprintf("%d.%d.%d.%d", n1, n2, n3, n4);
        data = openSocket(tmp->ptr, "", p1 * 256 + p2);
        break;
    default:
        return -1;
    }
    if (data < 0)
        return -1;
    ftp->data = fdopen(data, "rb");
    return 0;
}
Beispiel #22
0
static int
ftp_login(FTP ftp)
{
    int sock, status;

    sock = openSocket(ftp->host, "ftp", 21);
    if (sock < 0)
        goto open_err;
    if (ftppass_hostnamegen && !strcmp(ftp->user, "anonymous")) {
        size_t n = strlen(ftp->pass);

        if (n > 0 && ftp->pass[n - 1] == '@') {
#ifdef INET6
            struct sockaddr_storage sockname;
#else
            struct sockaddr_in sockname;
#endif
            socklen_t socknamelen = sizeof(sockname);

            if (!getsockname(sock, (struct sockaddr *)&sockname, &socknamelen)) {
                struct hostent *sockent;
                Str tmp = Strnew_charp(ftp->pass);
#ifdef INET6
                char hostbuf[NI_MAXHOST];

                if (getnameinfo((struct sockaddr *)&sockname, socknamelen,
                                hostbuf, sizeof hostbuf, NULL, 0, NI_NAMEREQD)
                        == 0)
                    Strcat_charp(tmp, hostbuf);
                else if (getnameinfo((struct sockaddr *)&sockname, socknamelen,
                                     hostbuf, sizeof hostbuf, NULL, 0, NI_NUMERICHOST)
                         == 0)
                    Strcat_m_charp(tmp, "[", hostbuf, "]", NULL);
                else
                    Strcat_charp(tmp, "unknown");
#else

                if ((sockent = gethostbyaddr((char *)&sockname.sin_addr,
                                             sizeof(sockname.sin_addr),
                                             sockname.sin_family)))
                    Strcat_charp(tmp, sockent->h_name);
                else
                    Strcat_m_charp(tmp, "[", inet_ntoa(sockname.sin_addr),
                                   "]", NULL);
#endif
                ftp->pass = tmp->ptr;
            }
        }
    }
    ftp->rf = newInputStream(sock);
    ftp->wf = fdopen(dup(sock), "wb");
    if (!ftp->rf || !ftp->wf)
        goto open_err;
    IStype(ftp->rf) |= IST_UNCLOSE;
    ftp_command(ftp, NULL, NULL, &status);
    if (status != 220)
        goto open_err;
    if (fmInitialized) {
        message(Sprintf("Sending FTP username (%s) to remote server.",
                        ftp->user)->ptr, 0, 0);
        refresh();
    }
    ftp_command(ftp, "USER", ftp->user, &status);
    /*
     * Some ftp daemons(e.g. publicfile) return code 230 for user command.
     */
    if (status == 230)
        goto succeed;
    if (status != 331)
        goto open_err;
    if (fmInitialized) {
        message("Sending FTP password to remote server.", 0, 0);
        refresh();
    }
    ftp_command(ftp, "PASS", ftp->pass, &status);
    if (status != 230)
        goto open_err;
succeed:
    return TRUE;
open_err:
    ftp_close(ftp);
    return FALSE;
}
Beispiel #23
0
int ftp_get_filesize(int sock, const char * remotename)
{
	int size = 0;
	char buf[2000];
	char file[500];
	char * ptr;
	int fd, rc, tot;
	int i;

	strcpy(buf, remotename);
	ptr = strrchr(buf, '/');
	if (!*ptr)
		return -1;
	*ptr = '\0';

	strcpy(file, ptr+1);

	if ((rc = ftp_command(sock, "CWD", buf))) {
		return -1;
	}

	fd = ftp_data_command(sock, "LIST", file);
	if (fd <= 0) {
		close(sock);
		return -1;
	}

	ptr = buf;
	while ((tot = read(fd, ptr, sizeof(buf) - (ptr - buf) - 1)) != 0)
		ptr += tot;
	*ptr = '\0';
	close(fd);

	if (!(ptr = strstr(buf, file))) {
		log_message("FTP/get_filesize: Bad mood, directory does not contain searched file (%s)", file);
		if (ftp_end_data_command(sock))
			close(sock);
		return -1;
	}

	for (i=0; i<4; i++) {
		while (*ptr && *ptr != ' ')
			ptr--;
		while (*ptr && *ptr == ' ')
			ptr--;
	}
	while (*ptr && *ptr != ' ')
		ptr--;

	if (ptr)
		size = charstar_to_int(ptr+1);
	else
		size = 0;

	if (ftp_end_data_command(sock)) {
		close(sock);
		return -1;
	}

	return size;
}
Beispiel #24
0
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);
}
Beispiel #25
0
Str
loadFTPDir0(ParsedURL *pu)
#endif
{
    Str FTPDIRtmp;
    Str tmp;
    int status;
    volatile int sv_type;
    char *realpathname, *fn, *q;
    char **flist;
    int i, nfile, nfile_max;
    MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL;
#ifdef USE_M17N
    wc_ces doc_charset = DocumentCharset;

    *charset = WC_CES_US_ASCII;
#endif
    if (current_ftp.data == NULL)
        return NULL;
    tmp = ftp_command(&current_ftp, "SYST", NULL, &status);
    if (strstr(tmp->ptr, "UNIX") != NULL || !strncmp(tmp->ptr + 4, "Windows_NT", 10))	/* :-) */
        sv_type = UNIXLIKE_SERVER;
    else
        sv_type = SERVER_NONE;
    if (pu->file == NULL || *pu->file == '\0') {
        if (sv_type == UNIXLIKE_SERVER)
            ftp_command(&current_ftp, "LIST", NULL, &status);
        else
            ftp_command(&current_ftp, "NLST", NULL, &status);
        pu->file = "/";
    }
    else {
        realpathname = file_unquote(pu->file);
        if (*realpathname == '/' && *(realpathname + 1) == '~')
            realpathname++;
        if (sv_type == UNIXLIKE_SERVER) {
            ftp_command(&current_ftp, "CWD", realpathname, &status);
            if (status == 250)
                ftp_command(&current_ftp, "LIST", NULL, &status);
        }
        else
            ftp_command(&current_ftp, "NLST", realpathname, &status);
    }
    if (status != 125 && status != 150) {
        fclose(current_ftp.data);
        current_ftp.data = NULL;
        return NULL;
    }
    tmp = parsedURL2Str(pu);
    if (Strlastchar(tmp) != '/')
        Strcat_char(tmp, '/');
    fn = html_quote(tmp->ptr);
    tmp =
        convertLine(NULL, Strnew_charp(file_unquote(tmp->ptr)), RAW_MODE,
                    charset, doc_charset);
    q = html_quote(tmp->ptr);
    FTPDIRtmp = Strnew_m_charp("<html>\n<head>\n<base href=\"", fn,
                               "\">\n<title>", q,
                               "</title>\n</head>\n<body>\n<h1>Index of ", q,
                               "</h1>\n", NULL);

    if (SETJMP(AbortLoading) != 0) {
        if (sv_type == UNIXLIKE_SERVER)
            Strcat_charp(FTPDIRtmp, "</a></pre>\n");
        else
            Strcat_charp(FTPDIRtmp, "</a></ul>\n");
        Strcat_charp(FTPDIRtmp, "<p>Transfer Interrupted!\n");
        goto ftp_end;
    }
    TRAP_ON;

    if (sv_type == UNIXLIKE_SERVER)
        Strcat_charp(FTPDIRtmp, "<pre>\n");
    else
        Strcat_charp(FTPDIRtmp, "<ul>\n<li>");
    Strcat_charp(FTPDIRtmp, "<a href=\"..\">[Upper Directory]</a>\n");

    nfile_max = 100;
    flist = New_N(char *, nfile_max);
    nfile = 0;
    if (sv_type == UNIXLIKE_SERVER) {
        char *name, *link, *date, *size, *type_str;
        int ftype, max_len, len, j;

        max_len = 20;
        while (tmp = Strfgets(current_ftp.data), tmp->length > 0) {
            Strchop(tmp);
            if ((ftype =
                        ex_ftpdir_name_size_date(tmp->ptr, &name, &link, &date,
                                                 &size)) == FTPDIR_NONE)
                continue;
            if (!strcmp(".", name) || !strcmp("..", name))
                continue;
            len = strlen(name);
            if (!len)
                continue;
            if (ftype == FTPDIR_DIR) {
                len++;
                type_str = "/";
            }
            else if (ftype == FTPDIR_LINK) {
                len++;
                type_str = "@";
            }
            else {
                type_str = " ";
            }
            if (max_len < len)
                max_len = len;
            flist[nfile++] = Sprintf("%s%s\n%s  %5s%s", name, type_str, date,
                                     size, link)->ptr;
            if (nfile == nfile_max) {
                nfile_max *= 2;
                flist = New_Reuse(char *, flist, nfile_max);
            }
        }
Beispiel #26
0
/*------------------------------------------------------------------*/
INT mftp_open(char *destination, FTP_CON ** con)
{
   INT status;
   short port = 0;
   char *token, host_name[HOST_NAME_LENGTH],
       user[256], pass[256], directory[256], file_name[256], file_mode[256];

   /* 
      destination should have the form:
      host, port, user, password, directory, run%05d.mid, file_mode, command, ...
    */

   /* break destination in components */
   token = strtok(destination, ",");
   if (token)
      strcpy(host_name, token);

   token = strtok(NULL, ",");
   if (token)
      port = atoi(token);

   token = strtok(NULL, ",");
   if (token)
      strcpy(user, token);

   token = strtok(NULL, ",");
   if (token)
      strcpy(pass, token);

   token = strtok(NULL, ",");
   if (token)
      strcpy(directory, token);

   token = strtok(NULL, ",");
   if (token)
      strcpy(file_name, token);

   token = strtok(NULL, ",");
   file_mode[0] = 0;
   if (token)
      strcpy(file_mode, token);

   status = ftp_login(con, host_name, port, user, pass, "");
   if (status >= 0)
      return status;

   status = ftp_chdir(*con, directory);
   if (status >= 0) {
      /* directory does not exist -> create it */
      ftp_mkdir(*con, directory);
      status = ftp_chdir(*con, directory);
   }
   if (status >= 0)
      return status;
   status = ftp_binary(*con);
   if (status >= 0)
      return status;

   if (file_mode[0]) {
      status = ftp_command(*con, "umask %s", file_mode, 200, 250, EOF);
      if (status >= 0)
         return status;
   }

   while (token) {
      token = strtok(NULL, ",");
      if (token) {
         status = ftp_command(*con, token, NULL, 200, 250, EOF);
         if (status >= 0)
            return status;
      }
   }

   if (ftp_open_write(*con, file_name) >= 0)
      return (*con)->err_no;

   return SS_SUCCESS;
}