Back to home page
Back to previous page

Author: R. Koucha
Last update: 07-Jul-2011

SourceForge.net Logo
Support This Project

Remote Operations On Files

(ROOF)


Introduction
Download
Installation
Installation from the sources with cmake
Installation from the sources with a custom script
Installation from the DEB binary package
Installation from the RPM binary package
Packaging
Generation of a DEB binary package
Generation of a RPM binary package
Generation of a ZIP tar file
Client program
Usage
Options
Commands
Example
API
Services
roof_new()
roof_delete()
roof_open_ctrl()
roof_open_ctrl2()
roof_open_ctrl3()
roof_close_ctrl()
roof_get_reply()
roof_login()
roof_login2()
roof_type()
roof_rm()
roof_rmdir()
roof_mkdir()
roof_mv()
roof_syst()
roof_cwd()
roof_cdup()
roof_pwd()
roof_list()
roof_nlst()
roof_retr()
roof_retr2()
roof_retr3()
roof_stor()
roof_stor2()
roof_stor3()
roof_set_debug_level()
roof_get_debug_level()
roof_help()
roof_site()
roof_set_data_mode()
roof_set_routing()
roof_noop()
roof_quit()
Return value
Errors
Examples
ftpfs
Usage
Options
Example
ftping
Usage
Options
Example
About the author
Related links



Introduction

roof stands for Remote Operations On Files.  It is a FTP related set of services compliant with RFC959. It comes with:
Its source code is described here.


Download

ROOF can be downloaded from sourceforge in one of the following three ways:

Concerning the source package, you can also use a CVS client and enter the following command under a shell like bash:

$ export CVSROOT=:pserver:anonymous@roof.cvs.sourceforge.net:/cvsroot/roof
$ cvs checkout roof

You will normally see a new local directory called 'roof' in which are located the downloaded source files. The subtree looks like:

roof source tree

The include directory contains the file roof.h in which are defined the services and data structures of the API.
The lib directory contains the implementation of the library libroof.so which is destined to be dynamically linked to the user program.
The man directory contains the on-line manuals.
The client directory contains an example of FTP client based on the API.
The fs directory contains a file system manager called ftpfs which mounts a remote file system through the FTP protocol.


Installation

Installation from the sources with cmake

The installation from the sources supposes that cmake is installed on your Linux machine.

Unpack the tar compressed file roof-xxx.tgz into a directory. This will create a sub-directory called roof-xxx with the source files of the program:

$ tar xvfz roof-xxx.tgz

Go into the newly created directory:

$ cd roof-xxx

While building the makefiles, you can choose where the files will be installed with the environment variable CMAKE_INSTALL_PREFIX. If not defined, the installation defaults to /usr/local.

$ cmake . -DCMAKE_INSTALL_PREFIX=<path_of_installation>

Then the build is triggered by invoking make:

$ make

And the installation is done specifying the install target:

$ make install

It is possible to trigger a cleanup of the built objects with the clean target:

$ make clean

If your PATH variable is correctly set, ROOF's help can be displayed:

$ roof --help

If your MANPATH variable is correctly set, ROOF's online manual can be displayed:

$ man 1 roof
$ man 3 roof
$ man 7 roof

Installation from the sources with a custom script

The installation from the sources supposes that cmake is installed on your Linux machine.

Unpack the tar compressed file roof-xxx.tgz into a directory. This will create a sub-directory called roof-xxx with the source files of the program:

$ tar xvfz roof-xxx.tgz

Go into the newly created directory:

$ cd roof-xxx

Make sure the file roof_install.sh has the execute permission:

$ chmod +x roof_install.sh

Launch the script roof_install.sh to get the help:

$ ./roof_install.sh -h

Usage: roof_install.sh [-d install_root_dir] [-P DEB | RPM] [-B] [-I] [-A] [-h]

             -d : Installation directory (default: /usr/local)
             -P : Generate a DEB or RPM package
             -B : Build the software
             -I : Install the software
             -A : Generate an archive of the software (sources)
             -h : this help

Under root identity, launch the installation by passing '-I' and optionnaly '-d' to specify an installation directory different than /usr/local. For example, for an installation in /usr/local, type:

$ sudo ./roof_install.sh -I

For an installation in '/usr', type;

$ sudo ./roof_install.sh -I -d /usr

If your PATH variable is correctly set, ROOF's help can be displayed:

$ roof --help

If your MANPATH variable is correctly set, ROOF's online manual can be displayed:

$ man 1 roof
$ man 3 roof
$ man 7 roof

Installation from the DEB binary package

The files are installed via the command:

$ sudo dpkg -i roof-xxx.deb

Installation from the RPM binary package

The files are installed via the command:

$ sudo rpm -i roof-xxx.rpm


Packaging

The packaging process supposes that cmake is installed on your Linux machine.

Generation of a DEB binary package

Unpack the tar compressed file roof-xxx.tgz into a directory. This will create a sub-directory called roof-xxx with the source files of the program:

$ tar xvfz roof-xxx.tgz

Go into the newly created directory:

$ cd roof-xxx

Make sure the file roof_install.sh has the execute permission:

$ chmod +x roof_install.sh

Launch the script roof_install.sh to get the help:

$ ./roof_install.sh -h

Usage: roof_install.sh [-d install_root_dir] [-P DEB | RPM] [-B] [-I] [-A] [-h]

             -d : Installation directory (default: /usr/local)
             -P : Generate a DEB or RPM package
             -B : Build the software
             -I : Install the software
             -A : Generate an archive of the software (sources)
             -h : this help

Under root identity, launch the installation by passing '-P DEB' and optionnaly '-d' to specify an installation directory different than /usr/local. For example, for a package which will be installed in /usr/local, type:

$ sudo ./roof_install.sh -P DEB

For an installation in /usr, type;

$ sudo ./roof_install.sh -P DEB -d /usr

Generation of a RPM binary package

Unpack the tar compressed file roof-xxx.tgz into a directory. This will create a sub-directory called roof-xxx with the source files of the program:

$ tar xvfz roof-xxx.tgz

Go into the newly created directory:

$ cd roof-xxx

Make sure the file roof_install.sh has the execute permission:

$ chmod +x roof_install.sh

Launch the script roof_install.sh to get the help:

$ ./roof_install.sh -h

Usage: roof_install.sh [-d install_root_dir] [-P DEB | RPM] [-B] [-I] [-A] [-h]

             -d : Installation directory (default: /usr/local)
             -P : Generate a DEB or RPM package
             -B : Build the software
             -I : Install the software
             -A : Generate an archive of the software (sources)
             -h : this help

Under root identity, launch the installation by passing '-P RPM' and optionnaly '-d' to specify an installation directory different than /usr/local. For example, for a package which will be installed in /usr/local, type:

$ sudo ./roof_install.sh -P RPM

For an installation in /usr, type;

$ sudo ./roof_install.sh -P RPM -d /usr

Generation of a ZIP tar file

Unpack the tar compressed file roof-xxx.tgz into a directory. This will create a sub-directory called roof-xxx with the source files of the program:

$ tar xvfz roof-xxx.tgz

Go into the newly created directory:

$ cd roof-xxx

Make sure the file roof_install.sh has the execute permission:

$ chmod +x roof_install.sh

Launch the script roof_install.sh to get the help:

$ ./roof_install.sh -h

Usage: roof_install.sh [-d install_root_dir] [-P DEB | RPM] [-B] [-I] [-A] [-h]

             -d : Installation directory (default: /usr/local)
             -P : Generate a DEB or RPM package
             -B : Build the software
             -I : Install the software
             -A : Generate an archive of the software (sources)
             -h : this help

Under root identity, launch the installation by passing '-A':

$ sudo ./roof_install.sh -A



Client program

roof is a FTP client compliant with RFC959.

Usage

roof [ -p port ] [ -H hostname ] [ -L login_name ] [ -P password ] [ -A account ] [ -b size ] [ -d debug_level ] [ -hV ]

Options

The options are:

       -p port
       --port=port
Server’s port number (default is 21).

       -H hostname
       --host=hostname
Server’s host name. The name can be an ascii name or a dotted IP address  (default  is  local host loop back 127.0.0.1).

       -L login_name
       --login=login_name
Login name for identification.

       -P password
       --passwd=password
Password for identification.

       -A account
       --acct=account
           Account information for identification.

       -b size
       --bufsz=size
           Set I/O buffer to size bytes (default 4096)

       -d debug_level
       --debug=debug_level
Set  the  debug  level to debug_level.  The value is a positive integer value. The bigger the value, the more debug traces will appear (0 unsets the debug mode).  This is useful to  catch the error messages from the server when a command fails.

       -h
       --help
Display the help of the command (subset of this man page).

       -V
       --version
Display the version of the software.

Commands

roof accepts a command line with the format:

cmd param1 param2 param3...

where  cmd  and  paramX  are strings that can be enclosed with double quotes to take in account blank characters and may contain the following control characters:

\  Space
\t Horizontal tabulation
\a Bell
\b Backspace
\n New line
\r Carriage return
\f Form feed
\v Vertical tabulation
\" Double quote
\\ Backslash

roof accepts the following commands:

? [ cmd ]
Display  the  list  of available commands. If followed by a command name cmd, it displays the help of this command. This is the same command as help.

       ascii Shortcut for ’type A N’ to set ASCII transfer type.

       bin   Shortcut for ’type I’ to set image (binary) transfer type.

cd dir
Change current directory to dir.

cnx [-H host] [-p port] [-L login] [-P password] [-A account]
Connect to the remote host. If no parameters or part of them are passed, the missing  one are  respectively  taken from the previous call to cnx and the options passed to the program (-H, -p, -L, -P and -A).  Once the connection is established, the prompt is  changed to reflect the remote host information.

dbg
Display the current debug level.

dbg level
Set the current debug level to level.

dcnx
Disconnect from the remote host.

dir
Same as ls command.

exit
Quit the program (Same effect as CTRL D or quit command).

get src_file [ dst_file ]
Transfer src_file from remote host into dst_file (default, basename of src_file in current local directory).

help [ cmd ]
Display  the list of available commands. If followed by a command name cmd, it displays the help of this command. This is the same command as ?.  When connected, the  help  is requested  to the remote server. When disconnected, the help is requested locally. When connected, use ’!help’ or ’!?’ to request the help locally.

ls [ -l ] [ dir ]
List the content of the remote directory dir (current directory by default). If -l option is  passed,  details about the size, right accesses and access times will be displayed if the server supports it.

mget file1 [ file2... ]
Transfer all the fileX from remote host to local host.

mkdir dir
Make the directory dir on the remote host.

mput file1 [ file2... ]
Transfer all the fileX from local host to remote host.

mv src_file dst_file
Rename the file src_file into dst_file on the remote host.

passive [on|off]
Set Passive (on) or Active (off) mode (display the the current mode if no parameters)

put src_file [ dst_file ]
Transfer the file src_file to the remote host into dst_file (by default, the same name is kept).      

pwd
Print the name of the current working directory.

quit
Quit the program (Same effect as CTRL D or exit command).

rm file_name
Remove the file file_name on the remote host.

rmdir dir_name
Remove the directory dir_name on the remote host.

site cmd [par1 par2...]
Launch the custom command cmd on the remote server.

       type [A|E [N|T|C]] [I] [L byte_size ]
Set  the transfer and format types (A = ASCII, E = EBCDIC, I = Image (binary), L = Local byte size associated with a size in bytes, N = Non print (default), T  =  Telnet  format effector, C = carriage control). There are two widely used forms for this commands: ’type A N’ for ASCII type and ’type I’ for binary type. Hence, the shortcuts ascii and bin.

up   Go to the upper directory.

!cmd
Run the command cmd locally if supported.

Examples

The  following  example  shows  a FTP connection to the default port 21 on a host called ’remote’ with the login name ’foo’ and password ’bar’.  A 'ls -l' command is launched  followed  by  a  'get'. Then  we  disconnect  and  reconnect  to the same host to make a directory called ’images’ before exiting from the program.

$ roof
ftp> cnx -H remote -L foo -P bar
Connection successful
Remote operating system is ’UNIX’
foo@remote:21> ls -l
drwx------  2 foo grp    4096 May  4  2007 VIDEO_WORK
drwx------  3 foo grp    4096 Oct 21 19:03 VIDEO_PERSO
-rwx------  1 foo grp    1718 Oct 28 22:58 qwerty.txt
-rwx------  1 foo grp   63328 Oct 27 19:49 azerty.txt
-rwx------  1 foo grp     198 Apr  9  2007 backup.sh
drwx------  8 foo grp    4096 Oct 30 23:41 cxoffice
drwx------  3 foo grp    4096 Nov  8 08:16 dvd_data
drwx------  4 foo grp    4096 May 31  2007 freeplayer
drwx------ 16 foo grp    4096 Apr  2  2007 folder
-rw-r--r--  1 foo grp  255999 Nov 30 07:57 saved.odt
foo@remote:21> get azerty.txt
’azerty.txt’ transfered successfully (63328 bytes)
foo@remote:21> dcnx
Connection closed
ftp> cnx
Connection successful
Remote operating system is ’UNIX’
foo@remote:21> mkdir images
’images’ made successfully
foo@remote:21> exit
End of session
$

The  following  example  shows a FTP connection to the port 2000 on a host called ’remote’ with the login name ’foo’ and password ’bar’.  A ls command is launched followed by a ls on the file named  "filename  with blanks" which contains blank characters. For the sake of the example, we use two different methods to match the spaces: the double  quotes  and  the  control  sequence. Then we disconnect.

$ roof -H remote -L foo -P bar -p 2000
ftp> cnx

Connection successful

Remote operating system is ’UNIX’

foo@remote:21> ls -l

VIDEO_WORK
VIDEO_PERSO
qwerty.txt

azerty.txt

backup.sh

cxoffice

filename with blanks

dvd_data

foo@remote:21> ls "filename "with\ blanks

filename with blanks

foo@remote:21> dcnx

Connection closed

ftp> exit

End of session

$



API

Services

The API is composed with the following functions:

#include <roof.h>

roof_ctx_t *roof_new(unsigned int timeout_ms, char *iobuf, unsigned int l_iobuf, void *ctx);
void roof_delete(roof_ctx_t *pContext);

int roof_open_ctrl(roof_ctx_t *pContext, const char *host, unsigned int port);
int roof_open_ctrl2(roof_ctx_t *pContext, const char *host, unsigned int port, unsigned int timeout);

int roof_open_ctrl3(roof_ctx_t *pContext, const char *host, unsigned int port, unsigned int timeout, const char **banner);
int roof_close_ctrl(roof_ctx_t *pContext);

int roof_get_reply(roof_ctx_t *pContext, const char **reply);

int roof_login(roof_ctx_t *pContext, const char *login, const char *passwd, const char *account);
int roof_login2(roof_ctx_t *pContext, const char *login, const char *passwd, const char *account, const char **banner);

int roof_type(roof_ctx_t *pContext, unsigned char type, unsigned char form);

int roof_rm(roof_ctx_t *pContext, const char *filename);

int roof_rmdir(roof_ctx_t *pContext, const char *dir_name);

int roof_mkdir(roof_ctx_t *pContext, const char *dir_name);

int roof_mv(roof_ctx_t *pContext, const char *src, const char *dst);

int roof_syst(roof_ctx_t *pContext, const char **syst);

int roof_cwd(roof_ctx_t *pContext, const char *dir_name);

int roof_cdup(roof_ctx_t *pContext);

int roof_pwd(roof_ctx_t *pContext, const char **dir_name);

int roof_list(roof_ctx_t *pContext, const char *dir_name, int (*write_cbk)(roof_ctx_t *ctx, const char *buf, unsigned int lbuf));

int roof_nlst(roof_ctx_t *pContext, const char *dir_name, int (*write_cbk)(roof_ctx_t *ctx, const char *buf, unsigned int lbuf));

int roof_retr(roof_ctx_t *pContext, const char *src, const char *dst, unsigned int *nb_bytes, unsigned char type, unsigned char form);
int roof_retr2(roof_ctx_t *pContext, const char *src, const char *dst, unsigned long long *nb_bytes, unsigned char type, unsigned char form, unsigned int progress, int (*progress_cbk)(roof_ctx_t *ctx, unsigned int progress));
int roof_retr3(roof_ctx_t *pContext, const char *src, int (*receive)(roof_ctx_t *ctx, char *data, unsigned int nb, void *private), void *private, unsigned long long *nb_bytes, unsigned char type, unsigned char form, unsigned int progress, int (*progress_cbk)(roof_ctx_t *ctx, unsigned int progress));

int roof_stor(roof_ctx_t *pContext, const char *src, const char *dst, unsigned int *nb_bytes, unsigned char type, unsigned char form);
int roof_stor2(roof_ctx_t *pContext, const char *src, const char *dst, unsigned long long *nb_bytes, unsigned char type, unsigned char form, unsigned int progress, int (*progress_cbk)(roof_ctx_t *ctx, unsigned int progress));
int roof_stor3(roof_ctx_t *pContext, int (*snd)(roof_ctx_t *ctx, int fd, unsigned long long off, void *priv), const char *dst, void *priv, unsigned long long *nb_bytes, unsigned char type, unsigned char form, unsigned int progress, int (*progress_cbk)(roof_ctx_t *ctx, unsigned int progress));

void roof_set_debug_level(roof_ctx_t *pContext, int level, FILE *out);
int roof_get_debug_level(roof_ctx_t *pContext);

int roof_help(roof_ctx_t *pContext, const char **hlp, const char *format, ...);

int roof_site(roof_ctx_t *pContext, const char **rsp, const char *format, ...);

int roof_set_data_mode(roof_ctx_t *pContext, int mode);

int roof_set_routing(roof_ctx_t *pContext, int routing);

int roof_noop(roof_ctx_t *pContext);

int roof_quit(roof_ctx_t *pContext);


roof_new

The function roof_new() gets a context in the ROOF API. It is passed the timeout timeout_ms in milliseconds  to  wait  for  messages  from  the server (0 specifies infinite wait), an Input/Output buffer iobuf, the length l_iobuf of this buffer and a pointer on an arbitrary user context. If the parameter iobuf is NULL, the buffer is allocated internally by the service with a size of l_iobuf if not 0 or with a default  size. The returned  value is a pointer on the context identifier of type roof_ctx_t.  The context identifier is passed to the other functions of the API. The type of this context is:

           typedef struct
           {
             void *ctx;     // User context
           } roof_ctx_t;

The field ctx is filled with the value of the last parameter passed to roof_new().

roof_delete

The function roof_delete() is passed a pointer on a context identifier pContext to deallocate. It is typically called when the application does not need to use the ROOF API any more.

roof_open_ctrl

The function roof_open_ctrl() opens the control connection with a remote host on the TCP port.  The host parameter is a string containing either the DNS name or the IP address in dotted notation of the remote host.  Normally a FTP server listens on TCP port 21 so the caller can pass the constant ROOF_DEF_PORT.  The return value is a socket descriptor on the control connection. This socket descriptor is typically used in a call to select(3) to get spontaneous messages from the server. Typically, those messages can be timeout notifications.  It is important for the user to catch those spontaneous messages because a disconnected server will make the following function calls to the ROOF API fail as the connection is no more valid. In this situation, the user should call  roof_open_ctrl()  again  to set  up  a  new control connection and roof_login() to open a user session. To get the messages from the server, the user is supposed to call roof_get_reply().  If the remote server is out of service, this function may last after several  minutes  to  report  a  connection error  depending  on  the  configuration  of the underlying stack. To have a better control on the connection time, it is advised to use roof_open_ctrl2().

roof_open_ctrl2

The function roof_open_ctrl2() behaves the same as roof_open_ctrl() except that it is passed the additional timeout argument which specifies  the  maximum  time  in  milliseconds  to wait for a server’s connection response. If set to 0, this function has exactly the same behaviour as roof_open_ctrl() since the timeout defaults to the unspecified value of the underlying stack which may be  several  minutes on some systems.

roof_open_ctrl3

The  function  roof_open_ctrl3()  behaves the same as roof_open_ctrl2() but it is passed an additional argument banner to receive the welcome banner sent by the server upon the control connection establishment. If the banner is not needed, the parameter can be set to NULL. The banner is a standard FTP reply compliant with the  format of  the strings received through roof_get_reply().  Be aware of the fact that as the returned pointer is an address in the internal I/O buffer, the referenced data are no longer valid after a call to any other ROOF service. The caller is supposed to copy the data somewhere else if necessary.

roof_close_ctrl

The  function  roof_close_ctrl()  closes  the  control connection with the remote host. It is the counter part of roof_open_ctrl().  It is typically  called  before  ending  a  session  with  the server.  It is not mandatory if the user calls roof_delete() to deallocate the session’s context.

roof_get_reply

The function roof_get_reply() is called to receive a spontaneous message on the  control  connection from the server. It is typically called after a select(3) has indicated that data are available on the control socket. The function is passed the address of a pointer. If OK,  the  pointer will be assigned with an address in the I/O buffer of the context pointing on the message sent by the server. The format of the message is compliant with RFC 959. Its format is a number of  three digits  followed  by an arbitrary string. For exampe, if the server closes the connection because of an internal timeout, it may send a message like the following:

421 No Transfer Timeout (45 seconds): closing control connection.

The signification of the beginning digits in the message is described in RFC  959.  The  function will  block  at  most  the timeout in milliseconds passed to roof_new().  Of course, if the value passed was 0, the function will wait indefinitely if the server does not send any message.  Be aware of the fact that as the returned pointer is an address in the I/O buffer, the data it references are no more valid after a call to any other ROOF service. The caller is supposed to copy the data somewhere else if necessary.

roof_login

The function roof_login() opens a user session onto the remote host. It is passed the login name login,  the  password  passwd and the account information account.  If the remote host accepts to open sessions without login name, password or account information, the  corresponding  parameters can be set to NULL. Typically, the account information are not needed by most of the FTP servers. This function is typically called right after roof_open_ctrl().

roof_login2

The function roof_login2() behaves the same as roof_login() but it is passed an additional argument banner to receive the welcome banner sent by the  server  upon  the connection. If  the  banner  is  not  needed,  the parameter can be set to NULL. The banner is a standard FTP reply compliant with the format of the strings received through roof_get_reply().  Be aware of the fact that as the returned pointer is an address in the internal I/O buffer, the referenced data are no longer valid after a call to any other ROOF service. The caller is supposed to copy the data somewhere else if necessary.

roof_type

The function roof_type() sets the type of data to be  transfered.  The  type  parameter  can  be either the character ’A’ for ASCII or ’E’ for EBCDIC or ’I’ for Image (binary format) or ’L’ for local byte size. Types ’A’ and ’E’ may come along with form set to ’N’ for non  print,  ’T’  for telnet  format  effector or ’C’ for carriage control (ASA).  Type ’I’ is standalone and so, does not accept any code.  Type ’L’ must come along with form set to the  size  of  the  bytes.  This value  must  be  a numerical value from 0 to 255.  If not used, form must be set to 0. When type and form are set to 0, the function behaves as if it received ’I’ for type.

roof_rm

The  function roof_rm() removes a file on the remote server. It is passed the file name to remove in the parameter filename.

roof_rmdir

The function roof_rmdir() removes a directory on the remote server. It is  passed  the  directory name  to  remove  in the parameter dir_name.  On most server this command will fail if the target directory is not empty.

roof_mkdir

The function roof_mkdir() makes a new directory on the remote server. It is passed the  directory name to create in the parameter dir_name.

roof_mv

The function roof_mv() renames a file or directory. The source name is passed in src and the destination in dst.

roof_syst

The function roof_syst() asks the server for its type. Most of the time, the operating system the server  is  running  on will be returned into syst.  This pointer is assigned with the address in the context’s I/O buffer of the string sent back by the server as response. The format  of  this string  is  described in RFC 959 (SYST command). For example, on some system, the returned string is:

215 UNIX Type: L8 (Linux)

The type of the system is the first word right after the first three digits.  As the returned address points into the I/O buffer, the pointed data are no more available after a new call  to the library. A copy must be done by the caller if necessary.

roof_cwd

The function roof_cwd() changes the current working directory  on  the  server  to  the  pathname dir_name.

roof_cdup

The function roof_cdup() changes the current working directory to the upper one on the server. If the target server has not a Linux tree-like file system, this command may fail.

roof_pwd

The function roof_pwd() returns the name of the current working  directory  on  the  server.  The parameter dir_name is assigned with the address of the response sent by the server. The format of this string begins with three digits and then it is followed by the name of  the  directory.  For example, the response can be something like:

257 "/home/foobar" is current directory.

As the returned address points into the I/O buffer, the pointed data are no more available after a new call to the library. A copy must be done by the caller if necessary.

roof_list

The  function  roof_list()  displays  the  detailed  list of files in the remote directory named dir_name.  If dir_name is NULL, the  function  lists  the  remote  current  directory  (the  one returned  by  roof_pwd()). The  meaning  of  "detailed  list"  depends  on the remote server’s behaviour. On Linux systems, this is equivalent to the result of "ls -la" shell call. That is to say  the  names  of the files are displayed along with the access rights, access times, sizes... The display is done through an invocation of the call back write_cbk which is  passed  the  ROOF context ctx, a pointer on the buffer containing the list of files and the length of the data in the buffer. The callback may be invoked several times depending on the amount of data to  return and  the size of the I/O buffer set up at context allocation time with roof_new(). The callback must return the number of "written" bytes which must be equal to the parameter lbuf to  be  considered  successful  and  any  other  value if error. In the latter situation, errno must be set accordingly. Be aware of the fact that the buffer passed to the callback is not NUL  terminated: the number of bytes in the buffer is lbuf.

roof_nlst

The  function roof_nlst() displays  the  short  list  of  files  in the remote directory named dir_name.  If dir_name is NULL, the  function  lists  the  remote  current  directory  (the  one returned  by roof_pwd()).  The meaning of "short list" depends on the remote server’s behaviour. On Linux systems, this is equivalent to the result of "ls -a" shell call. That is  to  say  only the names of the files are displayed. The display is done through an invocation of the call back write_cbk which is passed an arbitary pointer ctx supposed to contain some user  information  to set  up  the display, a pointer on the buffer containing the list of files and the length of the data in the buffer. The callback may be invoked several times depending on the amount of data to return  and  the  size of the I/O buffer set up at context allocation time with roof_new().  The callback must return the number of "written" bytes which must be equal to the parameter lbuf  to be  considered  successful  and any other value if error. In the latter situation, errno must be set accordingly. Be aware of the fact that the buffer passed to the callback is not  NUL  terminated: the number of bytes in the buffer is lbuf.

roof_retr

The  function  roof_retr() uploads the remote file src into the local file named dst.  If dst is NULL, the basename of the source file is used for the name of the destination file (i.e. the source file is transfered in the current local directory).  The  number  of read  bytes is returned in nb_bytes parameter. The parameters type and form are respectively the transfer type and format: cf.  roof_type() service.

roof_retr2

The  function  roof_retr2() behaves the same as roof_retr() but it takes two additionnal arguments to make the library invoke the  progress_cbk  callback  at  most every  progress bytes transfered. This can be useful for graphical applications to animate a progress bar. This function can also handle large files (more than 2 GB) as the parameter nb_bytes is an "unsigned long long".

roof_retr3

The function roof_retr3() behaves the same as roof_retr2() but instead of a destination file, the  content  of the  file  is  passed  to  the  receive callback. The callback is passed as parameters the roof context ctx, a buffer data of bytes from the source file, the number of bytes nb in the buffer and an arbitrary context  private  passed  by the caller through the private parameter.  receive is called as many times  as it is necessary to report the number of bytes from the source file.  receive must return the number of handled bytes. If the return value is not the same as nb then it is considered as an error.

roof_stor

The function roof_stor() downloads the local file src into the remote file named dst.  If dst is NULL, the  name of the source file is used for the name of the destination file. The number of read bytes is returned in nb_bytes parameter. The parameters type and form are respectively  the transfer type and format: cf.  roof_type() service.

roof_stor2

The function roof_stor2() behaves the same as roof_stor() but it takes  two  additionnal  arguments  to  make  the library invoke the progress_cbk callback at most every progress bytes transfered. This can be useful for graphical applications  to animate a progress bar. This function can also handle large files (more than 2 GB) as the parameter nb_bytes is an "unsigned long long".

roof_stor3

