diff options
Diffstat (limited to 'lib/inets/doc/src/tftp.xml')
-rw-r--r-- | lib/inets/doc/src/tftp.xml | 637 |
1 files changed, 637 insertions, 0 deletions
diff --git a/lib/inets/doc/src/tftp.xml b/lib/inets/doc/src/tftp.xml new file mode 100644 index 0000000000..96d6ae0dd5 --- /dev/null +++ b/lib/inets/doc/src/tftp.xml @@ -0,0 +1,637 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2006</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + </legalnotice> + + <title>tftp</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <module>tftp</module> + <modulesummary>Trivial FTP</modulesummary> + <description> + <p>This is a complete implementation of the following IETF standards:</p> + <list type="bulleted"> + <item>RFC 1350, The TFTP Protocol (revision 2).</item> + <item>RFC 2347, TFTP Option Extension.</item> + <item>RFC 2348, TFTP Blocksize Option.</item> + <item>RFC 2349, TFTP Timeout Interval and Transfer Size Options.</item> + </list> + <p>The only feature that not is implemented in this release is + the "netascii" transfer mode.</p> + <p>The <seealso marker="#start/1">start/1</seealso> function starts + a daemon process which listens for UDP packets on a port. When it + receives a request for read or write it spawns a temporary server + process which handles the actual transfer of the file.</p> + <p>On the client side + the <seealso marker="#read_file/3">read_file/3</seealso> + and <seealso marker="#write_file/3">write_file/3</seealso> + functions spawns a temporary client process which establishes + contact with a TFTP daemon and performs the actual transfer of + the file.</p> + <p><c>tftp</c> uses a callback module to handle the actual file + transfer. Two such callback modules are provided, + <c>tftp_binary</c> and <c>tftp_file</c>. See + <seealso marker="#read_file/3">read_file/3</seealso> and + <seealso marker="#write_file/3">write_file/3</seealso> for + more information about these. The user can also implement own + callback modules, see <seealso marker="#tftp_callback">CALLBACK FUNCTIONS</seealso> below. A callback module provided by + the user is registered using the <c>callback</c> option, see + <seealso marker="#options">DATA TYPES</seealso> below.</p> + </description> + + <section> + <title>TFTP SERVER SERVICE START/STOP </title> + + <p>A TFTP server can be configured to start statically when starting + the Inets application. Alternatively it can be started dynamically + (when Inets already is started) by calling the Inets application API + <c>inets:start(tftpd, ServiceConfig)</c>, or + <c>inets:start(tftpd, ServiceConfig, How)</c>, + see <seealso marker="inets">inets(3)</seealso> for details. + The <c>ServiceConfig</c> for TFTP is described below in + the <seealso marker="#options">COMMON DATA TYPES</seealso> + section.</p> + + <p>The TFTP server can be stopped using <c>inets:stop(tftpd, Pid)</c>, + see <seealso marker="inets">inets(3)</seealso> for details.</p> + + <p>The TPFT client is of such a temporary nature that it is not + handled as a service in the Inets service framework.</p> + + </section> + + <section> + <marker id="options"></marker> + <title>COMMON DATA TYPES</title> + <pre> + ServiceConfig = Options + Options = [option()] + option() -- see below + </pre> + <p>Most of the options are common for both the client and the server + side, but some of them differs a little. Here are the available + options:</p> + <taglist> + <tag><c>{debug, Level}</c></tag> + <item> + <p><c>Level = none | error | warning | brief | normal | verbose | all</c></p> + <p>Controls the level of debug printouts. The default is + <c>none</c>.</p> + </item> + <tag><c>{host, Host}</c></tag> + <item> + <p><c>Host = hostname()</c> see + <seealso marker="kernel:inet">inet(3)</seealso></p> + <p>The name or IP address of the host where the TFTP daemon + resides. This option is only used by the client.</p> + </item> + <tag><c>{port, Port}</c></tag> + <item> + <p><c>Port = int()</c></p> + <p>The TFTP port where the daemon listens. It defaults to + the standardized number 69. On the server side it may + sometimes make sense to set it to 0, which means that + the daemon just will pick a free port (which one is + returned by the <c>info/1</c> function).</p> + <p>If a socket has somehow already has been connected, the + {udp, [{fd, integer()}]} option can be used to pass the + open file descriptor to gen_udp. This can be automated + a bit by using a command line argument stating the + prebound file descriptor number. For example, if the + Port is 69 and the file descriptor 22 has been opened by + setuid_socket_wrap. Then the command line argument + "-tftpd_69 22" will trigger the prebound file + descriptor 22 to be used instead of opening port 69. + The UDP option {udp, [{fd, 22}]} automatically be added. + See init:get_argument/ about command line arguments and + gen_udp:open/2 about UDP options.</p> + </item> + <tag><c>{port_policy, Policy}</c></tag> + <item> + <p><c>Policy = random | Port | {range, MinPort, MaxPort}</c> <br></br> +<c>Port = MinPort = MaxPort = int()</c></p> + <p>Policy for the selection of the temporary port which is used + by the server/client during the file transfer. It defaults to + <c>random</c> which is the standardized policy. With this + policy a randomized free port used. A single port or a range + of ports can be useful if the protocol should pass through a + firewall.</p> + </item> + <tag><c>{udp, Options}</c></tag> + <item> + <p><c>Options = [Opt]</c> see + <seealso marker="kernel:gen_udp#open/1">gen_udp:open/2</seealso></p> + </item> + <tag><c>{use_tsize, Bool}</c></tag> + <item> + <p><c>Bool = bool()</c></p> + <p>Flag for automated usage of the <c>tsize</c> option. With + this set to true, the <c>write_file/3</c> client will + determine the filesize and send it to the server as + the standardized <c>tsize</c> option. A <c>read_file/3</c> + client will just acquire filesize from the server by sending + a zero <c>tsize</c>.</p> + </item> + <tag><c>{max_tsize, MaxTsize}</c></tag> + <item> + <p><c>MaxTsize = int() | infinity</c></p> + <p>Threshold for the maximal filesize in bytes. The transfer + will be aborted if the limit is exceeded. It defaults to + <c>infinity</c>.</p> + </item> + <tag><c>{max_conn, MaxConn}</c></tag> + <item> + <p><c>MaxConn = int() | infinity</c></p> + <p>Threshold for the maximal number of active connections. + The daemon will reject the setup of new connections if + the limit is exceeded. It defaults to <c>infinity</c>.</p> + </item> + <tag><c>{TftpKey, TftpVal}</c></tag> + <item> + <p><c>TftpKey = string()</c> <br></br> +<c>TftpVal = string()</c></p> + <p>The name and value of a TFTP option.</p> + </item> + <tag><c>{reject, Feature}</c></tag> + <item> + <p><c>Feature = Mode | TftpKey</c> <br></br> +<c> Mode = read | write</c> <br></br> +<c> TftpKey = string()</c></p> + <p>Control which features that should be rejected. This is + mostly useful for the server as it may restrict usage of + certain TFTP options or read/write access.</p> + </item> + <tag><c>{callback, {RegExp, Module, State}}</c></tag> + <item> + <p><c>RegExp = string()</c> <br></br> +<c>Module = atom()</c> <br></br> +<c>State = term()</c></p> + <p>Registration of a callback module. When a file is to be + transferred, its local filename will be matched to the regular + expressions of the registered callbacks. The first matching + callback will be used the during the transfer. See + <seealso marker="#read_file/3">read_file/3</seealso> and + <seealso marker="#write_file/3">write_file/3</seealso>. + </p> + <p>The callback module must implement the <c>tftp</c> behavior, + <seealso marker="#tftp_callback">CALLBACK FUNCTIONS</seealso>.</p> + </item> + + <tag><c>{logger, Module}</c></tag> + <item> + <p><c>Module = module()()</c></p> + + <p>Callback module for customized logging of error, warning and + info messages. >The callback module must implement the + <c>tftp_logger</c> behavior, + <seealso marker="#tftp_logger">LOGGER FUNCTIONS</seealso>. + The default module is <c>tftp_logger</c>.</p> + </item> + + <tag><c>{max_retries, MaxRetries}</c></tag> + <item> + <p><c>MaxRetries = int()</c></p> + + <p>Threshold for the maximal number of retries. By default + the server/client will try to resend a message up to + <c>5</c> times when the timeout expires.</p> + </item> + </taglist> + </section> + + <funcs> + <func> + <name>start(Options) -> {ok, Pid} | {error, Reason}</name> + <fsummary>Start a daemon process</fsummary> + <type> + <v>Options = [option()]</v> + <v>Pid = pid()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Starts a daemon process which listens for udp packets on a + port. When it receives a request for read or write it spawns + a temporary server process which handles the actual transfer + of the (virtual) file.</p> + </desc> + </func> + <func> + <name>read_file(RemoteFilename, LocalFilename, Options) -> {ok, LastCallbackState} | {error, Reason}</name> + <fsummary>Read a (virtual) file from a TFTP server</fsummary> + <type> + <v>RemoteFilename = string()</v> + <v>LocalFilename = binary | string()</v> + <v>Options = [option()]</v> + <v>LastCallbackState = term()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Reads a (virtual) file <c>RemoteFilename</c> from a TFTP + server.</p> + <p>If <c>LocalFilename</c> is the atom <c>binary</c>, + <c>tftp_binary</c> is used as callback module. It concatenates + all transferred blocks and returns them as one single binary + in <c>LastCallbackState</c>.</p> + <p>If <c>LocalFilename</c> is a string and there are no + registered callback modules, <c>tftp_file</c> is used as + callback module. It writes each transferred block to the file + named <c>LocalFilename</c> and returns the number of + transferred bytes in <c>LastCallbackState</c>.</p> + <p>If <c>LocalFilename</c> is a string and there are registered + callback modules, <c>LocalFilename</c> is tested against + the regexps of these and the callback module corresponding to + the first match is used, or an error tuple is returned if no + matching regexp is found.</p> + </desc> + </func> + <func> + <name>write_file(RemoteFilename, LocalFilename, Options) -> {ok, LastCallbackState} | {error, Reason}</name> + <fsummary>Write a (virtual) file to a TFTP server</fsummary> + <type> + <v>RemoteFilename = string()</v> + <v>LocalFilename = binary() | string()</v> + <v>Options = [option()]</v> + <v>LastCallbackState = term()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Writes a (virtual) file <c>RemoteFilename</c> to a TFTP + server.</p> + <p>If <c>LocalFilename</c> is a binary, <c>tftp_binary</c> is + used as callback module. The binary is transferred block by + block and the number of transferred bytes is returned in + <c>LastCallbackState</c>.</p> + <p>If <c>LocalFilename</c> is a string and there are no + registered callback modules, <c>tftp_file</c> is used as + callback module. It reads the file named <c>LocalFilename</c> + block by block and returns the number of transferred bytes + in <c>LastCallbackState</c>.</p> + <p>If <c>LocalFilename</c> is a string and there are registered + callback modules, <c>LocalFilename</c> is tested against + the regexps of these and the callback module corresponding to + the first match is used, or an error tuple is returned if no + matching regexp is found.</p> + </desc> + </func> + + <func> + <name>info(daemons) -> [{Pid, Options}]</name> + <fsummary>Return information about all daemons</fsummary> + <type> + <v>Pid = [pid()()]</v> + <v>Options = [option()]</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Returns info about all TFTP daemon processes. + </p> + </desc> + </func> + + <func> + <name>info(servers) -> [{Pid, Options}]</name> + <fsummary>Return information about all servers</fsummary> + <type> + <v>Pid = [pid()()]</v> + <v>Options = [option()]</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Returns info about all TFTP server processes. + </p> + </desc> + </func> + + <func> + <name>info(Pid) -> {ok, Options} | {error, Reason}</name> + <fsummary>Return information about a daemon, server or client process</fsummary> + <type> + <v>Options = [option()]</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Returns info about a TFTP daemon, server or client process.</p> + </desc> + </func> + + <func> + <name>change_config(daemons, Options) -> [{Pid, Result}]</name> + <fsummary>Changes config for all daemons + </fsummary> + <type> + <v>Options = [option()]</v> + <v>Pid = pid()</v> + <v>Result = ok | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Changes config for all TFTP daemon processes + </p> + </desc> + </func> + + <func> + <name>change_config(servers, Options) -> [{Pid, Result}]</name> + <fsummary>Changes config for all servers + </fsummary> + <type> + <v>Options = [option()]</v> + <v>Pid = pid()</v> + <v>Result = ok | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Changes config for all TFTP server processes + </p> + </desc> + </func> + + <func> + <name>change_config(Pid, Options) -> Result</name> + <fsummary>Changes config for a TFTP daemon, server or client process</fsummary> + <type> + <v>Pid = pid()</v> + <v>Options = [option()]</v> + <v>Result = ok | {error, Reason}</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Changes config for a TFTP daemon, server or client process</p> + </desc> + </func> + <func> + <name>start() -> ok | {error, Reason}</name> + <fsummary>Start the Inets application</fsummary> + <type> + <v>Reason = term()</v> + </type> + <desc> + <p>Starts the Inets application.</p> + </desc> + </func> + </funcs> + + <section> + <marker id="tftp_callback"></marker> + <title>CALLBACK FUNCTIONS</title> + <p>A <c>tftp</c> callback module should be implemented as a + <c>tftp</c> behavior and export the functions listed below.</p> + <p>On the server side the callback interaction starts with a call to + <c>open/5</c> with the registered initial callback state. + <c>open/5</c> is expected to open the (virtual) file. Then either + the <c>read/1</c> or <c>write/2</c> functions are invoked + repeatedly, once per transferred block. At each function call + the state returned from the previous call is obtained. When + the last block has been encountered the <c>read/1</c> or + <c>write/2</c> functions is expected to close the (virtual) file + and return its last state. The <c>abort/3</c> function is only + used in error situations. <c>prepare/5</c> is not used on + the server side.</p> + <p>On the client side the callback interaction is the same, but it + starts and ends a bit differently. It starts with a call to + <c>prepare/5</c> with the same arguments as <c>open/5</c> takes. + <c>prepare/5</c> is expected to validate the TFTP options, + suggested by the user and return the subset of them that it + accepts. Then the options is sent to the server which will perform + the same TFTP option negotiation procedure. The options that are + accepted by the server are forwarded to the <c>open/5</c> function + on the client side. On the client side the <c>open/5</c> function + must accept all option as is or reject the transfer. Then + the callback interaction follows the same pattern as described + above for the server side. When the last block is encountered in + <c>read/1</c> or <c>write/2</c> the returned state is forwarded to + the user and returned from <c>read_file</c>/3 or + <c>write_file/3</c>.</p> + + <p> If a callback (which performs the file access + in the TFTP server) takes too long time (more than + the double TFTP timeout), the server will abort the + connection and send an error reply to the client. + This implies that the server will release resources + attached to the connection faster than before. The + server simply assumes that the client has given + up.</p> + + <p>If the TFTP server receives yet another request from + the same client (same host and port) while it + already has an active connection to the client, it + will simply ignore the new request if the request is + equal with the first one (same filename and options). + This implies that the (new) client will be served + by the already ongoing connection on the server + side. By not setting up yet another connection, in + parallel with the ongoing one, the server will + consumer lesser resources. + </p> + </section> + + <funcs> + <func> + <name>prepare(Peer, Access, Filename, Mode, SuggestedOptions, InitialState) -> {ok, AcceptedOptions, NewState} | {error, {Code, Text}}</name> + <fsummary>Prepare to open a file on the client side</fsummary> + <type> + <v>Peer = {PeerType, PeerHost, PeerPort}</v> + <v>PeerType = inet | inet6</v> + <v>PeerHost = ip_address()</v> + <v>PeerPort = integer()</v> + <v>Access = read | write</v> + <v>Filename = string()</v> + <v>Mode = string()</v> + <v>SuggestedOptions = AcceptedOptions = [{Key, Value}]</v> + <v> Key = Value = string()</v> + <v>InitialState = [] | [{root_dir, string()}]</v> + <v>NewState = term()</v> + <v>Code = undef | enoent | eacces | enospc</v> + <v> | badop | eexist | baduser | badopt</v> + <v> | int()</v> + <v>Text = string()</v> + </type> + <desc> + <p>Prepares to open a file on the client side.</p> + <p>No new options may be added, but the ones that are present in + <c>SuggestedOptions</c> may be omitted or replaced with new + values in <c>AcceptedOptions</c>.</p> + <p>Will be followed by a call to <c>open/4</c> before any + read/write access is performed. <c>AcceptedOptions</c> is + sent to the server which replies with those options that it + accepts. These will be forwarded to <c>open/4</c> as + <c>SuggestedOptions</c>.</p> + </desc> + </func> + <func> + <name>open(Peer, Access, Filename, Mode, SuggestedOptions, State) -> {ok, AcceptedOptions, NewState} | {error, {Code, Text}}</name> + <fsummary>Open a file for read or write access</fsummary> + <type> + <v>Peer = {PeerType, PeerHost, PeerPort}</v> + <v>PeerType = inet | inet6</v> + <v>PeerHost = ip_address()</v> + <v>PeerPort = integer()</v> + <v>Access = read | write</v> + <v>Filename = string()</v> + <v>Mode = string()</v> + <v>SuggestedOptions = AcceptedOptions = [{Key, Value}]</v> + <v> Key = Value = string()</v> + <v>State = InitialState | term()</v> + <v> InitialState = [] | [{root_dir, string()}]</v> + <v>NewState = term()</v> + <v>Code = undef | enoent | eacces | enospc</v> + <v> | badop | eexist | baduser | badopt</v> + <v> | int()</v> + <v>Text = string()</v> + </type> + <desc> + <p>Opens a file for read or write access.</p> + <p>On the client side where the <c>open/5</c> call has been + preceded by a call to <c>prepare/5</c>, all options must be + accepted or rejected.</p> + <p>On the server side, where there is no preceding + <c>prepare/5</c> call, no new options may be added, but + the ones that are present in <c>SuggestedOptions</c> may be + omitted or replaced with new values in <c>AcceptedOptions</c>.</p> + </desc> + </func> + <func> + <name>read(State) -> {more, Bin, NewState} | {last, Bin, FileSize} | {error, {Code, Text}}</name> + <fsummary>Read a chunk from the file</fsummary> + <type> + <v>State = NewState = term()</v> + <v>Bin = binary()</v> + <v>FileSize = int()</v> + <v>Code = undef | enoent | eacces | enospc</v> + <v> | badop | eexist | baduser | badopt</v> + <v> | int()</v> + <v>Text = string()</v> + </type> + <desc> + <p>Read a chunk from the file.</p> + <p>The callback function is expected to close + the file when the last file chunk is + encountered. When an error is encountered + the callback function is expected to clean + up after the aborted file transfer, such as + closing open file descriptors etc. In both + cases there will be no more calls to any of + the callback functions.</p> + </desc> + </func> + <func> + <name>write(Bin, State) -> {more, NewState} | {last, FileSize} | {error, {Code, Text}}</name> + <fsummary>Write a chunk to the file</fsummary> + <type> + <v>Bin = binary()</v> + <v>State = NewState = term()</v> + <v>FileSize = int()</v> + <v>Code = undef | enoent | eacces | enospc</v> + <v> | badop | eexist | baduser | badopt</v> + <v> | int()</v> + <v>Text = string()</v> + </type> + <desc> + <p>Write a chunk to the file.</p> + <p>The callback function is expected to close + the file when the last file chunk is + encountered. When an error is encountered + the callback function is expected to clean + up after the aborted file transfer, such as + closing open file descriptors etc. In both + cases there will be no more calls to any of + the callback functions.</p> + </desc> + </func> + <func> + <name>abort(Code, Text, State) -> ok</name> + <fsummary>Abort the file transfer</fsummary> + <type> + <v>Code = undef | enoent | eacces | enospc</v> + <v> | badop | eexist | baduser | badopt</v> + <v> | int()</v> + <v>Text = string()</v> + <v>State = term()</v> + </type> + <desc> + <p>Invoked when the file transfer is aborted.</p> + <p>The callback function is expected to clean + up its used resources after the aborted file + transfer, such as closing open file + descriptors etc. The function will not be + invoked if any of the other callback + functions returns an error, as it is + expected that they already have cleaned up + the necessary resources. It will however be + invoked if the functions fails (crashes).</p> + </desc> + </func> + </funcs> + + <section> + <marker id="tftp_logger"></marker> + <title>LOGGER FUNCTIONS</title> + + <p>A <c>tftp_logger</c> callback module should be implemented as a + <c>tftp_logger</c> behavior and export the functions listed below.</p> + </section> + + <funcs> + <func> + <name>error_msg(Format, Data) -> ok | exit(Reason)</name> + <fsummary>Log an error message</fsummary> + <type> + <v>Format = string()</v> + <v>Data = [term()]</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Log an error message. See <c>error_logger:error_msg/2 for details.</c> </p> + </desc> + </func> + + <func> + <name>warning_msg(Format, Data) -> ok | exit(Reason)</name> + <fsummary>Log an error message</fsummary> + <type> + <v>Format = string()</v> + <v>Data = [term()]</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Log a warning message. See <c>error_logger:warning_msg/2 for details.</c> </p> + </desc> + </func> + + <func> + <name>info_msg(Format, Data) -> ok | exit(Reason)</name> + <fsummary>Log an error message</fsummary> + <type> + <v>Format = string()</v> + <v>Data = [term()]</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Log an info message. See <c>error_logger:info_msg/2 for details.</c> </p> + </desc> + </func> + </funcs> +</erlref> + + |