GithubHelp home page GithubHelp logo

rust-ftp's People

Contributors

17dec avatar benaryorg avatar bombless avatar daa84 avatar dbrgn avatar elrendio avatar emberian avatar little-dude avatar luxed avatar matt2xu avatar mattnenterprise avatar rrevenantt avatar veeso avatar workanator avatar yackushevas avatar zsck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

rust-ftp's Issues

Disable PASV mode

When I try some general command, e.g. LIST, I got below error:

Err(InvalidResponse("Expected code [227], got response: 550 Unknown error.\r\n"))

As my FTP server doesn't support PASV mode, so it's better to have some flag to disable it in the client also.

Add Tests

Some type of testing is needed to ensure the code still works when changes are made. We can test against a pure-ftpd server.

cannot log in ftp.hq.nasa.gov

I was trying to connect anonymously to ftp.hq.nasa.gov but I'm getting an "Invalid response". I suspect there is something wrong in read_response:

// nasa.rs
extern crate ftp;

use std::str;
use ftp::FTPStream;

fn main() {
    let mut ftp_stream = match FTPStream::connect("198.116.65.45".to_string(), 21) {
        Ok(s) => s,
        Err(e) => panic!("{}", e)
    };
}

Here is a capture:
ftp_failure.pcapng.zip

MLSD command

I need MLSD command.
Are there any plans for implementation?

Depends on old winapi: "the following packages contain code that will be rejected by a future version of rust"

Hey there, thanks for the great library!

On compiling with ftp 3.0.1 I get the following error:


❯ cargo b -r --future-incompat-report
    Finished release [optimized] target(s) in 0.13s
warning: the following packages contain code that will be rejected by a future version of Rust: winapi v0.2.8
note: 
To solve this problem, you can try the following approaches:


- Some affected dependencies have newer versions available.
You may want to consider updating them to a newer version to see if the issue has been fixed.

winapi v0.2.8 has the following newer versions available: 0.3.0, 0.3.1, 0.3.2, 0.3.3, 0.3.4, 0.3.5, 0.3.6, 0.3.7, 0.3.8, 0.3.9


- If the issue is not solved by updating the dependencies, a fix has to be
implemented by those dependencies. You can help with that by notifying the
maintainers of this problem (e.g. by creating a bug report) or by proposing a
fix to the maintainers (e.g. by creating a pull request):

  - [email protected]
  - Repository: https://github.com/retep998/winapi-rs
  - Detailed warning command: `cargo report future-incompatibilities --id 14 --package [email protected]`

- If waiting for an upstream fix is not an option, you can use the `[patch]`
section in `Cargo.toml` to use your own version of the dependency. For more
information, see:
https://doc.rust-lang.org/cargo/reference/overriding-dependencies.html#the-patch-section

note: this report can be shown with `cargo report future-incompatibilities --id 14`

It seems like winapi is required by the following sequence:

ftp v3.0.1
└── regex v0.1.80
    └── thread_local v0.2.7
        └── thread-id v2.0.0
            └── kernel32-sys v0.2.2
                └── winapi v0.2.8

Is there any chance to update these? Maybe a regex update might already suffice, or we might need to pass it down.

File size increase on download tranfer

Trying to use the library (on file who made 80Mo), I get a file with 81677962 bytes which become after the download to a size of 81969152.

I have take a look on the difference, and I found some additional bytes on 0x0A which was converted to 0x0D 0x0A.
Do you have any idea of the issue ?

Upgrade `regex` package versions to `>=1.5.5` (security vulnerabilities)

Im not sure if that is the right place but when I run cargo audit on the duckscript repo I get this error:

https://github.com/sagiegurari/duckscript

$ cargo audit
    Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
      Loaded 416 security advisories (from /Users/john/.cargo/advisory-db)
    Updating crates.io index
    Scanning Cargo.lock for vulnerabilities (124 crate dependencies)
Crate:     regex
Version:   0.1.80
Title:     Regexes with large repetitions on empty sub-expressions take a very long time to parse
Date:      2022-03-08
ID:        RUSTSEC-2022-0013
URL:       https://rustsec.org/advisories/RUSTSEC-2022-0013
Solution:  Upgrade to >=1.5.5
Dependency tree:
regex 0.1.80
└── ftp 3.0.1
    └── duckscriptsdk 0.8.12
        └── duckscript_cli 0.8.12

Crate:     thread_local
Version:   0.2.7
Title:     Data race in `Iter` and `IterMut`
Date:      2022-01-23
ID:        RUSTSEC-2022-0006
URL:       https://rustsec.org/advisories/RUSTSEC-2022-0006
Solution:  Upgrade to >=1.1.4
Dependency tree:
thread_local 0.2.7
└── regex 0.1.80
    └── ftp 3.0.1
        └── duckscriptsdk 0.8.12
            └── duckscript_cli 0.8.12

error: 2 vulnerabilities found!

So I'm not sure if that's the rust-ftp that has an old regex version or duckscript if its duckscript I will move my issue there.

Broken Files when upload rar,zip,msi,etc

I make a test to upload files with format: Zip, Rar,MSI, Exe, etc and always the file when it's uploaded its modified and then broken when it's downloaded and try to open.

on the other hand if i upload files type text like .txt, .php,.html,.js , etc i don't experiment any problem.

here it's the code example

use std::fs::{read, write};
use std::str;
use std::io::Cursor;
use ftp::FtpStream;


fn main() {
    let mut ftp_stream = FtpStream::connect("somehost.com:21").unwrap();
    let _ = ftp_stream.login("some_user", "some_password").unwrap();
    let read_bytes = read("test_file.rar").unwrap();
    let bytes = read_bytes.as_slice();
    println!("Total bytes read  : {}",read_bytes.iter().count());
    let mut reader = Cursor::new(bytes);
    let bytes_reader = reader.clone().into_inner();

    println!("Totalt bytes after reader {}",bytes_reader.iter().count());
                ftp_stream.cwd("public_html").unwrap();
                let _ = ftp_stream.put("file.rar", &mut reader);
}

'till this moment i know the problem exist when make the stream of the bytes, 'cause if i write the bytes of the reader on my disk the file it's OK.

So i will check the code of the stream to see what's it's going on.

Tested ON: Windows 10 21H2 and Mac OS Monterrey 12.6

Usability: FtpStream::connect doesn't default to port 21

Port 21 is the default port that an FTP client should try to use to connect to a provided address if no port is specified. It should be perfectly reasonable for someone to create an FtpStream with the address "127.0.0.1" and have the client implicitly use port 21.

Currently, if the port is left out of the address string, a Custom error with kind InvalidInput and error StringError("invalid socket address") is returned.

`std::old_io::IoResult`. Could not find `old_io` in `std`

$ cargo run
Updating registry https://github.com/rust-lang/crates.io-index
Downloading ftp v0.0.4
Downloading regex-syntax v0.1.2
Downloading regex v0.1.33
Compiling regex-syntax v0.1.2
Compiling regex v0.1.33
Compiling ftp v0.0.4
/home/dmitry/.cargo/registry/src/github.com-1285ae84e5963aae/ftp-0.0.4/src/ftp.rs:8:19: 8:27 error: unresolved import std::old_io::IoResult. Could not find old_io in std
/home/dmitry/.cargo/registry/src/github.com-1285ae84e5963aae/ftp-0.0.4/src/ftp.rs:8 use std::old_io::{IoResult, TcpStream, BufferedReader, BufferedWriter, MemReader, EndOfFile};
^~~~~~~~
/home/dmitry/.cargo/registry/src/github.com-1285ae84e5963aae/ftp-0.0.4/src/ftp.rs:8:29: 8:38 error: unresolved import std::old_io::TcpStream. Could not find old_io in std
/home/dmitry/.cargo/registry/src/github.com-1285ae84e5963aae/ftp-0.0.4/src/ftp.rs:8 use std::old_io::{IoResult, TcpStream, BufferedReader, BufferedWriter, MemReader, EndOfFile};
^~~~~~~~~
/home/dmitry/.cargo/registry/src/github.com-1285ae84e5963aae/ftp-0.0.4/src/ftp.rs:8:40: 8:54 error: unresolved import std::old_io::BufferedReader. Could not find old_io in std
/home/dmitry/.cargo/registry/src/github.com-1285ae84e5963aae/ftp-0.0.4/src/ftp.rs:8 use std::old_io::{IoResult, TcpStream, BufferedReader, BufferedWriter, MemReader, EndOfFile};
^~~~~~~~~~~~~~
/home/dmitry/.cargo/registry/src/github.com-1285ae84e5963aae/ftp-0.0.4/src/ftp.rs:8:56: 8:70 error: unresolved import std::old_io::BufferedWriter. Could not find old_io in std
/home/dmitry/.cargo/registry/src/github.com-1285ae84e5963aae/ftp-0.0.4/src/ftp.rs:8 use std::old_io::{IoResult, TcpStream, BufferedReader, BufferedWriter, MemReader, EndOfFile};
^~~~~~~~~~~~~~
/home/dmitry/.cargo/registry/src/github.com-1285ae84e5963aae/ftp-0.0.4/src/ftp.rs:8:72: 8:81 error: unresolved import std::old_io::MemReader. Could not find old_io in std
/home/dmitry/.cargo/registry/src/github.com-1285ae84e5963aae/ftp-0.0.4/src/ftp.rs:8 use std::old_io::{IoResult, TcpStream, BufferedReader, BufferedWriter, MemReader, EndOfFile};
^~~~~~~~~
/home/dmitry/.cargo/registry/src/github.com-1285ae84e5963aae/ftp-0.0.4/src/ftp.rs:8:83: 8:92 error: unresolved import std::old_io::EndOfFile. Could not find old_io in std
/home/dmitry/.cargo/registry/src/github.com-1285ae84e5963aae/ftp-0.0.4/src/ftp.rs:8 use std::old_io::{IoResult, TcpStream, BufferedReader, BufferedWriter, MemReader, EndOfFile};
^~~~~~~~~
/home/dmitry/.cargo/registry/src/github.com-1285ae84e5963aae/ftp-0.0.4/src/ftp.rs:11:5: 11:28 error: unresolved import std::old_io::util::copy. Could not find old_io in std
/home/dmitry/.cargo/registry/src/github.com-1285ae84e5963aae/ftp-0.0.4/src/ftp.rs:11 use std::old_io::util::copy;
^~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 7 previous errors
Could not compile ftp.

