⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftp.c

📁 vlc源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * ftp.c: FTP input module ***************************************************************************** * Copyright (C) 2001-2006 the VideoLAN team * Copyright © 2006 Rémi Denis-Courmont * $Id$ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> - original code *          Rémi Denis-Courmont <rem # videolan.org> - EPSV support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_plugin.h>#include <assert.h>#include <vlc_access.h>#include <vlc_interface.h>#include <vlc_network.h>#include "vlc_url.h"#include <vlc_sout.h>#ifndef IPPORT_FTP# define IPPORT_FTP 21u#endif/***************************************************************************** * Module descriptor *****************************************************************************/static int   InOpen ( vlc_object_t * );static void  InClose( vlc_object_t * );static int  OutOpen ( vlc_object_t * );static void OutClose( vlc_object_t * );#define CACHING_TEXT N_("Caching value in ms")#define CACHING_LONGTEXT N_( \    "Caching value for FTP streams. This " \    "value should be set in milliseconds." )#define USER_TEXT N_("FTP user name")#define USER_LONGTEXT N_("User name that will " \    "be used for the connection.")#define PASS_TEXT N_("FTP password")#define PASS_LONGTEXT N_("Password that will be " \    "used for the connection.")#define ACCOUNT_TEXT N_("FTP account")#define ACCOUNT_LONGTEXT N_("Account that will be " \    "used for the connection.")vlc_module_begin();    set_shortname( "FTP" );    set_description( N_("FTP input") );    set_capability( "access", 0 );    set_category( CAT_INPUT );    set_subcategory( SUBCAT_INPUT_ACCESS );    add_integer( "ftp-caching", 2 * DEFAULT_PTS_DELAY / 1000, NULL,                 CACHING_TEXT, CACHING_LONGTEXT, true );    add_string( "ftp-user", "anonymous", NULL, USER_TEXT, USER_LONGTEXT,                false );    add_string( "ftp-pwd", "anonymous@example.com", NULL, PASS_TEXT,                PASS_LONGTEXT, false );    add_string( "ftp-account", "anonymous", NULL, ACCOUNT_TEXT,                ACCOUNT_LONGTEXT, false );    add_shortcut( "ftp" );    set_callbacks( InOpen, InClose );    add_submodule();    set_shortname( "FTP" );    set_description( N_("FTP upload output") );    set_capability( "sout access", 0 );    set_category( CAT_SOUT );    set_subcategory( SUBCAT_SOUT_ACO );    set_callbacks( OutOpen, OutClose );vlc_module_end();/***************************************************************************** * Local prototypes *****************************************************************************/static ssize_t Read( access_t *, uint8_t *, size_t );static ssize_t Write( sout_access_out_t *, block_t * );static int Seek( access_t *, int64_t );static int OutSeek( sout_access_out_t *, off_t );static int Control( access_t *, int, va_list );struct access_sys_t{    vlc_url_t  url;    int        fd_cmd;    int        fd_data;    char       sz_epsv_ip[NI_MAXNUMERICHOST];    bool       out;};#define GET_OUT_SYS( p_this ) \    ((access_sys_t *)(((sout_access_out_t *)(p_this))->p_sys))static int ftp_SendCommand( vlc_object_t *, access_sys_t *, const char *, ... );static int ftp_ReadCommand( vlc_object_t *, access_sys_t *, int *, char ** );static int ftp_StartStream( vlc_object_t *, access_sys_t *, int64_t );static int ftp_StopStream ( vlc_object_t *, access_sys_t * );static int Login( vlc_object_t *p_access, access_sys_t *p_sys ){    int i_answer;    char *psz;    /* *** Open a TCP connection with server *** */    int fd = p_sys->fd_cmd = net_ConnectTCP( p_access, p_sys->url.psz_host,                                             p_sys->url.i_port );    if( fd == -1 )    {        msg_Err( p_access, "connection failed" );        intf_UserFatal( p_access, false, _("Network interaction failed"),                        _("VLC could not connect with the given server.") );        return -1;    }    while( ftp_ReadCommand( p_access, p_sys, &i_answer, NULL ) == 1 );    if( i_answer / 100 != 2 )    {        msg_Err( p_access, "connection rejected" );        intf_UserFatal( p_access, false, _("Network interaction failed"),                        _("VLC's connection to the given server was rejected.") );        return -1;    }    msg_Dbg( p_access, "connection accepted (%d)", i_answer );    if( p_sys->url.psz_username && *p_sys->url.psz_username )        psz = strdup( p_sys->url.psz_username );    else        psz = var_CreateGetString( p_access, "ftp-user" );    if( !psz )        return -1;    if( ftp_SendCommand( p_access, p_sys, "USER %s", psz ) < 0 ||        ftp_ReadCommand( p_access, p_sys, &i_answer, NULL ) < 0 )    {        free( psz );        return -1;    }    free( psz );    switch( i_answer / 100 )    {        case 2:            msg_Dbg( p_access, "user accepted" );            break;        case 3:            msg_Dbg( p_access, "password needed" );            if( p_sys->url.psz_password && *p_sys->url.psz_password )                psz = strdup( p_sys->url.psz_password );            else                psz = var_CreateGetString( p_access, "ftp-pwd" );            if( !psz )                return -1;            if( ftp_SendCommand( p_access, p_sys, "PASS %s", psz ) < 0 ||                ftp_ReadCommand( p_access, p_sys, &i_answer, NULL ) < 0 )            {                free( psz );                return -1;            }            free( psz );            switch( i_answer / 100 )            {                case 2:                    msg_Dbg( p_access, "password accepted" );                    break;                case 3:                    msg_Dbg( p_access, "account needed" );                    psz = var_CreateGetString( p_access, "ftp-account" );                    if( ftp_SendCommand( p_access, p_sys, "ACCT %s",                                         psz ) < 0 ||                        ftp_ReadCommand( p_access, p_sys, &i_answer, NULL ) < 0 )                    {                        free( psz );                        return -1;                    }                    free( psz );                    if( i_answer / 100 != 2 )                    {                        msg_Err( p_access, "account rejected" );                        intf_UserFatal( p_access, false,                                        _("Network interaction failed"),                                        _("Your account was rejected.") );                        return -1;                    }                    msg_Dbg( p_access, "account accepted" );                    break;                default:                    msg_Err( p_access, "password rejected" );                    intf_UserFatal( p_access, false,                                    _("Network interaction failed"),                                    _("Your password was rejected.") );                    return -1;            }            break;        default:            msg_Err( p_access, "user rejected" );            intf_UserFatal( p_access, false,                        _("Network interaction failed"),                        _("Your connection attempt to the server was rejected.") );            return -1;    }    return 0;}static int Connect( vlc_object_t *p_access, access_sys_t *p_sys ){    if( Login( p_access, p_sys ) < 0 )        return -1;    /* Extended passive mode */    if( ftp_SendCommand( p_access, p_sys, "EPSV ALL" ) < 0 )    {        msg_Err( p_access, "cannot request extended passive mode" );        net_Close( p_sys->fd_cmd );        return -1;    }    if( ftp_ReadCommand( p_access, p_sys, NULL, NULL ) == 2 )    {        if( net_GetPeerAddress( p_sys->fd_cmd, p_sys->sz_epsv_ip, NULL ) )        {            net_Close( p_sys->fd_cmd );            return -1;        }    }    else    {        /* If ESPV ALL fails, we fallback to PASV.         * We have to restart the connection in case there is a NAT that         * understands EPSV ALL in the way, and hence won't allow PASV on         * the initial connection.         */        msg_Info( p_access, "FTP Extended passive mode disabled" );        net_Close( p_sys->fd_cmd );        if( Login( p_access, p_sys ) )        {            net_Close( p_sys->fd_cmd );            return -1;        }    }    /* check binary mode support */    if( ftp_SendCommand( p_access, p_sys, "TYPE I" ) < 0 ||        ftp_ReadCommand( p_access, p_sys, NULL, NULL ) != 2 )    {        msg_Err( p_access, "cannot set binary transfer mode" );        net_Close( p_sys->fd_cmd );        return -1;    }    return 0;}static int parseURL( vlc_url_t *url, const char *path ){    if( path == NULL )        return VLC_EGENERIC;    /* *** Parse URL and get server addr/port and path *** */    while( *path == '/' )        path++;    vlc_UrlParse( url, path, 0 );    if( url->psz_host == NULL || *url->psz_host == '\0' )        return VLC_EGENERIC;    if( url->i_port <= 0 )        url->i_port = IPPORT_FTP; /* default port */    /* FTP URLs are relative to user's default directory (RFC1738)    For absolute path use ftp://foo.bar//usr/local/etc/filename */    if( url->psz_path && *url->psz_path == '/' )        url->psz_path++;    return VLC_SUCCESS;}/**************************************************************************** * Open: connect to ftp server and ask for file ****************************************************************************/static int InOpen( vlc_object_t *p_this ){    access_t     *p_access = (access_t*)p_this;    access_sys_t *p_sys;    char         *psz_arg;    /* Init p_access */    STANDARD_READ_ACCESS_INIT    p_sys->fd_data = -1;    p_sys->out = false;    if( parseURL( &p_sys->url, p_access->psz_path ) )        goto exit_error;    if( Connect( p_this, p_sys ) )        goto exit_error;    /* get size */    if( ftp_SendCommand( p_this, p_sys, "SIZE %s", p_sys->url.psz_path ? : "" ) < 0 ||        ftp_ReadCommand( p_this, p_sys, NULL, &psz_arg ) != 2 )    {        msg_Err( p_access, "cannot get file size" );        net_Close( p_sys->fd_cmd );        goto exit_error;    }    p_access->info.i_size = atoll( &psz_arg[4] );    free( psz_arg );    msg_Dbg( p_access, "file size: %"PRId64, p_access->info.i_size );    /* Start the 'stream' */    if( ftp_StartStream( p_this, p_sys, 0 ) < 0 )    {        msg_Err( p_access, "cannot retrieve file" );        net_Close( p_sys->fd_cmd );        goto exit_error;    }    /* Update default_pts to a suitable value for ftp access */    var_Create( p_access, "ftp-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );    return VLC_SUCCESS;exit_error:    vlc_UrlClean( &p_sys->url );    free( p_sys );    return VLC_EGENERIC;}static int OutOpen( vlc_object_t *p_this ){    sout_access_out_t *p_access = (sout_access_out_t *)p_this;    access_sys_t      *p_sys;    p_sys = malloc( sizeof( *p_sys ) );    if( p_sys == NULL )        return VLC_ENOMEM;    memset( p_sys, 0, sizeof( *p_sys ) );    /* Init p_access */    p_sys->fd_data = -1;    p_sys->out = true;    if( parseURL( &p_sys->url, p_access->psz_path ) )        goto exit_error;    if( Connect( p_this, p_sys ) )        goto exit_error;    /* Start the 'stream' */    if( ftp_StartStream( p_this, p_sys, 0 ) < 0 )    {        msg_Err( p_access, "cannot store file" );        net_Close( p_sys->fd_cmd );        goto exit_error;    }    p_access->pf_seek = OutSeek;    p_access->pf_write = Write;    p_access->p_sys = (void *)p_sys;    return VLC_SUCCESS;exit_error:    vlc_UrlClean( &p_sys->url );    free( p_sys );    return VLC_EGENERIC;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -