static int ftp_read(URLContext *h, unsigned char *buf, int size)

{

    FTPContext *s = h->priv_data;

    int read, err, retry_done = 0;



    av_dlog(h, "ftp protocol read %d bytes\n", size);

  retry:

    if (s->state == DISCONNECTED) {

        /* optimization */

        if (s->position >= s->filesize)

            return 0;

        if ((err = ftp_connect_data_connection(h)) < 0)

            return err;

    }

    if (s->state == READY) {

        if (s->position >= s->filesize)

            return 0;

        if ((err = ftp_retrieve(s)) < 0)

            return err;

    }

    if (s->conn_data && s->state == DOWNLOADING) {

        read = ffurl_read(s->conn_data, buf, size);

        if (read >= 0) {

            s->position += read;

            if (s->position >= s->filesize) {

                /* server will terminate, but keep current position to avoid madness */

                /* save position to restart from it */

                int64_t pos = s->position;

                if (ftp_abort(h) < 0) {

                    s->position = pos;

                    return AVERROR(EIO);

                }

                s->position = pos;

            }

        }

        if (read <= 0 && s->position < s->filesize && !h->is_streamed) {

            /* Server closed connection. Probably due to inactivity */

            int64_t pos = s->position;

            av_log(h, AV_LOG_INFO, "Reconnect to FTP server.\n");

            if ((err = ftp_abort(h)) < 0)

                return err;

            if ((err = ftp_seek(h, pos, SEEK_SET)) < 0) {

                av_log(h, AV_LOG_ERROR, "Position cannot be restored.\n");

                return err;

            }

            if (!retry_done) {

                retry_done = 1;

                goto retry;

            }

        }

        return read;

    }



    av_log(h, AV_LOG_DEBUG, "FTP read failed\n");

    return AVERROR(EIO);

}

static int ftp_read(URLContext *h, unsigned char *buf, int size)

{

    FTPContext *s = h->priv_data;

    int read, err, retry_done = 0;



    av_dlog(h, "ftp protocol read %d bytes\n", size);

  retry:

    if (s->state == DISCONNECTED) {

        

        if (s->position >= s->filesize)

            return 0;

        if ((err = ftp_connect_data_connection(h)) < 0)

            return err;

    }

    if (s->state == READY) {

        if (s->position >= s->filesize)

            return 0;

        if ((err = ftp_retrieve(s)) < 0)

            return err;

    }

    if (s->conn_data && s->state == DOWNLOADING) {

        read = ffurl_read(s->conn_data, buf, size);

        if (read >= 0) {

            s->position += read;

            if (s->position >= s->filesize) {

                

                

                int64_t pos = s->position;

                if (ftp_abort(h) < 0) {

                    s->position = pos;

                    return AVERROR(EIO);

                }

                s->position = pos;

            }

        }

        if (read <= 0 && s->position < s->filesize && !h->is_streamed) {

            

            int64_t pos = s->position;

            av_log(h, AV_LOG_INFO, "Reconnect to FTP server.\n");

            if ((err = ftp_abort(h)) < 0)

                return err;

            if ((err = ftp_seek(h, pos, SEEK_SET)) < 0) {

                av_log(h, AV_LOG_ERROR, "Position cannot be restored.\n");

                return err;

            }

            if (!retry_done) {

                retry_done = 1;

                goto retry;

            }

        }

        return read;

    }



    av_log(h, AV_LOG_DEBUG, "FTP read failed\n");

    return AVERROR(EIO);

}

static int FUNC_0(URLContext *VAR_0, unsigned char *VAR_1, int VAR_2)

{

    FTPContext *s = VAR_0->priv_data;

    int VAR_3, VAR_4, VAR_5 = 0;



    av_dlog(VAR_0, "ftp protocol VAR_3 %d bytes\n", VAR_2);

  retry:

    if (s->state == DISCONNECTED) {

        

        if (s->position >= s->filesize)

            return 0;

        if ((VAR_4 = ftp_connect_data_connection(VAR_0)) < 0)

            return VAR_4;

    }

    if (s->state == READY) {

        if (s->position >= s->filesize)

            return 0;

        if ((VAR_4 = ftp_retrieve(s)) < 0)

            return VAR_4;

    }

    if (s->conn_data && s->state == DOWNLOADING) {

        VAR_3 = ffurl_read(s->conn_data, VAR_1, VAR_2);

        if (VAR_3 >= 0) {

            s->position += VAR_3;

            if (s->position >= s->filesize) {

                

                

                int64_t pos = s->position;

                if (ftp_abort(VAR_0) < 0) {

                    s->position = pos;

                    return AVERROR(EIO);

                }

                s->position = pos;

            }

        }

        if (VAR_3 <= 0 && s->position < s->filesize && !VAR_0->is_streamed) {

            

            int64_t pos = s->position;

            av_log(VAR_0, AV_LOG_INFO, "Reconnect to FTP server.\n");

            if ((VAR_4 = ftp_abort(VAR_0)) < 0)

                return VAR_4;

            if ((VAR_4 = ftp_seek(VAR_0, pos, SEEK_SET)) < 0) {

                av_log(VAR_0, AV_LOG_ERROR, "Position cannot be restored.\n");

                return VAR_4;

            }

            if (!VAR_5) {

                VAR_5 = 1;

                goto retry;

            }

        }

        return VAR_3;

    }



    av_log(VAR_0, AV_LOG_DEBUG, "FTP VAR_3 failed\n");

    return AVERROR(EIO);

}

static int FUNC_0(URLContext *VAR_0, unsigned char *VAR_1, int VAR_2)
{ FTPContext *s = VAR_0->priv_data; int VAR_3, VAR_4, VAR_5 = 0; av_dlog(VAR_0, "ftp protocol VAR_3 %d bytes\n", VAR_2); retry:
if (s->state == DISCONNECTED) { if (s->position >= s->filesize)
return 0; if ((VAR_4 = ftp_connect_data_connection(VAR_0)) < 0)
return VAR_4; } if (s->state == READY) { if (s->position >= s->filesize)
return 0; if ((VAR_4 = ftp_retrieve(s)) < 0)
return VAR_4; } if (s->conn_data && s->state == DOWNLOADING) { VAR_3 = ffurl_read(s->conn_data, VAR_1, VAR_2); if (VAR_3 >= 0) { s->position += VAR_3; if (s->position >= s->filesize) { int64_t pos = s->position; if (ftp_abort(VAR_0) < 0) { s->position = pos; return AVERROR(EIO); } s->position = pos; } } if (VAR_3 <= 0 && s->position < s->filesize && !VAR_0->is_streamed) { int64_t pos = s->position; av_log(VAR_0, AV_LOG_INFO, "Reconnect to FTP server.\n"); if ((VAR_4 = ftp_abort(VAR_0)) < 0)
return VAR_4; if ((VAR_4 = ftp_seek(VAR_0, pos, SEEK_SET)) < 0) { av_log(VAR_0, AV_LOG_ERROR, "Position cannot be restored.\n"); return VAR_4; } if (!VAR_5) { VAR_5 = 1; goto retry; } } return VAR_3; } av_log(VAR_0, AV_LOG_DEBUG, "FTP VAR_3 failed\n"); return AVERROR(EIO); }