Back to index

avfs  1.0.1
Classes | Defines | Functions
ftp.c File Reference
#include "remote.h"
#include "socket.h"
#include "state.h"
#include "filebuf.h"
#include "parsels.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

Go to the source code of this file.

Classes

struct  ftpconn
struct  ftpsession
struct  ftpdata
struct  ftplocalfile

Defines

#define USER_SEP_STR   "@"
#define USER_SEP_CHAR   (USER_SEP_STR[0])
#define FTP_REPLY_TIMEOUT   30000
#define FTP_READ_TIMEOUT   60000
#define READBUF   4096

Functions

static AV_LOCK_DECL (ftp_lock)
static struct ftpsessionftp_find_session (struct ftpdata *ftd, const char *account)
static struct ftpsessionftp_get_session (struct ftpdata *ftd, const char *account)
static void ftp_remove_session (struct ftpsession *fts)
static void strip_crlf (char *line)
static void ftp_release_conn (struct ftpconn *conn)
static void ftp_close_conn (struct ftpconn *conn)
static int ftp_get_line (struct ftpconn *conn, char **linep)
static int ftp_check_reply (struct ftpconn *conn, const char *line)
static int ftp_wait_reply_code (struct ftpconn *conn)
static int write_socket (int sock, const char *buf, avsize_t buflen)
static int ftp_write_command (struct ftpconn *conn, const char *cmd)
static int ftp_command (struct ftpconn *conn, const char *cmd)
static int ftp_get_addrbytes (const char *line, int addrbytes[6])
static int ftp_check_passv_reply (struct ftpconn *conn, const char *line, char **resp)
static int ftp_open_dataconn (struct ftpconn *conn)
static int ftp_login (struct ftpconn *conn)
static int ftp_init_conn (struct ftpconn *conn)
static int ftp_open_conn (struct ftpconn *conn)
static void ftp_free_dirlist (struct remdirlist *dl)
static int ftp_read_list (struct filebuf *fb, struct remdirlist *dl, struct lscache *lc)
static int ftp_set_ascii (struct ftpconn *conn)
static int ftp_set_binary (struct ftpconn *conn)
static int ftp_set_cwd (struct ftpconn *conn, const char *dir)
static int ftp_do_list (struct ftpconn *conn, const char *dir, struct remdirlist *dl)
static const char * ftp_get_password (struct ftpdata *ftd, const char *host, const char *user)
static int ftp_split_path (struct ftpdata *ftd, char *hostpart, const char **hostp, const char **userp, const char **passp)
static struct ftpconnftp_find_conn (struct ftpdata *ftd, const char *host, const char *user, const char *password)
static int ftp_get_conn (struct ftpdata *ftd, const char *userhost, struct ftpconn **resp)
static int ftp_list (struct remote *rem, struct remdirlist *dl)
static void ftp_free_localfile (struct ftplocalfile *lf)
static int ftp_init_localfile (struct ftplocalfile *lf, int sock)
static int ftp_do_get (struct remgetparam *gp, const char *dir, const char *file, struct ftpconn *conn)
static int ftp_get (struct remote *rem, struct remgetparam *gp)
static int ftp_write_localfile (int fd, char *buf, avsize_t nbytes)
static int ftp_wait (struct remote *rem, void *data, avoff_t end)
static int ftp_password_set (struct entry *ent, const char *param, const char *val)
static int ftp_loggedin_get (struct entry *ent, const char *param, char **resp)
static int ftp_loggedin_val (const char *val, int *resp)
static int ftp_loggedin_set (struct entry *ent, const char *param, const char *val)
static int ftp_init_ctl (struct vmodule *module, struct ftpdata *ftd)
static void ftp_destroy (struct remote *rem)
int av_init_module_ftp (struct vmodule *module)

Class Documentation

struct ftpconn

Definition at line 43 of file ftp.c.

Collaboration diagram for ftpconn:
Class Members
int binary
int busy
char * cwd
char * host
struct ftpconn * next
char * password
int sock
struct filebuf * sockfb
char * user
struct ftpsession

Definition at line 55 of file ftp.c.

Collaboration diagram for ftpsession:
Class Members
char * account
struct ftpsession * next
char * password
struct ftpsession * prev
struct ftpdata

Definition at line 62 of file ftp.c.

Collaboration diagram for ftpdata:
Class Members
struct ftpconn * conns
struct ftplocalfile

Definition at line 67 of file ftp.c.

Collaboration diagram for ftplocalfile:
Class Members
struct ftpconn * conn
int fd
avoff_t numbytes
int sock
struct filebuf * sockfb
char * tmpfile

Define Documentation

#define FTP_READ_TIMEOUT   60000

Definition at line 39 of file ftp.c.

#define FTP_REPLY_TIMEOUT   30000

Definition at line 38 of file ftp.c.

#define READBUF   4096

Definition at line 908 of file ftp.c.

#define USER_SEP_CHAR   (USER_SEP_STR[0])

Definition at line 36 of file ftp.c.

#define USER_SEP_STR   "@"

Definition at line 35 of file ftp.c.


Function Documentation

int av_init_module_ftp ( struct vmodule module)

Definition at line 1111 of file ftp.c.

{
    int res;
    struct remote *rem;
    struct ftpdata *ftd;
    struct avfs *avfs;

    AV_NEW(ftd);
    ftd->conns = NULL;
    ftd->sessions.next = &ftd->sessions;
    ftd->sessions.prev = &ftd->sessions;

    AV_NEW(rem);

    rem->data    = ftd;
    rem->flags   = REM_DIR_ONLY;
    rem->name    = av_strdup("ftp");
    rem->list    = ftp_list;
    rem->get     = ftp_get;
    rem->wait    = ftp_wait;
    rem->destroy = ftp_destroy;
    
    res = av_remote_init(module, rem, &avfs);
    if(res == 0) {
        res = ftp_init_ctl(module, ftd);
        if(res < 0)
            av_unref_obj(avfs);
    }

    return res;
}

Here is the call graph for this function:

static AV_LOCK_DECL ( ftp_lock  ) [static]
static int ftp_check_passv_reply ( struct ftpconn conn,
const char *  line,
char **  resp 
) [static]

Definition at line 327 of file ftp.c.

{
    int res;
    int replycode;
    int addrbytes[6];
    char addrbuf[128];
    int port;
    
    res = ftp_check_reply(conn, line);
    if(res < 0)
        return res;

    replycode = res;
    
    if(replycode != 227) {
        av_log(AVLOG_ERROR, "FTP: %s", line);
        ftp_close_conn(conn);
        return -EIO;
    }
    
    av_log(AVLOG_DEBUG, "FTP: %s", line);
        
    if(line[3] != ' ') {
        av_log(AVLOG_ERROR, "FTP: Multiline reply to PASV: %s", line);
        ftp_close_conn(conn);
        return -EIO;
    }

    res = ftp_get_addrbytes(line, addrbytes);
    if(res < 0) {
        av_log(AVLOG_ERROR, "FTP: Bad reply to PASV: %s", line);
        ftp_close_conn(conn);
        return -EIO;
    }

    port = addrbytes[4] * 0x100 + addrbytes[5];
    sprintf(addrbuf, "%i.%i.%i.%i:%i", 
            addrbytes[0], addrbytes[1], addrbytes[2], addrbytes[3], port);

    *resp = av_strdup(addrbuf);

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_check_reply ( struct ftpconn conn,
const char *  line 
) [static]

Definition at line 179 of file ftp.c.

{
    int reply;

    if(strlen(line) < 4 || !isdigit((int) line[0]) ||
       !isdigit((int) line[1]) || !isdigit((int) line[2]) ||
       (line[3] != ' ' && line[3] != '-')) {
        ftp_close_conn(conn);
        av_log(AVLOG_ERROR, "FTP: malformed reply: %s", line);
        return -EIO;
    }

    reply = (line[0] - '0') * 100 + (line[1] - '0') * 10 + (line[2] - '0');

    if(reply == 421)
        ftp_close_conn(conn);

    return reply;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ftp_close_conn ( struct ftpconn conn) [static]

Definition at line 144 of file ftp.c.

{
    av_unref_obj(conn->sockfb);
    conn->sockfb = NULL;
    conn->sock = -1;
    conn->binary = -1;
    conn->cwd[0] = '\0';
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_command ( struct ftpconn conn,
const char *  cmd 
) [static]

Definition at line 278 of file ftp.c.

{
    int res;

    res = ftp_write_command(conn, cmd);
    if(res < 0)
        return res;

    res = ftp_wait_reply_code(conn);
    
    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ftp_destroy ( struct remote rem) [static]

Definition at line 1079 of file ftp.c.

{
    struct ftpdata *ftd = (struct ftpdata *) rem->data;
    struct ftpconn *conn;
    struct ftpconn *nextconn;

    for(conn = ftd->conns; conn != NULL; conn = nextconn) {
        nextconn = conn->next;

        ftp_close_conn(conn);
        av_free(conn->host);
        av_free(conn->user);
        av_free(conn->password);
        av_free(conn->cwd);
        av_free(conn);
        
        conn = nextconn;
    }

    AV_LOCK(ftp_lock);
    while(ftd->sessions.next != &ftd->sessions)
        ftp_remove_session(ftd->sessions.next);
    AV_UNLOCK(ftp_lock);

    av_free(ftd);

    av_free(rem->name);
    av_free(rem);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_do_get ( struct remgetparam gp,
const char *  dir,
const char *  file,
struct ftpconn conn 
) [static]

Definition at line 809 of file ftp.c.

{
    int res;
    int getsock;
    char *cmd;
    struct ftplocalfile *lf;

    res = ftp_open_conn(conn);
    if(res < 0)
        return res;

    res = ftp_set_binary(conn);
    if(res < 0)
        return res;
    
    res = ftp_set_cwd(conn, dir);
    if(res < 0)
        return res;

    res = ftp_open_dataconn(conn);
    if(res < 0)
        return res;

    getsock = res;
    cmd = av_stradd(NULL, "RETR ", file, NULL);
    res = ftp_command(conn, cmd);
    av_free(cmd);
    if(res >= 0 && res / 100 != 1)
        res = -EIO;
    
    if(res < 0) {
        close(getsock);
        return res;
    }

    AV_NEW_OBJ(lf, ftp_free_localfile);
    res = ftp_init_localfile(lf, getsock);
    if(res < 0) {
        av_unref_obj(lf);
        av_del_tmpfile(lf->tmpfile);
        return res;
    }

    lf->conn = conn;

    gp->data = lf;
    gp->localname = lf->tmpfile;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_do_list ( struct ftpconn conn,
const char *  dir,
struct remdirlist dl 
) [static]

Definition at line 584 of file ftp.c.

{
    int res;
    char *cmd;
    int listsock;
    struct filebuf *fb;
    struct lscache *lc;

    res = ftp_open_conn(conn);
    if(res < 0)
        return res;

    res = ftp_set_ascii(conn);
    if(res < 0)
        return res;
    
    res = ftp_set_cwd(conn, dir);
    if(res < 0)
        return res;

    res = ftp_open_dataconn(conn);
    if(res < 0)
        return res;
        
    listsock = res;
    cmd = av_strdup("LIST -al");
    res = ftp_command(conn, cmd);
    av_free(cmd);
    if(res >= 0 && res / 100 != 1)
        res = -EIO;
    
    if(res < 0) {
        close(listsock);
        return res;
    }
    
    fb = av_filebuf_new(listsock, 0);
    lc = av_new_lscache();
    res = ftp_read_list(fb, dl, lc);
    av_unref_obj(lc);
    av_unref_obj(fb);

    res = ftp_wait_reply_code(conn);
    if(res >= 0 && res / 100 != 2)
        res = -EIO;

    if(res < 0) {
        ftp_free_dirlist(dl);
        return res;
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct ftpconn* ftp_find_conn ( struct ftpdata ftd,
const char *  host,
const char *  user,
const char *  password 
) [static, read]

Definition at line 696 of file ftp.c.

{
    struct ftpconn *conn;
    struct ftpconn **cp;

    for(cp = &ftd->conns; *cp != NULL; cp = &(*cp)->next) {
        conn = *cp;

        if(strcmp(conn->host, host) == 0 && strcmp(conn->user, user) == 0 &&
           strcmp(conn->password, password) == 0 && !conn->busy) {
            conn->busy = 1;
            return conn;
        }
    }

    AV_NEW(conn);
    
    conn->host = av_strdup(host);
    conn->user = av_strdup(user);
    conn->password = av_strdup(password);
    conn->busy = 1;
    conn->sock = -1;
    conn->sockfb = NULL;
    conn->next = NULL;
    conn->binary = -1;
    conn->cwd = av_strdup("");
    
    *cp = conn;
    
    return conn;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct ftpsession* ftp_find_session ( struct ftpdata ftd,
const char *  account 
) [static, read]

Definition at line 76 of file ftp.c.

{
    struct ftpsession *fts;

    for(fts = ftd->sessions.next; fts != &ftd->sessions; fts = fts->next) {
        if(strcmp(account, fts->account) == 0)
            return fts;
    }
    
    return NULL;
}

Here is the caller graph for this function:

static void ftp_free_dirlist ( struct remdirlist dl) [static]

Definition at line 478 of file ftp.c.

{
    int i;

    for(i = 0; i < dl->num; i++) {
        av_free(dl->ents[i].name);
        av_free(dl->ents[i].linkname);
    }

    av_free(dl->ents);
    dl->ents = NULL;
    dl->num = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ftp_free_localfile ( struct ftplocalfile lf) [static]

Definition at line 773 of file ftp.c.

{
    if(lf->conn != NULL) {
        ftp_close_conn(lf->conn);
        ftp_release_conn(lf->conn);
    }
    av_unref_obj(lf->sockfb);
    close(lf->sock);
    close(lf->fd);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_get ( struct remote rem,
struct remgetparam gp 
) [static]

Definition at line 861 of file ftp.c.

{
    int res;
    struct ftpdata *ftd = (struct ftpdata *) rem->data;
    struct ftpconn *conn;
    char *dir;
    char *s;
    char *file;

    res = ftp_get_conn(ftd, gp->hostpath.host, &conn);
    if(res < 0)
        return res;

    dir = av_strdup(gp->hostpath.path);
    s = strrchr(dir, '/');
    *s = '\0';
    file = s + 1;

    res = ftp_do_get(gp, ( dir[0] == '\0' ) ? "/" : dir, file, conn);
    av_free(dir);

    if(res < 0)
        ftp_release_conn(conn);

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_get_addrbytes ( const char *  line,
int  addrbytes[6] 
) [static]

Definition at line 292 of file ftp.c.

{
    int i;
    int j;
    int val;
    const char *s;

    for(s = line; *s && *s != '('; s++);
    if(!*s)
        return -1;

    s++;
    for(i = 0; i < 6; i++) {
        val = 0;
        for(j = 0; j < 3; j++) {
            if(!isdigit((int) *s))
                return -1;
            val = val * 10 + (*s - '0');
            s++;
            if(*s == ',' || *s == ')')
                break;
        }
        if(*s != ',' && *s != ')')
            return -1;
        addrbytes[i] = val;
        if(*s == ')')
            break;
        s++;        
    }
    if(i != 5 || *s != ')')
        return -1;

    return 0;
}

Here is the caller graph for this function:

static int ftp_get_conn ( struct ftpdata ftd,
const char *  userhost,
struct ftpconn **  resp 
) [static]

Definition at line 729 of file ftp.c.

{
    int res;
    char *tmps;
    const char *host;
    const char *user;
    const char *password;
    struct ftpconn *conn = NULL;

    AV_LOCK(ftp_lock);
    tmps = av_strdup(userhost);
    res = ftp_split_path(ftd, tmps, &host, &user, &password);
    if(res == 0)
        conn = ftp_find_conn(ftd, host, user, password);

    av_free(tmps);
    AV_UNLOCK(ftp_lock);

    if(res < 0)
        return res;

    *resp = conn;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_get_line ( struct ftpconn conn,
char **  linep 
) [static]

Definition at line 153 of file ftp.c.

{
    int res;
    char *line;
    
    res = av_filebuf_getline(conn->sockfb, &line, FTP_REPLY_TIMEOUT);
    if(res <= 0 || line == NULL) {
        ftp_close_conn(conn);
        if(res < 0)
            return res;

        if(res == 0)
            av_log(AVLOG_ERROR, "FTP: timeout waiting for reply");
        else
            av_log(AVLOG_ERROR, "FTP: server closed ftpconn");

        return -EIO;
    }

    strip_crlf(line);
    *linep = line;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* ftp_get_password ( struct ftpdata ftd,
const char *  host,
const char *  user 
) [static]

Definition at line 639 of file ftp.c.

{
    struct ftpsession *fts;
    char *account;

    account = av_stradd(NULL, user, USER_SEP_STR, host, NULL);
    fts = ftp_find_session(ftd, account);
    av_free(account);
    if(fts == NULL) {
        account = av_stradd(NULL, user, USER_SEP_STR, NULL);
        fts = ftp_find_session(ftd, account);
        av_free(account);
    }
    
    if(fts != NULL)
        return fts->password;
    else
        return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct ftpsession* ftp_get_session ( struct ftpdata ftd,
const char *  account 
) [static, read]

Definition at line 89 of file ftp.c.

{
    struct ftpsession *fts;
    
    fts = ftp_find_session(ftd, account);
    if(fts == NULL) {
        struct ftpsession *next;
        struct ftpsession *prev;

        AV_NEW(fts);
        fts->account = av_strdup(account);
        fts->password = NULL;

        fts->next = next = ftd->sessions.next;
        fts->prev = prev = &ftd->sessions;
        next->prev = fts;
        prev->next = fts;
    }
    
    return fts;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_init_conn ( struct ftpconn conn) [static]

Definition at line 425 of file ftp.c.

{
    int res;

    res = ftp_wait_reply_code(conn);
    if(res == 120)
        res = ftp_wait_reply_code(conn);
    
    if(res < 0)
        return res;

    if(res != 220)
        return -EIO;
    
    res = ftp_login(conn);
    if(res < 0)
        return res;

    ftp_command(conn, "PWD");
    ftp_command(conn, "SYST");

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_init_ctl ( struct vmodule module,
struct ftpdata ftd 
) [static]

Definition at line 1048 of file ftp.c.

{
    int res;
    struct namespace *ns;
    struct statefile *stf;
    struct entry *ent;
    struct avfs *avfs;
    
    res = av_state_new(module, "ftp_ctl", &ns, &avfs);
    if(res < 0)
        return res;
    
    ent = av_namespace_lookup(ns, NULL, "password");
    AV_NEW(stf);
    stf->data = ftd;
    stf->get = NULL;
    stf->set = ftp_password_set;
    av_namespace_set(ent, stf);

    ent = av_namespace_lookup(ns, NULL, "loggedin");
    AV_NEW(stf);
    stf->data = ftd;
    stf->get = ftp_loggedin_get;
    stf->set = ftp_loggedin_set;
    av_namespace_set(ent, stf);
    
    av_unref_obj(ns);

    return 0;
}    

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_init_localfile ( struct ftplocalfile lf,
int  sock 
) [static]

Definition at line 784 of file ftp.c.

{
    int res;

    lf->fd = -1;
    lf->tmpfile = NULL;
    lf->sock = sock;
    lf->sockfb = NULL;
    lf->numbytes = 0;
    lf->conn = NULL;

    res = av_get_tmpfile(&lf->tmpfile);
    if(res < 0)
        return res;

    lf->fd = open(lf->tmpfile, O_RDWR | O_CREAT | O_TRUNC | O_APPEND, 0600);
    if(lf->fd == -1)
        return -errno;

    lf->sockfb = av_filebuf_new(lf->sock, 0);

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_list ( struct remote rem,
struct remdirlist dl 
) [static]

Definition at line 756 of file ftp.c.

{
    int res;
    struct ftpdata *ftd = (struct ftpdata *) rem->data;
    struct ftpconn *conn;

    res = ftp_get_conn(ftd, dl->hostpath.host, &conn);
    if(res < 0)
        return res;

    res = ftp_do_list(conn, dl->hostpath.path, dl);

    ftp_release_conn(conn);

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_loggedin_get ( struct entry ent,
const char *  param,
char **  resp 
) [static]

Definition at line 983 of file ftp.c.

{
    struct ftpsession *fts;
    struct statefile *sf = (struct statefile *) av_namespace_get(ent);
    struct ftpdata *ftd = (struct ftpdata *) sf->data;

    AV_LOCK(ftp_lock);
    fts = ftp_find_session(ftd, param);
    if(fts == NULL)
        *resp = av_strdup("0\n");
    else
        *resp = av_strdup("1\n");
    AV_UNLOCK(ftp_lock);

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_loggedin_set ( struct entry ent,
const char *  param,
const char *  val 
) [static]

Definition at line 1022 of file ftp.c.

{
    int res;
    struct ftpsession *fts;
    struct statefile *sf = (struct statefile *) av_namespace_get(ent);
    struct ftpdata *ftd = (struct ftpdata *) sf->data;

    AV_LOCK(ftp_lock);
    fts = ftp_find_session(ftd, param);
    if(fts == NULL)
        res = -EACCES;
    else {
        int ival;

        res = ftp_loggedin_val(val, &ival);
        if(res == 0 && ival == 0) {
            /* FIXME: end connections using this session */
            ftp_remove_session(fts);
        }
    }
    AV_UNLOCK(ftp_lock);

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_loggedin_val ( const char *  val,
int *  resp 
) [static]

Definition at line 1000 of file ftp.c.

{
    char *end;
    int ival;

    ival = strtol(val, &end, 10);
    if(end == val)
        return -EINVAL;

    if(*end == '\n')
        end++;
    if(*end != '\0')
        return -EINVAL;

    if(ival < 0 || ival > 1)
        return -EINVAL;
    
    *resp = ival;

    return 0;
}

Here is the caller graph for this function:

static int ftp_login ( struct ftpconn conn) [static]

Definition at line 402 of file ftp.c.

{
    int res;
    char *cmd;

    cmd = av_stradd(NULL, "USER ", conn->user, NULL);
    res = ftp_command(conn, cmd);
    av_free(cmd);

    if(res == 331) {
        cmd = av_stradd(NULL, "PASS ", conn->password, NULL);
        res = ftp_command(conn, cmd);
        av_free(cmd);
        if(res < 0)
            return res;
    }

    if(res != 230)
        return -EACCES;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_open_conn ( struct ftpconn conn) [static]

Definition at line 449 of file ftp.c.

{
    int res;

    if(conn->sock != -1) {
        res = ftp_command(conn, "NOOP");
        if(res < 0)
            return res;
        
        if(res != 421)
            return 0;
    }

    res = av_sock_connect(conn->host, 21);
    if(res < 0)
        return res;

    conn->sock = res;
    conn->sockfb = av_filebuf_new(conn->sock, 0);

    res = ftp_init_conn(conn);
    if(res < 0) {
        ftp_close_conn(conn);
        return res;
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_open_dataconn ( struct ftpconn conn) [static]

Definition at line 372 of file ftp.c.

{
    int res;
    char *line;
    char *host;

    res = ftp_write_command(conn, "PASV");
    if(res < 0)
        return res;

    res = ftp_get_line(conn, &line);
    if(res < 0)
        return res;

    res = ftp_check_passv_reply(conn, line, &host);
    av_free(line);
    if(res < 0)
        return res;

    av_log(AVLOG_DEBUG,"FTP: remote data address: %s", host);
    
    res = av_sock_connect(host, -1);
    if(res >= 0)
       av_registerfd(res);

    av_free(host);
    
    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_password_set ( struct entry ent,
const char *  param,
const char *  val 
) [static]

Definition at line 961 of file ftp.c.

{
    struct ftpsession *fts;
    struct statefile *sf = (struct statefile *) av_namespace_get(ent);
    struct ftpdata *ftd = (struct ftpdata *) sf->data;
    unsigned int len;

    AV_LOCK(ftp_lock);
    fts = ftp_get_session(ftd, param);
    av_free(fts->password);
    fts->password = av_strdup(val);
    len = strlen(fts->password);
    if(len > 0) {
        if(fts->password[len - 1] == '\n')
            fts->password[len - 1] = '\0';
    }
    AV_UNLOCK(ftp_lock);

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_read_list ( struct filebuf fb,
struct remdirlist dl,
struct lscache lc 
) [static]

Definition at line 492 of file ftp.c.

{
    int res;
    char *line;
    int eof = 0;

    do {
        res = av_filebuf_getline(fb, &line, FTP_READ_TIMEOUT);
        if(res < 0)
            return res;
        
        if(res == 0) {
            av_log(AVLOG_ERROR, "FTP: read timeout");
            return -EIO;
        }
        if(line == NULL)
            eof = 1;
        else {
            struct avstat stbuf;
            char *filename;
            char *linkname;
            strip_crlf(line);
            
            av_log(AVLOG_DEBUG, "FTP: %s", line);
            res = av_parse_ls(lc, line, &stbuf, &filename, &linkname);
            av_free(line);
            if(res == 1) {
                av_remote_add(dl, filename, linkname, &stbuf);
                av_free(filename);
                av_free(linkname);
            }
        }
    } while(!eof);

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ftp_release_conn ( struct ftpconn conn) [static]

Definition at line 137 of file ftp.c.

{
    AV_LOCK(ftp_lock);
    conn->busy = 0;
    AV_UNLOCK(ftp_lock);
}

Here is the caller graph for this function:

static void ftp_remove_session ( struct ftpsession fts) [static]

Definition at line 112 of file ftp.c.

{
    struct ftpsession *next = fts->next;
    struct ftpsession *prev = fts->prev;
    
    next->prev = prev;
    prev->next = next;

    av_free(fts->account);
    av_free(fts->password);
    av_free(fts);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_set_ascii ( struct ftpconn conn) [static]

Definition at line 530 of file ftp.c.

{
    int res;

    if(conn->binary != 0) {
        res = ftp_command(conn, "TYPE A");
        if(res < 0)
            return res;

        conn->binary = 0;
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_set_binary ( struct ftpconn conn) [static]

Definition at line 545 of file ftp.c.

{
    int res;

    if(conn->binary != 1) {
        res = ftp_command(conn, "TYPE I");
        if(res < 0)
            return res;

        conn->binary = 1;
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_set_cwd ( struct ftpconn conn,
const char *  dir 
) [static]

Definition at line 560 of file ftp.c.

{
    int res;
    char *cmd;

    if(strcmp(conn->cwd, dir) != 0) {
        cmd = av_stradd(NULL, "CWD ", dir, NULL);
        res = ftp_command(conn, cmd);
        av_free(cmd);
        if(res < 0)
            return res;
        
        if(res == 550)
            return -ENOENT;
        if(res / 100 != 2)
            return -EIO;

        av_free(conn->cwd);
        conn->cwd = av_strdup(dir);
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_split_path ( struct ftpdata ftd,
char *  hostpart,
const char **  hostp,
const char **  userp,
const char **  passp 
) [static]

Definition at line 660 of file ftp.c.

{
    char *s, *t;
    const char *host;
    const char *user;
    const char *pass;

    for(s = hostpart; *s && *s != USER_SEP_CHAR; s++);
    for(t = s; *t; t++) if (*t == USER_SEP_CHAR) s = t;
    if(*s != '\0') {
        *s = '\0';
        host = s + 1;
        user = hostpart;
        pass = ftp_get_password(ftd, host, user);
        if(pass == NULL)
            return -EACCES;
    }
    else {
        host = hostpart;
        user = "ftp";
        pass = "avfs@";
    }

    if(host[0] == '\0')
        return -ENOENT;

    *hostp = host;
    *userp = user;
    *passp = pass;

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_wait ( struct remote rem,
void *  data,
avoff_t  end 
) [static]

Definition at line 910 of file ftp.c.

{
    int res;
    struct ftplocalfile *lf = (struct ftplocalfile *) data;
    char buf[READBUF];
    avsize_t nbytes;
    
    do {
        nbytes = av_filebuf_read(lf->sockfb, buf, READBUF);
        if(nbytes != 0) {
            res = ftp_write_localfile(lf->fd, buf, nbytes);
            if(res < 0)
                return res;

            lf->numbytes += nbytes;
        }
        else {
            if(av_filebuf_eof(lf->sockfb)) {
                av_unref_obj(lf->sockfb);
                lf->sockfb = NULL;
                close(lf->sock);
                lf->sock = -1;

                res = ftp_wait_reply_code(lf->conn);
                if(res >= 0 && res / 100 != 2)
                    res = -EIO;
                
                if(res < 0)
                    return res;
                
                ftp_release_conn(lf->conn);
                lf->conn = NULL;

                return 0;
            }
            else {
                res = av_filebuf_check(&lf->sockfb, 1, FTP_READ_TIMEOUT);
                if(res < 0)
                    return res;

                if(res == 0) {
                    av_log(AVLOG_ERROR, "FTP: read timeout");
                    return -EIO;
                }
            }
        }
    } while(lf->numbytes < end);

    return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_wait_reply_code ( struct ftpconn conn) [static]

Definition at line 199 of file ftp.c.

{
    int res;
    char *line;
    char replystr[4];
    int firstline = 1;
    int cont;
    int replycode = 0;
    
    do {
        cont = 0;
        res = ftp_get_line(conn, &line);
        if(res < 0)
            return res;

        if(firstline) {
            res = ftp_check_reply(conn, line);
            if(res < 0) {
                av_free(line);
                return res;
            }

            replycode = res;

            if(line[3] == '-') {
                strncpy(replystr, line, 3);
                replystr[3] = ' ';
                firstline = 0;
                cont = 1;
            }
        }
        else if(strncmp(line, replystr, 4) != 0)
            cont = 1;

        if(replycode >= 400)
            av_log(AVLOG_ERROR, "FTP: %s", line);
        else
            av_log(AVLOG_DEBUG, "FTP: %s", line);

        av_free(line);
    } while(cont);
 
    return replycode;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_write_command ( struct ftpconn conn,
const char *  cmd 
) [static]

Definition at line 261 of file ftp.c.

{
    char *line;
    int res;

    if(strncmp(cmd, "PASS ", 5) == 0)
        av_log(AVLOG_DEBUG, "FTP: PASS *");
    else
        av_log(AVLOG_DEBUG, "FTP: %s", cmd);

    line = av_stradd(NULL, cmd, "\r\n", NULL);
    res = write_socket(conn->sock, line, strlen(line));
    av_free(line);

    return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ftp_write_localfile ( int  fd,
char *  buf,
avsize_t  nbytes 
) [static]

Definition at line 888 of file ftp.c.

{
    int res;

    res = write(fd, buf, nbytes);
    if(res == -1) {
        av_log(AVLOG_ERROR, "FTP: error writing to tmpfile: %s",
                 strerror(errno));
                
        return -EIO;
    }
    if(res != nbytes) {
        av_log(AVLOG_ERROR, "FTP: short write to tmpfile (%i/%i)",
                 res, nbytes);
        return -EIO;
    }
    
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void strip_crlf ( char *  line) [static]

Definition at line 125 of file ftp.c.

{
    avsize_t len = strlen(line);
    
    if(len > 0 && line[len-1] == '\n') {
        if(len > 1 && line[len-2] == '\r')
            line[len-2] = '\0';
        else
            line[len-1] = '\0';
    }
}

Here is the caller graph for this function:

static int write_socket ( int  sock,
const char *  buf,
avsize_t  buflen 
) [static]

Definition at line 245 of file ftp.c.

{
    int res;

    while(buflen > 0) {
        res = write(sock, buf, buflen);
        if(res == -1)
            return -errno;
        
        buf += res;
        buflen -= res;
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function: