Mats

Mats

FTP with Erlang FTP client

Hi,
I’ve seen a couple of examples using the Erlang FTP client from Elixir and I have succesfully stepped through an example but now I’m stuck.
I keep getting an {:error, :epath} error although the file is there.

ftp_target_directory = ftp_target_directory |> String.to_charlist
ftp_host = Config.get(:importer, :ftp_host) |> String.to_charlist
ftp_user = Config.get(:importer, :ftp_user) |> String.to_charlist
ftp_pass = Config.get(:importer, :ftp_pass) |> String.to_charlist

Logger.info("Downloading files from #{inspect ftp_host} to #{inspect ftp_target_directory}")

:application.start :inets 
{:ok, pid} = :inets.start(:ftpc, host: ftp_host)
:ftp.user(pid, ftp_user, ftp_pass)
:ftp.pwd(pid)
:ftp.lcd(pid, ftp_target_directory)
:ftp.type(pid, :binary)
directory_list = get_listing(pid)
Enum.each(directory_list, fn directory ->
    :ftp.cd(pid, directory)
    files = get_listing(pid)
    Enum.each(files, fn file ->
      Logger.info("Downloading #{inspect file}")
      status = :ftp.recv(pid, file)
      Logger.info("Status #{inspect status}")
    end) 
    :ftp.cd(pid, '..')
end)
end

defp get_listing(pid) do
   {:ok, listing} = :ftp.nlist(pid)
   listing = listing |> String.Chars.List.to_string |> String.split("\r\n", trim: true)
   Enum.map(listing, fn item -> String.to_char_list(item) end)
end

I’ve put the client in verbose mode but I can’t see the client actually requesting the file, all I get is the error above.
I’m using the bitwalker/alpine-erlang:6.1 with elixir 1.4.

iex(testdownload@127.0.0.1)6> {:ok, pid} = :inets.start(:ftpc, host: ftp_host, verbose: true)
\n220 Welcome to the FTP Service."er (v. 7.2.0)
{:ok, #PID<0.647.0>}
iex(testdownload@127.0.0.1)7> :ftp.user(pid, ftp_user, ftp_pass)
“Sending: USER secret”
“Receiving: 331 Password required for secret”
“Sending: PASS secretpass”
“Receiving: 230 Logon OK. Proceed.”
:ok
iex(testdownload@127.0.0.1)8> :ftp.pwd(pid)
“Sending: PWD”
“Receiving: 257 “/” is current directory.”
{:ok, ‘/’}
iex(testdownload@127.0.0.1)9> :ftp.lcd(pid, ftp_target_directory)
:ok
iex(testdownload@127.0.0.1)10> :ftp.type(pid, :binary)
“Sending: TYPE I”
“Receiving: 200 Type set to I”
:ok
iex(testdownload@127.0.0.1)11> :ftp.cd(pid, ‘files’)
“Sending: CWD files”
“Receiving: 250 CWD command successful.”
:ok
iex(testdownload@127.0.0.1)14> :ftp.nlist(pid)
“Sending: PASV”
“Receiving: 227 Entering Passive Mode (147,14,4,15,156,195)”
“Sending: NLST”
“Receiving: 150 Opening data connection for file list.”
“Receiving: 226 Transfer complete.”
{:ok, ‘file.csv\r\n’}
iex(testdownload@127.0.0.1)12> :ftp.recv(pid, ‘file.csv’)
{:error, :epath}

Can anyone tell me what I’m doing wrong? :slight_smile:

Most Liked

NobbZ

NobbZ

Please try to use :ftp.recv/3 and provide a path and filename that you are definitevely allowed to write. I’m not quite sure where BEAM will try to create the file if the third parameter is missing.

Mats

Mats

Just a quick follow up. It was indeed file system rights that were my problem.
I was building the release with a docker mix plugin that used the USER directive in the Dockerfile.
Everything works as expected now.

Thanks for your help!

jnmandal

jnmandal

According to the erlang docs, :epath means: “No such file or directory, or directory already exists, or permission denied.”

The error codes are listed at the bottom of this page: http://erlang.org/documentation/doc-5.2/lib/inets-3.0/doc/html/ftp.html

NobbZ

NobbZ

The error you get is described as foolows:

epath
No such file or directory, or directory already exists, or permission denied.

So have you checked with another FTP client if you can download the file using that one? Also put it in verbose and check if it uses relative path to current dir or full path for RECV, change your code accordingly then.

Mats

Mats

Hi,
Thanks for your response.
I’ve successfully downloaded the file with the linux ftp client.
The problem with verbose mode is that when I try recv I get the error right away. It is as if the client doesn’t even issue the command.
I’m completely baffled. :slight_smile:

Where Next?

Popular in Questions Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
pgiesin
This should be a simple problem but I just can’t seem to figure it out. I have a standalone Elixir app that won’t find the database. Dep...
New
Werner
Hi, I’m using Ubuntu 18.04 and after updating to OTP-24.0 yesterday i have this warning when I run “mix local.hex”: 14:57:30.512 [warn] ...
New
Kagamiiiii
Student &amp; New to elixir. Nice language. I want to convert a english character, e.g. “a”, which is stored in a variable, to it’s asci...
New
Phillipp
Hey, I have a NanoPi-M3 and try to install Elixir on their Ubuntu image. I followed the Raspberry Pi installation instructions from the ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
hpopp
To simplify some tasks at work, I wrote and published this package yesterday. It’s a simple macro that enables Access behaviour on struct...
New

Other popular topics Top

belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
AstonJ
by Lance Halvorsen Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
460 27162 124
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

We're in Beta

About us Mission Statement