To learn more, run the command again with --verbose.

$ rustc --version
rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14)

Make the code more ergonomic

Taking a new look at this crate after several months, it's looking great!
I have a few ideas to make the code more ergonomic, for instance replacing explicit drops by out-of-scope automatic drops, using AsRef<&str> or Into<Cow<'a, str>>, rewriting simple_retr_ to avoid a clone, this kind of things. Would you be interested in a PR with these changes?

list and nlst commands always return an error

I'm using Ubuntu server 16.04.

Program:

extern crate ftp;

use ftp::openssl::ssl::*;

fn main() {
    let ftp_stream = ftp::FtpStream::connect("127.0.0.1:21").unwrap();
    let ctx = SslContext::new(SslMethod::Sslv23).unwrap();
    let ssl = Ssl::new(&ctx).unwrap();

    // Switch to the secure mode
    let mut ftp_stream = ftp_stream.into_secure(ssl).unwrap();

    ftp_stream.login("account", "passwd").unwrap();

    let v_list = ftp_stream.nlst(Some("/")).unwrap();

    let _ = ftp_stream.quit();
}

Error:
thread 'main' panicked at 'called Result::unwrap() on an Err value: InvalidResponse("error: could not parse reply code: invalid digit found in string")', /checkout/src/libcore/result.rs:860:4

I tried with other values or even None for list() and nlst() with no luck. cwd() and pwd() work.

data_command can only use the default SSL_CONTEXT

The function data_command always uses the default SSL_CONTEXT global to establish a secure connection. I missed this when I added the secure_with_ssl function. Perhaps a new field should be added to FtpStream to have it hold onto a reference (or perhaps even clone, for simplicity?) an SslContext so that we can reuse a user-provided instance instead of the default in all cases?

No way to implement ssl session reuse since #92

Hello !

Context

We were working on a fork of your repo to allow ssl session reuse and planning to offer a PR once stabilized, however there's no way to implement this since #92 as native_tls doesn't offer an interface to use sessions reuse. This is actually quite problematique as some servers require to use session reuse when in passive mode.

Thoughts around native_tls

Apparently the change to native_tls was made in #92 to make it easier to run on Windows and MacOs machine. As I use ArchLinux I have no idea how much easier it is, however I would like to point out that more than 90% of cloud based webservers run on linux. Since native_tls uses three different crates to implement ssl the configuration available is actually minimal when openssl provides a large set of parameters. This can be easily seen in the number of functions in the builders, 61 for SslConnectorBuilder versus 9 for TlsConnectorBuilder. As an example, I've added at the end how we can implement session reuse with openssl. Therefore I'm not sure the flexibility loss is worth it and would love to read more arguments againts it.

Next Steps

I see three possible solutions:

  1. Revert to openssl (I can provide a PR)
  2. Use two different feature flags secure-openssl and secure-native-tls that would basically use openssl or native_tls (I can provide a PR)
  3. This crate stays on native_tls and we work on a fork.

Solution 1

Pros

  • Easy to maintain
  • Allows more flexibility
  • Always use the same implementation of SSL (easier to debug)
  • We'll provide updates to add features when required as #95

Cons

  • Running on Microsoft & MacOs would be more complicated

Solution 2

Pros

  • Keep it easy on Microsoft & MacOs
  • Allows more flexibility
  • We'll provide updates to add features when required as #95

Cons

  • Maintainance is twice as hard

Solution 3

Pros

  • Easy to maintain
  • Keep it easy on Microsoft & MacOs

Cons

  • Lot of flexibility lost
  • We'll probably maintain only our fork

@mattnenterprise Please tell me which which solution you prefer 🙂

Thanks and have a nice day !

Implementing Session Reuse

Basically it ends up in replacing the function data_command (taken from version 3.0.1) from:

    /// Execute command which send data back in a separate stream
    #[cfg(feature = "secure")]
    fn data_command(&mut self, cmd: &str) -> Result<DataStream> {
        self.pasv()
            .and_then(|addr| self.write_str(cmd).map(|_| addr))
            .and_then(|addr| TcpStream::connect(addr).map_err(|e| FtpError::ConnectionError(e)))
            .and_then(|stream| {
                match self.ssl_cfg {
                    Some(ref ssl) => {
                        Ssl::new(ssl).unwrap().connect(stream)
                            .map(|stream| DataStream::Ssl(stream))
                            .map_err(|e| FtpError::SecureError(e.description().to_owned()))
                    },
                    None => Ok(DataStream::Tcp(stream))
                }
            })
    }

To:

    /// Execute command which send data back in a separate stream
    #[cfg(feature = "secure")]
    fn data_command(&mut self, cmd: &str) -> Result<DataStream> {
        self.pasv()
            .and_then(|addr| self.write_str(cmd).map(|_| addr))
            .and_then(|addr| TcpStream::connect(addr).map_err(|e| FtpError::ConnectionError(e)))
            .and_then(|stream| match self.ssl_cfg {
                Some(ref ssl) => {
                    let mut ssl = Ssl::new(ssl).unwrap();
                    match self.reader.get_ref() {
                        DataStream::Tcp(_) => {}
                        DataStream::Ssl(ssl_stream) => unsafe {
                            // SAFETY: ssl_stream was also using the context from self.ssl_cfg
                            ssl.set_session(ssl_stream.ssl().session().unwrap())
                                .map_err(|e| FtpError::SecureError(format!("{}", e)))?
                        },
                    }
                    ssl.connect(stream)
                        .map(|stream| DataStream::Ssl(stream))
                        .map_err(|e| FtpError::SecureError(format!("{}", e)))
                }
                None => Ok(DataStream::Tcp(stream)),
            })
    }

Put() function works but returns an error

Yet another weird error.
The put function works, the file gets updated, but it still crashes when it gets out, returning a 426 error code.

Edit: after reading a little bit on the internet, this can be an issue on my side only. I will test with another machine to see if this is it.

Type of host parameter

Hi

The host parameter for FTPStream::connect has the type &'static str. If I understand it correctly, this means that the FTP host that a user connects to needs to be known at compile time, right?

It would probably be a good idea to change that to either a &str if the value can be borrowed, or to a String if it needs to be owned.

Consider using Clippy on the crate

Everything is in the title.
Clippy

Inconvenience:

  • Clippy requires rust nightly to work.

As always, I will test this in a separate branch and commit a PR if I find that it works well.

help wanted: save all files by match pattern

i don't figure out how save all files by wildcard, example **.txt*

for example from documentation we can save one file:

let result = ftp_stream.retr("test.txt", |stream| {
  let mut file = File::create("test.txt").unwrap();
  let mut buf = [0; 2048];

  loop {
    match stream.read(&mut buf) {
      Ok(0) => break,
      Ok(n) => file.write_all(&buf[0..n]).unwrap(),
      Err(err) => return Err(err)
    };
  }

  Ok(())
});

Large download example

Would be nice to have an example of how to properly download/upload a large file, avoiding the control stream timeout (null command)... I'm relatively new to rust and just trying to get a grasp of this.

Upgrade openssl to 0.10. or replace it with rusttls

I have an issue when building a project that use ftp 'Unable to detect OpenSSL version

from here you can see that we need to upgrade openssl, I saw that we had the same issue before so why we don't move to rusttls which is newer than OpenSSL, and doesn't provide any support for TLS 1.1 and older, or any known-insecure algorithms. As a consequence, it's a lot simpler than OpenSSL, and is built purely in Rust, so doesn't require any magic to cross-compile.

Set Read/Write Timeout

As far as I can tell, currently there's no way to set the used TCPStream's read/write timeout. Doing so would be very handy if the server is unresponsive. If this isn't too hard to do, I'd love to contribute a Pull Request. What do you think?

CDUP returns 200, not 250

Hi.
According to the RFC, the CDUP command should return 200, not 250 (like the CWD command), so this line is incorrect.
Thanks to fix this issue.

Rustls Support

Cross compilation of openssl is virtually impossible

Whether native-tls or openssl is used does not change anything as for example cross compiling from Mac to Linux even with native-tls enabled would require the openssl libs.

But rustls is a pure Rust implementation, thus shall solve all these issues and beyond

Changing method names to match FTP commands

For instance: make_dir => mkdir, current_dir => pwd, change_dir => cwd (or cd?), change_dir_to_parent => cdup, retr => get, stor => put, etc.

