xref: /netbsd-src/external/bsd/fetch/dist/libfetch/fetch.3 (revision da9817918ec7e88db2912a2882967c7570a83f47)
1.\"-
2.\" Copyright (c) 1998-2004 Dag-Erling Co�dan Sm�rgrav
3.\" All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\"    notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\"    notice, this list of conditions and the following disclaimer in the
12.\"    documentation and/or other materials provided with the distribution.
13.\"
14.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24.\" SUCH DAMAGE.
25.\"
26.\" $FreeBSD: fetch.3,v 1.64 2007/12/18 11:03:26 des Exp $
27.\" $NetBSD: fetch.3,v 1.1.1.6 2009/04/04 23:26:04 joerg Exp $
28.\"
29.Dd February 4, 2009
30.Dt FETCH 3
31.Os
32.Sh NAME
33.Nm fetchMakeURL ,
34.Nm fetchParseURL ,
35.Nm fetchCopyURL ,
36.Nm fetchFreeURL ,
37.Nm fetchXGetURL ,
38.Nm fetchGetURL ,
39.Nm fetchPutURL ,
40.Nm fetchStatURL ,
41.Nm fetchListURL ,
42.Nm fetchXGet ,
43.Nm fetchGet ,
44.Nm fetchPut ,
45.Nm fetchStat ,
46.Nm fetchList ,
47.Nm fetchXGetFile ,
48.Nm fetchGetFile ,
49.Nm fetchPutFile ,
50.Nm fetchStatFile ,
51.Nm fetchListFile ,
52.Nm fetchXGetHTTP ,
53.Nm fetchGetHTTP ,
54.Nm fetchPutHTTP ,
55.Nm fetchStatHTTP ,
56.Nm fetchListHTTP ,
57.Nm fetchXGetFTP ,
58.Nm fetchGetFTP ,
59.Nm fetchPutFTP ,
60.Nm fetchStatFTP ,
61.Nm fetchListFTP
62.Nm fetchInitURLList ,
63.Nm fetchFreeURLList ,
64.Nm fetchUnquotePath ,
65.Nm fetchUnquoteFilename ,
66.Nm fetchStringifyURL ,
67.Nm fetch
68.Nd file transfer functions
69.Sh LIBRARY
70.Lb libfetch
71.Sh SYNOPSIS
72.In stdio.h
73.In fetch.h
74.Ft struct url *
75.Fn fetchMakeURL "const char *scheme" "const char *host" "int port" "const char *doc" "const char *user" "const char *pwd"
76.Ft struct url *
77.Fn fetchParseURL "const char *URL"
78.Ft struct url *
79.Fn fetchCopyURL "const struct url *u"
80.Ft void
81.Fn fetchFreeURL "struct url *u"
82.Ft fetchIO *
83.Fn fetchXGetURL "const char *URL" "struct url_stat *us" "const char *flags"
84.Ft fetchIO *
85.Fn fetchGetURL "const char *URL" "const char *flags"
86.Ft fetchIO *
87.Fn fetchPutURL "const char *URL" "const char *flags"
88.Ft int
89.Fn fetchStatURL "const char *URL" "struct url_stat *us" "const char *flags"
90.Ft int
91.Fn fetchListURL "struct url_list *list" "const char *URL" "const char *flags"
92.Ft fetchIO *
93.Fn fetchXGet "struct url *u" "struct url_stat *us" "const char *flags"
94.Ft fetchIO *
95.Fn fetchGet "struct url *u" "const char *flags"
96.Ft fetchIO *
97.Fn fetchPut "struct url *u" "const char *flags"
98.Ft int
99.Fn fetchStat "struct url *u" "struct url_stat *us" "const char *flags"
100.Ft int
101.Fn fetchList "struct url_list *list" "struct url *u" "const char *flags"
102.Ft fetchIO *
103.Fn fetchXGetFile "struct url *u" "struct url_stat *us" "const char *flags"
104.Ft fetchIO *
105.Fn fetchGetFile "struct url *u" "const char *flags"
106.Ft fetchIO *
107.Fn fetchPutFile "struct url *u" "const char *flags"
108.Ft int
109.Fn fetchStatFile "struct url *u" "struct url_stat *us" "const char *flags"
110.Ft int
111.Fn fetchListFile "struct url_list *list" "struct url *u" "const char *flags"
112.Ft fetchIO *
113.Fn fetchXGetHTTP "struct url *u" "struct url_stat *us" "const char *flags"
114.Ft fetchIO *
115.Fn fetchGetHTTP "struct url *u" "const char *flags"
116.Ft fetchIO *
117.Fn fetchPutHTTP "struct url *u" "const char *flags"
118.Ft int
119.Fn fetchStatHTTP "struct url *u" "struct url_stat *us" "const char *flags"
120.Ft int
121.Fn fetchListHTTP "struct url_list *list" "struct url *u" "const char *flags"
122.Ft fetchIO *
123.Fn fetchXGetFTP "struct url *u" "struct url_stat *us" "const char *flags"
124.Ft fetchIO *
125.Fn fetchGetFTP "struct url *u" "const char *flags"
126.Ft fetchIO *
127.Fn fetchPutFTP "struct url *u" "const char *flags"
128.Ft int
129.Fn fetchStatFTP "struct url *u" "struct url_stat *us" "const char *flags"
130.Ft int
131.Fn fetchListFTP "struct url_list *list" "struct url *u" "const char *flags"
132.Ft void
133.Fn fetchInitURLList "struct url_list *ul"
134.Ft void
135.Fn fetchFreeURLList "struct url_list *ul"
136.Ft char *
137.Fn fetchUnquotePath "struct url *u"
138.Ft char *
139.Fn fetchUnquoteFilename "struct url *u"
140.Ft char *
141.Fn fetchStringifyURL "const struct url *u"
142.Sh DESCRIPTION
143These functions implement a high-level library for retrieving and
144uploading files using Uniform Resource Locators (URLs).
145.Pp
146.Fn fetchParseURL
147takes a URL in the form of a null-terminated string and splits it into
148its components function according to the Common Internet Scheme Syntax
149detailed in RFC 1738.
150A regular expression which produces this syntax is:
151.Bd -literal -offset indent
152\*[Lt]scheme\*[Gt]:(//(\*[Lt]user\*[Gt](:\*[Lt]pwd\*[Gt])?@)?\*[Lt]host\*[Gt](:\*[Lt]port\*[Gt])?)?/(\*[Lt]document\*[Gt])?
153.Ed
154.Pp
155If the URL does not seem to begin with a scheme name, it is assumed to be a local path.
156Only absolute path names are accepted.
157.Pp
158Note that some components of the URL are not necessarily relevant to
159all URL schemes.
160For instance, the file scheme only needs the
161.Aq scheme
162and
163.Aq document
164components.
165.Fn fetchParseURL
166quotes any unsafe character in the URL automatically.
167This is not done by
168.Fn fetchMakeURL .
169.Fn fetchCopyURL
170copies an existing
171.Vt url
172structure.
173.Pp
174.Fn fetchMakeURL ,
175.Fn fetchParseURL ,
176and
177.Fn fetchCopyURL
178return a pointer to a
179.Vt url
180structure, which is defined as follows in
181.In fetch.h :
182.Bd -literal
183#define URL_SCHEMELEN 16
184#define URL_USERLEN 256
185#define URL_PWDLEN 256
186#define URL_HOSTLEN 255
187
188struct url {
189    char	 scheme[URL_SCHEMELEN + 1];
190    char	 user[URL_USERLEN + 1];
191    char	 pwd[URL_PWDLEN + 1];
192    char	 host[URL_HOSTLEN + 1];
193    int		 port;
194    char	*doc;
195    off_t	 offset;
196    size_t	 length;
197    time_t	 last_modified;
198};
199.Ed
200.Pp
201The pointer returned by
202.Fn fetchMakeURL ,
203.Fn fetchCopyURL ,
204and
205.Fn fetchParseURL
206should be freed using
207.Fn fetchFreeURL .
208The size of
209.Vt struct URL
210is not part of the ABI.
211.Pp
212.Fn fetchXGetURL ,
213.Fn fetchGetURL ,
214and
215.Fn fetchPutURL
216constitute the recommended interface to the
217.Nm fetch
218library.
219They examine the URL passed to them to determine the transfer
220method, and call the appropriate lower-level functions to perform the
221actual transfer.
222.Fn fetchXGetURL
223also returns the remote document's metadata in the
224.Vt url_stat
225structure pointed to by the
226.Fa us
227argument.
228.Pp
229The
230.Fa flags
231argument is a string of characters which specify transfer options.
232The
233meaning of the individual flags is scheme-dependent, and is detailed
234in the appropriate section below.
235.Pp
236.Fn fetchStatURL
237attempts to obtain the requested document's metadata and fill in the
238structure pointed to by its second argument.
239The
240.Vt url_stat
241structure is defined as follows in
242.In fetch.h :
243.Bd -literal
244struct url_stat {
245    off_t	 size;
246    time_t	 atime;
247    time_t	 mtime;
248};
249.Ed
250.Pp
251If the size could not be obtained from the server, the
252.Fa size
253field is set to \-1.
254If the modification time could not be obtained from the server, the
255.Fa mtime
256field is set to the epoch.
257If the access time could not be obtained from the server, the
258.Fa atime
259field is set to the modification time.
260.Pp
261.Fn fetchListURL
262attempts to list the contents of the directory pointed to by the URL provided.
263The pattern can be a simple glob-like expression as hint.
264Callers should not depend on the server to filter names.
265If successful, it appends the list of entries to the
266.Vt url_list
267structure.
268The
269.Vt url_list
270structure is defined as follows in
271.In fetch.h :
272.Bd -literal
273struct url_list {
274    size_t	length;
275    size_t	alloc_size;
276    struct url	*urls;
277};
278.Ed
279.Pp
280The list should be initialized by calling
281.Fn fetchInitURLList
282and the entries be freed by calling
283.Fn fetchFreeURLList .
284.Pp
285.Fn fetchStringifyURL
286returns the URL as string.
287.Fn fetchUnquotePath
288returns the path name part of the URL with any quoting undone.
289Query arguments and fragment identifiers are not included.
290.Fn fetchUnquoteFilename
291returns the last component of the path name as returned by
292.Fn fetchUnquotePath .
293.Fn fetchStringifyURL ,
294.Fn fetchUnquotePath ,
295and
296.Fn fetchUnquoteFilename
297return a string that should be deallocated with
298.Fn free
299after use.
300.Pp
301.Fn fetchXGet ,
302.Fn fetchGet ,
303.Fn fetchPut ,
304and
305.Fn fetchStat
306are similar to
307.Fn fetchXGetURL ,
308.Fn fetchGetURL ,
309.Fn fetchPutURL ,
310and
311.Fn fetchStatURL ,
312except that they expect a pre-parsed URL in the form of a pointer to
313a
314.Vt struct url
315rather than a string.
316.Pp
317All of the
318.Fn fetchXGetXXX ,
319.Fn fetchGetXXX ,
320and
321.Fn fetchPutXXX
322functions return a pointer to a stream which can be used to read or
323write data from or to the requested document, respectively.
324Note that
325although the implementation details of the individual access methods
326vary, it can generally be assumed that a stream returned by one of the
327.Fn fetchXGetXXX
328or
329.Fn fetchGetXXX
330functions is read-only, and that a stream returned by one of the
331.Fn fetchPutXXX
332functions is write-only.
333.Sh PROTOCOL INDEPENDENT FLAGS
334If the
335.Ql i
336(if-modified-since) flag is specified, the library will try to fetch
337the content only if it is newer than
338.Va last_modified .
339For HTTP an
340.Li If-Modified-Since
341HTTP header is sent.
342For FTP a
343.Li MTDM
344command is sent first and compared locally.
345For FILE the source file is compared.
346.Sh FILE SCHEME
347.Fn fetchXGetFile ,
348.Fn fetchGetFile ,
349and
350.Fn fetchPutFile
351provide access to documents which are files in a locally mounted file
352system.
353Only the
354.Aq document
355component of the URL is used.
356.Pp
357.Fn fetchXGetFile
358and
359.Fn fetchGetFile
360do not accept any flags.
361.Pp
362.Fn fetchPutFile
363accepts the
364.Ql a
365(append to file) flag.
366If that flag is specified, the data written to
367the stream returned by
368.Fn fetchPutFile
369will be appended to the previous contents of the file, instead of
370replacing them.
371.Sh FTP SCHEME
372.Fn fetchXGetFTP ,
373.Fn fetchGetFTP ,
374and
375.Fn fetchPutFTP
376implement the FTP protocol as described in RFC 959.
377.Pp
378By default
379.Nm libfetch
380will attempt to use passive mode first and only fallback to active mode
381if the server reports a syntax error.
382If the
383.Ql a
384(active) flag is specified, a passive connection is not tried and active mode
385is used directly.
386.Pp
387If the
388.Ql l
389(low) flag is specified, data sockets will be allocated in the low (or
390default) port range instead of the high port range (see
391.Xr ip 4 ) .
392.Pp
393If the
394.Ql d
395(direct) flag is specified,
396.Fn fetchXGetFTP ,
397.Fn fetchGetFTP ,
398and
399.Fn fetchPutFTP
400will use a direct connection even if a proxy server is defined.
401.Pp
402If no user name or password is given, the
403.Nm fetch
404library will attempt an anonymous login, with user name "anonymous"
405and password "anonymous@\*[Lt]hostname\*[Gt]".
406.Sh HTTP SCHEME
407The
408.Fn fetchXGetHTTP ,
409.Fn fetchGetHTTP ,
410and
411.Fn fetchPutHTTP
412functions implement the HTTP/1.1 protocol.
413With a little luck, there is
414even a chance that they comply with RFC 2616 and RFC 2617.
415.Pp
416If the
417.Ql d
418(direct) flag is specified,
419.Fn fetchXGetHTTP ,
420.Fn fetchGetHTTP ,
421and
422.Fn fetchPutHTTP
423will use a direct connection even if a proxy server is defined.
424.Pp
425Since there seems to be no good way of implementing the HTTP PUT
426method in a manner consistent with the rest of the
427.Nm fetch
428library,
429.Fn fetchPutHTTP
430is currently unimplemented.
431.Sh AUTHENTICATION
432Apart from setting the appropriate environment variables and
433specifying the user name and password in the URL or the
434.Vt struct url ,
435the calling program has the option of defining an authentication
436function with the following prototype:
437.Pp
438.Ft int
439.Fn myAuthMethod "struct url *u"
440.Pp
441The callback function should fill in the
442.Fa user
443and
444.Fa pwd
445fields in the provided
446.Vt struct url
447and return 0 on success, or any other value to indicate failure.
448.Pp
449To register the authentication callback, simply set
450.Va fetchAuthMethod
451to point at it.
452The callback will be used whenever a site requires authentication and
453the appropriate environment variables are not set.
454.Pp
455This interface is experimental and may be subject to change.
456.Sh RETURN VALUES
457.Fn fetchParseURL
458returns a pointer to a
459.Vt struct url
460containing the individual components of the URL.
461If it is
462unable to allocate memory, or the URL is syntactically incorrect,
463.Fn fetchParseURL
464returns a
465.Dv NULL
466pointer.
467.Pp
468The
469.Fn fetchStat
470functions return 0 on success and \-1 on failure.
471.Pp
472All other functions return a stream pointer which may be used to
473access the requested document, or
474.Dv NULL
475if an error occurred.
476.Pp
477The following error codes are defined in
478.In fetch.h :
479.Bl -tag -width 18n
480.It Bq Er FETCH_ABORT
481Operation aborted
482.It Bq Er FETCH_AUTH
483Authentication failed
484.It Bq Er FETCH_DOWN
485Service unavailable
486.It Bq Er FETCH_EXISTS
487File exists
488.It Bq Er FETCH_FULL
489File system full
490.It Bq Er FETCH_INFO
491Informational response
492.It Bq Er FETCH_MEMORY
493Insufficient memory
494.It Bq Er FETCH_MOVED
495File has moved
496.It Bq Er FETCH_NETWORK
497Network error
498.It Bq Er FETCH_OK
499No error
500.It Bq Er FETCH_PROTO
501Protocol error
502.It Bq Er FETCH_RESOLV
503Resolver error
504.It Bq Er FETCH_SERVER
505Server error
506.It Bq Er FETCH_TEMP
507Temporary error
508.It Bq Er FETCH_TIMEOUT
509Operation timed out
510.It Bq Er FETCH_UNAVAIL
511File is not available
512.It Bq Er FETCH_UNKNOWN
513Unknown error
514.It Bq Er FETCH_URL
515Invalid URL
516.El
517.Pp
518The accompanying error message includes a protocol-specific error code
519and message, e.g.\& "File is not available (404 Not Found)"
520.Sh ENVIRONMENT
521.Bl -tag -width ".Ev FETCH_BIND_ADDRESS"
522.It Ev FETCH_BIND_ADDRESS
523Specifies a host name or IP address to which sockets used for outgoing
524connections will be bound.
525.It Ev FTP_LOGIN
526Default FTP login if none was provided in the URL.
527.It Ev FTP_PASSIVE_MODE
528If set to anything but
529.Ql no ,
530forces the FTP code to use passive mode.
531.It Ev FTP_PASSWORD
532Default FTP password if the remote server requests one and none was
533provided in the URL.
534.It Ev FTP_PROXY
535URL of the proxy to use for FTP requests.
536The document part is ignored.
537FTP and HTTP proxies are supported; if no scheme is specified, FTP is
538assumed.
539If the proxy is an FTP proxy,
540.Nm libfetch
541will send
542.Ql user@host
543as user name to the proxy, where
544.Ql user
545is the real user name, and
546.Ql host
547is the name of the FTP server.
548.Pp
549If this variable is set to an empty string, no proxy will be used for
550FTP requests, even if the
551.Ev HTTP_PROXY
552variable is set.
553.It Ev ftp_proxy
554Same as
555.Ev FTP_PROXY ,
556for compatibility.
557.It Ev HTTP_AUTH
558Specifies HTTP authorization parameters as a colon-separated list of
559items.
560The first and second item are the authorization scheme and realm
561respectively; further items are scheme-dependent.
562Currently, only basic authorization is supported.
563.Pp
564Basic authorization requires two parameters: the user name and
565password, in that order.
566.Pp
567This variable is only used if the server requires authorization and
568no user name or password was specified in the URL.
569.It Ev HTTP_PROXY
570URL of the proxy to use for HTTP requests.
571The document part is ignored.
572Only HTTP proxies are supported for HTTP requests.
573If no port number is specified, the default is 3128.
574.Pp
575Note that this proxy will also be used for FTP documents, unless the
576.Ev FTP_PROXY
577variable is set.
578.It Ev http_proxy
579Same as
580.Ev HTTP_PROXY ,
581for compatibility.
582.It Ev HTTP_PROXY_AUTH
583Specifies authorization parameters for the HTTP proxy in the same
584format as the
585.Ev HTTP_AUTH
586variable.
587.Pp
588This variable is used if and only if connected to an HTTP proxy, and
589is ignored if a user and/or a password were specified in the proxy
590URL.
591.It Ev HTTP_REFERER
592Specifies the referrer URL to use for HTTP requests.
593If set to
594.Dq auto ,
595the document URL will be used as referrer URL.
596.It Ev HTTP_USER_AGENT
597Specifies the User-Agent string to use for HTTP requests.
598This can be useful when working with HTTP origin or proxy servers that
599differentiate between user agents.
600.It Ev NETRC
601Specifies a file to use instead of
602.Pa ~/.netrc
603to look up login names and passwords for FTP sites.
604See
605.Xr ftp 1
606for a description of the file format.
607This feature is experimental.
608.It Ev NO_PROXY
609Either a single asterisk, which disables the use of proxies
610altogether, or a comma- or whitespace-separated list of hosts for
611which proxies should not be used.
612.It Ev no_proxy
613Same as
614.Ev NO_PROXY ,
615for compatibility.
616.El
617.Sh EXAMPLES
618To access a proxy server on
619.Pa proxy.example.com
620port 8080, set the
621.Ev HTTP_PROXY
622environment variable in a manner similar to this:
623.Pp
624.Dl HTTP_PROXY=http://proxy.example.com:8080
625.Pp
626If the proxy server requires authentication, there are
627two options available for passing the authentication data.
628The first method is by using the proxy URL:
629.Pp
630.Dl HTTP_PROXY=http://\*[Lt]user\*[Gt]:\*[Lt]pwd\*[Gt]@proxy.example.com:8080
631.Pp
632The second method is by using the
633.Ev HTTP_PROXY_AUTH
634environment variable:
635.Bd -literal -offset indent
636HTTP_PROXY=http://proxy.example.com:8080
637HTTP_PROXY_AUTH=basic:*:\*[Lt]user\*[Gt]:\*[Lt]pwd\*[Gt]
638.Ed
639.Pp
640To disable the use of a proxy for an HTTP server running on the local
641host, define
642.Ev NO_PROXY
643as follows:
644.Bd -literal -offset indent
645NO_PROXY=localhost,127.0.0.1
646.Ed
647.Sh SEE ALSO
648.\" .Xr fetch 1 ,
649.\" .Xr ftpio 3 ,
650.Xr ftp 1 ,
651.Xr ip 4
652.Rs
653.%A J. Postel
654.%A J. K. Reynolds
655.%D October 1985
656.%B File Transfer Protocol
657.%O RFC 959
658.Re
659.Rs
660.%A P. Deutsch
661.%A A. Emtage
662.%A A. Marine
663.%D May 1994
664.%T How to Use Anonymous FTP
665.%O RFC 1635
666.Re
667.Rs
668.%A T. Berners-Lee
669.%A L. Masinter
670.%A M. McCahill
671.%D December 1994
672.%T Uniform Resource Locators (URL)
673.%O RFC 1738
674.Re
675.Rs
676.%A R. Fielding
677.%A J. Gettys
678.%A J. Mogul
679.%A H. Frystyk
680.%A L. Masinter
681.%A P. Leach
682.%A T. Berners-Lee
683.%D January 1999
684.%B Hypertext Transfer Protocol -- HTTP/1.1
685.%O RFC 2616
686.Re
687.Rs
688.%A J. Franks
689.%A P. Hallam-Baker
690.%A J. Hostetler
691.%A S. Lawrence
692.%A P. Leach
693.%A A. Luotonen
694.%A L. Stewart
695.%D June 1999
696.%B HTTP Authentication: Basic and Digest Access Authentication
697.%O RFC 2617
698.Re
699.Sh HISTORY
700The
701.Nm fetch
702library first appeared in
703.Fx 3.0 .
704.Sh AUTHORS
705.An -nosplit
706The
707.Nm fetch
708library was mostly written by
709.An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org
710with numerous suggestions from
711.An Jordan K. Hubbard Aq jkh@FreeBSD.org ,
712.An Eugene Skepner Aq eu@qub.com
713and other
714.Fx
715developers.
716It replaces the older
717.Nm ftpio
718library written by
719.An Poul-Henning Kamp Aq phk@FreeBSD.org
720and
721.An Jordan K. Hubbard Aq jkh@FreeBSD.org .
722.Pp
723This manual page was written by
724.An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org .
725.Sh BUGS
726Some parts of the library are not yet implemented.
727The most notable
728examples of this are
729.Fn fetchPutHTTP
730and FTP proxy support.
731.Pp
732There is no way to select a proxy at run-time other than setting the
733.Ev HTTP_PROXY
734or
735.Ev FTP_PROXY
736environment variables as appropriate.
737.Pp
738.Nm libfetch
739does not understand or obey 305 (Use Proxy) replies.
740.Pp
741Error numbers are unique only within a certain context; the error
742codes used for FTP and HTTP overlap, as do those used for resolver and
743system errors.
744For instance, error code 202 means "Command not
745implemented, superfluous at this site" in an FTP context and
746"Accepted" in an HTTP context.
747.Pp
748.Fn fetchStatFTP
749does not check that the result of an MDTM command is a valid date.
750.Pp
751The man page is incomplete, poorly written and produces badly
752formatted text.
753.Pp
754The error reporting mechanism is unsatisfactory.
755.Pp
756Some parts of the code are not fully reentrant.
757