The function roof_stor3() behaves the same as roof_stor2() but instead of a source file, the  callback snd  is  invoked. The callback is passed as parameters the roof context ctx, the file descriptor fd of the data connection where to put the source data, the offset off in the source stream and an arbitrary context  priv  passed  by the caller through the priv parameter.  snd is called as many times as it is necessary to get the number of bytes from the source stream. It must  return  the  number  of  handled bytes  (0 means EOF). At each call, off is incremented by the number of bytes returned by the previous call. So, it is equal to 0 at the first call.  snd returns a negative errno in case of error.

roof_set_debug_level

The  function roof_set_debug_level() sets the debug level to level.  It is passed an output stream out where to redirect the debug messages. If NULL, it defaults to the standard output error (stderr).  The accepted  values  are  positive  values.  0 means  "no debug".  This service is very useful to narrow down communication problems with the server as all the responses coming from the server are displayed. The higher the value of the debug level, the more debug information are displayed.

roof_get_debug_level

The function roof_get_debug_level() returns the current value of the debug level.

roof_help

The  function  roof_help()  sends  a  HELP  command to the remote server and make the answer pointed by hlp.  The format is "printf-like". It may be NULL to request a global help or it describes the command for which the help is requested.

roof_site

The  function  roof_site()  sends a SITE (i.e. custom) command to the remote server and make the answer pointed by rsp.  The format is "printf-like". It may be NULL or it describes the command to launch.

roof_set_data_mode

The function roof_set_data_mode() sets the data connection mode to ROOF_PASSIVE for passive mode or to ROOF_ACTIVE for active mode. In  passive mode,  the  data  connection is done by the client (default behaviour).  In active mode, the data connection is done by the server. The passive mode is advised when firewalls are on the data paths. This service is typically  called  before  the  services involving a data connection: roof_list(), roof_nlst(), roof_retr(), roof_retr2(), roof_stor()...

roof_set_routing

The function roof_set_routing() is passed ROOF_GATEWAY to enable the routing of the network packets through a gateway (default behaviour) and passed ROOF_NO_GATEWAY to disable  the  routing  of  the network packets through a gateway. The latter is typically used to avoid the redirection of the network packets to a default destination when the target server is not directly connected to the local host (i.e. the routing table would specify a default gateway address to redirect the network packets).

roof_noop

The  function  roof_noop()  does  not trigger any action from the remote host except making it send an acknowlegment message. It may be useful to maintain an activity on the connection to avoid  a  disconnection timeout. It may also be used to check the connection state before any other action.

roof_quit

The function roof_quit() properly closes the connection with the server. It is typically called before roof_close_ctrl() or roof_delete().

Return value

The function roof_new() returns a pointer on the context if OK and NULL on error.

The function roof_open_ctrl() and roof_open_ctrl2() return the socket descriptor of the opened control connection or -1 if error.

The  functions  roof_close_ctrl()roof_get_reply(), roof_login(), roof_type(), roof_rm(), roof_rmdir(), roof_mkdir(), roof_mv(), roof_syst(), roof_cwd(), roof_quit(), roof_cdup(), roof_pwd(), roof_list(), roof_nlst(), roof_retr(), roof_retr2(), roof_retr3(), roof_stor(), roof_stor2(), roof_stor3(), roof_help()roof_site(), roof_set_data_mode(), roof_noop() and roof_set_routing() return 0 if OK and -1 on error.

The function roof_set_debug_level() returns the previous debug level (>= 0) and -1 on error.

The function roof_get_debug_level() returns the debug level if OK and -1 on error.

Errors

EIO Input/Output error.

ENOSPC No more free contexts or I/O buffer too short to receives messages from the server.

EINVAL Missing, invalid or unexpected parameter.

ETIMEDOUT Timeout during the communication with the server.

EBUSY Trying to open a control connection in a session where it is already opened or not closed properly.

EOPNOTSUPP Command not supported on local host.

EACCES Trying to launch a remote command in disconnected state.

EOVERFLOW Size of file too big for the interface.

EINPROGRESS The connection could not be established before specified timeout.

EALREADY The connection could not be established before specified timeout.

Example

The  following  example  shows  a session with a remote server to display the content of the home directory of the user "octopus":

           #include <roof.h>

           [...]

           // Callback to display directory content
           int display_dir(roof_ctx_t *pCtx, const char *buf, unsigned int lbuf)
           {
           int out_fd = (int)(pCtx->ctx);
           int rc;

             rc = write(out_fd, buf, lbuf);
             assert(lbuf == (unsigned)rc);

             // Return OK to the library (number of "written" bytes)
             return lbuf;
           }

           [...]

           int         ctrl;
           roof_ctx_t *pCtx;
           int         rc;
           char       *p;

           // Allocate a ROOF context with default values for the I/O buffer
           // and 10 seconds for the timeout. The user data is set with
           // the output file descriptor
           pCtx = roof_new(10000, NULL, 0, (void *)1);
           assert(NULL != pCtx);

           // Open the control connection with the server "foobar" on the default port.
           ctrl = roof_open_ctrl(pCtx, "foobar", ROOF_DEF_PORT);
           assert(ctrl >= 0);

           // Log as user "octopus" with the password "super_vilain"
           rc = roof_login(pCtx, "octopus", "super_vilain", NULL);
           assert(0 == rc);

           // Display the current working directory on the remote side
           rc = roof_pwd(pCtx, &p);
           assert(0 == rc);
           printf("Current directory is ’%s’0, p);

           // Display content of current directory on standard output (fd = 1)
           rc = roof_list(pCtx, NULL, display_dir);
           assert(0 == rc);

           // Close the control connection
           rc = roof_close_ctrl(pCtx);
           assert(0 == rc);

           // Deallocate the session’s context
           roof_delete(pCtx);


ftpfs

ftpfs is  a  file  system based on FTP: it mounts a remote file system using the FTP protocol. Internally, ftpfs is based on FUSE and roof's API.  The mounted file system is read only.

Usage

ftpfs [-V -h] [-d level] [-l log] [-t ms] [-s size] [-c ms] [-I] [-o owner] [-g group] mpath host login [ passwd [ account ] ]


ftpfs mounts the target host on the mount point (directory) mpath.  The connection to the  target  host uses the login name login, the password passwd and eventually the account information account (the latter is normally never used). The password defaults to the login name  and  the account defaults to "/".

Options

-V
Display the version of the program

-h
Display the help of the program

-d level
Set  the  debug  mode  to  level.  Debug messages are redirected to the log file if '-l' has been specified or stderr by default. The higher the level is, the more traces you get. The value 0 deactivates the debug mode.

-l log
Activates logging into the file log.

-t ms
Set the data transfer timeout for the interactions with the target host to ms milliseconds. The value defaults to 5000 (5 seconds).

-s size
Set the size in bytes of the internal I/O buffer. The greater it is, the faster the underlying FTP transfers are supposed to be. The default size of the I/O buffer is 4 KB.

-c ms
Set the connection timeout for the interactions with the target host to ms milliseconds.  The  value  defaults  to  the  unspecified underlying stack one.
-I
Use internal default connection parameters for login/password

-o owner
Specify the owner of the remote files. Ignored if it is a local connection. It defaults to the identifier of the user who mounted the file system.

-g group
Specify  the  group  of the remote files. Ignored if it is a local connection. It defaults to the group of the user specified by -o option (if any) or the group of the user who mounted the file system.

Example

The  following  example mounts the remote host ’wales’ with the login name ’josey’ and password ’alone’ on the local directory ’/mnt’. Then ’ls -l’ is invoked to list the  content  of  ’/mnt’ which is the content of the home directory of ’josey’ on the remote machine ’wales’. ’mount’ command is launched to display the list of mounted file systems. The remote host is unmounted with the ’umount’ command:

$ sudo ftpfs /mnt wales josey alone
$ cd /mnt

$ ls -l /mnt
total 0
-r--r--r-- 1 root root 63328 1970-01-01 01:00 garden.sh3d
dr-xr-xr-x 1 root root  4096 1970-01-01 01:00 Applications
-r--r--r-- 1 root root   198 1970-01-01 01:00 backup.sh
dr-xr-xr-x 1 root root  4096 1970-01-01 01:00 DEVS
$ cd /
$ mount
[...]
ftpfs on /mnt type fuse.ftpfs (rw,nosuid,nodev,default_permissions,allow_other)
$ sudo umount /mnt
$ ls -l /mnt
total 0
$


ftping

ftping  is a FTP client which tries to open a control connection to a remote FTP server. It is useful to check if a remote FTP server is up and ready to accept connections.

Usage


ftping [-p port] [-d debug_level] [-t timeout] [-h V n] [ hostname ]

Options

-p port
--port=port
Specify the TCP port of the remote FTP server (default is 21).

-d debug_level
--debug=debug_level
Set the debug level to debug_level.  The value is a positive integer value. The bigger the value, the more debug traces will appear  (0  unsets  the  debug  mode).
This is useful to catch the error messages from the server when a command fails.

-t timeout
--timeout=timeout
Specify the maximum timeout in milliseconds to wait for an answer from the remote FTP server. By default, it is an internal value coming from the IP stack.

-h
--help
Display the help of the command (subset of this man page).

-V
--version
Display the version of the software.


-n
--nogw
Avoid the sending of the connection tries through a gateway

Examples

The following example shows a FTP connection to the default port 21 on a host called 'remote'. The FTP server is up as the return code is 0.

$ ftping remote
$ echo $?
0
$

The  following  example shows a FTP connection to the port 2000 on a host called 'remote'. The remote server is not up on this port as the return code is not 0 after a maximum wait of 3 seconds (3000 ms).

$ ftping -t 3000 -p 2000 remote
$ echo $?
1
$



About the author

The author is an engineer in computer sciences located in France. He is glad to graciously offer this utility under the GPL open source license. He can be contacted through this page or you can have a look at his WEB home page.

Related links


Back to home page
Back to previous page