For listing the contents of a folder (pull request #20 ), use list or ls?

Status of rust-ftp

Hi,

I wonder what the current status is given that there are a bunch of PRs being open that fixes some fairly important issues (such as version of openssl) is this crate still being supported or not?

Make pasv() use the host returned by the FTP server

Make pasv() use the host returned by the FTP server, rather than self.host (after which probably self.host wouldn't be needed anymore, and the constructor of FtpStream could just take a ToSocketAddrs directly).

And remove command_port too.

Update to alpha version of rust

Could you update to at least the version alpha of Rust, please? (I tried to build with the nightly version launched after the alpha release but couldn't)
I tried to fix the errors myself but I'm still to new to rust, thanks.

Update FTPS usage documentation

Seems FTPS doc is outdated

error: no method named `secure` found for type `ftp::FtpStream` in the current scope
 --> src/main.rs:9:42
  |
9 |     let (mut ftp_stream, _) = ftp_stream.secure();
  |                                          ^^^^^^

error: aborting due to previous error

My Cargo.toml

[package]
name = "test_app"
version = "0.1.0"
authors = ["Redacted"]

[dependencies]
ftp = { version = "*", features = ["secure"] 

Maintenance status

Hi @mattnenterprise

Would you be happy for people still use this crate ?

e.g. say if I would send a security related PR or issue would you be open to merge / address ?

Would you like them privately or raise an issue here ? Thanks

Cheers

[feature]: support byte offset when retrieving a file

It would nice to be able to resume partial downloads by specifying the bytes offset from which to read from.

Python's ftplib supports this and can be a good reference source:

FTP.retrbinary(cmd, callback, blocksize=8192, rest=None)

Retrieve a file in binary transfer mode. [...]
rest means the same thing as in the transfercmd() method.

FTP.transfercmd(cmd, rest=None)
[...]
If optional rest is given, a REST command is sent to the server, passing rest as an argument. rest is usually a byte offset into the requested file, telling the server to restart sending the file’s bytes at the requested offset, skipping over the initial bytes. .....

QUIT on drop

Now the user should issue QUIT manually and I think that should be automated. I suggest implement Drop trait and issue quit on drop and probably make the function private.

list() is waiting indefinitely

Currently having an issue to get a file listing from the FreeBSD ftp archive. The following code fails:

    let host = "ftp-archive.freebsd.org:21";
    let path = "/mirror/FreeBSD-Archive/old-releases/i386/2.2.8-RELEASE/packages/Latest";

    let mut ftp = ftp::FtpStream::connect(host).unwrap();
    ftp.login("anonymous", "").unwrap();
    let lst = ftp.list(Some(path)).unwrap();
    for i in lst {
        println!("LIST: {}", i);
    }

Using strace I can see that a new passive connection is opened and I can see that the file listing is received, but list() only returns after the server eventually replies with a "426 Data connection: Bad file descriptor.".

This is with rustc 1.15.0-nightly (ba872f270 2016-11-17) and ftp 2.0.0 on Linux.

Question: Do get/retr methods return BufRead

I've tried get and retr and neither seem to return a BufRead

I ask because i'm trying to use read_line https://doc.rust-lang.org/beta/std/io/trait.BufRead.html#method.read_line

    let mut ftp_stream = FtpStream::connect(("ftp.arin.net", 21)).unwrap();
    ftp_stream.login("anonymous", "").unwrap();
    println!("current dir: {}", ftp_stream.pwd().unwrap());

    ftp_stream.cwd("pub/stats/arin").unwrap();

    let stream = ftp_stream.get("delegated-arin-extended-latest").unwrap();

    let mut buf = Vec::new();

    let num_bytes = stream.read_line(&mut buf);
    println!("got line: {}", str::from_utf8(&buf).unwrap());

    let num_bytes = stream.read_line(&mut buf);
    println!("got line: {}", str::from_utf8(&buf).unwrap());
error[E0599]: no method named `read_line` found for type `std::io::BufReader<ftp::data_stream::DataStream>` in the current scope

Relicense under dual MIT/Apache-2.0

This issue was automatically generated. Feel free to close without ceremony if
you do not agree with re-licensing or if it is not possible for other reasons.
Respond to @cmr with any questions or concerns, or pop over to
#rust-offtopic on IRC to discuss.

You're receiving this because someone (perhaps the project maintainer)
published a crates.io package with the license as "MIT" xor "Apache-2.0" and
the repository field pointing here.

Why?

The MIT license requires reproducing countless copies of the same copyright
header with different names in the copyright field, for every MIT library in
use. The Apache license does not have this drawback. However, this is not the
primary motivation for me creating these issues. The Apache license also has
protections from patent trolls and an explicit contribution licensing clause.
However, the Apache license is incompatible with GPLv2. This is why Rust is
dual-licensed as MIT/Apache (the "primary" license being Apache, MIT only for
GPLv2 compat), and doing so would be wise for this project. This also makes
this crate suitable for inclusion and unrestricted sharing in the Rust
standard distribution and other projects using dual MIT/Apache, such as my
personal ulterior motive, the Robigalia project.

Some ask, "Does this really apply to binary redistributions? Does MIT really
require reproducing the whole thing?" I'm not a lawyer, and I can't give legal
advice, but some Google Android apps include open source attributions using
this interpretation. Others also agree with
it
.
But, again, the copyright notice redistribution is not the primary motivation
for the dual-licensing. It's stronger protections to licensees and better
interoperation with the wider Rust ecosystem.

How?

To do this, get explicit approval from each contributor of copyrightable work
(as not all contributions qualify for copyright) and then add the following to
your README:

## License

Licensed under either of
 * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
 * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.

and in your license headers, use the following boilerplate (based on that used in Rust):

// Copyright (c) 2016 rust-ftp developers
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

Be sure to add the relevant LICENSE-{MIT,APACHE} files. You can copy these
from the Rust repo for a plain-text
version.

And don't forget to update the license metadata in your Cargo.toml to:

license = "MIT/Apache-2.0"

I'll be going through projects which agree to be relicensed and have approval
by the necessary contributors and doing this changes, so feel free to leave
the heavy lifting to me!

Contributor checkoff

To agree to relicensing, comment with :

I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to chose either at their option

My scripts will pick this exact phrase up and check your checkbox, but I'll
come through and manually review this issue later as well.

ftp list function only returning a String

This one is only for ease of use:
It would be great if the list function return a Struct containing all of the information in the String.

I will do yet another pull request adding the code that I made for this, but I would like the openssl issue #69 to be resolved first because the list function doesn't work without this update.

Cargo audit failed

Cargo audit failed

cargo check
cargo audit
    Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
      Loaded 433 security advisories (from /home/balrog/.cargo/advisory-db)
    Updating crates.io index
    Scanning Cargo.lock for vulnerabilities (57 crate dependencies)
Crate:     time
Version:   0.1.44
Title:     Potential segfault in the time crate
Date:      2020-11-18
ID:        RUSTSEC-2020-0071
URL:       https://rustsec.org/advisories/RUSTSEC-2020-0071
Solution:  Upgrade to >=0.2.23
Dependency tree:
time 0.1.44
└── chrono 0.4.20
    └── ftp 3.0.1

error: 1 vulnerability found!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.