summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/.gitignore2
-rw-r--r--docs/BINDINGS228
-rw-r--r--docs/BUGS148
-rw-r--r--docs/CONTRIBUTE303
-rw-r--r--docs/DISTRO-DILEMMA176
-rw-r--r--docs/FAQ1422
-rw-r--r--docs/FEATURES136
-rw-r--r--docs/HISTORY244
-rw-r--r--docs/HTTP-COOKIES123
-rw-r--r--docs/INSTALL1100
-rw-r--r--docs/INSTALL.cmake102
-rw-r--r--docs/INSTALL.devcpp302
-rw-r--r--docs/INTERNALS505
-rw-r--r--docs/KNOWN_BUGS242
-rw-r--r--docs/LICENSE-MIXING130
-rw-r--r--docs/MAIL-ETIQUETTE228
-rw-r--r--docs/MANUAL1023
-rw-r--r--docs/Makefile.am60
-rw-r--r--docs/README.cmake16
-rw-r--r--docs/README.netware27
-rw-r--r--docs/README.win3226
-rw-r--r--docs/RESOURCES83
-rw-r--r--docs/SSLCERTS116
-rw-r--r--docs/THANKS999
-rw-r--r--docs/TODO662
-rw-r--r--docs/TheArtOfHttpScripting507
-rw-r--r--docs/VERSIONS60
-rw-r--r--docs/curl-config.198
-rw-r--r--docs/curl.11944
-rw-r--r--docs/examples/.gitignore45
-rw-r--r--docs/examples/10-at-a-time.c197
-rw-r--r--docs/examples/Makefile.am64
-rw-r--r--docs/examples/Makefile.example53
-rw-r--r--docs/examples/Makefile.inc15
-rw-r--r--docs/examples/Makefile.m32282
-rw-r--r--docs/examples/Makefile.netware441
-rw-r--r--docs/examples/README80
-rwxr-xr-xdocs/examples/adddocsref.pl35
-rw-r--r--docs/examples/anyauthput.c185
-rw-r--r--docs/examples/asiohiper.cpp454
-rw-r--r--docs/examples/cacertinmem.c151
-rw-r--r--docs/examples/certinfo.c81
-rw-r--r--docs/examples/chkspeed.c176
-rw-r--r--docs/examples/cookie_interface.c124
-rw-r--r--docs/examples/curlgtk.c106
-rw-r--r--docs/examples/curlx.c513
-rw-r--r--docs/examples/debug.c144
-rw-r--r--docs/examples/evhiperfifo.c442
-rw-r--r--docs/examples/externalsocket.c153
-rw-r--r--docs/examples/fileupload.c86
-rw-r--r--docs/examples/fopen.c527
-rw-r--r--docs/examples/ftp-wildcard.c148
-rw-r--r--docs/examples/ftpget.c94
-rw-r--r--docs/examples/ftpgetinfo.c89
-rw-r--r--docs/examples/ftpgetresp.c76
-rw-r--r--docs/examples/ftpsget.c101
-rw-r--r--docs/examples/ftpupload.c140
-rw-r--r--docs/examples/ftpuploadresume.c174
-rw-r--r--docs/examples/getinfo.c53
-rw-r--r--docs/examples/getinmemory.c112
-rw-r--r--docs/examples/ghiper.c452
-rw-r--r--docs/examples/hiperfifo.c418
-rw-r--r--docs/examples/href_extractor.c86
-rw-r--r--docs/examples/htmltidy.c130
-rw-r--r--docs/examples/htmltitle.cpp313
-rw-r--r--docs/examples/http-post.c55
-rw-r--r--docs/examples/httpcustomheader.c61
-rw-r--r--docs/examples/httpput.c125
-rw-r--r--docs/examples/https.c74
-rw-r--r--docs/examples/imap.c44
-rw-r--r--docs/examples/makefile.dj60
-rw-r--r--docs/examples/multi-app.c153
-rw-r--r--docs/examples/multi-debugcallback.c205
-rw-r--r--docs/examples/multi-double.c119
-rw-r--r--docs/examples/multi-post.c148
-rw-r--r--docs/examples/multi-single.c116
-rw-r--r--docs/examples/multithread.c93
-rw-r--r--docs/examples/opensslthreadlock.c94
-rw-r--r--docs/examples/persistant.c64
-rw-r--r--docs/examples/pop3s.c73
-rw-r--r--docs/examples/pop3slist.c73
-rw-r--r--docs/examples/post-callback.c143
-rw-r--r--docs/examples/postit2.c103
-rw-r--r--docs/examples/progressfunc.c84
-rw-r--r--docs/examples/resolve.c51
-rw-r--r--docs/examples/rtsp.c271
-rw-r--r--docs/examples/sampleconv.c107
-rw-r--r--docs/examples/sendrecv.c135
-rw-r--r--docs/examples/sepheaders.c85
-rw-r--r--docs/examples/sftpget.c106
-rw-r--r--docs/examples/simple.c45
-rw-r--r--docs/examples/simplepost.c53
-rw-r--r--docs/examples/simplesmtp.c87
-rw-r--r--docs/examples/simplessl.c138
-rw-r--r--docs/examples/smooth-gtk-thread.c228
-rw-r--r--docs/examples/smtp-multi.c203
-rw-r--r--docs/examples/smtp-tls.c152
-rw-r--r--docs/examples/synctime.c366
-rw-r--r--docs/examples/threaded-ssl.c162
-rw-r--r--docs/examples/url2file.c81
-rwxr-xr-xdocs/examples/version-check.pl105
-rw-r--r--docs/index.html20
-rw-r--r--docs/libcurl/.gitignore2
-rw-r--r--docs/libcurl/ABI69
-rw-r--r--docs/libcurl/Makefile.am102
-rw-r--r--docs/libcurl/curl_easy_cleanup.357
-rw-r--r--docs/libcurl/curl_easy_duphandle.351
-rw-r--r--docs/libcurl/curl_easy_escape.346
-rw-r--r--docs/libcurl/curl_easy_getinfo.3292
-rw-r--r--docs/libcurl/curl_easy_init.351
-rw-r--r--docs/libcurl/curl_easy_pause.385
-rw-r--r--docs/libcurl/curl_easy_perform.357
-rw-r--r--docs/libcurl/curl_easy_recv.369
-rw-r--r--docs/libcurl/curl_easy_reset.343
-rw-r--r--docs/libcurl/curl_easy_send.364
-rw-r--r--docs/libcurl/curl_easy_setopt.32527
-rw-r--r--docs/libcurl/curl_easy_strerror.337
-rw-r--r--docs/libcurl/curl_easy_unescape.351
-rw-r--r--docs/libcurl/curl_escape.348
-rw-r--r--docs/libcurl/curl_formadd.3235
-rw-r--r--docs/libcurl/curl_formfree.344
-rw-r--r--docs/libcurl/curl_formget.370
-rw-r--r--docs/libcurl/curl_free.335
-rw-r--r--docs/libcurl/curl_getdate.3117
-rw-r--r--docs/libcurl/curl_getenv.349
-rw-r--r--docs/libcurl/curl_global_cleanup.349
-rw-r--r--docs/libcurl/curl_global_init.380
-rw-r--r--docs/libcurl/curl_global_init_mem.360
-rw-r--r--docs/libcurl/curl_mprintf.3109
-rw-r--r--docs/libcurl/curl_multi_add_handle.357
-rw-r--r--docs/libcurl/curl_multi_assign.363
-rw-r--r--docs/libcurl/curl_multi_cleanup.346
-rw-r--r--docs/libcurl/curl_multi_fdset.370
-rw-r--r--docs/libcurl/curl_multi_info_read.376
-rw-r--r--docs/libcurl/curl_multi_init.340
-rw-r--r--docs/libcurl/curl_multi_perform.378
-rw-r--r--docs/libcurl/curl_multi_remove_handle.343
-rw-r--r--docs/libcurl/curl_multi_setopt.3103
-rw-r--r--docs/libcurl/curl_multi_socket.3158
-rw-r--r--docs/libcurl/curl_multi_socket_action.3149
-rw-r--r--docs/libcurl/curl_multi_socket_all.31
-rw-r--r--docs/libcurl/curl_multi_strerror.337
-rw-r--r--docs/libcurl/curl_multi_timeout.363
-rw-r--r--docs/libcurl/curl_multi_wait.375
-rw-r--r--docs/libcurl/curl_share_cleanup.340
-rw-r--r--docs/libcurl/curl_share_init.344
-rw-r--r--docs/libcurl/curl_share_setopt.385
-rw-r--r--docs/libcurl/curl_share_strerror.337
-rw-r--r--docs/libcurl/curl_slist_append.356
-rw-r--r--docs/libcurl/curl_slist_free_all.337
-rw-r--r--docs/libcurl/curl_strequal.351
-rw-r--r--docs/libcurl/curl_strnequal.31
-rw-r--r--docs/libcurl/curl_unescape.348
-rw-r--r--docs/libcurl/curl_version.336
-rw-r--r--docs/libcurl/curl_version_info.3154
-rw-r--r--docs/libcurl/getinfo-times27
-rw-r--r--docs/libcurl/index.html61
-rw-r--r--docs/libcurl/libcurl-easy.345
-rw-r--r--docs/libcurl/libcurl-errors.3289
-rw-r--r--docs/libcurl/libcurl-multi.3151
-rw-r--r--docs/libcurl/libcurl-share.362
-rw-r--r--docs/libcurl/libcurl-tutorial.31369
-rw-r--r--docs/libcurl/libcurl.3222
-rw-r--r--docs/libcurl/libcurl.m4251
-rw-r--r--docs/libcurl/symbols-in-versions705
-rwxr-xr-xdocs/libcurl/symbols.pl100
-rw-r--r--docs/mk-ca-bundle.151
167 files changed, 31514 insertions, 0 deletions
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 000000000..23f832b73
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,2 @@
+*.html
+*.pdf
diff --git a/docs/BINDINGS b/docs/BINDINGS
new file mode 100644
index 000000000..5cf07fecd
--- /dev/null
+++ b/docs/BINDINGS
@@ -0,0 +1,228 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+ libcurl bindings
+
+Creative people have written bindings or interfaces for various environments
+and programming languages. Using one of these allows you to take advantage of
+curl powers from within your favourite language or system.
+
+This is a list of all known interfaces as of this writing.
+
+The bindings listed below are not part of the curl/libcurl distribution
+archives, but must be downloaded and installed separately.
+
+Ada95
+
+ Writtten by Andreas Almroth
+ http://www.almroth.com/adacurl/index.html
+
+Basic
+
+ ScriptBasic bindings to libcurl. Writtten by Peter Verhas
+ http://scriptbasic.com/
+
+C
+ libcurl is a C library in itself!
+ http://curl.haxx.se/libcurl/
+
+C++
+
+ Written by Jean-Philippe Barrette-LaPierre
+ http://curlpp.org/
+
+Ch
+
+ Written by Stephen Nestinger and Jonathan Rogado
+ http://chcurl.sourceforge.net/
+
+Cocoa
+
+ Written by Dan Wood
+ http://curlhandle.sourceforge.net/
+
+D
+
+ Written by Kenneth Bogert
+ http://curl.haxx.se/libcurl/d/
+
+Dylan
+
+ Written by Chris Double
+ http://dylanlibs.sourceforge.net/
+
+Eiffel
+ Written by Eiffel Software
+ http://curl.haxx.se/libcurl/eiffel/
+
+Euphoria
+
+ Written by Ray Smith
+ http://rays-web.com/eulibcurl.htm
+
+Falcon
+
+ http://www.falconpl.org/index.ftd?page_id=prjs&prj_id=curl
+
+Ferite
+
+ Written by Paul Querna
+ http://www.ferite.org/
+
+Gambas
+
+ http://gambas.sourceforge.net
+
+glib/GTK+
+
+ Written by Richard Atterer
+ http://atterer.net/glibcurl/
+
+Haskell
+
+ Written by Galois, Inc
+ http://hackage.haskell.org/cgi-bin/hackage-scripts/package/curl
+
+Java
+
+ Maintained by [blank]
+ http://curl.haxx.se/libcurl/java/
+
+Lisp
+
+ Written by Liam Healy
+ http://common-lisp.net/project/cl-curl/
+
+Lua
+
+ luacurl by Alexander Marinov
+ http://luacurl.luaforge.net/
+
+ Lua-cURL by Jürgen Hötzel
+ http://luaforge.net/projects/lua-curl/
+
+Mono
+
+ Written by Jeffrey Phillips
+ http://forge.novell.com/modules/xfmod/project/?libcurl-mono
+
+.NET
+
+ libcurl-net by Jeffrey Phillips
+ http://sourceforge.net/projects/libcurl-net/
+
+Object-Pascal
+
+ Free Pascal, Delphi and Kylix binding written by Christophe Espern.
+ http://www.tekool.com/opcurl
+
+O'Caml
+
+ Written by Lars Nilsson
+ http://sourceforge.net/projects/ocurl/
+
+Pascal
+
+ Free Pascal, Delphi and Kylix binding written by Jeffrey Pohlmeyer.
+ http://houston.quik.com/jkp/curlpas/
+
+Perl
+
+ Maintained by Cris Bailiff
+ http://curl.haxx.se/libcurl/perl/
+
+PHP
+
+ Written by Sterling Hughes
+ http://curl.haxx.se/libcurl/php/
+
+PostgreSQL
+
+ Written by Gian Paolo Ciceri
+ http://gborg.postgresql.org/project/pgcurl/projdisplay.php
+
+Python
+
+ PycURL by Kjetil Jacobsen
+ http://pycurl.sourceforge.net/
+
+R
+
+ RCurl by Duncan Temple Lang
+ http://www.omegahat.org/RCurl/
+
+Rexx
+
+ Written Mark Hessling
+ http://rexxcurl.sourceforge.net/
+
+RPG
+
+ Support for ILE/RPG on OS/400 is included in source distribution
+ http://curl.haxx.se/libcurl/
+ See packages/OS400/README.OS400 and packages/OS400/curl.inc.in
+
+Ruby
+
+ curb - written by Ross Bamford
+ http://curb.rubyforge.org/
+
+ ruby-curl-multi - written by Kristjan Petursson and Keith Rarick
+ http://curl-multi.rubyforge.org/
+
+Scheme
+
+ Bigloo binding by Kirill Lisovsky
+ http://curl.haxx.se/libcurl/scheme/
+
+S-Lang
+
+ S-Lang binding by John E Davis
+ http://www.jedsoft.org/slang/modules/curl.html
+
+Smalltalk
+
+ Smalltalk binding by Danil Osipchuk
+ http://www.squeaksource.com/CurlPlugin/
+
+SP-Forth
+
+ SP-Forth binding by ygrek
+ http://www.forth.org.ru/~ac/lib/lin/curl/
+
+SPL
+
+ SPL binding by Clifford Wolf
+ http://www.clifford.at/spl/
+
+Tcl
+
+ Tclcurl by Andrés García
+ http://personal1.iddeo.es/andresgarci/tclcurl/english/docs.html
+
+Visual Basic
+
+ libcurl-vb by Jeffrey Phillips
+ http://sourceforge.net/projects/libcurl-vb/
+
+Visual Foxpro
+
+ by Carlos Alloatti
+ http://www.ctl32.com.ar/libcurl.asp
+
+Q
+ The libcurl module is part of the default install
+ http://q-lang.sourceforge.net/
+
+wxWidgets
+
+ Written by Casey O'Donnell
+ http://wxcode.sourceforge.net/components/wxcurl/
+
+XBLite
+
+ Written by David Szafranski
+ http://perso.wanadoo.fr/xblite/libraries.html
diff --git a/docs/BUGS b/docs/BUGS
new file mode 100644
index 000000000..697b4e5c7
--- /dev/null
+++ b/docs/BUGS
@@ -0,0 +1,148 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+BUGS
+
+ 1. Bugs
+ 1.1 There are still bugs
+ 1.2 Where to report
+ 1.3 What to report
+ 1.4 libcurl problems
+ 1.5 Who will fix the problems
+ 1.6 How to get a stack trace
+ 1.7 Bugs in libcurl bindings
+
+==============================================================================
+
+1.1 There are still bugs
+
+ Curl and libcurl have grown substantially since the beginning. At the time
+ of writing (September 2011), there are about 66000 lines of source code, and
+ by the time you read this it has probably grown even more.
+
+ Of course there are lots of bugs left. And lots of misfeatures.
+
+ To help us make curl the stable and solid product we want it to be, we need
+ bug reports and bug fixes.
+
+1.2 Where to report
+
+ If you can't fix a bug yourself and submit a fix for it, try to report an as
+ detailed report as possible to a curl mailing list to allow one of us to
+ have a go at a solution. You can optionally also post your bug/problem at
+ curl's bug tracking system over at
+
+ http://sourceforge.net/tracker/?group_id=976&atid=100976
+
+ Please read the rest of this document below first before doing that! Also,
+ you need to login to your sourceforge account before being able to submit a
+ bug report (necessary evil done to avoid spam).
+
+ If you feel you need to ask around first, find a suitable mailing list and
+ post there. The lists are available on http://curl.haxx.se/mail/
+
+1.3 What to report
+
+ When reporting a bug, you should include all information that will help us
+ understand what's wrong, what you expected to happen and how to repeat the
+ bad behavior. You therefore need to tell us:
+
+ - your operating system's name and version number
+
+ - what version of curl you're using (curl -V is fine)
+
+ - versions of the used libraries that libcurl is built to use
+
+ - what URL you were working with (if possible), at least which protocol
+
+ and anything and everything else you think matters. Tell us what you
+ expected to happen, tell use what did happen, tell us how you could make it
+ work another way. Dig around, try out, test. Then include all the tiny bits
+ and pieces in your report. You will benefit from this yourself, as it will
+ enable us to help you quicker and more accurately.
+
+ Since curl deals with networks, it often helps us if you include a protocol
+ debug dump with your bug report. The output you get by using the -v or
+ --trace options.
+
+ If curl crashed, causing a core dump (in unix), there is hardly any use to
+ send that huge file to anyone of us. Unless we have an exact same system
+ setup as you, we can't do much with it. Instead we ask you to get a stack
+ trace and send that (much smaller) output to us instead!
+
+ The address and how to subscribe to the mailing lists are detailed in the
+ MANUAL file.
+
+1.4 libcurl problems
+
+ First, post all libcurl problems on the curl-library mailing list.
+
+ When you've written your own application with libcurl to perform transfers,
+ it is even more important to be specific and detailed when reporting bugs.
+
+ Tell us the libcurl version and your operating system. Tell us the name and
+ version of all relevant sub-components like for example the SSL library
+ you're using and what name resolving your libcurl uses. If you use SFTP or
+ SCP, the libssh2 version is relevant etc.
+
+ Showing us a real source code example repeating your problem is the best way
+ to get our attention and it will greatly increase our chances to understand
+ your problem and to work on a fix (if we agree it truly is a problem).
+
+ Lots of problems that appear to be libcurl problems are actually just abuses
+ of the libcurl API or other malfunctions in your applications. It is advised
+ that you run your problematic program using a memory debug tool like
+ valgrind or similar before you post memory-related or "crashing" problems to
+ us.
+
+1.5 Who will fix the problems
+
+ If the problems or bugs you describe are considered to be bugs, we want to
+ have the problems fixed.
+
+ There are no developers in the curl project that are paid to work on bugs.
+ All developers that take on reported bugs do this on a voluntary basis. We
+ do it out of an ambition to keep curl and libcurl excellent products and out
+ of pride.
+
+ But please do not assume that you can just lump over something to us and it
+ will then magically be fixed after some given time. Most often we need
+ feedback and help to understand what you've experienced and how to repeat a
+ problem. Then we may only be able to assist YOU to debug the problem and to
+ track down the proper fix.
+
+ We get reports from many people every month and each report can take a
+ considerable amount of time to really go to the bottom with.
+
+1.6 How to get a stack trace
+
+ First, you must make sure that you compile all sources with -g and that you
+ don't 'strip' the final executable. Try to avoid optimizing the code as
+ well, remove -O, -O2 etc from the compiler options.
+
+ Run the program until it cores.
+
+ Run your debugger on the core file, like '<debugger> curl core'. <debugger>
+ should be replaced with the name of your debugger, in most cases that will
+ be 'gdb', but 'dbx' and others also occur.
+
+ When the debugger has finished loading the core file and presents you a
+ prompt, enter 'where' (without the quotes) and press return.
+
+ The list that is presented is the stack trace. If everything worked, it is
+ supposed to contain the chain of functions that were called when curl
+ crashed. Include the stack trace with your detailed bug report. It'll help a
+ lot.
+
+1.7 Bugs in libcurl bindings
+
+ There will of course pop up bugs in libcurl bindings. You should then
+ primarily approach the team that works on that particular binding and see
+ what you can do to help them fix the problem.
+
+ If you suspect that the problem exists in the underlying libcurl, then
+ please convert your program over to plain C and follow the steps outlined
+ above.
diff --git a/docs/CONTRIBUTE b/docs/CONTRIBUTE
new file mode 100644
index 000000000..33a1f21e8
--- /dev/null
+++ b/docs/CONTRIBUTE
@@ -0,0 +1,303 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+ When Contributing Source Code
+
+ This document is intended to offer guidelines that can be useful to keep in
+ mind when you decide to contribute to the project. This concerns new features
+ as well as corrections to existing flaws or bugs.
+
+ 1. Learning cURL
+ 1.1 Join the Community
+ 1.2 License
+ 1.3 What To Read
+
+ 2. cURL Coding Standards
+ 2.1 Naming
+ 2.2 Indenting
+ 2.3 Commenting
+ 2.4 Line Lengths
+ 2.5 General Style
+ 2.6 Non-clobbering All Over
+ 2.7 Platform Dependent Code
+ 2.8 Write Separate Patches
+ 2.9 Patch Against Recent Sources
+ 2.10 Document
+ 2.11 Test Cases
+
+ 3. Pushing Out Your Changes
+ 3.1 Write Access to git Repository
+ 3.2 How To Make a Patch with git
+ 3.3 How To Make a Patch without git
+ 3.4 How to get your changes into the main sources
+ 3.5 Write good commit messages
+ 3.6 Please don't send pull requests
+
+==============================================================================
+
+1. Learning cURL
+
+1.1 Join the Community
+
+ Skip over to http://curl.haxx.se/mail/ and join the appropriate mailing
+ list(s). Read up on details before you post questions. Read this file before
+ you start sending patches! We prefer patches and discussions being held on
+ the mailing list(s), not sent to individuals.
+
+ Before posting to one of the curl mailing lists, please read up on the mailing
+ list etiquette: http://curl.haxx.se/mail/etiquette.html
+
+ We also hang out on IRC in #curl on irc.freenode.net
+
+1.2. License
+
+ When contributing with code, you agree to put your changes and new code under
+ the same license curl and libcurl is already using unless stated and agreed
+ otherwise.
+
+ If you add a larger piece of code, you can opt to make that file or set of
+ files to use a different license as long as they don't enforce any changes to
+ the rest of the package and they make sense. Such "separate parts" can not be
+ GPL licensed (as we don't want copyleft to affect users of libcurl) but they
+ must use "GPL compatible" licenses (as we want to allow users to use libcurl
+ properly in GPL licensed environments).
+
+ When changing existing source code, you do not alter the copyright of the
+ original file(s). The copyright will still be owned by the original
+ creator(s) or those who have been assigned copyright by the original
+ author(s).
+
+ By submitting a patch to the curl project, you are assumed to have the right
+ to the code and to be allowed by your employer or whatever to hand over that
+ patch/code to us. We will credit you for your changes as far as possible, to
+ give credit but also to keep a trace back to who made what changes. Please
+ always provide us with your full real name when contributing!
+
+1.3 What To Read
+
+ Source code, the man pages, the INTERNALS document, TODO, KNOWN_BUGS, the
+ most recent CHANGES. Just lurking on the libcurl mailing list is gonna give
+ you a lot of insights on what's going on right now. Asking there is a good
+ idea too.
+
+2. cURL Coding Standards
+
+2.1 Naming
+
+ Try using a non-confusing naming scheme for your new functions and variable
+ names. It doesn't necessarily have to mean that you should use the same as in
+ other places of the code, just that the names should be logical,
+ understandable and be named according to what they're used for. File-local
+ functions should be made static. We like lower case names.
+
+ See the INTERNALS document on how we name non-exported library-global
+ symbols.
+
+2.2 Indenting
+
+ Please try using the same indenting levels and bracing method as all the
+ other code already does. It makes the source code a lot easier to follow if
+ all of it is written using the same style. We don't ask you to like it, we
+ just ask you to follow the tradition! ;-) This mainly means: 2-level indents,
+ using spaces only (no tabs) and having the opening brace ({) on the same line
+ as the if() or while().
+
+ Also note that we use if() and while() with no space before the parenthesis.
+
+2.3 Commenting
+
+ Comment your source code extensively using C comments (/* comment */), DO NOT
+ use C++ comments (// this style). Commented code is quality code and enables
+ future modifications much more. Uncommented code risk having to be completely
+ replaced when someone wants to extend things, since other persons' source
+ code can get quite hard to read.
+
+2.4 Line Lengths
+
+ We write source lines shorter than 80 columns.
+
+2.5 General Style
+
+ Keep your functions small. If they're small you avoid a lot of mistakes and
+ you don't accidentally mix up variables etc.
+
+2.6 Non-clobbering All Over
+
+ When you write new functionality or fix bugs, it is important that you don't
+ fiddle all over the source files and functions. Remember that it is likely
+ that other people have done changes in the same source files as you have and
+ possibly even in the same functions. If you bring completely new
+ functionality, try writing it in a new source file. If you fix bugs, try to
+ fix one bug at a time and send them as separate patches.
+
+2.7 Platform Dependent Code
+
+ Use #ifdef HAVE_FEATURE to do conditional code. We avoid checking for
+ particular operating systems or hardware in the #ifdef lines. The
+ HAVE_FEATURE shall be generated by the configure script for unix-like systems
+ and they are hard-coded in the config-[system].h files for the others.
+
+2.8 Write Separate Patches
+
+ It is annoying when you get a huge patch from someone that is said to fix 511
+ odd problems, but discussions and opinions don't agree with 510 of them - or
+ 509 of them were already fixed in a different way. Then the patcher needs to
+ extract the single interesting patch from somewhere within the huge pile of
+ source, and that gives a lot of extra work. Preferably, all fixes that
+ correct different problems should be in their own patch with an attached
+ description exactly what they correct so that all patches can be selectively
+ applied by the maintainer or other interested parties.
+
+2.9 Patch Against Recent Sources
+
+ Please try to get the latest available sources to make your patches
+ against. It makes the life of the developers so much easier. The very best is
+ if you get the most up-to-date sources from the git repository, but the
+ latest release archive is quite OK as well!
+
+2.10 Document
+
+ Writing docs is dead boring and one of the big problems with many open source
+ projects. Someone's gotta do it. It makes it a lot easier if you submit a
+ small description of your fix or your new features with every contribution so
+ that it can be swiftly added to the package documentation.
+
+ The documentation is always made in man pages (nroff formatted) or plain
+ ASCII files. All HTML files on the web site and in the release archives are
+ generated from the nroff/ASCII versions.
+
+2.11 Test Cases
+
+ Since the introduction of the test suite, we can quickly verify that the main
+ features are working as they're supposed to. To maintain this situation and
+ improve it, all new features and functions that are added need to be tested
+ in the test suite. Every feature that is added should get at least one valid
+ test case that verifies that it works as documented. If every submitter also
+ posts a few test cases, it won't end up as a heavy burden on a single person!
+
+3. Pushing Out Your Changes
+
+3.1 Write Access to git Repository
+
+ If you are a frequent contributor, or have another good reason, you can of
+ course get write access to the git repository and then you'll be able to push
+ your changes straight into the git repo instead of sending changes by mail as
+ patches. Just ask if this is what you'd want. You will be required to have
+ posted a few quality patches first, before you can be granted push access.
+
+3.2 How To Make a Patch with git
+
+ You need to first checkout the repository:
+
+ git clone git://github.com/bagder/curl.git
+
+ You then proceed and edit all the files you like and you commit them to your
+ local repository:
+
+ git commit [file]
+
+ As usual, group your commits so that you commit all changes that at once that
+ constitutes a logical change. See also section "3.5 Write good commit
+ messages".
+
+ Once you have done all your commits and you're happy with what you see, you
+ can make patches out of your changes that are suitable for mailing:
+
+ git format-patch remotes/origin/master
+
+ This creates files in your local directory named NNNN-[name].patch for each
+ commit.
+
+ Now send those patches off to the curl-library list. You can of course opt to
+ do that with the 'get send-email' command.
+
+3.3 How To Make a Patch without git
+
+ Keep a copy of the unmodified curl sources. Make your changes in a separate
+ source tree. When you think you have something that you want to offer the
+ curl community, use GNU diff to generate patches.
+
+ If you have modified a single file, try something like:
+
+ diff -u unmodified-file.c my-changed-one.c > my-fixes.diff
+
+ If you have modified several files, possibly in different directories, you
+ can use diff recursively:
+
+ diff -ur curl-original-dir curl-modified-sources-dir > my-fixes.diff
+
+ The GNU diff and GNU patch tools exist for virtually all platforms, including
+ all kinds of Unixes and Windows:
+
+ For unix-like operating systems:
+
+ http://www.gnu.org/software/patch/patch.html
+ http://www.gnu.org/directory/diffutils.html
+
+ For Windows:
+
+ http://gnuwin32.sourceforge.net/packages/patch.htm
+ http://gnuwin32.sourceforge.net/packages/diffutils.htm
+
+3.4 How to get your changes into the main sources
+
+ Submit your patch to the curl-library mailing list.
+
+ Make the patch against as recent sources as possible.
+
+ Make sure your patch adheres to the source indent and coding style of already
+ existing source code. Failing to do so just adds more work for me.
+
+ Respond to replies on the list about the patch and answer questions and/or
+ fix nits/flaws. This is very important. I will take lack of replies as a sign
+ that you're not very anxious to get your patch accepted and I tend to simply
+ drop such patches from my TODO list.
+
+ If you've followed the above paragraphs and your patch still hasn't been
+ incorporated after some weeks, consider resubmitting it to the list.
+
+3.5 Write good commit messages
+
+ A short guide to how to do fine commit messages in the curl project.
+
+ ---- start ----
+ [area]: [short line describing the main effect]
+
+ [separate the above single line from the rest with an empty line]
+
+ [full description, no wider than 72 columns that describe as much as
+ possible as to why this change is made, and possibly what things
+ it fixes and everything else that is related]
+ ---- stop ----
+
+ Don't forget to use commit --author="" if you commit someone else's work,
+ and make sure that you have your own user and email setup correctly in git
+ before you commit
+
+3.6 Please don't send pull requests
+
+ With git (and especially github) it is easy and tempting to send a pull
+ request to one or more people in the curl project to have changes merged this
+ way instead of mailing patches to the curl-library mailing list.
+
+ We don't like that. We want them mailed for these reasons:
+
+ - Peer review. Anyone and everyone on the list can review, comment and
+ improve on the patch. Pull requests limit this ability.
+
+ - Anyone can merge the patch into their own trees for testing and those who
+ have push rights can push it to the main repo. It doesn't have to be anyone
+ the patch author knows beforehand.
+
+ - Commit messages can be tweaked and changed if merged locally instead of
+ using github. Merges directly on github requires the changes to be perfect
+ already, which they seldom are.
+
+ - Merges on github prevents rebases and even enforces --no-ff which is a git
+ style we don't otherwise use in the project
+
+ However: once patches have been reviewed and deemed fine on list they are
+ perfectly OK to be pulled from a published git tree.
diff --git a/docs/DISTRO-DILEMMA b/docs/DISTRO-DILEMMA
new file mode 100644
index 000000000..108e6bad1
--- /dev/null
+++ b/docs/DISTRO-DILEMMA
@@ -0,0 +1,176 @@
+ Date: February 11, 2007
+ Author: Daniel Stenberg <daniel@haxx.se>
+ URL: http://curl.haxx.se/legal/distro-dilemma.html
+
+Condition
+
+ This document is written to describe the situation as it is right now.
+ libcurl 7.16.1 is currently the latest version available. Things may of
+ course change in the future.
+
+ This document reflects my view and understanding of these things. Please tell
+ me where and how you think I'm wrong, and I'll try to correct my mistakes.
+
+Background
+
+ The Free Software Foundation has deemed the Original BSD license[1] to be
+ "incompatible"[2] with GPL[3]. I'd rather say it is the other way around, but
+ the point is the same: if you distribute a binary version of a GPL program,
+ it MUST NOT be linked with any Original BSD-licensed parts or libraries.
+ Doing so will violate the GPL license. For a long time, very many GPL
+ licensed programs have avoided this license mess by adding an exception[8] to
+ their license. And many others have just closed their eyes for this problem.
+
+ libcurl is MIT-style[4] licensed - how on earth did this dilemma fall onto
+ our plates?
+
+ libcurl is only a little library. libcurl can be built to use OpenSSL for its
+ SSL/TLS capabilities. OpenSSL is basically Original BSD licensed[5].
+
+ If libcurl built to use OpenSSL is used by a GPL-licensed application and you
+ decide to distribute a binary version of it (Linux distros - for example -
+ tend to), you have a clash. GPL vs Original BSD.
+
+ This dilemma is not libcurl-specific nor is it specific to any particular
+ Linux distro. (This article mentions and refers to Debian several times, but
+ only because Debian seems to be the only Linux distro to have faced this
+ issue yet since no other distro is shipping libcurl built with two SSL
+ libraries.)
+
+Part of the Operating System
+
+ This would not be a problem if the used lib would be considered part of the
+ underlying operating system, as then the GPL license has an exception
+ clause[6] that allows applications to use such libs without having to be
+ allowed to distribute it or its sources. Possibly some distros will claim
+ that OpenSSL is part of their operating system.
+
+ Debian does however not take this stance and has officially(?) claimed that
+ OpenSSL is not a required part of the Debian operating system
+
+ Some people claim that this paragraph cannot be exploited this way by a Linux
+ distro, but I am not a lawyer and that is a discussion left outside of this
+ document.
+
+GnuTLS
+
+ Since May 2005 libcurl can get built to use GnuTLS instead of OpenSSL. GnuTLS
+ is an LGPL[7] licensed library that offers a matching set of features as
+ OpenSSL does. Now, you can build and distribute an TLS/SSL capable libcurl
+ without including any Original BSD licensed code.
+
+ I believe Debian is the first (only?) distro that provides libcurl/GnutTLS
+ packages.
+
+yassl
+
+ libcurl can get also get built to use yassl for the TLS/SSL layer. yassl is a
+ GPL[3] licensed library.
+
+
+GnuTLS vs OpenSSL vs yassl
+
+ While these three libraries offer similar features, they are not equal.
+ libcurl does not (yet) offer a standardized stable ABI if you decide to
+ switch from using libcurl-openssl to libcurl-gnutls or vice versa. The GnuTLS
+ and yassl support is very recent in libcurl and it has not been tested nor
+ used very extensively, while the OpenSSL equivalent code has been used and
+ thus matured since 1999.
+
+ GnuTLS
+ - LGPL licensened
+ - supports SRP
+ - lacks SSLv2 support
+ - lacks MD2 support (used by at least some CA certs)
+ - lacks the crypto functions libcurl uses for NTLM
+
+ OpenSSL
+ - Original BSD licensened
+ - lacks SRP
+ - supports SSLv2
+ - older and more widely used
+ - provides crypto functions libcurl uses for NTLM
+ - libcurl can do non-blocking connects with it in 7.15.4 and later
+
+ yassl
+ - GPL licensed
+ - much untested and unproven in the real work by (lib)curl users so we don't
+ know a lot about restrictions or benefits from using this
+
+The Better License, Original BSD, GPL or LGPL?
+
+ It isn't obvious or without debate to any objective interested party that
+ either of these licenses are the "better" or even the "preferred" one in a
+ generic situation.
+
+ Instead, I think we should accept the fact that the SSL/TLS libraries and
+ their different licenses will fit different applications and their authors
+ differently depending on the applications' licenses and their general usage
+ pattern (considering how GPL and LGPL libraries for example can be burdensome
+ for embedded systems usage).
+
+ In Debian land, there seems to be a common opinion that LGPL is "maximally
+ compatible" with apps while Original BSD is not. Like this:
+
+ http://lists.debian.org/debian-devel/2005/09/msg01417.html
+
+More SSL Libraries
+
+ In libcurl, there's no stopping us here. There are more Open Source/Free
+ SSL/TLS libraries out there and we would very much like to support them as
+ well, to offer application authors an even wider scope of choice.
+
+Application Angle of this Problem
+
+ libcurl is built to use one SSL/TLS library. It uses a single fixed name (by
+ default) on the built/created lib file, and applications are built/linked to
+ use that single lib. Replacing one libcurl instance with another one that
+ uses the other SSL/TLS library might break one or more applications (due to
+ ABI differences and/or different feature set). You want your application to
+ use the libcurl it was built for.
+
+Project cURL Angle of this Problem
+
+ We distribute libcurl and everyone may build libcurl with either library at
+ their choice. This problem is not directly a problem of ours. It merely
+ affects users - GPL application authors only - of our lib as it comes
+ included and delivered on some distros.
+
+ libcurl has different ABI when built with different SSL/TLS libraries due to
+ these reasons:
+
+ 1. No one has worked on fixing this. The mutex/lock callbacks should be set
+ with a generic libcurl function that should use the proper underlying
+ functions.
+
+ 2. The CURLOPT_SSL_CTX_FUNCTION option is not possible to "emulate" on GnuTLS
+ but simply requires OpenSSL.
+
+ 3. There might be some other subtle differences just because nobody has yet
+ tried to make a fixed ABI like this.
+
+Distro Angle of this Problem
+
+ To my knowledge there is only one distro that ships libcurl built with either
+ OpenSSL or GnuTLS.
+
+ Debian Linux is now (since mid September 2005) providing two different
+ libcurl packages, one for libcurl built with OpenSSL and one built with
+ GnuTLS. They use different .so names and can this both be installed in a
+ single system simultaneously. This has been said to be a transitional system
+ not desired to keep in the long run.
+
+Footnotes
+
+ [1] = http://www.xfree86.org/3.3.6/COPYRIGHT2.html#6
+ [2] = http://www.fsf.org/licensing/essays/bsd.html
+ [3] = http://www.fsf.org/licensing/licenses/gpl.html
+ [4] = http://curl.haxx.se/docs/copyright.html
+ [5] = http://www.openssl.org/source/license.html
+ [6] = http://www.fsf.org/licensing/licenses/gpl.html end of section 3
+ [7] = http://www.fsf.org/licensing/licenses/lgpl.html
+ [8] = http://en.wikipedia.org/wiki/OpenSSL_exception
+
+Feedback/Updates provided by
+
+ Eric Cooper
diff --git a/docs/FAQ b/docs/FAQ
new file mode 100644
index 000000000..130111108
--- /dev/null
+++ b/docs/FAQ
@@ -0,0 +1,1422 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+FAQ
+
+ 1. Philosophy
+ 1.1 What is cURL?
+ 1.2 What is libcurl?
+ 1.3 What is curl not?
+ 1.4 When will you make curl do XXXX ?
+ 1.5 Who makes curl?
+ 1.6 What do you get for making curl?
+ 1.7 What about CURL from curl.com?
+ 1.8 I have a problem who do I mail?
+ 1.9 Where do I buy commercial support for curl?
+ 1.10 How many are using curl?
+ 1.11 Why don't you update ca-bundle.crt
+ 1.12 I have a problem who can I chat with?
+ 1.13 curl's ECCN number?
+ 1.14 How do I submit my patch?
+
+ 2. Install Related Problems
+ 2.1 configure doesn't find OpenSSL even when it is installed
+ 2.1.1 native linker doesn't find OpenSSL
+ 2.1.2 only the libssl lib is missing
+ 2.2 Does curl work/build with other SSL libraries?
+ 2.3 Where can I find a copy of LIBEAY32.DLL?
+ 2.4 Does curl support SOCKS (RFC 1928) ?
+
+ 3. Usage Problems
+ 3.1 curl: (1) SSL is disabled, https: not supported
+ 3.2 How do I tell curl to resume a transfer?
+ 3.3 Why doesn't my posting using -F work?
+ 3.4 How do I tell curl to run custom FTP commands?
+ 3.5 How can I disable the Accept: */* header?
+ 3.6 Does curl support ASP, XML, XHTML or HTML version Y?
+ 3.7 Can I use curl to delete/rename a file through FTP?
+ 3.8 How do I tell curl to follow HTTP redirects?
+ 3.9 How do I use curl in my favorite programming language?
+ 3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP?
+ 3.11 How do I POST with a different Content-Type?
+ 3.12 Why do FTP specific features over HTTP proxy fail?
+ 3.13 Why does my single/double quotes fail?
+ 3.14 Does curl support Javascript or PAC (automated proxy config)?
+ 3.15 Can I do recursive fetches with curl?
+ 3.16 What certificates do I need when I use SSL?
+ 3.17 How do I list the root dir of an FTP server?
+ 3.18 Can I use curl to send a POST/PUT and not wait for a response?
+ 3.19 How do I get HTTP from a host using a specific IP address?
+ 3.20 How to SFTP from my user's home directory?
+ 3.21 Protocol xxx not supported or disabled in libcurl
+
+ 4. Running Problems
+ 4.1 Problems connecting to SSL servers.
+ 4.2 Why do I get problems when I use & or % in the URL?
+ 4.3 How can I use {, }, [ or ] to specify multiple URLs?
+ 4.4 Why do I get downloaded data even though the web page doesn't exist?
+ 4.5 Why do I get return code XXX from a HTTP server?
+ 4.5.1 "400 Bad Request"
+ 4.5.2 "401 Unauthorized"
+ 4.5.3 "403 Forbidden"
+ 4.5.4 "404 Not Found"
+ 4.5.5 "405 Method Not Allowed"
+ 4.5.6 "301 Moved Permanently"
+ 4.6 Can you tell me what error code 142 means?
+ 4.7 How do I keep user names and passwords secret in Curl command lines?
+ 4.8 I found a bug!
+ 4.9 Curl can't authenticate to the server that requires NTLM?
+ 4.10 My HTTP request using HEAD, PUT or DELETE doesn't work!
+ 4.11 Why does my HTTP range requests return the full document?
+ 4.12 Why do I get "certificate verify failed" ?
+ 4.13 Why is curl -R on Windows one hour off?
+ 4.14 Redirects work in browser but not with curl!
+ 4.15 FTPS doesn't work
+ 4.16 My HTTP POST or PUT requests are slow!
+ 4.17 Non-functional connect timeouts on Windows
+ 4.18 file:// URLs containing drive letters (Windows, NetWare)
+ 4.19 Why doesn't cURL return an error when the network cable is unplugged?
+
+ 5. libcurl Issues
+ 5.1 Is libcurl thread-safe?
+ 5.2 How can I receive all data into a large memory chunk?
+ 5.3 How do I fetch multiple files with libcurl?
+ 5.4 Does libcurl do Winsock initing on win32 systems?
+ 5.5 Does CURLOPT_WRITEDATA and CURLOPT_READDATA work on win32 ?
+ 5.6 What about Keep-Alive or persistent connections?
+ 5.7 Link errors when building libcurl on Windows!
+ 5.8 libcurl.so.X: open failed: No such file or directory
+ 5.9 How does libcurl resolve host names?
+ 5.10 How do I prevent libcurl from writing the response to stdout?
+ 5.11 How do I make libcurl not receive the whole HTTP response?
+ 5.12 Can I make libcurl fake or hide my real IP address?
+ 5.13 How do I stop an ongoing transfer?
+ 5.14 Using C++ non-static functions for callbacks?
+ 5.15 How do I get an FTP directory listing?
+ 5.16 I want a different time-out!
+
+ 6. License Issues
+ 6.1 I have a GPL program, can I use the libcurl library?
+ 6.2 I have a closed-source program, can I use the libcurl library?
+ 6.3 I have a BSD licensed program, can I use the libcurl library?
+ 6.4 I have a program that uses LGPL libraries, can I use libcurl?
+ 6.5 Can I modify curl/libcurl for my program and keep the changes secret?
+ 6.6 Can you please change the curl/libcurl license to XXXX?
+ 6.7 What are my obligations when using libcurl in my commercial apps?
+
+ 7. PHP/CURL Issues
+ 7.1 What is PHP/CURL?
+ 7.2 Who wrote PHP/CURL?
+ 7.3 Can I perform multiple requests using the same handle?
+
+==============================================================================
+
+1. Philosophy
+
+ 1.1 What is cURL?
+
+ cURL is the name of the project. The name is a play on 'Client for URLs',
+ originally with URL spelled in uppercase to make it obvious it deals with
+ URLs. The fact it can also be pronounced 'see URL' also helped, it works as
+ an abbreviation for "Client URL Request Library" or why not the recursive
+ version: "Curl URL Request Library".
+
+ The cURL project produces two products:
+
+ libcurl
+
+ A free and easy-to-use client-side URL transfer library, supporting DICT,
+ FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3,
+ POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP.
+
+ libcurl supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading,
+ kerberos, HTTP form based upload, proxies, cookies, user+password
+ authentication, file transfer resume, http proxy tunneling and more!
+
+ libcurl is highly portable, it builds and works identically on numerous
+ platforms, including Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HPUX,
+ IRIX, AIX, Tru64, Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOS, Mac
+ OS X, Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS, Symbian, OSF,
+ Android, Minix, IBM TPF and more...
+
+ libcurl is free, thread-safe, IPv6 compatible, feature rich, well
+ supported and fast.
+
+ curl
+
+ A command line tool for getting or sending files using URL syntax.
+
+ Since curl uses libcurl, curl supports the same wide range of common
+ Internet protocols that libcurl does.
+
+ We pronounce curl and cURL with an initial k sound: [kurl].
+
+ There are numerous sub-projects and related projects that also use the word
+ curl in the project names in various combinations, but you should take
+ notice that this FAQ is directed at the command-line tool named curl (and
+ libcurl the library), and may therefore not be valid for other curl-related
+ projects. (There is however a small section for the PHP/CURL in this FAQ.)
+
+ 1.2 What is libcurl?
+
+ libcurl is a reliable and portable library which provides you with an easy
+ interface to a range of common Internet protocols.
+
+ You can use libcurl for free in your application, be it open source,
+ commercial or closed-source.
+
+ libcurl is most probably the most portable, most powerful and most often
+ used C-based multi-platform file transfer library on this planet - be it
+ open source or commercial.
+
+ 1.3 What is curl not?
+
+ Curl is not a wget clone. That is a common misconception. Never, during
+ curl's development, have we intended curl to replace wget or compete on its
+ market. Curl is targeted at single-shot file transfers.
+
+ Curl is not a web site mirroring program. If you want to use curl to mirror
+ something: fine, go ahead and write a script that wraps around curl to make
+ it reality (like curlmirror.pl does).
+
+ Curl is not an FTP site mirroring program. Sure, get and send FTP with curl
+ but if you want systematic and sequential behavior you should write a
+ script (or write a new program that interfaces libcurl) and do it.
+
+ Curl is not a PHP tool, even though it works perfectly well when used from
+ or with PHP (when using the PHP/CURL module).
+
+ Curl is not a program for a single operating system. Curl exists, compiles,
+ builds and runs under a wide range of operating systems, including all
+ modern Unixes (and a bunch of older ones too), Windows, Amiga, BeOS, OS/2,
+ OS X, QNX etc.
+
+ 1.4 When will you make curl do XXXX ?
+
+ We love suggestions of what to change in order to make curl and libcurl
+ better. We do however believe in a few rules when it comes to the future of
+ curl:
+
+ * Curl -- the command line tool -- is to remain a non-graphical command line
+ tool. If you want GUIs or fancy scripting capabilities, you should look
+ for another tool that uses libcurl.
+
+ * We do not add things to curl that other small and available tools already
+ do very fine at the side. Curl's output is fine to pipe into another
+ program or redirect to another file for the next program to interpret.
+
+ * We focus on protocol related issues and improvements. If you wanna do more
+ magic with the supported protocols than curl currently does, chances are
+ big we will agree. If you wanna add more protocols, we may very well
+ agree.
+
+ * If you want someone else to make all the work while you wait for us to
+ implement it for you, that is not a very friendly attitude. We spend a
+ considerable time already on maintaining and developing curl. In order to
+ get more out of us, you should consider trading in some of your time and
+ efforts in return.
+
+ * If you write the code, chances are bigger that it will get into curl
+ faster.
+
+ 1.5 Who makes curl?
+
+ curl and libcurl are not made by any single individual. Daniel Stenberg is
+ project leader and main developer, but other persons' submissions are
+ important and crucial. Anyone can contribute and post their changes and
+ improvements and have them inserted in the main sources (of course on the
+ condition that developers agree on that the fixes are good).
+
+ The full list of all contributors is found in the docs/THANKS file.
+
+ curl is developed by a community, with Daniel at the wheel.
+
+ 1.6 What do you get for making curl?
+
+ Project cURL is entirely free and open. No person gets paid for developing
+ (lib)curl on full or even part time. We do this voluntarily on our spare
+ time. Occasionally companies pay individual developers to work on curl, but
+ that's up to each company and developer. It is not controlled by nor
+ supervised in any way by the project.
+
+ We still get help from companies. Haxx provides web site, bandwidth, mailing
+ lists etc and sourceforge.net hosts project services we take advantage from,
+ like the bug tracker. Also again, some companies have sponsored certain
+ parts of the development in the past and I hope some will continue to do so
+ in the future.
+
+ If you want to support our project, consider a donation or a banner-program
+ or even better: by helping us coding, documenting, testing etc.
+
+ 1.7 What about CURL from curl.com?
+
+ During the summer 2001, curl.com was busy advertising their client-side
+ programming language for the web, named CURL.
+
+ We are in no way associated with curl.com or their CURL programming
+ language.
+
+ Our project name curl has been in effective use since 1998. We were not the
+ first computer related project to use the name "curl" and do not claim any
+ first-hand rights to the name.
+
+ We recognize that we will be living in parallel with curl.com and wish them
+ every success.
+
+ 1.8 I have a problem who do I mail?
+
+ Please do not mail any single individual unless you really need to. Keep
+ curl-related questions on a suitable mailing list. All available mailing
+ lists are listed in the MANUAL document and online at
+ http://curl.haxx.se/mail/
+
+ Keeping curl-related questions and discussions on mailing lists allows
+ others to join in and help, to share their ideas, contribute their
+ suggestions and spread their wisdom. Keeping discussions on public mailing
+ lists also allows for others to learn from this (both current and future
+ users thanks to the web based archives of the mailing lists), thus saving us
+ from having to repeat ourselves even more. Thanks for respecting this.
+
+ If you have found or simply suspect a security problem in curl or libcurl,
+ mail curl-security at haxx.se (closed list of receivers, mails are not
+ disclosed) and tell. Then we can produce a fix in a timely manner before the
+ flaw is announced to the world, thus lessen the impact the problem will have
+ on existing users.
+
+ 1.9 Where do I buy commercial support for curl?
+
+ curl is fully open source. It means you can hire any skilled engineer to fix
+ your curl-related problems.
+
+ We list available alternatives on the curl web site:
+ http://curl.haxx.se/support.html
+
+ 1.10 How many are using curl?
+
+ It is impossible to tell.
+
+ We don't know how many users that knowingly have installed and use curl.
+
+ We don't know how many users that use curl without knowing that they are in
+ fact using it.
+
+ We don't know how many users that downloaded or installed curl and then
+ never use it.
+
+ In May 2012 Daniel did a counting game and came up with a number that may
+ be completely wrong or somewhat accurate. 300 million!
+
+ See http://daniel.haxx.se/blog/2012/05/16/300m-users/
+
+ 1.11 Why don't you update ca-bundle.crt
+
+ The ca-bundle.crt file that used to be bundled with curl was very outdated
+ (it being last modified year 2000 should tell) and must be replaced with a
+ much more modern and up-to-date version by anyone who wants to verify peers
+ anyway. It is no longer provided, the last curl release that shipped it was
+ curl 7.18.0.
+
+ In the cURL project we've decided not to attempt to keep this file updated
+ (or even present anymore) since deciding what to add to a ca cert bundle is
+ an undertaking we've not been ready to accept, and the one we can get from
+ Mozilla is perfectly fine so there's no need to duplicate that work.
+
+ Today, with many services performed over HTTPS, every operating system
+ should come with a default ca cert bundle that can be deemed somewhat
+ trustworthy and that collection (if reasonably updated) should be deemed to
+ be a lot better than a private curl version.
+
+ If you want the most recent collection of ca certs that Mozilla Firefox
+ uses, we recommend that you extract the collection yourself from Mozilla
+ Firefox (by running 'make ca-bundle), or by using our online service setup
+ for this purpose: http://curl.haxx.se/docs/caextract.html
+
+ 1.12 I have a problem who can I chat with?
+
+ There's a bunch of friendly people hanging out in the #curl channel on the
+ IRC network irc.freenode.net. If you're polite and nice, chances are big
+ that you can get -- or provide -- help instantly.
+
+ 1.13 curl's ECCN number?
+
+ The US government restricts exports of software that contains or uses
+ cryptography. When doing so, the Export Control Classification Number (ECCN)
+ is used to identify the level of export control etc.
+
+ ASF gives a good explanation at http://www.apache.org/dev/crypto.html
+
+ We believe curl's number might be ECCN 5D002, another possibility is
+ 5D992. It seems necessary to write them, asking to confirm.
+
+ Comprehensible explanations of the meaning of such numbers and how to
+ obtain them (resp.) are here
+
+ http://www.bis.doc.gov/licensing/exportingbasics.htm
+ http://www.bis.doc.gov/licensing/do_i_needaneccn.html
+
+ An incomprehensible description of the two numbers above is here
+ http://www.access.gpo.gov/bis/ear/pdf/ccl5-pt2.pdf
+
+ 1.14 How do I submit my patch?
+
+ When you have made a patch or a change of whatever sort, and want to submit
+ that to the project, there are a few different ways we prefer:
+
+ o send a patch to the curl-library mailing list. We're many subscribers
+ there and there are lots of people who can review patches, comment on them
+ and "receive" them properly.
+
+ o if your patch changes or fixes a bug, you can also opt to submit a bug
+ report in the bug tracker and attach your patch there. There are less
+ people involved there.
+
+ Lots of more details are found in the CONTRIBUTE and INTERNALS docs.
+
+
+2. Install Related Problems
+
+ 2.1 configure doesn't find OpenSSL even when it is installed
+
+ This may be because of several reasons.
+
+ 2.1.1 native linker doesn't find openssl
+
+ Affected platforms:
+ Solaris (native cc compiler)
+ HPUX (native cc compiler)
+ SGI IRIX (native cc compiler)
+ SCO UNIX (native cc compiler)
+
+ When configuring curl, I specify --with-ssl. OpenSSL is installed in
+ /usr/local/ssl Configure reports SSL in /usr/local/ssl, but fails to find
+ CRYPTO_lock in -lcrypto
+
+ Cause: The cc for this test places the -L/usr/local/ssl/lib AFTER
+ -lcrypto, so ld can't find the library. This is due to a bug in the GNU
+ autoconf tool.
+
+ Workaround: Specifying "LDFLAGS=-L/usr/local/ssl/lib" in front of
+ ./configure places the -L/usr/local/ssl/lib early enough in the command
+ line to make things work
+
+ 2.1.2 only the libssl lib is missing
+
+ If all include files and the libcrypto lib is present, with only the
+ libssl being missing according to configure, this is mostly likely because
+ a few functions are left out from the libssl.
+
+ If the function names missing include RSA or RSAREF you can be certain
+ that this is because libssl requires the RSA and RSAREF libs to build.
+
+ See the INSTALL file section that explains how to add those libs to
+ configure. Make sure that you remove the config.cache file before you
+ rerun configure with the new flags.
+
+ 2.2 Does curl work/build with other SSL libraries?
+
+ Curl has been written to use OpenSSL, GnuTLS, yassl, NSS, PolarSSL, axTLS or
+ qssl, although there should not be many problems using a different
+ library. If anyone does "port" curl to use a different SSL library, we are
+ of course very interested in getting the patch!
+
+ 2.3 Where can I find a copy of LIBEAY32.DLL?
+
+ That is an OpenSSL binary built for Windows.
+
+ Curl uses OpenSSL to do the SSL stuff. The LIBEAY32.DLL is what curl needs
+ on a windows machine to do https://. Check out the curl web site to find
+ accurate and up-to-date pointers to recent OpenSSL DLLs and other binary
+ packages.
+
+ 2.4 Does curl support SOCKS (RFC 1928) ?
+
+ Yes, SOCKS 4 and 5 are supported.
+
+
+3. Usage problems
+
+ 3.1 curl: (1) SSL is disabled, https: not supported
+
+ If you get this output when trying to get anything from a https:// server,
+ it means that the instance of curl/libcurl that you're using was built
+ without support for this protocol.
+
+ This could've happened if the configure script that was run at build time
+ couldn't find all libs and include files curl requires for SSL to work. If
+ the configure script fails to find them, curl is simply built without SSL
+ support.
+
+ To get the https:// support into a curl that was previously built but that
+ reports that https:// is not supported, you should dig through the document
+ and logs and check out why the configure script doesn't find the SSL libs
+ and/or include files.
+
+ Also, check out the other paragraph in this FAQ labelled "configure doesn't
+ find OpenSSL even when it is installed".
+
+ 3.2 How do I tell curl to resume a transfer?
+
+ Curl supports resumed transfers both ways on both FTP and HTTP.
+ Try the -C option.
+
+ 3.3 Why doesn't my posting using -F work?
+
+ You can't simply use -F or -d at your choice. The web server that will
+ receive your post assumes one of the formats. If the form you're trying to
+ "fake" sets the type to 'multipart/form-data', then and only then you must
+ use the -F type. In all the most common cases, you should use -d which then
+ causes a posting with the type 'application/x-www-form-urlencoded'.
+
+ This is described in some detail in the MANUAL and TheArtOfHttpScripting
+ documents, and if you don't understand it the first time, read it again
+ before you post questions about this to the mailing list. Also, try reading
+ through the mailing list archives for old postings and questions regarding
+ this.
+
+ 3.4 How do I tell curl to run custom FTP commands?
+
+ You can tell curl to perform optional commands both before and/or after a
+ file transfer. Study the -Q/--quote option.
+
+ Since curl is used for file transfers, you don't normally use curl to
+ perform FTP commands without transferring anything. Therefore you must
+ always specify a URL to transfer to/from even when doing custom FTP
+ commands, or use -I which implies the "no body" option sent to libcurl.
+
+ 3.5 How can I disable the Accept: */* header?
+
+ You can change all internally generated headers by adding a replacement with
+ the -H/--header option. By adding a header with empty contents you safely
+ disable that one. Use -H "Accept:" to disable that specific header.
+
+ 3.6 Does curl support ASP, XML, XHTML or HTML version Y?
+
+ To curl, all contents are alike. It doesn't matter how the page was
+ generated. It may be ASP, PHP, Perl, shell-script, SSI or plain
+ HTML-files. There's no difference to curl and it doesn't even know what kind
+ of language that generated the page.
+
+ See also item 3.14 regarding javascript.
+
+ 3.7 Can I use curl to delete/rename a file through FTP?
+
+ Yes. You specify custom FTP commands with -Q/--quote.
+
+ One example would be to delete a file after you have downloaded it:
+
+ curl -O ftp://download.com/coolfile -Q '-DELE coolfile'
+
+ or rename a file after upload:
+
+ curl -T infile ftp://upload.com/dir/ -Q "-RNFR infile" -Q "-RNTO newname"
+
+ 3.8 How do I tell curl to follow HTTP redirects?
+
+ Curl does not follow so-called redirects by default. The Location: header
+ that informs the client about this is only interpreted if you're using the
+ -L/--location option. As in:
+
+ curl -L http://redirector.com
+
+ Not all redirects are HTTP ones, see 4.14
+
+ 3.9 How do I use curl in my favorite programming language?
+
+ There exist many language interfaces/bindings for curl that integrates it
+ better with various languages. If you are fluid in a script language, you
+ may very well opt to use such an interface instead of using the command line
+ tool.
+
+ Find out more about which languages that support curl directly, and how to
+ install and use them, in the libcurl section of the curl web site:
+ http://curl.haxx.se/libcurl/
+
+ All the various bindings to libcurl are made by other projects and people,
+ outside of the cURL project. The cURL project itself only produces libcurl
+ with its plain C API. If you don't find anywhere else to ask you can ask
+ about bindings on the curl-library list too, but be prepared that people on
+ that list may not know anything about bindings.
+
+ In October 2009, there were interfaces available for the following
+ languages: Ada95, Basic, C, C++, Ch, Cocoa, D, Dylan, Eiffel, Euphoria,
+ Ferite, Gambas, glib/GTK+, Haskell, ILE/RPG, Java, Lisp, Lua, Mono, .NET,
+ Object-Pascal, O'Caml, Pascal, Perl, PHP, PostgreSQL, Python, R, Rexx, Ruby,
+ Scheme, S-Lang, Smalltalk, SP-Forth, SPL, Tcl, Visual Basic, Visual FoxPro,
+ Q, wxwidgets and XBLite. By the time you read this, additional ones may have
+ appeared!
+
+ 3.10 What about SOAP, WebDAV, XML-RPC or similar protocols over HTTP?
+
+ Curl adheres to the HTTP spec, which basically means you can play with *any*
+ protocol that is built on top of HTTP. Protocols such as SOAP, WEBDAV and
+ XML-RPC are all such ones. You can use -X to set custom requests and -H to
+ set custom headers (or replace internally generated ones).
+
+ Using libcurl is of course just as fine and you'd just use the proper
+ library options to do the same.
+
+ 3.11 How do I POST with a different Content-Type?
+
+ You can always replace the internally generated headers with -H/--header.
+ To make a simple HTTP POST with text/xml as content-type, do something like:
+
+ curl -d "datatopost" -H "Content-Type: text/xml" [URL]
+
+ 3.12 Why do FTP specific features over HTTP proxy fail?
+
+ Because when you use a HTTP proxy, the protocol spoken on the network will
+ be HTTP, even if you specify a FTP URL. This effectively means that you
+ normally can't use FTP specific features such as FTP upload and FTP quote
+ etc.
+
+ There is one exception to this rule, and that is if you can "tunnel through"
+ the given HTTP proxy. Proxy tunneling is enabled with a special option (-p)
+ and is generally not available as proxy admins usually disable tunneling to
+ other ports than 443 (which is used for HTTPS access through proxies).
+
+ 3.13 Why does my single/double quotes fail?
+
+ To specify a command line option that includes spaces, you might need to
+ put the entire option within quotes. Like in:
+
+ curl -d " with spaces " url.com
+
+ or perhaps
+
+ curl -d ' with spaces ' url.com
+
+ Exactly what kind of quotes and how to do this is entirely up to the shell
+ or command line interpreter that you are using. For most unix shells, you
+ can more or less pick either single (') or double (") quotes. For
+ Windows/DOS prompts I believe you're forced to use double (") quotes.
+
+ Please study the documentation for your particular environment. Examples in
+ the curl docs will use a mix of both these ones as shown above. You must
+ adjust them to work in your environment.
+
+ Remember that curl works and runs on more operating systems than most single
+ individuals have ever tried.
+
+ 3.14 Does curl support Javascript or PAC (automated proxy config)?
+
+ Many web pages do magic stuff using embedded Javascript. Curl and libcurl
+ have no built-in support for that, so it will be treated just like any other
+ contents.
+
+ .pac files are a netscape invention and are sometimes used by organizations
+ to allow them to differentiate which proxies to use. The .pac contents is
+ just a Javascript program that gets invoked by the browser and that returns
+ the name of the proxy to connect to. Since curl doesn't support Javascript,
+ it can't support .pac proxy configuration either.
+
+ Some workarounds usually suggested to overcome this Javascript dependency:
+
+ - Depending on the Javascript complexity, write up a script that
+ translates it to another language and execute that.
+
+ - Read the Javascript code and rewrite the same logic in another language.
+
+ - Implement a Javascript interpreter, people have successfully used the
+ Mozilla Javascript engine in the past.
+
+ - Ask your admins to stop this, for a static proxy setup or similar.
+
+ 3.15 Can I do recursive fetches with curl?
+
+ No. curl itself has no code that performs recursive operations, such as
+ those performed by wget and similar tools.
+
+ There exist wrapper scripts with that functionality (for example the
+ curlmirror perl script), and you can write programs based on libcurl to do
+ it, but the command line tool curl itself cannot.
+
+ 3.16 What certificates do I need when I use SSL?
+
+ There are three different kinds of "certificates" to keep track of when we
+ talk about using SSL-based protocols (HTTPS or FTPS) using curl or libcurl.
+
+ - Client certificate. The server you communicate may require that you can
+ provide this in order to prove that you actually are who you claim to be.
+ If the server doesn't require this, you don't need a client certificate.
+
+ A client certificate is always used together with a private key, and the
+ private key has a pass phrase that protects it.
+
+ - Server certificate. The server you communicate with has a server
+ certificate. You can and should verify this certificate to make sure that
+ you are truly talking to the real server and not a server impersonating
+ it.
+
+ - Certificate Authority certificate ("CA cert"). You often have several CA
+ certs in a CA cert bundle that can be used to verify a server certificate
+ that was signed by one of the authorities in the bundle. curl does not
+ come with a CA cert bundle but most curl installs provide one. You can
+ also override the default.
+
+ The server certificate verification process is made by using a Certificate
+ Authority certificate ("CA cert") that was used to sign the server
+ certificate. Server certificate verification is enabled by default in curl
+ and libcurl and is often the reason for problems as explained in FAQ entry
+ 4.12 and the SSLCERTS document
+ (http://curl.haxx.se/docs/sslcerts.html). Server certificates that are
+ "self-signed" or otherwise signed by a CA that you do not have a CA cert
+ for, cannot be verified. If the verification during a connect fails, you
+ are refused access. You then need to explicitly disable the verification
+ to connect to the server.
+
+ 3.17 How do I list the root dir of an FTP server?
+
+ There are two ways. The way defined in the RFC is to use an encoded slash
+ in the first path part. List the "/tmp" dir like this:
+
+ curl ftp://ftp.sunet.se/%2ftmp/
+
+ or the not-quite-kosher-but-more-readable way, by simply starting the path
+ section of the URL with a slash:
+
+ curl ftp://ftp.sunet.se//tmp/
+
+ 3.18 Can I use curl to send a POST/PUT and not wait for a response?
+
+ No.
+
+ But you could easily write your own program using libcurl to do such stunts.
+
+ 3.19 How do I get HTTP from a host using a specific IP address?
+
+ For example, you may be trying out a web site installation that isn't yet in
+ the DNS. Or you have a site using multiple IP addresses for a given host
+ name and you want to address a specific one out of the set.
+
+ Set a custom Host: header that identifies the server name you want to reach
+ but use the target IP address in the URL:
+
+ curl --header "Host: www.example.com" http://127.0.0.1/
+
+ You can also opt to add faked host name entries to curl with the --resolve
+ option. That has the added benefit that things like redirects will also work
+ properly. The above operation would instead be done as:
+
+ curl --resolve www.example.com:80:127.0.0.1 http://www.example.com/
+
+ 3.20 How to SFTP from my user's home directory?
+
+ Contrary to how FTP works, SFTP and SCP URLs specify the exact directory to
+ work with. It means that if you don't specify that you want the user's home
+ directory, you get the actual root directory.
+
+ To specify a file in your user's home directory, you need to use the correct
+ URL syntax which for sftp might look similar to:
+
+ curl -O -u user:password sftp://example.com/~/file.txt
+
+ and for SCP it is just a different protocol prefix:
+
+ curl -O -u user:password scp://example.com/~/file.txt
+
+ 3.21 Protocol xxx not supported or disabled in libcurl
+
+ When passing on a URL to curl to use, it may respond that the particular
+ protocol is not supported or disabled. The particular way this error message
+ is phrased is because curl doesn't make a distinction internally of whether
+ a particular protocol is not supported (ie never got any code added that
+ knows how to speak that protocol) or if it was explicitly disabled. curl can
+ be built to only support a given set of protocols, and the rest would then
+ be disabled or not supported.
+
+ Note that this error will also occur if you pass a wrongly spelled protocol
+ part as in "htpt://example.com" or as in the less evident case if you prefix
+ the protocol part with a space as in " http://example.com/".
+
+
+4. Running Problems
+
+ 4.1 Problems connecting to SSL servers.
+
+ It took a very long time before we could sort out why curl had problems to
+ connect to certain SSL servers when using SSLeay or OpenSSL v0.9+. The
+ error sometimes showed up similar to:
+
+ 16570:error:1407D071:SSL routines:SSL2_READ:bad mac decode:s2_pkt.c:233:
+
+ It turned out to be because many older SSL servers don't deal with SSLv3
+ requests properly. To correct this problem, tell curl to select SSLv2 from
+ the command line (-2/--sslv2).
+
+ There have also been examples where the remote server didn't like the SSLv2
+ request and instead you had to force curl to use SSLv3 with -3/--sslv3.
+
+ 4.2 Why do I get problems when I use & or % in the URL?
+
+ In general unix shells, the & symbol is treated specially and when used, it
+ runs the specified command in the background. To safely send the & as a part
+ of a URL, you should quote the entire URL by using single (') or double (")
+ quotes around it. Similar problems can also occur on some shells with other
+ characters, including ?*!$~(){}<>\|;`. When in doubt, quote the URL.
+
+ An example that would invoke a remote CGI that uses &-symbols could be:
+
+ curl 'http://www.altavista.com/cgi-bin/query?text=yes&q=curl'
+
+ In Windows, the standard DOS shell treats the %-symbol specially and you
+ need to use TWO %-symbols for each single one you want to use in the URL.
+
+ Also note that if you want the literal %-symbol to be part of the data you
+ pass in a POST using -d/--data you must encode it as '%25' (which then also
+ needs the %-symbol doubled on Windows machines).
+
+ 4.3 How can I use {, }, [ or ] to specify multiple URLs?
+
+ Because those letters have a special meaning to the shell, and to be used in
+ a URL specified to curl you must quote them.
+
+ An example that downloads two URLs (sequentially) would do:
+
+ curl '{curl,www}.haxx.se'
+
+ To be able to use those letters as actual parts of the URL (without using
+ them for the curl URL "globbing" system), use the -g/--globoff option:
+
+ curl -g 'www.site.com/weirdname[].html'
+
+ 4.4 Why do I get downloaded data even though the web page doesn't exist?
+
+ Curl asks remote servers for the page you specify. If the page doesn't exist
+ at the server, the HTTP protocol defines how the server should respond and
+ that means that headers and a "page" will be returned. That's simply how
+ HTTP works.
+
+ By using the --fail option you can tell curl explicitly to not get any data
+ if the HTTP return code doesn't say success.
+
+ 4.5 Why do I get return code XXX from a HTTP server?
+
+ RFC2616 clearly explains the return codes. This is a short transcript. Go
+ read the RFC for exact details:
+
+ 4.5.1 "400 Bad Request"
+
+ The request could not be understood by the server due to malformed
+ syntax. The client SHOULD NOT repeat the request without modifications.
+
+ 4.5.2 "401 Unauthorized"
+
+ The request requires user authentication.
+
+ 4.5.3 "403 Forbidden"
+
+ The server understood the request, but is refusing to fulfil it.
+ Authorization will not help and the request SHOULD NOT be repeated.
+
+ 4.5.4 "404 Not Found"
+
+ The server has not found anything matching the Request-URI. No indication
+ is given of whether the condition is temporary or permanent.
+
+ 4.5.5 "405 Method Not Allowed"
+
+ The method specified in the Request-Line is not allowed for the resource
+ identified by the Request-URI. The response MUST include an Allow header
+ containing a list of valid methods for the requested resource.
+
+ 4.5.6 "301 Moved Permanently"
+
+ If you get this return code and an HTML output similar to this:
+
+ <H1>Moved Permanently</H1> The document has moved <A
+ HREF="http://same_url_now_with_a_trailing_slash/">here</A>.
+
+ it might be because you request a directory URL but without the trailing
+ slash. Try the same operation again _with_ the trailing URL, or use the
+ -L/--location option to follow the redirection.
+
+ 4.6 Can you tell me what error code 142 means?
+
+ All curl error codes are described at the end of the man page, in the
+ section called "EXIT CODES".
+
+ Error codes that are larger than the highest documented error code means
+ that curl has exited due to a crash. This is a serious error, and we
+ appreciate a detailed bug report from you that describes how we could go
+ ahead and repeat this!
+
+ 4.7 How do I keep user names and passwords secret in Curl command lines?
+
+ This problem has two sides:
+
+ The first part is to avoid having clear-text passwords in the command line
+ so that they don't appear in 'ps' outputs and similar. That is easily
+ avoided by using the "-K" option to tell curl to read parameters from a file
+ or stdin to which you can pass the secret info. curl itself will also
+ attempt to "hide" the given password by blanking out the option - this
+ doesn't work on all platforms.
+
+ To keep the passwords in your account secret from the rest of the world is
+ not a task that curl addresses. You could of course encrypt them somehow to
+ at least hide them from being read by human eyes, but that is not what
+ anyone would call security.
+
+ Also note that regular HTTP (using Basic authentication) and FTP passwords
+ are sent in clear across the network. All it takes for anyone to fetch them
+ is to listen on the network. Eavesdropping is very easy. Use more secure
+ authentication methods (like Digest, Negotiate or even NTLM) or consider the
+ SSL-based alternatives HTTPS and FTPS.
+
+ 4.8 I found a bug!
+
+ It is not a bug if the behavior is documented. Read the docs first.
+ Especially check out the KNOWN_BUGS file, it may be a documented bug!
+
+ If it is a problem with a binary you've downloaded or a package for your
+ particular platform, try contacting the person who built the package/archive
+ you have.
+
+ If there is a bug, read the BUGS document first. Then report it as described
+ in there.
+
+ 4.9 Curl can't authenticate to the server that requires NTLM?
+
+ NTLM support requires OpenSSL, GnuTLS, NSS or Microsoft Windows libraries at
+ build-time to provide this functionality.
+
+ NTLM is a Microsoft proprietary protocol. Proprietary formats are evil. You
+ should not use such ones.
+
+ 4.10 My HTTP request using HEAD, PUT or DELETE doesn't work!
+
+ Many web servers allow or demand that the administrator configures the
+ server properly for these requests to work on the web server.
+
+ Some servers seem to support HEAD only on certain kinds of URLs.
+
+ To fully grasp this, try the documentation for the particular server
+ software you're trying to interact with. This is not anything curl can do
+ anything about.
+
+ 4.11 Why does my HTTP range requests return the full document?
+
+ Because the range may not be supported by the server, or the server may
+ choose to ignore it and return the full document anyway.
+
+ 4.12 Why do I get "certificate verify failed" ?
+
+ You invoke curl 7.10 or later to communicate on a https:// URL and get an
+ error back looking something similar to this:
+
+ curl: (35) SSL: error:14090086:SSL routines:
+ SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
+
+ Then it means that curl couldn't verify that the server's certificate was
+ good. Curl verifies the certificate using the CA cert bundle that comes with
+ the curl installation.
+
+ To disable the verification (which makes it act like curl did before 7.10),
+ use -k. This does however enable man-in-the-middle attacks.
+
+ If you get this failure but are having a CA cert bundle installed and used,
+ the server's certificate is not signed by one of the CA's in the bundle. It
+ might for example be self-signed. You then correct this problem by obtaining
+ a valid CA cert for the server. Or again, decrease the security by disabling
+ this check.
+
+ Details are also in the SSLCERTS file in the release archives, found online
+ here: http://curl.haxx.se/docs/sslcerts.html
+
+ 4.13 Why is curl -R on Windows one hour off?
+
+ During daylight savings time, when -R is used, curl will set a time that
+ appears one hour off. This happens due to a flaw in how Windows stores and
+ uses file modification times and it is not easily worked around. For details
+ on this problem, read this: http://www.codeproject.com/datetime/dstbugs.asp
+
+ 4.14 Redirects work in browser but not with curl!
+
+ curl supports HTTP redirects fine (see item 3.8). Browsers generally support
+ at least two other ways to perform directs that curl does not:
+
+ - Meta tags. You can write a HTML tag that will cause the browser to
+ redirect to another given URL after a certain time.
+
+ - Javascript. You can write a Javascript program embedded in a HTML page
+ that redirects the browser to another given URL.
+
+ There is no way to make curl follow these redirects. You must either
+ manually figure out what the page is set to do, or you write a script that
+ parses the results and fetches the new URL.
+
+ 4.15 FTPS doesn't work
+
+ curl supports FTPS (sometimes known as FTP-SSL) both implicit and explicit
+ mode.
+
+ When a URL is used that starts with FTPS://, curl assumes implicit SSL on
+ the control connection and will therefore immediately connect and try to
+ speak SSL. FTPS:// connections default to port 990.
+
+ To use explicit FTPS, you use a FTP:// URL and the --ftp-ssl option (or one
+ of its related flavours). This is the most common method, and the one
+ mandated by RFC4217. This kind of connection then of course uses the
+ standard FTP port 21 by default.
+
+ 4.16 My HTTP POST or PUT requests are slow!
+
+ libcurl makes all POST and PUT requests (except for POST requests with a
+ very tiny request body) use the "Expect: 100-continue" header. This header
+ allows the server to deny the operation early so that libcurl can bail out
+ already before having to send any data. This is useful in authentication
+ cases and others.
+
+ However, many servers don't implement the Expect: stuff properly and if the
+ server doesn't respond (positively) within 1 second libcurl will continue
+ and send off the data anyway.
+
+ You can disable libcurl's use of the Expect: header the same way you disable
+ any header, using -H / CURLOPT_HTTPHEADER, or by forcing it to use HTTP 1.0.
+
+ 4.17 Non-functional connect timeouts
+
+ In most Windows setups having a timeout longer than 21 seconds make no
+ difference, as it will only send 3 TCP SYN packets and no more. The second
+ packet sent three seconds after the first and the third six seconds after
+ the second. No more than three packets are sent, no matter how long the
+ timeout is set.
+
+ See option TcpMaxConnectRetransmissions on this page:
+ http://support.microsoft.com/?scid=kb%3Ben-us%3B175523&x=6&y=7
+
+ Also, even on non-Windows systems there may run a firewall or anti-virus
+ software or similar that accepts the connection but does not actually do
+ anything else. This will make (lib)curl to consider the connection connected
+ and thus the connect timeout won't trigger.
+
+ 4.18 file:// URLs containing drive letters (Windows, NetWare)
+
+ When using cURL to try to download a local file, one might use a URL
+ in this format:
+
+ file://D:/blah.txt
+
+ You'll find that even if D:\blah.txt does exist, cURL returns a 'file
+ not found' error.
+
+ According to RFC 1738 (http://www.faqs.org/rfcs/rfc1738.html),
+ file:// URLs must contain a host component, but it is ignored by
+ most implementations. In the above example, 'D:' is treated as the
+ host component, and is taken away. Thus, cURL tries to open '/blah.txt'.
+ If your system is installed to drive C:, that will resolve to 'C:\blah.txt',
+ and if that doesn't exist you will get the not found error.
+
+ To fix this problem, use file:// URLs with *three* leading slashes:
+
+ file:///D:/blah.txt
+
+ Alternatively, if it makes more sense, specify 'localhost' as the host
+ component:
+
+ file://localhost/D:/blah.txt
+
+ In either case, cURL should now be looking for the correct file.
+
+ 4.19 Why doesn't cURL return an error when the network cable is unplugged?
+
+ Unplugging the cable is not an error situation. The TCP/IP protocol stack
+ was designed to be fault tolerant, so even though there may be a physical
+ break somewhere the connection shouldn't be affected, just possibly
+ delayed. Eventually, the physical break will be fixed or the data will be
+ re-routed around the physical problem.
+
+ In such cases, the TCP/IP stack is responsible for detecting when the
+ network connection is irrevocably lost. Since with some protocols it is
+ perfectly legal for the client wait indefinitely for data, the stack may
+ never report a problem, and even when it does, it can take up to 20 minutes
+ for it to detect an issue. The curl option --keepalive-time enables
+ keep-alive support in the TCP/IP stack which makes it periodically probe the
+ connection to make sure it is still available to send data. That should
+ reliably detect any TCP/IP network failure.
+
+ But even that won't detect the network going down before the TCP/IP
+ connection is established (e.g. during a DNS lookup) or using protocols that
+ don't use TCP. To handle those situations, curl offers a number of timeouts
+ on its own. --speed-limit/--speed-time will abort if the data transfer rate
+ falls too low, and --connect-timeout and --max-time can be used to put an
+ overall timeout on the connection phase or the entire transfer.
+
+
+5. libcurl Issues
+
+ 5.1 Is libcurl thread-safe?
+
+ Yes.
+
+ We have written the libcurl code specifically adjusted for multi-threaded
+ programs. libcurl will use thread-safe functions instead of non-safe ones if
+ your system has such.
+
+ If you use a OpenSSL-powered libcurl in a multi-threaded environment, you
+ need to provide one or two locking functions:
+
+ http://www.openssl.org/docs/crypto/threads.html
+
+ If you use a GnuTLS-powered libcurl in a multi-threaded environment, you
+ need to provide locking function(s) for libgcrypt (which is used by GnuTLS
+ for the crypto functions).
+
+ http://www.gnu.org/software/gnutls/manual/html_node/Multi_002dthreaded-applications.html
+
+ No special locking is needed with a NSS-powered libcurl. NSS is thread-safe.
+
+ 5.2 How can I receive all data into a large memory chunk?
+
+ [ See also the examples/getinmemory.c source ]
+
+ You are in full control of the callback function that gets called every time
+ there is data received from the remote server. You can make that callback do
+ whatever you want. You do not have to write the received data to a file.
+
+ One solution to this problem could be to have a pointer to a struct that you
+ pass to the callback function. You set the pointer using the
+ CURLOPT_WRITEDATA option. Then that pointer will be passed to the callback
+ instead of a FILE * to a file:
+
+ /* imaginary struct */
+ struct MemoryStruct {
+ char *memory;
+ size_t size;
+ };
+
+ /* imaginary callback function */
+ size_t
+ WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
+ {
+ size_t realsize = size * nmemb;
+ struct MemoryStruct *mem = (struct MemoryStruct *)data;
+
+ mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1);
+ if (mem->memory) {
+ memcpy(&(mem->memory[mem->size]), ptr, realsize);
+ mem->size += realsize;
+ mem->memory[mem->size] = 0;
+ }
+ return realsize;
+ }
+
+ 5.3 How do I fetch multiple files with libcurl?
+
+ libcurl has excellent support for transferring multiple files. You should
+ just repeatedly set new URLs with curl_easy_setopt() and then transfer it
+ with curl_easy_perform(). The handle you get from curl_easy_init() is not
+ only reusable, but you're even encouraged to reuse it if you can, as that
+ will enable libcurl to use persistent connections.
+
+ 5.4 Does libcurl do Winsock initialization on win32 systems?
+
+ Yes, if told to in the curl_global_init() call.
+
+ 5.5 Does CURLOPT_WRITEDATA and CURLOPT_READDATA work on win32 ?
+
+ Yes, but you cannot open a FILE * and pass the pointer to a DLL and have
+ that DLL use the FILE * (as the DLL and the client application cannot access
+ each others' variable memory areas). If you set CURLOPT_WRITEDATA you must
+ also use CURLOPT_WRITEFUNCTION as well to set a function that writes the
+ file, even if that simply writes the data to the specified FILE *.
+ Similarly, if you use CURLOPT_READDATA you must also specify
+ CURLOPT_READFUNCTION.
+
+ 5.6 What about Keep-Alive or persistent connections?
+
+ curl and libcurl have excellent support for persistent connections when
+ transferring several files from the same server. Curl will attempt to reuse
+ connections for all URLs specified on the same command line/config file, and
+ libcurl will reuse connections for all transfers that are made using the
+ same libcurl handle.
+
+ When you use the easy interface, the connection cache is kept within the
+ easy handle. If you instead use the multi interface, the connection cache
+ will be kept within the multi handle and will be shared among all the easy
+ handles that are used within the same multi handle.
+
+ 5.7 Link errors when building libcurl on Windows!
+
+ You need to make sure that your project, and all the libraries (both static
+ and dynamic) that it links against, are compiled/linked against the same run
+ time library.
+
+ This is determined by the /MD, /ML, /MT (and their corresponding /M?d)
+ options to the command line compiler. /MD (linking against MSVCRT dll) seems
+ to be the most commonly used option.
+
+ When building an application that uses the static libcurl library, you must
+ add -DCURL_STATICLIB to your CFLAGS. Otherwise the linker will look for
+ dynamic import symbols. If you're using Visual Studio, you need to instead
+ add CURL_STATICLIB in the "Preprocessor Definitions" section.
+
+ If you get linker error like "unknown symbol __imp__curl_easy_init ..." you
+ have linked against the wrong (static) library. If you want to use the
+ libcurl.dll and import lib, you don't need any extra CFLAGS, but use one of
+ the import libraries below. These are the libraries produced by the various
+ lib/Makefile.* files:
+
+ Target: static lib. import lib for libcurl*.dll.
+ -----------------------------------------------------------
+ MingW: libcurl.a libcurldll.a
+ MSVC (release): libcurl.lib libcurl_imp.lib
+ MSVC (debug): libcurld.lib libcurld_imp.lib
+ Borland: libcurl.lib libcurl_imp.lib
+
+ 5.8 libcurl.so.X: open failed: No such file or directory
+
+ This is an error message you might get when you try to run a program linked
+ with a shared version of libcurl and your run-time linker (ld.so) couldn't
+ find the shared library named libcurl.so.X. (Where X is the number of the
+ current libcurl ABI, typically 3 or 4).
+
+ You need to make sure that ld.so finds libcurl.so.X. You can do that
+ multiple ways, and it differs somewhat between different operating systems,
+ but they are usually:
+
+ * Add an option to the linker command line that specify the hard-coded path
+ the run-time linker should check for the lib (usually -R)
+
+ * Set an environment variable (LD_LIBRARY_PATH for example) where ld.so
+ should check for libs
+
+ * Adjust the system's config to check for libs in the directory where you've
+ put the dir (like Linux's /etc/ld.so.conf)
+
+ 'man ld.so' and 'man ld' will tell you more details
+
+ 5.9 How does libcurl resolve host names?
+
+ libcurl supports a large a number of different name resolve functions. One
+ of them is picked at build-time and will be used unconditionally. Thus, if
+ you want to change name resolver function you must rebuild libcurl and tell
+ it to use a different function.
+
+ - The non-ipv6 resolver that can use one out of four host name resolve calls
+ (depending on what your system supports):
+
+ A - gethostbyname()
+ B - gethostbyname_r() with 3 arguments
+ C - gethostbyname_r() with 5 arguments
+ D - gethostbyname_r() with 6 arguments
+
+ - The ipv6-resolver that uses getaddrinfo()
+
+ - The c-ares based name resolver that uses the c-ares library for resolves.
+ Using this offers asynchronous name resolves.
+
+ - The threaded resolver (default option on Windows). It uses:
+
+ A - gethostbyname() on plain ipv4 hosts
+ B - getaddrinfo() on ipv6-enabled hosts
+
+ Also note that libcurl never resolves or reverse-lookups addresses given as
+ pure numbers, such as 127.0.0.1 or ::1.
+
+ 5.10 How do I prevent libcurl from writing the response to stdout?
+
+ libcurl provides a default built-in write function that writes received data
+ to stdout. Set the CURLOPT_WRITEFUNCTION to receive the data, or possibly
+ set CURLOPT_WRITEDATA to a different FILE * handle.
+
+ 5.11 How do I make libcurl not receive the whole HTTP response?
+
+ You make the write callback (or progress callback) return an error and
+ libcurl will then abort the transfer.
+
+ 5.12 Can I make libcurl fake or hide my real IP address?
+
+ No. libcurl operates on a higher level than so. Besides, faking IP address
+ would imply sending IP packages with a made-up source address, and then you
+ normally get a problem with intercepting the packages sent back as they
+ would then not be routed to you!
+
+ If you use a proxy to access remote sites, the sites will not see your local
+ IP address but instead the address of the proxy.
+
+ Also note that on many networks NATs or other IP-munging techniques are used
+ that makes you see and use a different IP address locally than what the
+ remote server will see you coming from.
+
+ 5.13 How do I stop an ongoing transfer?
+
+ With the easy interface you make sure to return the correct error code from
+ one of the callbacks, but none of them are instant. There is no function you
+ can call from another thread or similar that will stop it immediately.
+ Instead, you need to make sure that one of the callbacks you use returns an
+ appropriate value that will stop the transfer. Suitable callbacks that you
+ can do this with include the progress callback, the read callback and the
+ write callback.
+
+ If you're using the multi interface, you can also stop a transfer by
+ removing the particular easy handle from the multi stack at any moment you
+ think the transfer is done.
+
+ 5.14 Using C++ non-static functions for callbacks?
+
+ libcurl is a C library, it doesn't know anything about C++ member functions.
+
+ You can overcome this "limitation" with a relative ease using a static
+ member function that is passed a pointer to the class:
+
+ // f is the pointer to your object.
+ static YourClass::func(void *buffer, size_t sz, size_t n, void *f)
+ {
+ // Call non-static member function.
+ static_cast<YourClass*>(f)->nonStaticFunction();
+ }
+
+ // This is how you pass pointer to the static function:
+ curl_easy_setopt(hcurl, CURLOPT_WRITEFUNCTION, YourClass:func);
+ curl_easy_setopt(hcurl, CURLOPT_WRITEDATA, this);
+
+ 5.15 How do I get an FTP directory listing?
+
+ If you end the FTP URL you request with a slash, libcurl will provide you
+ with a directory listing of that given directory. You can also set
+ CURLOPT_CUSTOMREQUEST to alter what exact listing command libcurl would use
+ to list the files.
+
+ The follow-up question that tend to follow the previous one, is how a
+ program is supposed to parse the directory listing. How does it know what's
+ a file and what's a dir and what's a symlink etc. The harsh reality is that
+ FTP provides no such fine and easy-to-parse output. The output format FTP
+ servers respond to LIST commands are entirely at the server's own liking and
+ the NLST output doesn't reveal any types and in many cases don't even
+ include all the directory entries. Also, both LIST and NLST tend to hide
+ unix-style hidden files (those that start with a dot) by default so you need
+ to do "LIST -a" or similar to see them.
+
+ The application thus needs to parse the LIST output. One such existing
+ list parser is available at http://cr.yp.to/ftpparse.html Versions of
+ libcurl since 7.21.0 also provide the ability to specify a wildcard to
+ download multiple files from one FTP directory.
+
+ 5.16 I want a different time-out!
+
+ Time and time again users realize that CURLOPT_TIMEOUT and
+ CURLOPT_CONNECTIMEOUT are not sufficiently advanced or flexible to cover all
+ the various use cases and scenarios applications end up with.
+
+ libcurl offers many more ways to time-out operations. A common alternative
+ is to use the CURLOPT_LOW_SPEED_LIMIT and CURLOPT_LOW_SPEED_TIME options to
+ specify the lowest possible speed to accept before to consider the transfer
+ timed out.
+
+ The most flexible way is by writing your own time-out logic and using
+ CURLOPT_PROGRESSFUNCTION (perhaps in combination with other callbacks) and
+ use that to figure out exactly when the right condition is met when the
+ transfer should get stopped.
+
+
+6. License Issues
+
+ Curl and libcurl are released under a MIT/X derivate license. The license is
+ very liberal and should not impose a problem for your project. This section
+ is just a brief summary for the cases we get the most questions. (Parts of
+ this section was much enhanced by Bjorn Reese.)
+
+ We are not lawyers and this is not legal advice. You should probably consult
+ one if you want true and accurate legal insights without our prejudice. Note
+ especially that this section concerns the libcurl license only; compiling in
+ features of libcurl that depend on other libraries (e.g. OpenSSL) may affect
+ the licensing obligations of your application.
+
+ 6.1 I have a GPL program, can I use the libcurl library?
+
+ Yes!
+
+ Since libcurl may be distributed under the MIT/X derivate license, it can be
+ used together with GPL in any software.
+
+ 6.2 I have a closed-source program, can I use the libcurl library?
+
+ Yes!
+
+ libcurl does not put any restrictions on the program that uses the library.
+
+ 6.3 I have a BSD licensed program, can I use the libcurl library?
+
+ Yes!
+
+ libcurl does not put any restrictions on the program that uses the library.
+
+ 6.4 I have a program that uses LGPL libraries, can I use libcurl?
+
+ Yes!
+
+ The LGPL license doesn't clash with other licenses.
+
+ 6.5 Can I modify curl/libcurl for my program and keep the changes secret?
+
+ Yes!
+
+ The MIT/X derivate license practically allows you to do almost anything with
+ the sources, on the condition that the copyright texts in the sources are
+ left intact.
+
+ 6.6 Can you please change the curl/libcurl license to XXXX?
+
+ No.
+
+ We have carefully picked this license after years of development and
+ discussions and a large amount of people have contributed with source code
+ knowing that this is the license we use. This license puts the restrictions
+ we want on curl/libcurl and it does not spread to other programs or
+ libraries that use it. It should be possible for everyone to use libcurl or
+ curl in their projects, no matter what license they already have in use.
+
+ 6.7 What are my obligations when using libcurl in my commercial apps?
+
+ Next to none. All you need to adhere to is the MIT-style license (stated in
+ the COPYING file) which basically says you have to include the copyright
+ notice in "all copies" and that you may not use the copyright holder's name
+ when promoting your software.
+
+ You do not have to release any of your source code.
+
+ You do not have to reveal or make public any changes to the libcurl source
+ code.
+
+ You do not have to broadcast to the world that you are using libcurl within
+ your app.
+
+ All we ask is that you disclose "the copyright notice and this permission
+ notice" somewhere. Most probably like in the documentation or in the section
+ where other third party dependencies already are mentioned and acknowledged.
+
+ As can be seen here: http://curl.haxx.se/docs/companies.html and elsewhere,
+ more and more companies are discovering the power of libcurl and take
+ advantage of it even in commercial environments.
+
+
+7. PHP/CURL Issues
+
+ 7.1 What is PHP/CURL?
+
+ The module for PHP that makes it possible for PHP programs to access curl-
+ functions from within PHP.
+
+ In the cURL project we call this module PHP/CURL to differentiate it from
+ curl the command line tool and libcurl the library. The PHP team however
+ does not refer to it like this (for unknown reasons). They call it plain
+ CURL (often using all caps) or sometimes ext/curl, but both cause much
+ confusion to users which in turn gives us a higher question load.
+
+ 7.2 Who wrote PHP/CURL?
+
+ PHP/CURL is a module that comes with the regular PHP package. It depends and
+ uses libcurl, so you need to have libcurl installed properly first before
+ PHP/CURL can be used. PHP/CURL was initially written by Sterling Hughes.
+
+ 7.3 Can I perform multiple requests using the same handle?
+
+ Yes - at least in PHP version 4.3.8 and later (this has been known to not
+ work in earlier versions, but the exact version when it started to work is
+ unknown to me).
+
+ After a transfer, you just set new options in the handle and make another
+ transfer. This will make libcurl to re-use the same connection if it can.
diff --git a/docs/FEATURES b/docs/FEATURES
new file mode 100644
index 000000000..930222240
--- /dev/null
+++ b/docs/FEATURES
@@ -0,0 +1,136 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+FEATURES
+
+curl tool
+ - config file support
+ - multiple URLs in a single command line
+ - range "globbing" support: [0-13], {one,two,three}
+ - multiple file upload on a single command line
+ - custom maximum transfer rate
+ - redirectable stderr
+
+libcurl supports
+ - full URL syntax with no length limit
+ - custom maximum download time
+ - custom least download speed acceptable
+ - custom output result after completion
+ - guesses protocol from host name unless specified
+ - uses .netrc
+ - progress bar/time specs while downloading
+ - "standard" proxy environment variables support
+ - compiles on win32 (reported builds on 40+ operating systems)
+ - selectable network interface for outgoing traffic
+ - IPv6 support on unix and Windows
+ - persistent connections
+ - socks5 support
+ - supports user name + password in proxy environment variables
+ - operations through proxy "tunnel" (using CONNECT)
+ - supports large files (>2GB and >4GB) both upload/download
+ - replaceable memory functions (malloc, free, realloc, etc)
+ - asynchronous name resolving (*6)
+ - both a push and a pull style interface
+
+HTTP
+ - HTTP/1.1 compliant (optionally uses 1.0)
+ - GET
+ - PUT
+ - HEAD
+ - POST
+ - Pipelining
+ - multipart formpost (RFC1867-style)
+ - authentication: Basic, Digest, NTLM(*9), GSS-Negotiate/Negotiate(*3) and
+ SPNEGO (*4) to server and proxy
+ - resume (both GET and PUT)
+ - follow redirects
+ - maximum amount of redirects to follow
+ - custom HTTP request
+ - cookie get/send fully parsed
+ - reads/writes the netscape cookie file format
+ - custom headers (replace/remove internally generated headers)
+ - custom user-agent string
+ - custom referer string
+ - range
+ - proxy authentication
+ - time conditions
+ - via http-proxy
+ - retrieve file modification date
+ - Content-Encoding support for deflate and gzip
+ - "Transfer-Encoding: chunked" support for "uploads"
+
+HTTPS (*1)
+ - (all the HTTP features)
+ - using client certificates
+ - verify server certificate
+ - via http-proxy
+ - select desired encryption
+ - force usage of a specific SSL version (SSLv2(*7), SSLv3 or TLSv1)
+
+FTP
+ - download
+ - authentication
+ - kerberos4 (*5), kerberos5 (*3)
+ - active/passive using PORT, EPRT, PASV or EPSV
+ - single file size information (compare to HTTP HEAD)
+ - 'type=' URL support
+ - dir listing
+ - dir listing names-only
+ - upload
+ - upload append
+ - upload via http-proxy as HTTP PUT
+ - download resume
+ - upload resume
+ - custom ftp commands (before and/or after the transfer)
+ - simple "range" support
+ - via http-proxy
+ - all operations can be tunneled through a http-proxy
+ - customizable to retrieve file modification date
+ - no dir depth limit
+
+FTPS (*1)
+ - implicit ftps:// support that use SSL on both connections
+ - explicit "AUTH TSL" and "AUTH SSL" usage to "upgrade" plain ftp://
+ connection to use SSL for both or one of the connections
+
+SCP (*8)
+ - both password and public key auth
+
+SFTP (*8)
+ - both password and public key auth
+ - with custom commands sent before/after the transfer
+
+TFTP
+ - download / upload
+
+TELNET
+ - connection negotiation
+ - custom telnet options
+ - stdin/stdout I/O
+
+LDAP (*2)
+ - full LDAP URL support
+
+DICT
+ - extended DICT URL support
+
+FILE
+ - URL support
+ - "uploads"
+ - resume
+
+FOOTNOTES
+=========
+
+ *1 = requires OpenSSL, GnuTLS, NSS, yassl, axTLS, PolarSSL or schannel
+ *2 = requires OpenLDAP
+ *3 = requires a GSSAPI-compliant library, such as Heimdal or similar.
+ *4 = requires FBopenssl
+ *5 = requires a krb4 library, such as the MIT one or similar.
+ *6 = requires c-ares
+ *7 = requires OpenSSL or NSS, as GnuTLS only supports SSLv3 and TLSv1
+ *8 = requires libssh2
+ *9 = requires OpenSSL, GnuTLS, NSS or yassl
diff --git a/docs/HISTORY b/docs/HISTORY
new file mode 100644
index 000000000..e04fb53df
--- /dev/null
+++ b/docs/HISTORY
@@ -0,0 +1,244 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+ How cURL Became Like This
+
+
+In the second half of 1997, Daniel Stenberg came up with the idea to make
+currency-exchange calculations available to Internet Relay Chat (IRC)
+users. All the necessary data are published on the Web; he just needed to
+automate their retrieval.
+
+Daniel simply adopted an existing command-line open-source tool, httpget, that
+Brazilian Rafael Sagula had written. After a few minor adjustments, it did
+just what he needed.
+
+Soon, he found currencies on a GOPHER site, so support for that had to go in,
+and not before long FTP download support was added as well. The name of the
+project was changed to urlget to better fit what it actually did now, since
+the http-only days were already passed.
+
+The project slowly grew bigger. When upload capabilities were added and the
+name once again was misleading, a second name change was made and on March 20,
+1998 curl 4 was released. (The version numbering from the previous names was
+kept.)
+
+(Unrelated to this project a company called Curl Corporation registered a US
+trademark on the name "CURL" on May 18 1998. That company had then already
+registered the curl.com domain back in November of the previous year. All this
+was revealed to us much later.)
+
+SSL support was added, powered by the SSLeay library.
+
+August 1998, first announcement of curl on freshmeat.net.
+
+October 1998, with the curl 4.9 release and the introduction of cookie
+support, curl was no longer released under the GPL license. Now we're at 4000
+lines of code, we switched over to the MPL license to restrict the effects of
+"copyleft".
+
+November 1998, configure script and reported successful compiles on several
+major operating systems. The never-quite-understood -F option was added and
+curl could now simulate quite a lot of a browser. TELNET support was added.
+
+Curl 5 was released in December 1998 and introduced the first ever curl man
+page. People started making Linux RPM packages out of it.
+
+January 1999, DICT support added.
+
+OpenSSL took over where SSLeay was abandoned.
+
+May 1999, first Debian package.
+
+August 1999, LDAP:// and FILE:// support added. The curl web site gets 1300
+visits weekly.
+
+Released curl 6.0 in September. 15000 lines of code.
+
+December 28 1999, added the project on Sourceforge and started using its
+services for managing the project.
+
+Spring 2000, major internal overhaul to provide a suitable library interface.
+The first non-beta release was named 7.1 and arrived in August. This offered
+the easy interface and turned out to be the beginning of actually getting
+other software and programs to get based on and powered by libcurl. Almost
+20000 lines of code.
+
+August 2000, the curl web site gets 4000 visits weekly.
+
+The PHP guys adopted libcurl already the same month, when the first ever third
+party libcurl binding showed up. CURL has been a supported module in PHP since
+the release of PHP 4.0.2. This would soon get followers. More than 16
+different bindings exist at the time of this writing.
+
+September 2000, kerberos4 support was added.
+
+In November 2000 started the work on a test suite for curl. It was later
+re-written from scratch again. The libcurl major SONAME number was set to 1.
+
+January 2001, Daniel released curl 7.5.2 under a new license again: MIT (or
+MPL). The MIT license is extremely liberal and can be used combined with GPL
+in other projects. This would finally put an end to the "complaints" from
+people involved in GPLed projects that previously were prohibited from using
+libcurl while it was released under MPL only. (Due to the fact that MPL is
+deemed "GPL incompatible".)
+
+curl supports HTTP 1.1 starting with the release of 7.7, March 22 2001. This
+also introduced libcurl's ability to do persistent connections. 24000 lines of
+code. The libcurl major SONAME number was bumped to 2 due to this overhaul.
+
+The first experimental ftps:// support was added in March 2001.
+
+August 2001. curl is bundled in Mac OS X, 10.1. It was already becoming more
+and more of a standard utility of Linux distributions and a regular in the BSD
+ports collections. The curl web site gets 8000 visits weekly. Curl Corporation
+contacted Daniel to discuss "the name issue". After Daniel's reply, they have
+never since got in touch again.
+
+September 2001, libcurl 7.9 introduces cookie jar and curl_formadd(). During
+the forthcoming 7.9.x releases, we introduced the multi interface slowly and
+without much whistles.
+
+June 2002, the curl web site gets 13000 visits weekly. curl and libcurl is
+35000 lines of code. Reported successful compiles on more than 40 combinations
+of CPUs and operating systems.
+
+To estimate number of users of the curl tool or libcurl library is next to
+impossible. Around 5000 downloaded packages each week from the main site gives
+a hint, but the packages are mirrored extensively, bundled with numerous OS
+distributions and otherwise retrieved as part of other software.
+
+September 2002, with the release of curl 7.10 it is released under the MIT
+license only.
+
+January 2003. Started working on the distributed curl tests. The autobuilds.
+
+February 2003, the curl site averages at 20000 visits weekly. At any given
+moment, there's an average of 3 people browsing the curl.haxx.se site.
+
+Multiple new authentication schemes are supported: Digest (May), NTLM (June)
+and Negotiate (June).
+
+November 2003: curl 7.10.8 is released. 45000 lines of code. ~55000 unique
+visitors to the curl.haxx.se site. Five official web mirrors.
+
+December 2003, full-fledged SSL for FTP is supported.
+
+January 2004: curl 7.11.0 introduced large file support.
+
+June 2004:
+
+ curl 7.12.0 introduced IDN support. 10 official web mirrors.
+
+ This release bumped the major SONAME to 3 due to the removal of the
+ curl_formparse() function
+
+August 2004:
+ Curl and libcurl 7.12.1
+
+ Public curl release number: 82
+ Releases counted from the very beginning: 109
+ Available command line options: 96
+ Available curl_easy_setopt() options: 120
+ Number of public functions in libcurl: 36
+ Amount of public web site mirrors: 12
+ Number of known libcurl bindings: 26
+
+April 2005:
+
+ GnuTLS can now optionally be used for the secure layer when curl is built.
+
+September 2005:
+
+ TFTP support was added.
+
+ More than 100,000 unique visitors of the curl web site. 25 mirrors.
+
+December 2005:
+
+ security vulnerability: libcurl URL Buffer Overflow
+
+January 2006:
+
+ We dropped support for Gopher. We found bugs in the implementation that
+ turned out having been introduced years ago, so with the conclusion that
+ nobody had found out in all this time we removed it instead of fixing it.
+
+March 2006:
+
+ security vulnerability: libcurl TFTP Packet Buffer Overflow
+
+April 2006:
+
+ Added the multi_socket() API
+
+September 2006:
+
+ The major SONAME number for libcurl was bumped to 4 due to the removal of
+ ftp third party transfer support.
+
+November 2006:
+
+ Added SCP and SFTP support
+
+February 2007:
+
+ Added support for the Mozilla NSS library to do the SSL/TLS stuff
+
+July 2007:
+
+ security vulnerability: libcurl GnuTLS insufficient cert verification
+
+November 2008:
+
+ Command line options: 128
+ curl_easy_setopt() options: 158
+ Public functions in libcurl: 58
+ Known libcurl bindings: 37
+ Contributors: 683
+
+ 145,000 unique visitors. >100 GB downloaded.
+
+March 2009:
+
+ security vulnerability: libcurl Arbitrary File Access
+
+August 2009:
+
+ security vulnerability: libcurl embedded zero in cert name
+
+December 2009:
+
+ Added support for IMAP, POP3 and SMTP
+
+January 2010:
+
+ Added support for RTSP
+
+February 2010:
+
+ security vulnerability: libcurl data callback excessive length
+
+March 2010:
+
+ The project switched over to use git instead of CVS for source code control
+
+May 2010:
+
+ Added support for RTMP
+
+ Added support for PolarSSL to do the SSL/TLS stuff
+
+August 2010:
+
+ Public curl releases: 117
+ Command line options: 138
+ curl_easy_setopt() options: 180
+ Public functions in libcurl: 58
+ Known libcurl bindings: 39
+ Contributors: 808
+
+ Gopher support added (re-added actually)
diff --git a/docs/HTTP-COOKIES b/docs/HTTP-COOKIES
new file mode 100644
index 000000000..818e161ee
--- /dev/null
+++ b/docs/HTTP-COOKIES
@@ -0,0 +1,123 @@
+Updated: July 3, 2012 (http://curl.haxx.se/docs/http-cookies.html)
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+
+HTTP Cookies
+
+ 1. HTTP Cookies
+ 1.1 Cookie overview
+ 1.2 Cookies saved to disk
+ 1.3 Cookies with curl the command line tool
+ 1.4 Cookies with libcurl
+ 1.5 Cookies with javascript
+
+==============================================================================
+
+1. HTTP Cookies
+
+ 1.1 Cookie overview
+
+ HTTP cookies are pieces of 'name=contents' snippets that a server tells the
+ client to hold and then the client sends back those the server on subsequent
+ requests to the same domains/paths for which the cookies were set.
+
+ Cookies are either "session cookies" which typically are forgotten when the
+ session is over which is often translated to equal when browser quits, or
+ the cookies aren't session cookies they have expiration dates after which
+ the client will throw them away.
+
+ Cookies are set to the client with the Set-Cookie: header and are sent to
+ servers with the Cookie: header.
+
+ For a very long time, the only spec explaining how to use cookies was the
+ original Netscape spec from 1994: http://curl.haxx.se/rfc/cookie_spec.html
+
+ In 2011, RFC6265 (http://www.ietf.org/rfc/rfc6265.txt) was finally published
+ and details how cookies work within HTTP.
+
+ 1.2 Cookies saved to disk
+
+ Netscape once created a file format for storing cookies on disk so that they
+ would survive browser restarts. curl adopted that file format to allow
+ sharing the cookies with browsers, only to see browsers move away from that
+ format. Modern browsers no longer use it, while curl still does.
+
+ The netscape cookie file format stores one cookie per physical line in the
+ file with a bunch of associated meta data, each field separated with
+ TAB. That file is called the cookiejar in curl terminology.
+
+ When libcurl saves a cookiejar, it creates a file header of its own in which
+ there is a URL mention that will link to the web version of this document.
+
+ 1.3 Cookies with curl the command line tool
+
+ curl has a full cookie "engine" built in. If you just activate it, you can
+ have curl receive and send cookies exactly as mandated in the specs.
+
+ Command line options:
+
+ -b, --cookie
+
+ tell curl a file to read cookies from and start the cookie engine, or if
+ it isn't a file it will pass on the given string. -b name=var works and so
+ does -b cookiefile.
+
+ -j, --junk-session-cookies
+
+ when used in combination with -b, it will skip all "session cookies" on
+ load so as to appear to start a new cookie session.
+
+ -c, --cookie-jar
+
+ tell curl to start the cookie engine and write cookies to the given file
+ after the request(s)
+
+ 1.4 Cookies with libcurl
+
+ libcurl offers several ways to enable and interface the cookie engine. These
+ options are the ones provided by the native API. libcurl bindings may offer
+ access to them using other means.
+
+ CURLOPT_COOKIE
+
+ Is used when you want to specify the exact contents of a cookie header to
+ send to the server.
+
+ CURLOPT_COOKIEFILE
+
+ Tell libcurl to activate the cookie engine, and to read the initial set of
+ cookies from the given file. Read-only.
+
+ CURLOPT_COOKIEJAR
+
+ Tell libcurl to activate the cookie engine, and when the easy handle is
+ closed save all known cookies to the given cookiejar file. Write-only.
+
+ CURLOPT_COOKIELIST
+
+ Provide detailed information about a single cookie to add to the internal
+ storage of cookies. Pass in the cookie as a HTTP header with all the
+ details set, or pass in a line from a netscape cookie file. This option
+ can also be used to flush the cookies etc.
+
+ CURLINFO_COOKIELIST
+
+ Extract cookie information from the internal cookie storage as a linked
+ list.
+
+ 1.5 Cookies with javascript
+
+ These days a lot of the web is built up by javascript. The webbrowser loads
+ complete programs that render the page you see. These javascript programs
+ can also set and access cookies.
+
+ Since curl and libcurl are plain HTTP clients without any knowledge of or
+ capability to handle javascript, such cookies will not be detected or used.
+
+ Often, if you want to mimic what a browser does on such web sites, you can
+ record web browser HTTP traffic when using such a site and then repeat the
+ cookie operations using curl or libcurl.
diff --git a/docs/INSTALL b/docs/INSTALL
new file mode 100644
index 000000000..eac3cd555
--- /dev/null
+++ b/docs/INSTALL
@@ -0,0 +1,1100 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+ How To Compile
+
+Installing Binary Packages
+==========================
+
+ Lots of people download binary distributions of curl and libcurl. This
+ document does not describe how to install curl or libcurl using such a
+ binary package. This document describes how to compile, build and install
+ curl and libcurl from source code.
+
+Building from git
+=================
+
+ If you get your code off a git repository, see the GIT-INFO file in the
+ root directory for specific instructions on how to proceed.
+
+UNIX
+====
+ A normal unix installation is made in three or four steps (after you've
+ unpacked the source archive):
+
+ ./configure
+ make
+ make test (optional)
+ make install
+
+ You probably need to be root when doing the last command.
+
+ If you have checked out the sources from the git repository, read the
+ GIT-INFO on how to proceed.
+
+ Get a full listing of all available configure options by invoking it like:
+
+ ./configure --help
+
+ If you want to install curl in a different file hierarchy than /usr/local,
+ you need to specify that already when running configure:
+
+ ./configure --prefix=/path/to/curl/tree
+
+ If you happen to have write permission in that directory, you can do 'make
+ install' without being root. An example of this would be to make a local
+ install in your own home directory:
+
+ ./configure --prefix=$HOME
+ make
+ make install
+
+ The configure script always tries to find a working SSL library unless
+ explicitly told not to. If you have OpenSSL installed in the default search
+ path for your compiler/linker, you don't need to do anything special. If
+ you have OpenSSL installed in /usr/local/ssl, you can run configure like:
+
+ ./configure --with-ssl
+
+ If you have OpenSSL installed somewhere else (for example, /opt/OpenSSL)
+ and you have pkg-config installed, set the pkg-config path first, like this:
+
+ env PKG_CONFIG_PATH=/opt/OpenSSL/lib/pkgconfig ./configure --with-ssl
+
+ Without pkg-config installed, use this:
+
+ ./configure --with-ssl=/opt/OpenSSL
+
+ If you insist on forcing a build without SSL support, even though you may
+ have OpenSSL installed in your system, you can run configure like this:
+
+ ./configure --without-ssl
+
+ If you have OpenSSL installed, but with the libraries in one place and the
+ header files somewhere else, you have to set the LDFLAGS and CPPFLAGS
+ environment variables prior to running configure. Something like this
+ should work:
+
+ (with the Bourne shell and its clones):
+
+ CPPFLAGS="-I/path/to/ssl/include" LDFLAGS="-L/path/to/ssl/lib" \
+ ./configure
+
+ (with csh, tcsh and their clones):
+
+ env CPPFLAGS="-I/path/to/ssl/include" LDFLAGS="-L/path/to/ssl/lib" \
+ ./configure
+
+ If you have shared SSL libs installed in a directory where your run-time
+ linker doesn't find them (which usually causes configure failures), you can
+ provide the -R option to ld on some operating systems to set a hard-coded
+ path to the run-time linker:
+
+ env LDFLAGS=-R/usr/local/ssl/lib ./configure --with-ssl
+
+ MORE OPTIONS
+ ------------
+
+ To force configure to use the standard cc compiler if both cc and gcc are
+ present, run configure like
+
+ CC=cc ./configure
+ or
+ env CC=cc ./configure
+
+ To force a static library compile, disable the shared library creation
+ by running configure like:
+
+ ./configure --disable-shared
+
+ To tell the configure script to skip searching for thread-safe functions,
+ add an option like:
+
+ ./configure --disable-thread
+
+ To build curl with kerberos4 support enabled, curl requires the krb4 libs
+ and headers installed. You can then use a set of options to tell
+ configure where those are:
+
+ --with-krb4-includes[=DIR] Specify location of kerberos4 headers
+ --with-krb4-libs[=DIR] Specify location of kerberos4 libs
+ --with-krb4[=DIR] where to look for Kerberos4
+
+ In most cases, /usr/athena is the install prefix and then it works with
+
+ ./configure --with-krb4=/usr/athena
+
+ If you're a curl developer and use gcc, you might want to enable more
+ debug options with the --enable-debug option.
+
+ curl can be built to use a whole range of libraries to provide various
+ useful services, and configure will try to auto-detect a decent
+ default. But if you want to alter it, you can select how to deal with
+ each individual library.
+
+ To build with GnuTLS support instead of OpenSSL for SSL/TLS, note that
+ you need to use both --without-ssl and --with-gnutls.
+
+ To build with yassl support instead of OpenSSL or GnuTLS, you must build
+ yassl with its OpenSSL emulation enabled and point to that directory root
+ with configure --with-ssl.
+
+ To build with NSS support instead of OpenSSL for SSL/TLS, note that
+ you need to use both --without-ssl and --with-nss.
+
+ To build with PolarSSL support instead of OpenSSL for SSL/TLS, note that
+ you need to use both --without-ssl and --with-polarssl.
+
+ To build with axTLS support instead of OpenSSL for TLS, note that you
+ need to use both --without-ssl and --with-axtls.
+
+ To get GSSAPI support, build with --with-gssapi and have the MIT or
+ Heimdal Kerberos 5 packages installed.
+
+ To get support for SCP and SFTP, build with --with-libssh2 and have
+ libssh2 0.16 or later installed.
+
+ To get Metalink support, build with --with-libmetalink and have the
+ libmetalink packages installed.
+
+ SPECIAL CASES
+ -------------
+ Some versions of uClibc require configuring with CPPFLAGS=-D_GNU_SOURCE=1
+ to get correct large file support.
+
+ The Open Watcom C compiler on Linux requires configuring with the variables:
+
+ ./configure CC=owcc AR="$WATCOM/binl/wlib" AR_FLAGS=-q \
+ RANLIB=/bin/true STRIP="$WATCOM/binl/wstrip" CFLAGS=-Wextra
+
+
+Win32
+=====
+
+ Building Windows DLLs and C run-time (CRT) linkage issues
+ ---------------------------------------------------------
+
+ As a general rule, building a DLL with static CRT linkage is highly
+ discouraged, and intermixing CRTs in the same app is something to
+ avoid at any cost.
+
+ Reading and comprehension of Microsoft Knowledge Base articles
+ KB94248 and KB140584 is a must for any Windows developer. Especially
+ important is full understanding if you are not going to follow the
+ advice given above.
+
+ KB94248 - How To Use the C Run-Time
+ http://support.microsoft.com/kb/94248/en-us
+
+ KB140584 - How to link with the correct C Run-Time (CRT) library
+ http://support.microsoft.com/kb/140584/en-us
+
+ KB190799 - Potential Errors Passing CRT Objects Across DLL Boundaries
+ http://msdn.microsoft.com/en-us/library/ms235460
+
+ If your app is misbehaving in some strange way, or it is suffering
+ from memory corruption, before asking for further help, please try
+ first to rebuild every single library your app uses as well as your
+ app using the debug multithreaded dynamic C runtime.
+
+ If you get linkage errors read section 5.7 of the FAQ document.
+
+
+ MingW32
+ -------
+
+ Make sure that MinGW32's bin dir is in the search path, for example:
+
+ set PATH=c:\mingw32\bin;%PATH%
+
+ then run 'mingw32-make mingw32' in the root dir. There are other
+ make targets available to build libcurl with more features, use:
+ 'mingw32-make mingw32-zlib' to build with Zlib support;
+ 'mingw32-make mingw32-ssl-zlib' to build with SSL and Zlib enabled;
+ 'mingw32-make mingw32-ssh2-ssl-zlib' to build with SSH2, SSL, Zlib;
+ 'mingw32-make mingw32-ssh2-ssl-sspi-zlib' to build with SSH2, SSL, Zlib
+ and SSPI support.
+
+ If you have any problems linking libraries or finding header files, be sure
+ to verify that the provided "Makefile.m32" files use the proper paths, and
+ adjust as necessary. It is also possible to override these paths with
+ environment variables, for example:
+
+ set ZLIB_PATH=c:\zlib-1.2.7
+ set OPENSSL_PATH=c:\openssl-0.9.8x
+ set LIBSSH2_PATH=c:\libssh2-1.4.2
+
+ ATTENTION: if you want to build with libssh2 support you have to use latest
+ version 0.17 - previous versions will NOT work with 7.17.0 and later!
+ Use 'mingw32-make mingw32-ssh2-ssl-zlib' to build with SSH2 and SSL enabled.
+
+ It is now also possible to build with other LDAP SDKs than MS LDAP;
+ currently it is possible to build with native Win32 OpenLDAP, or with the
+ Novell CLDAP SDK. If you want to use these you need to set these vars:
+
+ set LDAP_SDK=c:\openldap
+ set USE_LDAP_OPENLDAP=1
+
+ or for using the Novell SDK:
+
+ set USE_LDAP_NOVELL=1
+
+ If you want to enable LDAPS support then set LDAPS=1.
+
+ - optional MingW32-built OpenLDAP SDK available from:
+ http://www.gknw.net/mirror/openldap/
+ - optional recent Novell CLDAP SDK available from:
+ http://developer.novell.com/ndk/cldap.htm
+
+
+ Cygwin
+ ------
+
+ Almost identical to the unix installation. Run the configure script in the
+ curl root with 'sh configure'. Make sure you have the sh executable in
+ /bin/ or you'll see the configure fail toward the end.
+
+ Run 'make'
+
+ Dev-Cpp
+ -------
+
+ See the separate INSTALL.devcpp file for details.
+
+ MSVC 6 caveats
+ --------------
+
+ If you use MSVC 6 it is required that you use the February 2003 edition PSDK:
+ http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm
+
+ Building any software with MSVC 6 without having PSDK installed is just
+ asking for trouble down the road once you have released it, you might notice
+ the problems in the first corner or ten miles ahead, depending mostly on your
+ choice of static vs dynamic runtime and third party libraries. Anyone using
+ software built in such way will at some point regret having done so.
+
+ When someone uses MSVC 6 without PSDK he is using a compiler back from 1998.
+
+ If the compiler has been updated with the installation of a service pack as
+ those mentioned in http://support.microsoft.com/kb/194022 the compiler can be
+ safely used to read source code, translate and make it object code.
+
+ But, even with the service packs mentioned above installed, the resulting
+ software generated in such an environment will be using outdated system
+ header files and libraries with bugs and security issues which have already
+ been addressed and fixed long time ago.
+
+ In order to make use of the updated system headers and fixed libraries
+ for MSVC 6, it is required that 'Platform SDK', PSDK from now onwards,
+ is installed. The specific PSDK that must be installed for MSVC 6 is the
+ February 2003 edition, which is the latest one supporting the MSVC 6 compiler,
+ this PSDK is also known as 'Windows Server 2003 PSDK' and can be downloaded
+ from http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm
+
+ So, building curl and libcurl with MSVC 6 without PSDK is absolutely
+ discouraged for the benefit of anyone using software built in such
+ environment. And it will not be supported in any way, as we could just
+ be hunting bugs which have already been fixed way back in 2003.
+
+ When building with MSVC 6 we attempt to detect if PSDK is not being used,
+ and if this is the case the build process will fail hard with an error
+ message stating that the February 2003 PSDK is required. This is done to
+ protect the unsuspecting and avoid PEBKAC issues.
+
+ Additionally it might happen that a die hard MSVC hacker still wants to
+ build curl and libcurl with MSVC 6 without PSDK installed, even knowing
+ that this is a highly discouraged and unsupported build environment. In
+ this case the brave of heart will be able to build in such an environment
+ with the requisite of defining preprocessor symbol ALLOW_MSVC6_WITHOUT_PSDK
+ in lib/config-win32.h and knowing that LDAP and IPv6 support will be missing.
+
+ MSVC from command line
+ ----------------------
+
+ Run the 'vcvars32.bat' file to get a proper environment. The
+ vcvars32.bat file is part of the Microsoft development environment and
+ you may find it in 'C:\Program Files\Microsoft Visual Studio\vc98\bin'
+ provided that you installed Visual C/C++ 6 in the default directory.
+
+ Then run 'nmake vc' in curl's root directory.
+
+ If you want to compile with zlib support, you will need to build
+ zlib (http://www.gzip.org/zlib/) as well. Please read the zlib
+ documentation on how to compile zlib. Define the ZLIB_PATH environment
+ variable to the location of zlib.h and zlib.lib, for example:
+
+ set ZLIB_PATH=c:\zlib-1.2.7
+
+ Then run 'nmake vc-zlib' in curl's root directory.
+
+ If you want to compile with SSL support you need the OpenSSL package.
+ Please read the OpenSSL documentation on how to compile and install
+ the OpenSSL libraries. The build process of OpenSSL generates the
+ libeay32.dll and ssleay32.dll files in the out32dll subdirectory in
+ the OpenSSL home directory. OpenSSL static libraries (libeay32.lib,
+ ssleay32.lib, RSAglue.lib) are created in the out32 subdirectory.
+
+ Before running nmake define the OPENSSL_PATH environment variable with
+ the root/base directory of OpenSSL, for example:
+
+ set OPENSSL_PATH=c:\openssl-0.9.8x
+
+ Then run 'nmake vc-ssl' or 'nmake vc-ssl-dll' in curl's root
+ directory. 'nmake vc-ssl' will create a libcurl static and dynamic
+ libraries in the lib subdirectory, as well as a statically linked
+ version of curl.exe in the src subdirectory. This statically linked
+ version is a standalone executable not requiring any DLL at
+ runtime. This make method requires that you have the static OpenSSL
+ libraries available in OpenSSL's out32 subdirectory.
+ 'nmake vc-ssl-dll' creates the libcurl dynamic library and
+ links curl.exe against libcurl and OpenSSL dynamically.
+ This executable requires libcurl.dll and the OpenSSL DLLs
+ at runtime.
+ Run 'nmake vc-ssl-zlib' to build with both ssl and zlib support.
+
+ MSVC 6 IDE
+ ----------
+
+ A minimal VC++ 6.0 reference workspace (vc6curl.dsw) is available with the
+ source distribution archive to allow proper building of the two included
+ projects, the libcurl library and the curl tool.
+
+ 1) Open the vc6curl.dsw workspace with MSVC6's IDE.
+ 2) Select 'Build' from top menu.
+ 3) Select 'Batch Build' from dropdown menu.
+ 4) Make sure that the eight project configurations are 'checked'.
+ 5) Click on the 'Build' button.
+ 6) Once the eight project configurations are built you are done.
+
+ Dynamic and static libcurl libraries are built in debug and release flavours,
+ and can be located each one in its own subdirectory, DLL-Debug, DLL-Release,
+ LIB-Debug and LIB-Release, all of them below the 'lib' subdirectory.
+
+ In the same way four curl executables are created, each using its respective
+ library. The resulting curl executables are located in its own subdirectory,
+ DLL-Debug, DLL-Release, LIB-Debug and LIB-Release, below the 'src' subdir.
+
+ These reference VC++ 6.0 configurations are generated using the dynamic CRT.
+
+ Intentionally, these reference VC++ 6.0 projects and configurations don't use
+ third party libraries, such as OpenSSL or Zlib, to allow proper compilation
+ and configuration for all new users without further requirements.
+
+ If you need something more 'involved' you might adjust them for your own use,
+ or explore the world of makefiles described above 'MSVC from command line'.
+
+ Borland C++ compiler
+ ---------------------
+
+ Ensure that your build environment is properly set up to use the compiler
+ and associated tools. PATH environment variable must include the path to
+ bin subdirectory of your compiler installation, eg: c:\Borland\BCC55\bin
+
+ It is advisable to set environment variable BCCDIR to the base path of
+ the compiler installation.
+
+ set BCCDIR=c:\Borland\BCC55
+
+ In order to build a plain vanilla version of curl and libcurl run the
+ following command from curl's root directory:
+
+ make borland
+
+ To build curl and libcurl with zlib and OpenSSL support set environment
+ variables ZLIB_PATH and OPENSSL_PATH to the base subdirectories of the
+ already built zlib and OpenSSL libraries and from curl's root directory
+ run command:
+
+ make borland-ssl-zlib
+
+ libcurl library will be built in 'lib' subdirectory while curl tool
+ is built in 'src' subdirectory. In order to use libcurl library it is
+ advisable to modify compiler's configuration file bcc32.cfg located
+ in c:\Borland\BCC55\bin to reflect the location of libraries include
+ paths for example the '-I' line could result in something like:
+
+ -I"c:\Borland\BCC55\include;c:\curl\include;c:\openssl\inc32"
+
+ bcc3.cfg '-L' line could also be modified to reflect the location of
+ of libcurl library resulting for example:
+
+ -L"c:\Borland\BCC55\lib;c:\curl\lib;c:\openssl\out32"
+
+ In order to build sample program 'simple.c' from the docs\examples
+ subdirectory run following command from mentioned subdirectory:
+
+ bcc32 simple.c libcurl.lib cw32mt.lib
+
+ In order to build sample program simplessl.c an SSL enabled libcurl
+ is required, as well as the OpenSSL libeay32.lib and ssleay32.lib
+ libraries.
+
+
+ OTHER MSVC IDEs
+ ---------------
+
+ If you use VC++, Borland or similar compilers. Include all lib source
+ files in a static lib "project" (all .c and .h files that is).
+ (you should name it libcurl or similar)
+
+ Make the sources in the src/ drawer be a "win32 console application"
+ project. Name it curl.
+
+
+ Disabling Specific Protocols in Win32 builds
+ --------------------------------------------
+
+ The configure utility, unfortunately, is not available for the Windows
+ environment, therefore, you cannot use the various disable-protocol
+ options of the configure utility on this platform.
+
+ However, you can use the following defines to disable specific
+ protocols:
+
+ HTTP_ONLY disables all protocols except HTTP
+ CURL_DISABLE_FTP disables FTP
+ CURL_DISABLE_LDAP disables LDAP
+ CURL_DISABLE_TELNET disables TELNET
+ CURL_DISABLE_DICT disables DICT
+ CURL_DISABLE_FILE disables FILE
+ CURL_DISABLE_TFTP disables TFTP
+ CURL_DISABLE_HTTP disables HTTP
+
+ If you want to set any of these defines you have the following
+ possibilities:
+
+ - Modify lib/config-win32.h
+ - Modify lib/setup.h
+ - Modify lib/Makefile.vc6
+ - Add defines to Project/Settings/C/C++/General/Preprocessor Definitions
+ in the vc6libcurl.dsw/vc6libcurl.dsp Visual C++ 6 IDE project.
+
+
+ Using BSD-style lwIP instead of Winsock TCP/IP stack in Win32 builds
+ --------------------------------------------------------------------
+
+ In order to compile libcurl and curl using BSD-style lwIP TCP/IP stack
+ it is necessary to make definition of preprocessor symbol USE_LWIPSOCK
+ visible to libcurl and curl compilation processes. To set this definition
+ you have the following alternatives:
+
+ - Modify lib/config-win32.h and src/config-win32.h
+ - Modify lib/Makefile.vc6
+ - Add definition to Project/Settings/C/C++/General/Preprocessor Definitions
+ in the vc6libcurl.dsw/vc6libcurl.dsp Visual C++ 6 IDE project.
+
+ Once that libcurl has been built with BSD-style lwIP TCP/IP stack support,
+ in order to use it with your program it is mandatory that your program
+ includes lwIP header file <lwip/opt.h> (or another lwIP header that includes
+ this) before including any libcurl header. Your program does not need the
+ USE_LWIPSOCK preprocessor definition which is for libcurl internals only.
+
+ Compilation has been verified with lwIP 1.4.0 and contrib-1.4.0 from:
+
+ http://download.savannah.gnu.org/releases/lwip/lwip-1.4.0.zip
+ http://download.savannah.gnu.org/releases/lwip/contrib-1.4.0.zip
+
+ This BSD-style lwIP TCP/IP stack support must be considered experimental
+ given that it has been verified that lwIP 1.4.0 still needs some polish,
+ and libcurl might yet need some additional adjustment, caveat emptor.
+
+ Important static libcurl usage note
+ -----------------------------------
+
+ When building an application that uses the static libcurl library, you must
+ add '-DCURL_STATICLIB' to your CFLAGS. Otherwise the linker will look for
+ dynamic import symbols.
+
+
+IBM OS/2
+========
+ Building under OS/2 is not much different from building under unix.
+ You need:
+
+ - emx 0.9d
+ - GNU make
+ - GNU patch
+ - ksh
+ - GNU bison
+ - GNU file utilities
+ - GNU sed
+ - autoconf 2.13
+
+ If you want to build with OpenSSL or OpenLDAP support, you'll need to
+ download those libraries, too. Dirk Ohme has done some work to port SSL
+ libraries under OS/2, but it looks like he doesn't care about emx. You'll
+ find his patches on: http://come.to/Dirk_Ohme
+
+ If during the linking you get an error about _errno being an undefined
+ symbol referenced from the text segment, you need to add -D__ST_MT_ERRNO__
+ in your definitions.
+
+ If everything seems to work fine but there's no curl.exe, you need to add
+ -Zexe to your linker flags.
+
+ If you're getting huge binaries, probably your makefiles have the -g in
+ CFLAGS.
+
+
+VMS
+===
+ (The VMS section is in whole contributed by the friendly Nico Baggus)
+
+ Curl seems to work with FTP & HTTP other protocols are not tested. (the
+ perl http/ftp testing server supplied as testing too cannot work on VMS
+ because vms has no concept of fork(). [ I tried to give it a whack, but
+ that's of no use.
+
+ SSL stuff has not been ported.
+
+ Telnet has about the same issues as for Win32. When the changes for Win32
+ are clear maybe they'll work for VMS too. The basic problem is that select
+ ONLY works for sockets.
+
+ Marked instances of fopen/[f]stat that might become a problem, especially
+ for non stream files. In this regard, the files opened for writing will be
+ created stream/lf and will thus be safe. Just keep in mind that non-binary
+ read/wring from/to files will have a records size limit of 32767 bytes
+ imposed.
+
+ Stat to get the size of the files is again only safe for stream files &
+ fixed record files without implied CC.
+
+ -- My guess is that only allowing access to stream files is the quickest
+ way to get around the most issues. Therefore all files need to to be
+ checked to be sure they will be stream/lf before processing them. This is
+ the easiest way out, I know. The reason for this is that code that needs to
+ report the filesize will become a pain in the ass otherwise.
+
+ Exit status.... Well we needed something done here,
+
+ VMS has a structured exist status:
+ | 3 | 2 | 1 | 0|
+ |1098|765432109876|5432109876543|210|
+ +----+------------+-------------+---+
+ |Ctrl| Facility | Error code |sev|
+ +----+------------+-------------+---+
+
+ With the Ctrl-bits an application can tell if part or the whole message has
+ already been printed from the program, DCL doesn't need to print it again.
+
+ Facility - basically the program ID. A code assigned to the program
+ the name can be fetched from external or internal message libraries
+ Error code - the err codes assigned by the application
+ Sev. - severity: Even = error, off = non error
+ 0 = Warning
+ 1 = Success
+ 2 = Error
+ 3 = Information
+ 4 = Fatal
+ <5-7> reserved.
+
+ This all presents itself with:
+ %<FACILITY>-<Sev>-<Errorname>, <Error message>
+
+ See also the src/curlmsg.msg file, it has the source for the messages In
+ src/main.c a section is devoted to message status values, the globalvalues
+ create symbols with certain values, referenced from a compiled message
+ file. Have all exit function use a exit status derived from a translation
+ table with the compiled message codes.
+
+ This was all compiled with:
+
+ Compaq C V6.2-003 on OpenVMS Alpha V7.1-1H2
+
+ So far for porting notes as of:
+ 13-jul-2001
+ N. Baggus
+
+
+QNX
+===
+ (This section was graciously brought to us by David Bentham)
+
+ As QNX is targeted for resource constrained environments, the QNX headers
+ set conservative limits. This includes the FD_SETSIZE macro, set by default
+ to 32. Socket descriptors returned within the CURL library may exceed this,
+ resulting in memory faults/SIGSEGV crashes when passed into select(..)
+ calls using fd_set macros.
+
+ A good all-round solution to this is to override the default when building
+ libcurl, by overriding CFLAGS during configure, example
+ # configure CFLAGS='-DFD_SETSIZE=64 -g -O2'
+
+
+RISC OS
+=======
+ The library can be cross-compiled using gccsdk as follows:
+
+ CC=riscos-gcc AR=riscos-ar RANLIB='riscos-ar -s' ./configure \
+ --host=arm-riscos-aof --without-random --disable-shared
+ make
+
+ where riscos-gcc and riscos-ar are links to the gccsdk tools.
+ You can then link your program with curl/lib/.libs/libcurl.a
+
+
+AmigaOS
+=======
+ (This section was graciously brought to us by Diego Casorran)
+
+ To build cURL/libcurl on AmigaOS just type 'make amiga' ...
+
+ What you need is: (not tested with others versions)
+
+ GeekGadgets / gcc 2.95.3 (http://www.geekgadgets.org/)
+
+ AmiTCP SDK v4.3 (http://www.aminet.net/comm/tcp/AmiTCP-SDK-4.3.lha)
+
+ Native Developer Kit (http://www.amiga.com/3.9/download/NDK3.9.lha)
+
+ As no ixemul.library is required you will be able to build it for
+ WarpOS/PowerPC (not tested by me), as well a MorphOS version should be
+ possible with no problems.
+
+ To enable SSL support, you need a OpenSSL native version (without ixemul),
+ you can find a precompiled package at http://amiga.sourceforge.net/OpenSSL/
+
+
+NetWare
+=======
+ To compile curl.nlm / libcurl.nlm you need:
+ - either any gcc / nlmconv, or CodeWarrior 7 PDK 4 or later.
+ - gnu make and awk running on the platform you compile on;
+ native Win32 versions can be downloaded from:
+ http://www.gknw.net/development/prgtools/
+ - recent Novell LibC SDK available from:
+ http://developer.novell.com/ndk/libc.htm
+ - or recent Novell CLib SDK available from:
+ http://developer.novell.com/ndk/clib.htm
+ - optional recent Novell CLDAP SDK available from:
+ http://developer.novell.com/ndk/cldap.htm
+ - optional zlib sources (static or dynamic linking with zlib.imp);
+ sources with NetWare Makefile can be obtained from:
+ http://www.gknw.net/mirror/zlib/
+ - optional OpenSSL sources (version 0.9.8 or later build with BSD sockets);
+ you can find precompiled packages at:
+ http://www.gknw.net/development/ossl/netware/
+ for CLIB-based builds OpenSSL 0.9.8h or later is required - earlier versions
+ don't support building with CLIB BSD sockets.
+ - optional SSH2 sources (version 0.17 or later);
+
+ Set a search path to your compiler, linker and tools; on Linux make
+ sure that the var OSTYPE contains the string 'linux'; set the var
+ NDKBASE to point to the base of your Novell NDK; and then type
+ 'make netware' from the top source directory; other targets available
+ are 'netware-ssl', 'netware-ssl-zlib', 'netware-zlib' and 'netware-ares';
+ if you need other combinations you can control the build with the
+ environment variables WITH_SSL, WITH_ZLIB, WITH_ARES, WITH_SSH2, and
+ ENABLE_IPV6; you can set LINK_STATIC=1 to link curl.nlm statically.
+ By default LDAP support is enabled, however currently you will need a patch
+ in order to use the CLDAP NDK with BSD sockets (Novell Bug 300237):
+ http://www.gknw.net/test/curl/cldap_ndk/ldap_ndk.diff
+ I found on some Linux systems (RH9) that OS detection didn't work although
+ a 'set | grep OSTYPE' shows the var present and set; I simply overwrote it
+ with 'OSTYPE=linux-rh9-gnu' and the detection in the Makefile worked...
+ Any help in testing appreciated!
+ Builds automatically created 8 times a day from current git are here:
+ http://www.gknw.net/mirror/curl/autobuilds/
+ the status of these builds can be viewed at the autobuild table:
+ http://curl.haxx.se/dev/builds.html
+
+
+eCos
+====
+ curl does not use the eCos build system, so you must first build eCos
+ separately, then link curl to the resulting eCos library. Here's a sample
+ configure line to do so on an x86 Linux box targeting x86:
+
+ GCCLIB=`gcc -print-libgcc-file-name` && \
+ CFLAGS="-D__ECOS=1 -nostdinc -I$ECOS_INSTALL/include \
+ -I`dirname $GCCLIB`/include" \
+ LDFLAGS="-nostdlib -Wl,--gc-sections -Wl,-static \
+ -L$ECOS_INSTALL/lib -Ttarget.ld -ltarget" \
+ ./configure --host=i386 --disable-shared \
+ --without-ssl --without-zlib --disable-manual --disable-ldap
+
+ In most cases, eCos users will be using libcurl from within a custom
+ embedded application. Using the standard 'curl' executable from
+ within eCos means facing the limitation of the standard eCos C
+ startup code which does not allow passing arguments in main(). To
+ run 'curl' from eCos and have it do something useful, you will need
+ to either modify the eCos startup code to pass in some arguments, or
+ modify the curl application itself to retrieve its arguments from
+ some location set by the bootloader or hard-code them.
+
+ Something like the following patch could be used to hard-code some
+ arguments. The MTAB_ENTRY line mounts a RAM disk as the root filesystem
+ (without mounting some kind of filesystem, eCos errors out all file
+ operations which curl does not take to well). The next section synthesizes
+ some command-line arguments for curl to use, in this case to direct curl
+ to read further arguments from a file. It then creates that file on the
+ RAM disk and places within it a URL to download: a file: URL that
+ just happens to point to the configuration file itself. The results
+ of running curl in this way is the contents of the configuration file
+ printed to the console.
+
+--- src/main.c 19 Jul 2006 19:09:56 -0000 1.363
++++ src/main.c 24 Jul 2006 21:37:23 -0000
+@@ -4286,11 +4286,31 @@
+ }
+
+
++#ifdef __ECOS
++#include <cyg/fileio/fileio.h>
++MTAB_ENTRY( testfs_mte1,
++ "/",
++ "ramfs",
++ "",
++ 0);
++#endif
+
+ int main(int argc, char *argv[])
+ {
+ int res;
+ struct Configurable config;
++#ifdef __ECOS
++ char *args[] = {"ecos-curl", "-K", "curlconf.txt"};
++ FILE *f;
++ argc = sizeof(args)/sizeof(args[0]);
++ argv = args;
++
++ f = fopen("curlconf.txt", "w");
++ if (f) {
++ fprintf(f, "--url file:curlconf.txt");
++ fclose(f);
++ }
++#endif
+ memset(&config, 0, sizeof(struct Configurable));
+
+ config.errors = stderr; /* default errors to stderr */
+
+
+Minix
+=====
+ curl can be compiled on Minix 3 using gcc or ACK (starting with
+ ver. 3.1.3). Ensure that GNU gawk and bash are both installed and
+ available in the PATH.
+
+ ACK
+ ---
+ Increase the heap sizes of the compiler with the command:
+
+ binsizes xxl
+
+ then configure and compile curl with:
+
+ ./configure CC=cc LD=cc AR=/usr/bin/aal GREP=grep \
+ CPPFLAGS='-D_POSIX_SOURCE=1 -I/usr/local/include'
+ make
+ chmem =256000 src/curl
+
+ GCC
+ ---
+ Make sure gcc is in your PATH with the command:
+
+ export PATH=/usr/gnu/bin:$PATH
+
+ then configure and compile curl with:
+
+ ./configure CC=gcc AR=/usr/gnu/bin/gar GREP=grep
+ make
+ chmem =256000 src/curl
+
+
+Symbian OS
+==========
+ The Symbian OS port uses the Symbian build system to compile. From the
+ packages/Symbian/group/ directory, run:
+
+ bldmake bldfiles
+ abld build
+
+ to compile and install curl and libcurl using SBSv1. If your Symbian
+ SDK doesn't include support for P.I.P.S., you will need to contact
+ your SDK vendor to obtain that first.
+
+
+VxWorks
+========
+ Build for VxWorks is performed using cross compilation.
+ That means you build on Windows machine using VxWorks tools and
+ run the built image on the VxWorks device.
+
+ To build libcurl for VxWorks you need:
+
+ - CYGWIN (free, http://cygwin.com/)
+ - Wind River Workbench (commercial)
+
+ If you have CYGWIN and Workbench installed on you machine
+ follow after next steps:
+
+ 1. Open the Command Prompt window and change directory ('cd')
+ to the libcurl 'lib' folder.
+ 2. Add CYGWIN 'bin' folder to the PATH environment variable.
+ For example, type 'set PATH=C:/embedded/cygwin/bin;%PATH%'.
+ 3. Adjust environment variables defined in 'Environment' section
+ of the Makefile.vxworks file to point to your software folders.
+ 4. Build the libcurl by typing 'make -f ./Makefile.vxworks'
+
+ As a result the libcurl.a library should be created in the 'lib' folder.
+ To clean the build results type 'make -f ./Makefile.vxworks clean'.
+
+
+Android
+=======
+ Method using the static makefile:
+ - see the build notes in the Android.mk file.
+
+ Method using a configure cross-compile (tested with Android NDK r7c, r8):
+ - prepare the toolchain of the Android NDK for standalone use; this can
+ be done by invoking the script:
+ ./build/tools/make-standalone-toolchain.sh
+ which creates a usual cross-compile toolchain. Lets assume that you put
+ this toolchain below /opt then invoke configure with something like:
+ export PATH=/opt/arm-linux-androideabi-4.4.3/bin:$PATH
+ ./configure --host=arm-linux-androideabi [more configure options]
+ make
+ - if you want to compile directly from our GIT repo you might run into
+ this issue with older automake stuff:
+ checking host system type...
+ Invalid configuration `arm-linux-androideabi':
+ system `androideabi' not recognized
+ configure: error: /bin/sh ./config.sub arm-linux-androideabi failed
+ this issue can be fixed with using more recent versions of config.sub
+ and config.guess which can be obtained here:
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=tree
+ you need to replace your system-own versions which usually can be
+ found in your automake folder:
+ find /usr -name config.sub
+
+ Wrapper for pkg-config
+ - In order to make proper use of pkg-config so that configure is able to
+ find all dependencies you should create a wrapper script for pkg-config;
+ file /opt/arm-linux-androideabi-4.4.3/bin/arm-linux-androideabi-pkg-config:
+
+ #!/bin/sh
+ SYSROOT=$(dirname ${0%/*})/sysroot
+ export PKG_CONFIG_DIR=
+ export PKG_CONFIG_LIBDIR=${SYSROOT}/usr/local/lib/pkgconfig:${SYSROOT}/usr/share/pkgconfig
+ export PKG_CONFIG_SYSROOT_DIR=${SYSROOT}
+ exec pkg-config "$@"
+
+ also create a copy or symlink with name arm-unknown-linux-androideabi-pkg-config.
+
+
+CROSS COMPILE
+=============
+ (This section was graciously brought to us by Jim Duey, with additions by
+ Dan Fandrich)
+
+ Download and unpack the cURL package.
+
+ 'cd' to the new directory. (e.g. cd curl-7.12.3)
+
+ Set environment variables to point to the cross-compile toolchain and call
+ configure with any options you need. Be sure and specify the '--host' and
+ '--build' parameters at configuration time. The following script is an
+ example of cross-compiling for the IBM 405GP PowerPC processor using the
+ toolchain from MonteVista for Hardhat Linux.
+
+ (begin script)
+
+ #! /bin/sh
+
+ export PATH=$PATH:/opt/hardhat/devkit/ppc/405/bin
+ export CPPFLAGS="-I/opt/hardhat/devkit/ppc/405/target/usr/include"
+ export AR=ppc_405-ar
+ export AS=ppc_405-as
+ export LD=ppc_405-ld
+ export RANLIB=ppc_405-ranlib
+ export CC=ppc_405-gcc
+ export NM=ppc_405-nm
+
+ ./configure --target=powerpc-hardhat-linux \
+ --host=powerpc-hardhat-linux \
+ --build=i586-pc-linux-gnu \
+ --prefix=/opt/hardhat/devkit/ppc/405/target/usr/local \
+ --exec-prefix=/usr/local
+
+ (end script)
+
+ You may also need to provide a parameter like '--with-random=/dev/urandom'
+ to configure as it cannot detect the presence of a random number
+ generating device for a target system. The '--prefix' parameter
+ specifies where cURL will be installed. If 'configure' completes
+ successfully, do 'make' and 'make install' as usual.
+
+ In some cases, you may be able to simplify the above commands to as
+ little as:
+
+ ./configure --host=ARCH-OS
+
+
+REDUCING SIZE
+=============
+ There are a number of configure options that can be used to reduce the
+ size of libcurl for embedded applications where binary size is an
+ important factor. First, be sure to set the CFLAGS variable when
+ configuring with any relevant compiler optimization flags to reduce the
+ size of the binary. For gcc, this would mean at minimum the -Os option,
+ and potentially the -march=X and -mdynamic-no-pic options as well, e.g.
+
+ ./configure CFLAGS='-Os' ...
+
+ Note that newer compilers often produce smaller code than older versions
+ due to improved optimization.
+
+ Be sure to specify as many --disable- and --without- flags on the configure
+ command-line as you can to disable all the libcurl features that you
+ know your application is not going to need. Besides specifying the
+ --disable-PROTOCOL flags for all the types of URLs your application
+ will not use, here are some other flags that can reduce the size of the
+ library:
+
+ --disable-ares (disables support for the C-ARES DNS library)
+ --disable-cookies (disables support for HTTP cookies)
+ --disable-crypto-auth (disables HTTP cryptographic authentication)
+ --disable-ipv6 (disables support for IPv6)
+ --disable-manual (disables support for the built-in documentation)
+ --disable-proxy (disables support for HTTP and SOCKS proxies)
+ --disable-verbose (eliminates debugging strings and error code strings)
+ --enable-hidden-symbols (eliminates unneeded symbols in the shared library)
+ --without-libidn (disables support for the libidn DNS library)
+ --without-ssl (disables support for SSL/TLS)
+ --without-zlib (disables support for on-the-fly decompression)
+
+ The GNU compiler and linker have a number of options that can reduce the
+ size of the libcurl dynamic libraries on some platforms even further.
+ Specify them by providing appropriate CFLAGS and LDFLAGS variables on the
+ configure command-line, e.g.
+ CFLAGS="-Os -ffunction-sections -fdata-sections \
+ -fno-unwind-tables -fno-asynchronous-unwind-tables" \
+ LDFLAGS="-Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections"
+
+ Be sure also to strip debugging symbols from your binaries after
+ compiling using 'strip' (or the appropriate variant if cross-compiling).
+ If space is really tight, you may be able to remove some unneeded
+ sections of the shared library using the -R option to objcopy (e.g. the
+ .comment section).
+
+ Using these techniques it is possible to create a basic HTTP-only shared
+ libcurl library for i386 Linux platforms that is only 106 KiB in size, and
+ an FTP-only library that is 108 KiB in size (as of libcurl version 7.27.0,
+ using gcc 4.6.3).
+
+ You may find that statically linking libcurl to your application will
+ result in a lower total size than dynamically linking.
+
+ Note that the curl test harness can detect the use of some, but not all, of
+ the --disable statements suggested above. Use will cause tests relying on
+ those features to fail. The test harness can be manually forced to skip
+ the relevant tests by specifying certain key words on the runtests.pl
+ command line. Following is a list of appropriate key words:
+
+ --disable-cookies !cookies
+ --disable-crypto-auth !HTTP\ Digest\ auth !HTTP\ proxy\ Digest\ auth
+ --disable-manual !--manual
+ --disable-proxy !HTTP\ proxy !proxytunnel !SOCKS4 !SOCKS5
+
+
+PORTS
+=====
+ This is a probably incomplete list of known hardware and operating systems
+ that curl has been compiled for. If you know a system curl compiles and
+ runs on, that isn't listed, please let us know!
+
+ - Alpha DEC OSF 4
+ - Alpha Digital UNIX v3.2
+ - Alpha FreeBSD 4.1, 4.5
+ - Alpha Linux 2.2, 2.4
+ - Alpha NetBSD 1.5.2
+ - Alpha OpenBSD 3.0
+ - Alpha OpenVMS V7.1-1H2
+ - Alpha Tru64 v5.0 5.1
+ - AVR32 Linux
+ - ARM Android 1.5, 2.1
+ - ARM INTEGRITY
+ - ARM iPhone OS
+ - Cell Linux
+ - Cell Cell OS
+ - HP-PA HP-UX 9.X 10.X 11.X
+ - HP-PA Linux
+ - HP3000 MPE/iX
+ - MicroBlaze uClinux
+ - MIPS IRIX 6.2, 6.5
+ - MIPS Linux
+ - OS/400
+ - Pocket PC/Win CE 3.0
+ - Power AIX 3.2.5, 4.2, 4.3.1, 4.3.2, 5.1, 5.2
+ - PowerPC Darwin 1.0
+ - PowerPC INTEGRITY
+ - PowerPC Linux
+ - PowerPC Mac OS 9
+ - PowerPC Mac OS X
+ - SH4 Linux 2.6.X
+ - SH4 OS21
+ - SINIX-Z v5
+ - Sparc Linux
+ - Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8, 9, 10
+ - Sparc SunOS 4.1.X
+ - StrongARM (and other ARM) RISC OS 3.1, 4.02
+ - StrongARM/ARM7/ARM9 Linux 2.4, 2.6
+ - StrongARM NetBSD 1.4.1
+ - Symbian OS (P.I.P.S.) 9.x
+ - TPF
+ - Ultrix 4.3a
+ - UNICOS 9.0
+ - i386 BeOS
+ - i386 DOS
+ - i386 eCos 1.3.1
+ - i386 Esix 4.1
+ - i386 FreeBSD
+ - i386 HURD
+ - i386 Haiku OS
+ - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6
+ - i386 MINIX 3.1
+ - i386 NetBSD
+ - i386 Novell NetWare
+ - i386 OS/2
+ - i386 OpenBSD
+ - i386 QNX 6
+ - i386 SCO unix
+ - i386 Solaris 2.7
+ - i386 Windows 95, 98, ME, NT, 2000, XP, 2003
+ - i486 ncr-sysv4.3.03 (NCR MP-RAS)
+ - ia64 Linux 2.3.99
+ - m68k AmigaOS 3
+ - m68k Linux
+ - m68k uClinux
+ - m68k OpenBSD
+ - m88k dg-dgux5.4R3.00
+ - s390 Linux
+ - x86_64 Linux
+ - XScale/PXA250 Linux 2.4
+ - Nios II uClinux
+
+Useful URLs
+===========
+
+axTLS http://axtls.sourceforge.net/
+c-ares http://c-ares.haxx.se/
+GNU GSS http://www.gnu.org/software/gss/
+GnuTLS http://www.gnu.org/software/gnutls/
+Heimdal http://www.pdc.kth.se/heimdal/
+libidn http://www.gnu.org/software/libidn/
+libssh2 http://www.libssh2.org/
+MIT Kerberos http://web.mit.edu/kerberos/www/dist/
+NSS http://www.mozilla.org/projects/security/pki/nss/
+OpenLDAP http://www.openldap.org/
+OpenSSL http://www.openssl.org/
+PolarSSL http://polarssl.org/
+yassl http://www.yassl.com/
+Zlib http://www.zlib.net/
+
+MingW http://www.mingw.org/
+MinGW-w64 http://mingw-w64.sourceforge.net/
+OpenWatcom http://www.openwatcom.org/
diff --git a/docs/INSTALL.cmake b/docs/INSTALL.cmake
new file mode 100644
index 000000000..e44f514e5
--- /dev/null
+++ b/docs/INSTALL.cmake
@@ -0,0 +1,102 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+ How To Compile with CMake
+
+Building with CMake
+==========================
+ This document describes how to compile, build and install curl and libcurl
+ from source code using the CMake build tool. To build with CMake, you will
+ of course have to first install CMake. The minimum required version of
+ CMake is specified in the file CMakeLists.txt found in the top of the curl
+ source tree. Once the correct version of CMake is installed you can follow
+ the instructions below for the platform you are building on.
+
+ CMake builds can be configured either from the command line, or from one
+ of CMake's GUI's.
+
+Current flaws in the curl CMake build
+=====================================
+
+ Missing features in the cmake build:
+
+ - Builds libcurl without large file support
+ - It doesn't build src/hugehelp.c which creates the --manual output
+ - Can't select which SSL library to build with, only OpenSSL
+ - Doesn't build with SCP and SFTP support (libssh2)
+ - Doesn't allow different resolver backends (no c-ares build support)
+ - No RTMP support built
+ - Doesn't allow build curl and libcurl debug enabled
+ - Doesn't allow a custom CA bundle path
+ - Doesn't allow you to disable specific protocols from the build
+ - Doesn't properly enable IPv6 support by default
+ - Doesn't find or use krb4 or GSS
+ - Rebuilds test files too eagerly, but still can't run the tests
+
+
+Important notice
+==================
+ If you got your curl sources from a distribution tarball, make sure to
+ delete the generic 'include/curl/curlbuild.h' file that comes with it:
+ rm -f curl/include/curl/curlbuild.h
+
+ The purpose of this file is to provide reasonable definitions for systems
+ where autoconfiguration is not available. CMake will create its own
+ version of this file in its build directory. If the "generic" version
+ is not deleted, weird build errors may occur on some systems.
+
+Command Line CMake
+==================
+ A CMake build of curl is similar to the autotools build of curl. It
+ consists of the following steps after you have unpacked the source.
+
+ 1. Create an out of source build tree parallel to the curl source
+ tree and change into that directory
+
+ $ mkdir curl-build
+ $ cd curl-build
+
+ 2. Run CMake from the build tree, giving it the path to the top of
+ the curl source tree. CMake will pick a compiler for you. If you
+ want to specify the compile, you can set the CC environment
+ variable prior to running CMake.
+
+ $ cmake ../curl
+ $ make
+
+ 3. Install to default location:
+
+ $ make install
+
+ (The teste suit does not work with the cmake build)
+
+ccmake
+=========
+ CMake comes with a curses based interface called ccmake. To run ccmake on
+ a curl use the instructions for the command line cmake, but substitute
+ ccmake ../curl for cmake ../curl. This will bring up a curses interface
+ with instructions on the bottom of the screen. You can press the "c" key
+ to configure the project, and the "g" key to generate the project. After
+ the project is generated, you can run make.
+
+cmake-gui
+=========
+ CMake also comes with a Qt based GUI called cmake-gui. To configure with
+ cmake-gui, you run cmake-gui and follow these steps:
+ 1. Fill in the "Where is the source code" combo box with the path to
+ the curl source tree.
+ 2. Fill in the "Where to build the binaries" combo box with the path
+ to the directory for your build tree, ideally this should not be the
+ same as the source tree, but a parallel directory called curl-build or
+ something similar.
+ 3. Once the source and binary directories are specified, press the
+ "Configure" button.
+ 4. Select the native build tool that you want to use.
+ 5. At this point you can change any of the options presented in the
+ GUI. Once you have selected all the options you want, click the
+ "Generate" button.
+ 6. Run the native build tool that you used CMake to generate.
+
diff --git a/docs/INSTALL.devcpp b/docs/INSTALL.devcpp
new file mode 100644
index 000000000..46d1836af
--- /dev/null
+++ b/docs/INSTALL.devcpp
@@ -0,0 +1,302 @@
+DevCpp-Mingw Install & Compilation Sept 2005
+==================================
+
+Reference Emails available at curl@haxx.se:
+
+ Libcurl Install and Use Issues
+ Awaiting an Answer for Win 32 Install
+ res = curl_easy_perform(curl); Error
+ Makefile Issues
+
+
+Having previously done a thorough review of what was available that met my
+requirements under GPL, I settled for Libcurl as the software of choice for
+many reasons not the least of which was the support.
+
+Background
+----------
+
+This quest started when I innocently tried to incorporate the libcurl library
+into my simple source code. I figured that a few easy steps would accomplish
+this without major headaches. I had no idea that I would be facing an almost
+insurmountable challenge.
+
+The main problem lies in two areas. First the bulk of support for libcurl
+exists for a Unix/linux command line environments. This is of little help when
+it comes to Windows O/S.
+
+Secondly the help that does exist for the Windows O/S focused around mingw
+through a command line argument environment.
+
+You may ask "Why is this a problem?"
+
+I'm using a Windows O/S with DevCpp. For those of you who are unfamiliar with
+DevCpp, it is a window shell GUI that replaces the command line environment
+for gcc. A definite improvement that I am unwilling to give up. However using
+DevCpp presented its own set of issues. Inadvertently I also made some
+careless errors such as compiling the 7.14 version of Makefile with an older
+version of source code. Thanks to Dan Fandrich for picking this up.
+
+I did eventually with the help of Daniel, Phillipe and others manage to
+implement successfully (the only mingw available version)
+curl-7.13.0-win32-ssl-devel-mingw32 into the DevCpp environment. Only the
+dynamic libcurl.dll libcurldll.a libraries worked. The static library which I
+was interested in did not. Furthermore when I tried to implement one of the
+examples included with the curl package (get info.c) it caused the executable
+to crash. Tracing the bug I found it in the code and function res =
+curl_easy_perform(curl);.
+
+At this point I had to make a choice as to whether invest my limited
+time-energy resource to fixing the bug or to compile the new version
+available. After searching the archives I found a very similar or the same bug
+reported from version 7.12x on. Daniel did inform me that he thought that this
+bug had been fixed with the latest version. So I proceeded to compile the
+latest SSL version where I faced other challenges.
+
+In order to make this process unremarkable for others using the same
+environment I decided to document the process so that others will find it
+routine. It would be a shame if newbies could not implement this excellent
+package for their use.
+
+I would like to thank the many others in this forum and in the DevCpp forum
+for their help. Without your help I may either have given up or it would have
+taken me many times longer to achieve success.
+
+The Cookbook Approach
+---------------------
+
+This discussion will be confined to a SSL static library compilation and
+installation. Limited mention and comments will be inserted where appropriate
+to help with non-SSL, dynamic libraries and executables.
+
+
+ Using Makefile from DevCpp to compile Libcurl libraries
+
+Preamble
+--------
+
+Using the latest version release - curl-7.14.0.tar.gz. Curl source code is
+platform independent. This simply means that the source code can be compiled
+for any Operating System (Linux/Unix Windows etc. and variations of thereof).
+
+The first thing to note is that inside curl-7.14.0 you will find two folders
+lib and src. Both contain Makefile.m32 (required for win mingw library or exe
+compilation) files which are different. The main difference between these two
+folders and the makefiles is that the src folder contents are used to compile
+an executable file(curl.exe) while the lib folder contents are used to compile
+a static (libcurl.a) and dynamic (libcurl.dll & libcurldll.a) file that can be
+used to compile libcurl with your own source code so that one can use and
+access all libcurl functions.
+
+Before we start please make sure that DevCpp is installed properly. In
+particular make sure you have no spaces in the name of any of the directories
+and subdirectories where DevCpp is installed. Failure to comply with the
+install instructions may produce erratic behaviour in DevCpp. For further info
+check the following sites
+
+http://aditsu.freeunixhost.com/dev-cpp-faq.html
+http://sourceforge.net/forum/message.php?msg_id=3252213
+
+As I have mentioned before I will confine this to the SSL Library compilations
+but the process is very similar for compilation of the executable - curl.exe;
+just substitute the src folder makefile in its stead.
+
+First use a text processor Notepad, or your own favourite text processor. To
+engage your favourite text processor, select Makefile.m32 click once with your
+mouse on file icon; icon turns blue, press the shift key and right-click on
+mouse, menu appears select "Open with", select your favourite text processor.
+
+Next read the contents of Makefile.m32. It includes instructions on its use.
+
+Method I - DOS Command Line
+---------------------------
+
+Note - The only reason I have included this method is that Method II which is
+the preferred method for compiling does not allow for the setting of option
+switches (e.g. SSL = 1 or SSL =0). At least that's what they tell me at the
+Dev-Cpp forum.
+
+1 - Make a copy of (D:\Dev-Cpp\bin) bin folder and name it "bin Original"
+place it in the Dev-Cpp installed directory (D:\Dev-Cpp\ for this example)
+
+2 - Copy the entire contents of the LIB folder of curl-7.14.0.tar.gz or zip
+version into the bin folder above (D:\Dev-Cpp\bin). The reason being is that
+the make.exe file resides in this folder. Make.exe will use - Makefile.m32,
+Makefile.inc, and the source code included in the lib folder to compile the
+source code. There is a PATH issue with make.exe that remains unresolved at
+least for me. Unless the entire source code to be compiled is placed entirely
+within the directory of make.exe an error message will be generated - "file
+xxxx.yyy not available".
+
+3- Go to Dev-Cpp\bin and double click on make .exe. You will see a DOS window
+quickly pop up and close very quickly. Not to worry! Please do not skip this
+step.
+
+4- Click on the start button\Programs\MS-DOS Prompt.Once the DOS Window is up
+Type the disk drive letter (e.g. E: ) engage the enter button. The path should
+automatically take you to the directory of the make.exe file.
+
+5- To compile the source code simply type at the DOS prompt make -f
+Makefile.m32 as per instructions contained in the Makefile.m32 file (use any
+text processor to read instructions). I don't believe that this makefile
+allows for the option of non SSL. Ignore any warnings.
+
+6- Collect and make copies of libcurl.a, libcurl.dll, libcurldll.a and any *.o
+compilations you might need in another directory outside of the bin directory
+as you will need this files shortly to set up libcurl for use with
+Dev-cpp. For most apps *.o is not required. Later on we will show what to do
+with these files.
+
+7- You are finished but before closing we need to do cleanup - erase the bin
+folder and rename the "bin Original" folder created in step 1 to bin.
+
+Note to compile a curl executable the process is probably similar but instead
+of using the LIB folder contents use the SRC folder contents and Makefiles in
+curl-7.14.0.tar.gz. File directories relative placements must be respected for
+compiling to take place successfully. This may not be possible with the PATH
+problem that make.exe experiences. If anyone has solved this PATH issue and
+please make sure it actually works on Win 9x/2000/XP before letting me
+know. Then please let me or Daniel in on the solution so that it can be
+included with these instructions. Thanks.
+
+or
+
+Method II - Dev-Cpp GUI
+-----------------------
+
+1- Copy the entire contents of the LIB folder of curl-7.14.0.tar.gz or zip
+version into any folder outside of (Dev-Cpp\bin).
+
+2- Drop the File/New/click on Project.
+
+3- New Project Dialogue box appears. Double click on the Static Library.
+
+4- Create Project Dialogue box appears. Select the LIB folder location to
+place and locate your Project File Name. Placing the Project File Name
+elsewhere may cause problems (PATH issue problem again).
+
+5- Drop down the Project/Project Options. Project Options Dialogue box
+appears.
+
+6- Select the Makefile tab in the Project Options Dialogue Box. Check Box -
+Use Custom Makefile. Click on the Folder icon at the extreme right of the
+Check Box. Select Makefile.m32 in the folder wherever you have placed the
+contents of the LIB Folder. Press OK and close the Dialogue Box.
+
+7- Drop the Menu Project/Click on Add to Project. Open File Dialogue Box
+appears. The Dialogue Box should open in the folder wherever you have placed
+the contents of the LIB Folder. If not go there.
+
+8- Select Crtl-A to select all files in the LIB folder. Click on open to add
+files and close box. Wait till all files are added. This may take 30 seconds
+or longer.
+
+9- Drop the Menu Execute/Click on Compile.
+
+10- That's it.
+
+
+ The following steps must be completed if Curl is to work properly
+ =================================================================
+
+LIB folder inclusions (*.a placement)
+-------------------------------------
+
+1- Refer to Method I - DOS Command Line point # 6 Take libcurl.a, libcurldll.a
+and install it in the directory C( or whichever drive Dev is installed)
+:\Dev-Cpp\lib.
+
+
+Include Folder
+--------------
+
+1- Create a new folder by the name of curl (do not change the name curl to
+some other name as it will cause major issues) in the directory
+C:\Dev-Cpp\include.
+
+2- Copy the entire contents of the curl folder of curl-7.14.0.tar.gz or zip
+ version into the newly created curl directory - C:\Dev-Cpp\include\curl.
+
+Links To Include And Lib Folder
+-------------------------------
+
+1- Drop the Menu - Tools\Compiler Options\Directories\Libraries. Make sure
+that C( or whichever drive Dev is installed):\DEV-CPP\lib is included.
+
+2- Next select the Menu - Tools\Compiler Options\Directories\C Includes. Make
+sure that C:\DEV-CPP\include and C:\Dev-Cpp\include\curl are included.
+
+3- Next select the Menu - Tools\Compiler Options\Directories\C++
+Includes. Make sure that C:\DEV-CPP\include and C:\Dev-Cpp\include\curl are
+included.
+
+Linker Links
+------------
+
+1- Drop the Menu - Tools\Compiler Options\Directories\Compiler.
+
+2- Make sure that the box "Add these commands to the linker command line" is
+checked.
+
+3- Include in the white space immediately below the box referred in 2 -lcurl
+-lws2_32.
+
+SSL Files
+---------
+
+1- Get the latest openSSL (as of time of this writing)
+openssl-0.9.7e-win32-bin.zip for the minimalist package of the openssl-0.9.7e
+binaries ported to MS Windows 95/98/NT/XP using the MingW32/GCC-3.1
+development environment. The file may be downloaded at
+http://curl.haxx.se/download/.
+
+2- Open the above zip file. You will find two files - SDL.dll,
+SDL_mixer.dll. Install them in the directory C:\WINDOWS\SYSTEM32 for Win 9x
+users and c:\winnt\system32 for NT-family users.
+
+Multithreading Files
+--------------------
+
+To be completed
+
+#define
+-------
+
+1- Make sure that your program includes the following - #define CURL_STATICLIB
+must be declared FIRST before any other define functions may be
+added. Otherwise you may experience link errors.
+
+2- Don't forget to include #include "curl/curl.h".
+
+e.g.
+ #define CURL_STATICLIB
+#include <windows.h>
+ #include "curl/curl.h"
+#include <fstream>
+#include <iostream>
+#include <vector>
+etc...
+
+
+Static or Dynamic Library
+-------------------------
+
+The above steps apply for the use by a static library. Should you choose to
+use a dynamic library you will be required to perform these additional steps.
+
+1- Refer to Method I - DOS Command Line point # 6. Install libcurl.dll in the
+directory C:\WINDOWS\SYSTEM32 for Win 9x users and c:\winnt\system32 for
+NT-family users.
+
+2- Refer to Linker Links point 3 - Replace -lcurl with -lcurldll.
+
+Voila you're done.
+
+The non-SSL static Library build may not be possible to use at least as of the
+time of this writing - v7.14. Check reference emails - Phillipe and I found it
+impossible to fully compile as certain files were missing for linking. No big
+loss as SSL is a major plus.
+
+Hope this Helps
+
+Tom
diff --git a/docs/INTERNALS b/docs/INTERNALS
new file mode 100644
index 000000000..d06d62209
--- /dev/null
+++ b/docs/INTERNALS
@@ -0,0 +1,505 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+INTERNALS
+
+ The project is split in two. The library and the client. The client part uses
+ the library, but the library is designed to allow other applications to use
+ it.
+
+ The largest amount of code and complexity is in the library part.
+
+GIT
+===
+ All changes to the sources are committed to the git repository as soon as
+ they're somewhat verified to work. Changes shall be committed as independently
+ as possible so that individual changes can be easier spotted and tracked
+ afterwards.
+
+ Tagging shall be used extensively, and by the time we release new archives we
+ should tag the sources with a name similar to the released version number.
+
+Portability
+===========
+
+ We write curl and libcurl to compile with C89 compilers. On 32bit and up
+ machines. Most of libcurl assumes more or less POSIX compliance but that's
+ not a requirement.
+
+ We write libcurl to build and work with lots of third party tools, and we
+ want it to remain functional and buildable with these and later versions
+ (older versions may still work but is not what we work hard to maintain):
+
+ OpenSSL 0.9.6
+ GnuTLS 1.2
+ zlib 1.1.4
+ libssh2 0.16
+ c-ares 1.6.0
+ libidn 0.4.1
+ cyassl 2.0.0
+ openldap 2.0
+ MIT krb5 lib 1.2.4
+ qsossl V5R2M0
+ NSS 3.12.x
+ axTLS 1.2.7
+ Heimdal ?
+
+ * = only partly functional, but that's due to bugs in the third party lib, not
+ because of libcurl code
+
+ On systems where configure runs, we aim at working on them all - if they have
+ a suitable C compiler. On systems that don't run configure, we strive to keep
+ curl running fine on:
+
+ Windows 98
+ AS/400 V5R2M0
+ Symbian 9.1
+ Windows CE ?
+ TPF ?
+
+ When writing code (mostly for generating stuff included in release tarballs)
+ we use a few "build tools" and we make sure that we remain functional with
+ these versions:
+
+ GNU Libtool 1.4.2
+ GNU Autoconf 2.57
+ GNU Automake 1.7 (we currently avoid 1.10 due to Solaris-related bugs)
+ GNU M4 1.4
+ perl 5.004
+ roffit 0.5
+ groff ? (any version that supports "groff -Tps -man [in] [out]")
+ ps2pdf (gs) ?
+
+Windows vs Unix
+===============
+
+ There are a few differences in how to program curl the unix way compared to
+ the Windows way. The four perhaps most notable details are:
+
+ 1. Different function names for socket operations.
+
+ In curl, this is solved with defines and macros, so that the source looks
+ the same at all places except for the header file that defines them. The
+ macros in use are sclose(), sread() and swrite().
+
+ 2. Windows requires a couple of init calls for the socket stuff.
+
+ That's taken care of by the curl_global_init() call, but if other libs also
+ do it etc there might be reasons for applications to alter that behaviour.
+
+ 3. The file descriptors for network communication and file operations are
+ not easily interchangeable as in unix.
+
+ We avoid this by not trying any funny tricks on file descriptors.
+
+ 4. When writing data to stdout, Windows makes end-of-lines the DOS way, thus
+ destroying binary data, although you do want that conversion if it is
+ text coming through... (sigh)
+
+ We set stdout to binary under windows
+
+ Inside the source code, We make an effort to avoid '#ifdef [Your OS]'. All
+ conditionals that deal with features *should* instead be in the format
+ '#ifdef HAVE_THAT_WEIRD_FUNCTION'. Since Windows can't run configure scripts,
+ we maintain a curl_config-win32.h file in lib directory that is supposed to
+ look exactly as a curl_config.h file would have looked like on a Windows
+ machine!
+
+ Generally speaking: always remember that this will be compiled on dozens of
+ operating systems. Don't walk on the edge.
+
+Library
+=======
+
+ There are plenty of entry points to the library, namely each publicly defined
+ function that libcurl offers to applications. All of those functions are
+ rather small and easy-to-follow. All the ones prefixed with 'curl_easy' are
+ put in the lib/easy.c file.
+
+ curl_global_init_() and curl_global_cleanup() should be called by the
+ application to initialize and clean up global stuff in the library. As of
+ today, it can handle the global SSL initing if SSL is enabled and it can init
+ the socket layer on windows machines. libcurl itself has no "global" scope.
+
+ All printf()-style functions use the supplied clones in lib/mprintf.c. This
+ makes sure we stay absolutely platform independent.
+
+ curl_easy_init() allocates an internal struct and makes some initializations.
+ The returned handle does not reveal internals. This is the 'SessionHandle'
+ struct which works as an "anchor" struct for all curl_easy functions. All
+ connections performed will get connect-specific data allocated that should be
+ used for things related to particular connections/requests.
+
+ curl_easy_setopt() takes three arguments, where the option stuff must be
+ passed in pairs: the parameter-ID and the parameter-value. The list of
+ options is documented in the man page. This function mainly sets things in
+ the 'SessionHandle' struct.
+
+ curl_easy_perform() does a whole lot of things:
+
+ It starts off in the lib/easy.c file by calling Curl_perform() and the main
+ work then continues in lib/url.c. The flow continues with a call to
+ Curl_connect() to connect to the remote site.
+
+ o Curl_connect()
+
+ ... analyzes the URL, it separates the different components and connects to
+ the remote host. This may involve using a proxy and/or using SSL. The
+ Curl_resolv() function in lib/hostip.c is used for looking up host names
+ (it does then use the proper underlying method, which may vary between
+ platforms and builds).
+
+ When Curl_connect is done, we are connected to the remote site. Then it is
+ time to tell the server to get a document/file. Curl_do() arranges this.
+
+ This function makes sure there's an allocated and initiated 'connectdata'
+ struct that is used for this particular connection only (although there may
+ be several requests performed on the same connect). A bunch of things are
+ inited/inherited from the SessionHandle struct.
+
+ o Curl_do()
+
+ Curl_do() makes sure the proper protocol-specific function is called. The
+ functions are named after the protocols they handle. Curl_ftp(),
+ Curl_http(), Curl_dict(), etc. They all reside in their respective files
+ (ftp.c, http.c and dict.c). HTTPS is handled by Curl_http() and FTPS by
+ Curl_ftp().
+
+ The protocol-specific functions of course deal with protocol-specific
+ negotiations and setup. They have access to the Curl_sendf() (from
+ lib/sendf.c) function to send printf-style formatted data to the remote
+ host and when they're ready to make the actual file transfer they call the
+ Curl_Transfer() function (in lib/transfer.c) to setup the transfer and
+ returns.
+
+ If this DO function fails and the connection is being re-used, libcurl will
+ then close this connection, setup a new connection and re-issue the DO
+ request on that. This is because there is no way to be perfectly sure that
+ we have discovered a dead connection before the DO function and thus we
+ might wrongly be re-using a connection that was closed by the remote peer.
+
+ Some time during the DO function, the Curl_setup_transfer() function must
+ be called with some basic info about the upcoming transfer: what socket(s)
+ to read/write and the expected file transfer sizes (if known).
+
+ o Transfer()
+
+ Curl_perform() then calls Transfer() in lib/transfer.c that performs the
+ entire file transfer.
+
+ During transfer, the progress functions in lib/progress.c are called at a
+ frequent interval (or at the user's choice, a specified callback might get
+ called). The speedcheck functions in lib/speedcheck.c are also used to
+ verify that the transfer is as fast as required.
+
+ o Curl_done()
+
+ Called after a transfer is done. This function takes care of everything
+ that has to be done after a transfer. This function attempts to leave
+ matters in a state so that Curl_do() should be possible to call again on
+ the same connection (in a persistent connection case). It might also soon
+ be closed with Curl_disconnect().
+
+ o Curl_disconnect()
+
+ When doing normal connections and transfers, no one ever tries to close any
+ connections so this is not normally called when curl_easy_perform() is
+ used. This function is only used when we are certain that no more transfers
+ is going to be made on the connection. It can be also closed by force, or
+ it can be called to make sure that libcurl doesn't keep too many
+ connections alive at the same time (there's a default amount of 5 but that
+ can be changed with the CURLOPT_MAXCONNECTS option).
+
+ This function cleans up all resources that are associated with a single
+ connection.
+
+ Curl_perform() is the function that does the main "connect - do - transfer -
+ done" loop. It loops if there's a Location: to follow.
+
+ When completed, the curl_easy_cleanup() should be called to free up used
+ resources. It runs Curl_disconnect() on all open connections.
+
+ A quick roundup on internal function sequences (many of these call
+ protocol-specific function-pointers):
+
+ Curl_connect - connects to a remote site and does initial connect fluff
+ This also checks for an existing connection to the requested site and uses
+ that one if it is possible.
+
+ Curl_do - starts a transfer
+ Curl_handler::do_it() - transfers data
+ Curl_done - ends a transfer
+
+ Curl_disconnect - disconnects from a remote site. This is called when the
+ disconnect is really requested, which doesn't necessarily have to be
+ exactly after curl_done in case we want to keep the connection open for
+ a while.
+
+ HTTP(S)
+
+ HTTP offers a lot and is the protocol in curl that uses the most lines of
+ code. There is a special file (lib/formdata.c) that offers all the multipart
+ post functions.
+
+ base64-functions for user+password stuff (and more) is in (lib/base64.c) and
+ all functions for parsing and sending cookies are found in (lib/cookie.c).
+
+ HTTPS uses in almost every means the same procedure as HTTP, with only two
+ exceptions: the connect procedure is different and the function used to read
+ or write from the socket is different, although the latter fact is hidden in
+ the source by the use of Curl_read() for reading and Curl_write() for writing
+ data to the remote server.
+
+ http_chunks.c contains functions that understands HTTP 1.1 chunked transfer
+ encoding.
+
+ An interesting detail with the HTTP(S) request, is the Curl_add_buffer()
+ series of functions we use. They append data to one single buffer, and when
+ the building is done the entire request is sent off in one single write. This
+ is done this way to overcome problems with flawed firewalls and lame servers.
+
+ FTP
+
+ The Curl_if2ip() function can be used for getting the IP number of a
+ specified network interface, and it resides in lib/if2ip.c.
+
+ Curl_ftpsendf() is used for sending FTP commands to the remote server. It was
+ made a separate function to prevent us programmers from forgetting that they
+ must be CRLF terminated. They must also be sent in one single write() to make
+ firewalls and similar happy.
+
+ Kerberos
+
+ The kerberos support is mainly in lib/krb4.c and lib/security.c.
+
+ TELNET
+
+ Telnet is implemented in lib/telnet.c.
+
+ FILE
+
+ The file:// protocol is dealt with in lib/file.c.
+
+ LDAP
+
+ Everything LDAP is in lib/ldap.c and lib/openldap.c
+
+ GENERAL
+
+ URL encoding and decoding, called escaping and unescaping in the source code,
+ is found in lib/escape.c.
+
+ While transferring data in Transfer() a few functions might get used.
+ curl_getdate() in lib/parsedate.c is for HTTP date comparisons (and more).
+
+ lib/getenv.c offers curl_getenv() which is for reading environment variables
+ in a neat platform independent way. That's used in the client, but also in
+ lib/url.c when checking the proxy environment variables. Note that contrary
+ to the normal unix getenv(), this returns an allocated buffer that must be
+ free()ed after use.
+
+ lib/netrc.c holds the .netrc parser
+
+ lib/timeval.c features replacement functions for systems that don't have
+ gettimeofday() and a few support functions for timeval conversions.
+
+ A function named curl_version() that returns the full curl version string is
+ found in lib/version.c.
+
+Persistent Connections
+======================
+
+ The persistent connection support in libcurl requires some considerations on
+ how to do things inside of the library.
+
+ o The 'SessionHandle' struct returned in the curl_easy_init() call must never
+ hold connection-oriented data. It is meant to hold the root data as well as
+ all the options etc that the library-user may choose.
+ o The 'SessionHandle' struct holds the "connection cache" (an array of
+ pointers to 'connectdata' structs). There's one connectdata struct
+ allocated for each connection that libcurl knows about. Note that when you
+ use the multi interface, the multi handle will hold the connection cache
+ and not the particular easy handle. This of course to allow all easy handles
+ in a multi stack to be able to share and re-use connections.
+ o This enables the 'curl handle' to be reused on subsequent transfers.
+ o When we are about to perform a transfer with curl_easy_perform(), we first
+ check for an already existing connection in the cache that we can use,
+ otherwise we create a new one and add to the cache. If the cache is full
+ already when we add a new connection, we close one of the present ones. We
+ select which one to close dependent on the close policy that may have been
+ previously set.
+ o When the transfer operation is complete, we try to leave the connection
+ open. Particular options may tell us not to, and protocols may signal
+ closure on connections and then we don't keep it open of course.
+ o When curl_easy_cleanup() is called, we close all still opened connections,
+ unless of course the multi interface "owns" the connections.
+
+ You do realize that the curl handle must be re-used in order for the
+ persistent connections to work.
+
+multi interface/non-blocking
+============================
+
+ We make an effort to provide a non-blocking interface to the library, the
+ multi interface. To make that interface work as good as possible, no
+ low-level functions within libcurl must be written to work in a blocking
+ manner.
+
+ One of the primary reasons we introduced c-ares support was to allow the name
+ resolve phase to be perfectly non-blocking as well.
+
+ The ultimate goal is to provide the easy interface simply by wrapping the
+ multi interface functions and thus treat everything internally as the multi
+ interface is the single interface we have.
+
+ The FTP and the SFTP/SCP protocols are thus perfect examples of how we adapt
+ and adjust the code to allow non-blocking operations even on multi-stage
+ protocols. They are built around state machines that return when they could
+ block waiting for data. The DICT, LDAP and TELNET protocols are crappy
+ examples and they are subject for rewrite in the future to better fit the
+ libcurl protocol family.
+
+SSL libraries
+=============
+
+ Originally libcurl supported SSLeay for SSL/TLS transports, but that was then
+ extended to its successor OpenSSL but has since also been extended to several
+ other SSL/TLS libraries and we expect and hope to further extend the support
+ in future libcurl versions.
+
+ To deal with this internally in the best way possible, we have a generic SSL
+ function API as provided by the sslgen.[ch] system, and they are the only SSL
+ functions we must use from within libcurl. sslgen is then crafted to use the
+ appropriate lower-level function calls to whatever SSL library that is in
+ use.
+
+Library Symbols
+===============
+
+ All symbols used internally in libcurl must use a 'Curl_' prefix if they're
+ used in more than a single file. Single-file symbols must be made static.
+ Public ("exported") symbols must use a 'curl_' prefix. (There are exceptions,
+ but they are to be changed to follow this pattern in future versions.) Public
+ API functions are marked with CURL_EXTERN in the public header files so that
+ all others can be hidden on platforms where this is possible.
+
+Return Codes and Informationals
+===============================
+
+ I've made things simple. Almost every function in libcurl returns a CURLcode,
+ that must be CURLE_OK if everything is OK or otherwise a suitable error code
+ as the curl/curl.h include file defines. The very spot that detects an error
+ must use the Curl_failf() function to set the human-readable error
+ description.
+
+ In aiding the user to understand what's happening and to debug curl usage, we
+ must supply a fair amount of informational messages by using the Curl_infof()
+ function. Those messages are only displayed when the user explicitly asks for
+ them. They are best used when revealing information that isn't otherwise
+ obvious.
+
+API/ABI
+=======
+
+ We make an effort to not export or show internals or how internals work, as
+ that makes it easier to keep a solid API/ABI over time. See docs/libcurl/ABI
+ for our promise to users.
+
+Client
+======
+
+ main() resides in src/main.c together with most of the client code.
+
+ src/hugehelp.c is automatically generated by the mkhelp.pl perl script to
+ display the complete "manual" and the src/urlglob.c file holds the functions
+ used for the URL-"globbing" support. Globbing in the sense that the {} and []
+ expansion stuff is there.
+
+ The client mostly messes around to setup its 'config' struct properly, then
+ it calls the curl_easy_*() functions of the library and when it gets back
+ control after the curl_easy_perform() it cleans up the library, checks status
+ and exits.
+
+ When the operation is done, the ourWriteOut() function in src/writeout.c may
+ be called to report about the operation. That function is using the
+ curl_easy_getinfo() function to extract useful information from the curl
+ session.
+
+ Recent versions may loop and do all this several times if many URLs were
+ specified on the command line or config file.
+
+Memory Debugging
+================
+
+ The file lib/memdebug.c contains debug-versions of a few functions. Functions
+ such as malloc, free, fopen, fclose, etc that somehow deal with resources
+ that might give us problems if we "leak" them. The functions in the memdebug
+ system do nothing fancy, they do their normal function and then log
+ information about what they just did. The logged data can then be analyzed
+ after a complete session,
+
+ memanalyze.pl is the perl script present in tests/ that analyzes a log file
+ generated by the memory tracking system. It detects if resources are
+ allocated but never freed and other kinds of errors related to resource
+ management.
+
+ Internally, definition of preprocessor symbol DEBUGBUILD restricts code which
+ is only compiled for debug enabled builds. And symbol CURLDEBUG is used to
+ differentiate code which is _only_ used for memory tracking/debugging.
+
+ Use -DCURLDEBUG when compiling to enable memory debugging, this is also
+ switched on by running configure with --enable-curldebug. Use -DDEBUGBUILD
+ when compiling to enable a debug build or run configure with --enable-debug.
+
+ curl --version will list 'Debug' feature for debug enabled builds, and
+ will list 'TrackMemory' feature for curl debug memory tracking capable
+ builds. These features are independent and can be controlled when running
+ the configure script. When --enable-debug is given both features will be
+ enabled, unless some restriction prevents memory tracking from being used.
+
+Test Suite
+==========
+
+ The test suite is placed in its own subdirectory directly off the root in the
+ curl archive tree, and it contains a bunch of scripts and a lot of test case
+ data.
+
+ The main test script is runtests.pl that will invoke test servers like
+ httpserver.pl and ftpserver.pl before all the test cases are performed. The
+ test suite currently only runs on unix-like platforms.
+
+ You'll find a description of the test suite in the tests/README file, and the
+ test case data files in the tests/FILEFORMAT file.
+
+ The test suite automatically detects if curl was built with the memory
+ debugging enabled, and if it was it will detect memory leaks, too.
+
+Building Releases
+=================
+
+ There's no magic to this. When you consider everything stable enough to be
+ released, do this:
+
+ 1. Tag the source code accordingly.
+
+ 2. run the 'maketgz' script (using 'make distcheck' will give you a pretty
+ good view on the status of the current sources). maketgz requires a
+ version number and creates the release archive. maketgz uses 'make dist'
+ for the actual archive building, why you need to fill in the Makefile.am
+ files properly for which files that should be included in the release
+ archives.
+
+ 3. When that's complete, sign the output files.
+
+ 4. Upload
+
+ 5. Update web site and changelog on site
+
+ 6. Send announcement to the mailing lists
+
+ NOTE: you must have curl checked out from git to be able to do a proper
+ release build. The release tarballs do not have everything setup in order to
+ do releases properly.
diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS
new file mode 100644
index 000000000..d36382740
--- /dev/null
+++ b/docs/KNOWN_BUGS
@@ -0,0 +1,242 @@
+These are problems known to exist at the time of this release. Feel free to
+join in and help us correct one or more of these! Also be sure to check the
+changelog of the current development status, as one or more of these problems
+may have been fixed since this was written!
+
+80. Curl doesn't recognize certificates in DER format in keychain, but it
+ works with PEM.
+ http://curl.haxx.se/bug/view.cgi?id=3439999
+
+79. SMTP. When sending data to multiple recipients, curl will abort and return
+ failure if one of the recipients indicate failure (on the "RCPT TO"
+ command). Ordinary mail programs would proceed and still send to the ones
+ that can receive data. This is subject for change in the future.
+ http://curl.haxx.se/bug/view.cgi?id=3438362
+
+78. curl and libcurl don't always signal the client properly when "sending"
+ zero bytes files - it makes for example the command line client not creating
+ any file at all. Like when using FTP.
+ http://curl.haxx.se/bug/view.cgi?id=3438362
+
+77. CURLOPT_FORBID_REUSE on a handle prevents NTLM from working since it
+ "abuses" the underlying connection re-use system and if connections are
+ forced to close they break the NTLM support.
+
+76. The SOCKET type in Win64 is 64 bits large (and thus so is curl_socket_t on
+ that platform), and long is only 32 bits. It makes it impossible for
+ curl_easy_getinfo() to return a socket properly with the CURLINFO_LASTSOCKET
+ option as for all other operating systems.
+
+75. NTLM authentication involving unicode user name or password only works
+ properly if built with UNICODE defined together with the schannel/winssl
+ backend. The original problem was mentioned in:
+ http://curl.haxx.se/mail/lib-2009-10/0024.html
+ http://curl.haxx.se/bug/view.cgi?id=2944325
+
+ The schannel version verified to work as mentioned in
+ http://curl.haxx.se/mail/lib-2012-07/0073.html
+
+73. if a connection is made to a FTP server but the server then just never
+ sends the 220 response or otherwise is dead slow, libcurl will not
+ acknowledge the connection timeout during that phase but only the "real"
+ timeout - which may surprise users as it is probably considered to be the
+ connect phase to most people. Brought up (and is being misunderstood) in:
+ http://curl.haxx.se/bug/view.cgi?id=2844077
+
+72. "Pausing pipeline problems."
+ http://curl.haxx.se/mail/lib-2009-07/0214.html
+
+70. Problem re-using easy handle after call to curl_multi_remove_handle
+ http://curl.haxx.se/mail/lib-2009-07/0249.html
+
+68. "More questions about ares behavior".
+ http://curl.haxx.se/mail/lib-2009-08/0012.html
+
+67. When creating multipart formposts. The file name part can be encoded with
+ something beyond ascii but currently libcurl will only pass in the verbatim
+ string the app provides. There are several browsers that already do this
+ encoding. The key seems to be the updated draft to RFC2231:
+ http://tools.ietf.org/html/draft-reschke-rfc2231-in-http-02
+
+66. When using telnet, the time limitation options don't work.
+ http://curl.haxx.se/bug/view.cgi?id=2818950
+
+65. When doing FTP over a socks proxy or CONNECT through HTTP proxy and the
+ multi interface is used, libcurl will fail if the (passive) TCP connection
+ for the data transfer isn't more or less instant as the code does not
+ properly wait for the connect to be confirmed. See test case 564 for a first
+ shot at a test case.
+
+63. When CURLOPT_CONNECT_ONLY is used, the handle cannot reliably be re-used
+ for any further requests or transfers. The work-around is then to close that
+ handle with curl_easy_cleanup() and create a new. Some more details:
+ http://curl.haxx.se/mail/lib-2009-04/0300.html
+
+61. If an upload using Expect: 100-continue receives an HTTP 417 response,
+ it ought to be automatically resent without the Expect:. A workaround is
+ for the client application to redo the transfer after disabling Expect:.
+ http://curl.haxx.se/mail/archive-2008-02/0043.html
+
+60. libcurl closes the connection if an HTTP 401 reply is received while it
+ is waiting for the the 100-continue response.
+ http://curl.haxx.se/mail/lib-2008-08/0462.html
+
+58. It seems sensible to be able to use CURLOPT_NOBODY and
+ CURLOPT_FAILONERROR with FTP to detect if a file exists or not, but it is
+ not working: http://curl.haxx.se/mail/lib-2008-07/0295.html
+
+57. On VMS-Alpha: When using an http-file-upload the file is not sent to the
+ Server with the correct content-length. Sending a file with 511 or less
+ bytes, content-length 512 is used. Sending a file with 513 - 1023 bytes,
+ content-length 1024 is used. Files with a length of a multiple of 512 Bytes
+ show the correct content-length. Only these files work for upload.
+ http://curl.haxx.se/bug/view.cgi?id=2057858
+
+56. When libcurl sends CURLOPT_POSTQUOTE commands when connected to a SFTP
+ server using the multi interface, the commands are not being sent correctly
+ and instead the connection is "cancelled" (the operation is considered done)
+ prematurely. There is a half-baked (busy-looping) patch provided in the bug
+ report but it cannot be accepted as-is. See
+ http://curl.haxx.se/bug/view.cgi?id=2006544
+
+55. libcurl fails to build with MIT Kerberos for Windows (KfW) due to KfW's
+ library header files exporting symbols/macros that should be kept private
+ to the KfW library. See ticket #5601 at http://krbdev.mit.edu/rt/
+
+52. Gautam Kachroo's issue that identifies a problem with the multi interface
+ where a connection can be re-used without actually being properly
+ SSL-negotiated:
+ http://curl.haxx.se/mail/lib-2008-01/0277.html
+
+49. If using --retry and the transfer timeouts (possibly due to using -m or
+ -y/-Y) the next attempt doesn't resume the transfer properly from what was
+ downloaded in the previous attempt but will truncate and restart at the
+ original position where it was at before the previous failed attempt. See
+ http://curl.haxx.se/mail/lib-2008-01/0080.html and Mandriva bug report
+ https://qa.mandriva.com/show_bug.cgi?id=22565
+
+48. If a CONNECT response-headers are larger than BUFSIZE (16KB) when the
+ connection is meant to be kept alive (like for NTLM proxy auth), the
+ function will return prematurely and will confuse the rest of the HTTP
+ protocol code. This should be very rare.
+
+43. There seems to be a problem when connecting to the Microsoft telnet server.
+ http://curl.haxx.se/bug/view.cgi?id=1720605
+
+41. When doing an operation over FTP that requires the ACCT command (but not
+ when logging in), the operation will fail since libcurl doesn't detect this
+ and thus fails to issue the correct command:
+ http://curl.haxx.se/bug/view.cgi?id=1693337
+
+39. Steffen Rumler's Race Condition in Curl_proxyCONNECT:
+ http://curl.haxx.se/mail/lib-2007-01/0045.html
+
+38. Kumar Swamy Bhatt's problem in ftp/ssl "LIST" operation:
+ http://curl.haxx.se/mail/lib-2007-01/0103.html
+
+35. Both SOCKS5 and SOCKS4 proxy connections are done blocking, which is very
+ bad when used with the multi interface.
+
+34. The SOCKS4 connection codes don't properly acknowledge (connect) timeouts.
+ Also see #12. According to bug #1556528, even the SOCKS5 connect code does
+ not do it right: http://curl.haxx.se/bug/view.cgi?id=1556528,
+
+31. "curl-config --libs" will include details set in LDFLAGS when configure is
+ run that might be needed only for building libcurl. Further, curl-config
+ --cflags suffers from the same effects with CFLAGS/CPPFLAGS.
+
+30. You need to use -g to the command line tool in order to use RFC2732-style
+ IPv6 numerical addresses in URLs.
+
+29. IPv6 URLs with zone ID is not nicely supported.
+ http://www.ietf.org/internet-drafts/draft-fenner-literal-zone-02.txt (expired)
+ specifies the use of a plus sign instead of a percent when specifying zone
+ IDs in URLs to get around the problem of percent signs being
+ special. According to the reporter, Firefox deals with the URL _with_ a
+ percent letter (which seems like a blatant URL spec violation).
+ libcurl supports zone IDs where the percent sign is URL-escaped (i.e. %25).
+
+ See http://curl.haxx.se/bug/view.cgi?id=1371118
+
+26. NTLM authentication using SSPI (on Windows) when (lib)curl is running in
+ "system context" will make it use wrong(?) user name - at least when compared
+ to what winhttp does. See http://curl.haxx.se/bug/view.cgi?id=1281867
+
+23. SOCKS-related problems:
+ B) libcurl doesn't support FTPS over a SOCKS proxy.
+ E) libcurl doesn't support active FTP over a SOCKS proxy
+
+ We probably have even more bugs and lack of features when a SOCKS proxy is
+ used.
+
+22. Sending files to a FTP server using curl on VMS, might lead to curl
+ complaining on "unaligned file size" on completion. The problem is related
+ to VMS file structures and the perceived file sizes stat() returns. A
+ possible fix would involve sending a "STRU VMS" command.
+ http://curl.haxx.se/bug/view.cgi?id=1156287
+
+21. FTP ASCII transfers do not follow RFC959. They don't convert the data
+ accordingly (not for sending nor for receiving). RFC 959 section 3.1.1.1
+ clearly describes how this should be done:
+
+ The sender converts the data from an internal character representation to
+ the standard 8-bit NVT-ASCII representation (see the Telnet
+ specification). The receiver will convert the data from the standard
+ form to his own internal form.
+
+ Since 7.15.4 at least line endings are converted.
+
+16. FTP URLs passed to curl may contain NUL (0x00) in the RFC 1738 <user>,
+ <password>, and <fpath> components, encoded as "%00". The problem is that
+ curl_unescape does not detect this, but instead returns a shortened C
+ string. From a strict FTP protocol standpoint, NUL is a valid character
+ within RFC 959 <string>, so the way to handle this correctly in curl would
+ be to use a data structure other than a plain C string, one that can handle
+ embedded NUL characters. From a practical standpoint, most FTP servers
+ would not meaningfully support NUL characters within RFC 959 <string>,
+ anyway (e.g., UNIX pathnames may not contain NUL).
+
+14. Test case 165 might fail on a system which has libidn present, but with an
+ old iconv version (2.1.3 is a known bad version), since it doesn't recognize
+ the charset when named ISO8859-1. Changing the name to ISO-8859-1 makes the
+ test pass, but instead makes it fail on Solaris hosts that use its native
+ iconv.
+
+13. curl version 7.12.2 fails on AIX if compiled with --enable-ares.
+ The workaround is to combine --enable-ares with --disable-shared
+
+12. When connecting to a SOCKS proxy, the (connect) timeout is not properly
+ acknowledged after the actual TCP connect (during the SOCKS "negotiate"
+ phase).
+
+10. To get HTTP Negotiate authentication to work fine, you need to provide a
+ (fake) user name (this concerns both curl and the lib) because the code
+ wrongly only considers authentication if there's a user name provided.
+ http://curl.haxx.se/bug/view.cgi?id=1004841. How?
+ http://curl.haxx.se/mail/lib-2004-08/0182.html
+
+8. Doing resumed upload over HTTP does not work with '-C -', because curl
+ doesn't do a HEAD first to get the initial size. This needs to be done
+ manually for HTTP PUT resume to work, and then '-C [index]'.
+
+6. libcurl ignores empty path parts in FTP URLs, whereas RFC1738 states that
+ such parts should be sent to the server as 'CWD ' (without an argument).
+ The only exception to this rule, is that we knowingly break this if the
+ empty part is first in the path, as then we use the double slashes to
+ indicate that the user wants to reach the root dir (this exception SHALL
+ remain even when this bug is fixed).
+
+5. libcurl doesn't treat the content-length of compressed data properly, as
+ it seems HTTP servers send the *uncompressed* length in that header and
+ libcurl thinks of it as the *compressed* length. Some explanations are here:
+ http://curl.haxx.se/mail/lib-2003-06/0146.html
+
+2. If a HTTP server responds to a HEAD request and includes a body (thus
+ violating the RFC2616), curl won't wait to read the response but just stop
+ reading and return back. If a second request (let's assume a GET) is then
+ immediately made to the same server again, the connection will be re-used
+ fine of course, and the second request will be sent off but when the
+ response is to get read, the previous response-body is what curl will read
+ and havoc is what happens.
+ More details on this is found in this libcurl mailing list thread:
+ http://curl.haxx.se/mail/lib-2002-08/0000.html
diff --git a/docs/LICENSE-MIXING b/docs/LICENSE-MIXING
new file mode 100644
index 000000000..f596546da
--- /dev/null
+++ b/docs/LICENSE-MIXING
@@ -0,0 +1,130 @@
+ License Mixing with apps, libcurl and Third Party Libraries
+ ===========================================================
+
+libcurl can be built to use a fair amount of various third party libraries,
+libraries that are written and provided by other parties that are distributed
+using their own licenses. Even libcurl itself contains code that may cause
+problems to some. This document attempts to describe what licenses libcurl and
+the other libraries use and what possible dilemmas linking and mixing them all
+can lead to for end users.
+
+I am not a lawyer and this is not legal advice!
+
+One common dilemma is that GPL[1]-licensed code is not allowed to be linked
+with code licensed under the Original BSD license (with the announcement
+clause). You may still build your own copies that use them all, but
+distributing them as binaries would be to violate the GPL license - unless you
+accompany your license with an exception[2]. This particular problem was
+addressed when the Modified BSD license was created, which does not have the
+announcement clause that collides with GPL.
+
+libcurl http://curl.haxx.se/docs/copyright.html
+
+ Uses an MIT (or Modified BSD)-style license that is as liberal as
+ possible. Some of the source files that deal with KRB4 have Original
+ BSD-style announce-clause licenses. You may not distribute binaries
+ with krb4-enabled libcurl that also link with GPL-licensed code!
+
+OpenSSL http://www.openssl.org/source/license.html
+
+ (May be used for SSL/TLS support) Uses an Original BSD-style license
+ with an announcement clause that makes it "incompatible" with GPL. You
+ are not allowed to ship binaries that link with OpenSSL that includes
+ GPL code (unless that specific GPL code includes an exception for
+ OpenSSL - a habit that is growing more and more common). If OpenSSL's
+ licensing is a problem for you, consider using GnuTLS or yassl
+ instead.
+
+GnuTLS http://www.gnutls.org/
+
+ (May be used for SSL/TLS support) Uses the LGPL[3] license. If this is
+ a problem for you, consider using OpenSSL instead. Also note that
+ GnuTLS itself depends on and uses other libs (libgcrypt and
+ libgpg-error) and they too are LGPL- or GPL-licensed.
+
+yassl http://www.yassl.com/
+
+ (May be used for SSL/TLS support) Uses the GPL[1] license. If this is
+ a problem for you, consider using OpenSSL or GnuTLS instead.
+
+NSS http://www.mozilla.org/projects/security/pki/nss/
+
+ (May be used for SSL/TLS support) Is covered by the MPL[4] license,
+ the GPL[1] license and the LGPL[3] license. You may choose to license
+ the code under MPL terms, GPL terms, or LGPL terms. These licenses
+ grant you different permissions and impose different obligations. You
+ should select the license that best meets your needs.
+
+axTLS http://axtls.sourceforge.net/
+
+ (May be used for SSL/TLS support) Uses a Modified BSD-style license.
+
+c-ares http://daniel.haxx.se/projects/c-ares/license.html
+
+ (Used for asynchronous name resolves) Uses an MIT license that is very
+ liberal and imposes no restrictions on any other library or part you
+ may link with.
+
+zlib http://www.gzip.org/zlib/zlib_license.html
+
+ (Used for compressed Transfer-Encoding support) Uses an MIT-style
+ license that shouldn't collide with any other library.
+
+krb4
+
+ While nothing in particular says that a Kerberos4 library must use any
+ particular license, the one I've tried and used successfully so far
+ (kth-krb4) is partly Original BSD-licensed with the announcement
+ clause. Some of the code in libcurl that is written to deal with
+ Kerberos4 is Modified BSD-licensed.
+
+MIT Kerberos http://web.mit.edu/kerberos/www/dist/
+
+ (May be used for GSS support) MIT licensed, that shouldn't collide
+ with any other parts.
+
+Heimdal http://www.pdc.kth.se/heimdal/
+
+ (May be used for GSS support) Heimdal is Original BSD licensed with
+ the announcement clause.
+
+GNU GSS http://www.gnu.org/software/gss/
+
+ (May be used for GSS support) GNU GSS is GPL licensed. Note that you
+ may not distribute binary curl packages that uses this if you build
+ curl to also link and use any Original BSD licensed libraries!
+
+fbopenssl
+
+ (Used for SPNEGO support) Unclear license. Based on its name, I assume
+ that it uses the OpenSSL license and thus shares the same issues as
+ described for OpenSSL above.
+
+libidn http://josefsson.org/libidn/
+
+ (Used for IDNA support) Uses the GNU Lesser General Public
+ License [3]. LGPL is a variation of GPL with slightly less aggressive
+ "copyleft". This license requires more requirements to be met when
+ distributing binaries, see the license for details. Also note that if
+ you distribute a binary that includes this library, you must also
+ include the full LGPL license text. Please properly point out what
+ parts of the distributed package that the license addresses.
+
+OpenLDAP http://www.openldap.org/software/release/license.html
+
+ (Used for LDAP support) Uses a Modified BSD-style license. Since
+ libcurl uses OpenLDAP as a shared library only, I have not heard of
+ anyone that ships OpenLDAP linked with libcurl in an app.
+
+libssh2 http://www.libssh2.org/
+
+ (Used for scp and sftp support) libssh2 uses a Modified BSD-style
+ license.
+
+[1] = GPL - GNU General Public License: http://www.gnu.org/licenses/gpl.html
+[2] = http://www.fsf.org/licenses/gpl-faq.html#GPLIncompatibleLibs details on
+ how to write such an exception to the GPL
+[3] = LGPL - GNU Lesser General Public License:
+ http://www.gnu.org/licenses/lgpl.html
+[4] = MPL - Mozilla Public License:
+ http://www.mozilla.org/MPL/
diff --git a/docs/MAIL-ETIQUETTE b/docs/MAIL-ETIQUETTE
new file mode 100644
index 000000000..ae1821a89
--- /dev/null
+++ b/docs/MAIL-ETIQUETTE
@@ -0,0 +1,228 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+MAIL ETIQUETTE
+
+ 1. About the lists
+ 1.1 Mailing Lists
+ 1.2 Netiquette
+ 1.3 Do Not Mail a Single Individual
+ 1.4 Subscription Required
+ 1.5 Moderation of new posters
+ 1.6 Handling trolls and spam
+ 1.7 How to unsubscribe
+
+ 2. Sending mail
+ 2.1 Reply or New Mail
+ 2.2 Reply to the List
+ 2.3 Use a Sensible Subject
+ 2.4 Do Not Top-Post
+ 2.5 HTML is not for mails
+ 2.6 Quoting
+ 2.7 Digest
+ 2.8 Please Tell Us How You Solved The Problem!
+
+==============================================================================
+
+1. About the lists
+
+ 1.1 Mailing Lists
+
+ The mailing lists we have are all listed and described at
+ http://curl.haxx.se/mail/
+
+ Each mailing list is targeted to a specific set of users and subjects,
+ please use the one or the ones that suit you the most.
+
+ Each mailing list have hundreds up to thousands of readers, meaning that
+ each mail sent will be received and read by a very large amount of people.
+ People from various cultures, regions, religions and continents.
+
+ 1.2 Netiquette
+
+ Netiquette is a common name for how to behave on the internet. Of course, in
+ each particular group and subculture there will be differences in what is
+ acceptable and what is considered good manners.
+
+ This document outlines what we in the cURL project considers to be good
+ etiquette, and primarily this focus on how to behave on and how to use our
+ mailing lists.
+
+ 1.3 Do Not Mail a Single Individual
+
+ Many people send one question to one person. One person gets many mails, and
+ there is only one person who can give you a reply. The question may be
+ something that other people are also wanting to ask. These other people have
+ no way to read the reply, but to ask the one person the question. The one
+ person consequently gets overloaded with mail.
+
+ If you really want to contact an individual and perhaps pay for his or her
+ services, by all means go ahead, but if it's just another curl question,
+ take it to a suitable list instead.
+
+ 1.4 Subscription Required
+
+ All curl mailing lists require that you are subscribed to allow a mail to go
+ through to all the subscribers.
+
+ If you post without being subscribed (or from a different mail address than
+ the one you are subscribed with), your mail will simply be silently
+ discarded. You have to subscribe first, then post.
+
+ The reason for this unfortunate and strict subscription policy is of course
+ to stop spam from pestering the lists.
+
+ 1.5 Moderation of new posters
+
+ Several of the curl mailing lists automatically make all posts from new
+ subscribers require moderation. This means that after you've subscribed and
+ send your first mail to a list, that mail will not be let through to the
+ list until a mailing list administrator has verified that it is OK and
+ permits it to get posted.
+
+ Once a first post has been made that proves the sender is actually talking
+ about curl-related subjects, the moderation "flag" will be switched off and
+ future posts will go through without being moderated.
+
+ The reason for this moderation policy is that we do suffer from spammers who
+ actually subscribe and send spam to our lists.
+
+ 1.6 Handling trolls and spam
+
+ Despite our good intentions and hard work to keep spam off the lists and to
+ maintain a friendly and positive atmosphere, there will be times when spam
+ and or trolls get through.
+
+ Troll - "someone who posts inflammatory, extraneous, or off-topic messages
+ in an online community"
+
+ Spam - "use of electronic messaging systems to send unsolicited bulk
+ messages"
+
+ No matter what, we NEVER EVER respond to trolls or spammers on the list. If
+ you believe the list admin should do something particular, contact him/her
+ off-list. The subject will be taken care of as good as possible to prevent
+ repeated offences, but responding on the list to such messages never lead to
+ anything good and only puts the light even more on the offender: which was
+ the entire purpose of it getting to the list in the first place.
+
+ Don't feed the trolls!
+
+ 1.7 How to unsubscribe
+
+ You unsubscribe the same way you subscribed in the first place. You go to
+ the page for the particular mailing list you're subscribed to and you enter
+ your email address and password and press the unsubscribe button.
+
+ Also, this information is included in the headers of every mail that is sent
+ out to all curl related mailing lists and there's footer in each mail that
+ links to the "admin" page on which you can unsubscribe and change other
+ options.
+
+ You NEVER EVER email the mailing list requesting someone else to get you off
+ the list.
+
+
+2. Sending mail
+
+ 2.1 Reply or New Mail
+
+ Please do not reply to an existing message as a short-cut to post a message
+ to the lists.
+
+ Many mail programs and web archivers use information within mails to keep
+ them together as "threads", as collections of posts that discuss a certain
+ subject. If you don't intend to reply on the same or similar subject, don't
+ just hit reply on an existing mail and change subject, create a new mail.
+
+ 2.2 Reply to the List
+
+ When replying to a message from the list, make sure that you do "group
+ reply" or "reply to all", and not just reply to the author of the single
+ mail you reply to.
+
+ We're actively discouraging replying back to the single person by setting
+ the Reply-To: field in outgoing mails back to the mailing list address,
+ making it harder for people to mail the author only by mistake.
+
+ 2.3 Use a Sensible Subject
+
+ Please use a subject of the mail that makes sense and that is related to the
+ contents of your mail. It makes it a lot easier to find your mail afterwards
+ and it makes it easier to track mail threads and topics.
+
+ 2.4 Do Not Top-Post
+
+ If you reply to a message, don't use top-posting. Top-posting is when you
+ write the new text at the top of a mail and you insert the previous quoted
+ mail conversation below. It forces users to read the mail in a backwards
+ order to properly understand it.
+
+ This is why top posting is so bad:
+
+ A: Because it messes up the order in which people normally read
+ text.
+ Q: Why is top-posting such a bad thing?
+ A: Top-posting.
+ Q: What is the most annoying thing in e-mail?
+
+ Apart from the screwed up read order (especially when mixed together in a
+ thread when someone responds using the mandated bottom-posting style), it
+ also makes it impossible to quote only parts of the original mail.
+
+ When you reply to a mail. You let the mail client insert the previous mail
+ quoted. Then you put the cursor on the first line of the mail and you move
+ down through the mail, deleting all parts of the quotes that don't add
+ context for your comments. When you want to add a comment you do so, inline,
+ right after the quotes that relate to your comment. Then you continue
+ downwards again.
+
+ When most of the quotes have been removed and you've added your own words,
+ you're done!
+
+ 2.5 HTML is not for mails
+
+ Please switch off those HTML encoded messages. You can mail all those funny
+ mails to your friends. We speak plain text mails.
+
+ 2.6 Quoting
+
+ Quote as little as possible. Just enough to provide the context you cannot
+ leave out. A lengthy description can be found here:
+
+ http://www.netmeister.org/news/learn2quote.html
+
+ 2.7 Digest
+
+ We allow subscribers to subscribe to the "digest" version of the mailing
+ lists. A digest is a collection of mails lumped together in one single mail.
+
+ Should you decide to reply to a mail sent out as a digest, there are two
+ things you MUST consider if you really really cannot subscribe normally
+ instead:
+
+ Cut off all mails and chatter that is not related to the mail you want to
+ reply to.
+
+ Change the subject name to something sensible and related to the subject,
+ preferably even the actual subject of the single mail you wanted to reply to
+
+ 2.8 Please Tell Us How You Solved The Problem!
+
+ Many people mail questions to the list, people spend some of their time and
+ make an effort in providing good answers to these questions.
+
+ If you are the one who asks, please consider responding once more in case
+ one of the hints was what solved your problems. The guys who write answers
+ feel good to know that they provided a good answer and that you fixed the
+ problem. Far too often, the person who asked the question is never heard of
+ again, and we never get to know if he/she is gone because the problem was
+ solved or perhaps because the problem was unsolvable!
+
+ Getting the solution posted also helps other users that experience the same
+ problem(s). They get to see (possibly in the web archives) that the
+ suggested fixes actually has helped at least one person.
+
diff --git a/docs/MANUAL b/docs/MANUAL
new file mode 100644
index 000000000..4ad2e135e
--- /dev/null
+++ b/docs/MANUAL
@@ -0,0 +1,1023 @@
+LATEST VERSION
+
+ You always find news about what's going on as well as the latest versions
+ from the curl web pages, located at:
+
+ http://curl.haxx.se
+
+SIMPLE USAGE
+
+ Get the main page from Netscape's web-server:
+
+ curl http://www.netscape.com/
+
+ Get the README file the user's home directory at funet's ftp-server:
+
+ curl ftp://ftp.funet.fi/README
+
+ Get a web page from a server using port 8000:
+
+ curl http://www.weirdserver.com:8000/
+
+ Get a directory listing of an FTP site:
+
+ curl ftp://cool.haxx.se/
+
+ Get the definition of curl from a dictionary:
+
+ curl dict://dict.org/m:curl
+
+ Fetch two documents at once:
+
+ curl ftp://cool.haxx.se/ http://www.weirdserver.com:8000/
+
+ Get a file off an FTPS server:
+
+ curl ftps://files.are.secure.com/secrets.txt
+
+ or use the more appropriate FTPS way to get the same file:
+
+ curl --ftp-ssl ftp://files.are.secure.com/secrets.txt
+
+ Get a file from an SSH server using SFTP:
+
+ curl -u username sftp://shell.example.com/etc/issue
+
+ Get a file from an SSH server using SCP using a private key to authenticate:
+
+ curl -u username: --key ~/.ssh/id_dsa --pubkey ~/.ssh/id_dsa.pub \
+ scp://shell.example.com/~/personal.txt
+
+ Get the main page from an IPv6 web server:
+
+ curl -g "http://[2001:1890:1112:1::20]/"
+
+DOWNLOAD TO A FILE
+
+ Get a web page and store in a local file with a specific name:
+
+ curl -o thatpage.html http://www.netscape.com/
+
+ Get a web page and store in a local file, make the local file get the name
+ of the remote document (if no file name part is specified in the URL, this
+ will fail):
+
+ curl -O http://www.netscape.com/index.html
+
+ Fetch two files and store them with their remote names:
+
+ curl -O www.haxx.se/index.html -O curl.haxx.se/download.html
+
+USING PASSWORDS
+
+ FTP
+
+ To ftp files using name+passwd, include them in the URL like:
+
+ curl ftp://name:passwd@machine.domain:port/full/path/to/file
+
+ or specify them with the -u flag like
+
+ curl -u name:passwd ftp://machine.domain:port/full/path/to/file
+
+ FTPS
+
+ It is just like for FTP, but you may also want to specify and use
+ SSL-specific options for certificates etc.
+
+ Note that using FTPS:// as prefix is the "implicit" way as described in the
+ standards while the recommended "explicit" way is done by using FTP:// and
+ the --ftp-ssl option.
+
+ SFTP / SCP
+
+ This is similar to FTP, but you can specify a private key to use instead of
+ a password. Note that the private key may itself be protected by a password
+ that is unrelated to the login password of the remote system. If you
+ provide a private key file you must also provide a public key file.
+
+ HTTP
+
+ Curl also supports user and password in HTTP URLs, thus you can pick a file
+ like:
+
+ curl http://name:passwd@machine.domain/full/path/to/file
+
+ or specify user and password separately like in
+
+ curl -u name:passwd http://machine.domain/full/path/to/file
+
+ HTTP offers many different methods of authentication and curl supports
+ several: Basic, Digest, NTLM and Negotiate. Without telling which method to
+ use, curl defaults to Basic. You can also ask curl to pick the most secure
+ ones out of the ones that the server accepts for the given URL, by using
+ --anyauth.
+
+ NOTE! According to the URL specification, HTTP URLs can not contain a user
+ and password, so that style will not work when using curl via a proxy, even
+ though curl allows it at other times. When using a proxy, you _must_ use
+ the -u style for user and password.
+
+ HTTPS
+
+ Probably most commonly used with private certificates, as explained below.
+
+PROXY
+
+ curl supports both HTTP and SOCKS proxy servers, with optional authentication.
+ It does not have special support for FTP proxy servers since there are no
+ standards for those, but it can still be made to work with many of them. You
+ can also use both HTTP and SOCKS proxies to transfer files to and from FTP
+ servers.
+
+ Get an ftp file using an HTTP proxy named my-proxy that uses port 888:
+
+ curl -x my-proxy:888 ftp://ftp.leachsite.com/README
+
+ Get a file from an HTTP server that requires user and password, using the
+ same proxy as above:
+
+ curl -u user:passwd -x my-proxy:888 http://www.get.this/
+
+ Some proxies require special authentication. Specify by using -U as above:
+
+ curl -U user:passwd -x my-proxy:888 http://www.get.this/
+
+ A comma-separated list of hosts and domains which do not use the proxy can
+ be specified as:
+
+ curl --noproxy localhost,get.this -x my-proxy:888 http://www.get.this/
+
+ If the proxy is specified with --proxy1.0 instead of --proxy or -x, then
+ curl will use HTTP/1.0 instead of HTTP/1.1 for any CONNECT attempts.
+
+ curl also supports SOCKS4 and SOCKS5 proxies with --socks4 and --socks5.
+
+ See also the environment variables Curl supports that offer further proxy
+ control.
+
+ Most FTP proxy servers are set up to appear as a normal FTP server from the
+ client's perspective, with special commands to select the remote FTP server.
+ curl supports the -u, -Q and --ftp-account options that can be used to
+ set up transfers through many FTP proxies. For example, a file can be
+ uploaded to a remote FTP server using a Blue Coat FTP proxy with the
+ options:
+
+ curl -u "Remote-FTP-Username@remote.ftp.server Proxy-Username:Remote-Pass" \
+ --ftp-account Proxy-Password --upload-file local-file \
+ ftp://my-ftp.proxy.server:21/remote/upload/path/
+
+ See the manual for your FTP proxy to determine the form it expects to set up
+ transfers, and curl's -v option to see exactly what curl is sending.
+
+RANGES
+
+ HTTP 1.1 introduced byte-ranges. Using this, a client can request
+ to get only one or more subparts of a specified document. Curl supports
+ this with the -r flag.
+
+ Get the first 100 bytes of a document:
+
+ curl -r 0-99 http://www.get.this/
+
+ Get the last 500 bytes of a document:
+
+ curl -r -500 http://www.get.this/
+
+ Curl also supports simple ranges for FTP files as well. Then you can only
+ specify start and stop position.
+
+ Get the first 100 bytes of a document using FTP:
+
+ curl -r 0-99 ftp://www.get.this/README
+
+UPLOADING
+
+ FTP / FTPS / SFTP / SCP
+
+ Upload all data on stdin to a specified server:
+
+ curl -T - ftp://ftp.upload.com/myfile
+
+ Upload data from a specified file, login with user and password:
+
+ curl -T uploadfile -u user:passwd ftp://ftp.upload.com/myfile
+
+ Upload a local file to the remote site, and use the local file name at the remote
+ site too:
+
+ curl -T uploadfile -u user:passwd ftp://ftp.upload.com/
+
+ Upload a local file to get appended to the remote file:
+
+ curl -T localfile -a ftp://ftp.upload.com/remotefile
+
+ Curl also supports ftp upload through a proxy, but only if the proxy is
+ configured to allow that kind of tunneling. If it does, you can run curl in
+ a fashion similar to:
+
+ curl --proxytunnel -x proxy:port -T localfile ftp.upload.com
+
+ HTTP
+
+ Upload all data on stdin to a specified HTTP site:
+
+ curl -T - http://www.upload.com/myfile
+
+ Note that the HTTP server must have been configured to accept PUT before
+ this can be done successfully.
+
+ For other ways to do HTTP data upload, see the POST section below.
+
+VERBOSE / DEBUG
+
+ If curl fails where it isn't supposed to, if the servers don't let you in,
+ if you can't understand the responses: use the -v flag to get verbose
+ fetching. Curl will output lots of info and what it sends and receives in
+ order to let the user see all client-server interaction (but it won't show
+ you the actual data).
+
+ curl -v ftp://ftp.upload.com/
+
+ To get even more details and information on what curl does, try using the
+ --trace or --trace-ascii options with a given file name to log to, like
+ this:
+
+ curl --trace trace.txt www.haxx.se
+
+
+DETAILED INFORMATION
+
+ Different protocols provide different ways of getting detailed information
+ about specific files/documents. To get curl to show detailed information
+ about a single file, you should use -I/--head option. It displays all
+ available info on a single file for HTTP and FTP. The HTTP information is a
+ lot more extensive.
+
+ For HTTP, you can get the header information (the same as -I would show)
+ shown before the data by using -i/--include. Curl understands the
+ -D/--dump-header option when getting files from both FTP and HTTP, and it
+ will then store the headers in the specified file.
+
+ Store the HTTP headers in a separate file (headers.txt in the example):
+
+ curl --dump-header headers.txt curl.haxx.se
+
+ Note that headers stored in a separate file can be very useful at a later
+ time if you want curl to use cookies sent by the server. More about that in
+ the cookies section.
+
+POST (HTTP)
+
+ It's easy to post data using curl. This is done using the -d <data>
+ option. The post data must be urlencoded.
+
+ Post a simple "name" and "phone" guestbook.
+
+ curl -d "name=Rafael%20Sagula&phone=3320780" \
+ http://www.where.com/guest.cgi
+
+ How to post a form with curl, lesson #1:
+
+ Dig out all the <input> tags in the form that you want to fill in. (There's
+ a perl program called formfind.pl on the curl site that helps with this).
+
+ If there's a "normal" post, you use -d to post. -d takes a full "post
+ string", which is in the format
+
+ <variable1>=<data1>&<variable2>=<data2>&...
+
+ The 'variable' names are the names set with "name=" in the <input> tags, and
+ the data is the contents you want to fill in for the inputs. The data *must*
+ be properly URL encoded. That means you replace space with + and that you
+ replace weird letters with %XX where XX is the hexadecimal representation of
+ the letter's ASCII code.
+
+ Example:
+
+ (page located at http://www.formpost.com/getthis/
+
+ <form action="post.cgi" method="post">
+ <input name=user size=10>
+ <input name=pass type=password size=10>
+ <input name=id type=hidden value="blablabla">
+ <input name=ding value="submit">
+ </form>
+
+ We want to enter user 'foobar' with password '12345'.
+
+ To post to this, you enter a curl command line like:
+
+ curl -d "user=foobar&pass=12345&id=blablabla&ding=submit" (continues)
+ http://www.formpost.com/getthis/post.cgi
+
+
+ While -d uses the application/x-www-form-urlencoded mime-type, generally
+ understood by CGI's and similar, curl also supports the more capable
+ multipart/form-data type. This latter type supports things like file upload.
+
+ -F accepts parameters like -F "name=contents". If you want the contents to
+ be read from a file, use <@filename> as contents. When specifying a file,
+ you can also specify the file content type by appending ';type=<mime type>'
+ to the file name. You can also post the contents of several files in one
+ field. For example, the field name 'coolfiles' is used to send three files,
+ with different content types using the following syntax:
+
+ curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html" \
+ http://www.post.com/postit.cgi
+
+ If the content-type is not specified, curl will try to guess from the file
+ extension (it only knows a few), or use the previously specified type (from
+ an earlier file if several files are specified in a list) or else it will
+ use the default type 'application/octet-stream'.
+
+ Emulate a fill-in form with -F. Let's say you fill in three fields in a
+ form. One field is a file name which to post, one field is your name and one
+ field is a file description. We want to post the file we have written named
+ "cooltext.txt". To let curl do the posting of this data instead of your
+ favourite browser, you have to read the HTML source of the form page and
+ find the names of the input fields. In our example, the input field names
+ are 'file', 'yourname' and 'filedescription'.
+
+ curl -F "file=@cooltext.txt" -F "yourname=Daniel" \
+ -F "filedescription=Cool text file with cool text inside" \
+ http://www.post.com/postit.cgi
+
+ To send two files in one post you can do it in two ways:
+
+ 1. Send multiple files in a single "field" with a single field name:
+
+ curl -F "pictures=@dog.gif,cat.gif"
+
+ 2. Send two fields with two field names:
+
+ curl -F "docpicture=@dog.gif" -F "catpicture=@cat.gif"
+
+ To send a field value literally without interpreting a leading '@'
+ or '<', or an embedded ';type=', use --form-string instead of
+ -F. This is recommended when the value is obtained from a user or
+ some other unpredictable source. Under these circumstances, using
+ -F instead of --form-string would allow a user to trick curl into
+ uploading a file.
+
+REFERRER
+
+ An HTTP request has the option to include information about which address
+ referred it to the actual page. Curl allows you to specify the
+ referrer to be used on the command line. It is especially useful to
+ fool or trick stupid servers or CGI scripts that rely on that information
+ being available or contain certain data.
+
+ curl -e www.coolsite.com http://www.showme.com/
+
+ NOTE: The Referer: [sic] field is defined in the HTTP spec to be a full URL.
+
+USER AGENT
+
+ An HTTP request has the option to include information about the browser
+ that generated the request. Curl allows it to be specified on the command
+ line. It is especially useful to fool or trick stupid servers or CGI
+ scripts that only accept certain browsers.
+
+ Example:
+
+ curl -A 'Mozilla/3.0 (Win95; I)' http://www.nationsbank.com/
+
+ Other common strings:
+ 'Mozilla/3.0 (Win95; I)' Netscape Version 3 for Windows 95
+ 'Mozilla/3.04 (Win95; U)' Netscape Version 3 for Windows 95
+ 'Mozilla/2.02 (OS/2; U)' Netscape Version 2 for OS/2
+ 'Mozilla/4.04 [en] (X11; U; AIX 4.2; Nav)' NS for AIX
+ 'Mozilla/4.05 [en] (X11; U; Linux 2.0.32 i586)' NS for Linux
+
+ Note that Internet Explorer tries hard to be compatible in every way:
+ 'Mozilla/4.0 (compatible; MSIE 4.01; Windows 95)' MSIE for W95
+
+ Mozilla is not the only possible User-Agent name:
+ 'Konqueror/1.0' KDE File Manager desktop client
+ 'Lynx/2.7.1 libwww-FM/2.14' Lynx command line browser
+
+COOKIES
+
+ Cookies are generally used by web servers to keep state information at the
+ client's side. The server sets cookies by sending a response line in the
+ headers that looks like 'Set-Cookie: <data>' where the data part then
+ typically contains a set of NAME=VALUE pairs (separated by semicolons ';'
+ like "NAME1=VALUE1; NAME2=VALUE2;"). The server can also specify for what
+ path the "cookie" should be used for (by specifying "path=value"), when the
+ cookie should expire ("expire=DATE"), for what domain to use it
+ ("domain=NAME") and if it should be used on secure connections only
+ ("secure").
+
+ If you've received a page from a server that contains a header like:
+ Set-Cookie: sessionid=boo123; path="/foo";
+
+ it means the server wants that first pair passed on when we get anything in
+ a path beginning with "/foo".
+
+ Example, get a page that wants my name passed in a cookie:
+
+ curl -b "name=Daniel" www.sillypage.com
+
+ Curl also has the ability to use previously received cookies in following
+ sessions. If you get cookies from a server and store them in a file in a
+ manner similar to:
+
+ curl --dump-header headers www.example.com
+
+ ... you can then in a second connect to that (or another) site, use the
+ cookies from the 'headers' file like:
+
+ curl -b headers www.example.com
+
+ While saving headers to a file is a working way to store cookies, it is
+ however error-prone and not the preferred way to do this. Instead, make curl
+ save the incoming cookies using the well-known netscape cookie format like
+ this:
+
+ curl -c cookies.txt www.example.com
+
+ Note that by specifying -b you enable the "cookie awareness" and with -L
+ you can make curl follow a location: (which often is used in combination
+ with cookies). So that if a site sends cookies and a location, you can
+ use a non-existing file to trigger the cookie awareness like:
+
+ curl -L -b empty.txt www.example.com
+
+ The file to read cookies from must be formatted using plain HTTP headers OR
+ as netscape's cookie file. Curl will determine what kind it is based on the
+ file contents. In the above command, curl will parse the header and store
+ the cookies received from www.example.com. curl will send to the server the
+ stored cookies which match the request as it follows the location. The
+ file "empty.txt" may be a nonexistent file.
+
+ Alas, to both read and write cookies from a netscape cookie file, you can
+ set both -b and -c to use the same file:
+
+ curl -b cookies.txt -c cookies.txt www.example.com
+
+PROGRESS METER
+
+ The progress meter exists to show a user that something actually is
+ happening. The different fields in the output have the following meaning:
+
+ % Total % Received % Xferd Average Speed Time Curr.
+ Dload Upload Total Current Left Speed
+ 0 151M 0 38608 0 0 9406 0 4:41:43 0:00:04 4:41:39 9287
+
+ From left-to-right:
+ % - percentage completed of the whole transfer
+ Total - total size of the whole expected transfer
+ % - percentage completed of the download
+ Received - currently downloaded amount of bytes
+ % - percentage completed of the upload
+ Xferd - currently uploaded amount of bytes
+ Average Speed
+ Dload - the average transfer speed of the download
+ Average Speed
+ Upload - the average transfer speed of the upload
+ Time Total - expected time to complete the operation
+ Time Current - time passed since the invoke
+ Time Left - expected time left to completion
+ Curr.Speed - the average transfer speed the last 5 seconds (the first
+ 5 seconds of a transfer is based on less time of course.)
+
+ The -# option will display a totally different progress bar that doesn't
+ need much explanation!
+
+SPEED LIMIT
+
+ Curl allows the user to set the transfer speed conditions that must be met
+ to let the transfer keep going. By using the switch -y and -Y you
+ can make curl abort transfers if the transfer speed is below the specified
+ lowest limit for a specified time.
+
+ To have curl abort the download if the speed is slower than 3000 bytes per
+ second for 1 minute, run:
+
+ curl -Y 3000 -y 60 www.far-away-site.com
+
+ This can very well be used in combination with the overall time limit, so
+ that the above operation must be completed in whole within 30 minutes:
+
+ curl -m 1800 -Y 3000 -y 60 www.far-away-site.com
+
+ Forcing curl not to transfer data faster than a given rate is also possible,
+ which might be useful if you're using a limited bandwidth connection and you
+ don't want your transfer to use all of it (sometimes referred to as
+ "bandwidth throttle").
+
+ Make curl transfer data no faster than 10 kilobytes per second:
+
+ curl --limit-rate 10K www.far-away-site.com
+
+ or
+
+ curl --limit-rate 10240 www.far-away-site.com
+
+ Or prevent curl from uploading data faster than 1 megabyte per second:
+
+ curl -T upload --limit-rate 1M ftp://uploadshereplease.com
+
+ When using the --limit-rate option, the transfer rate is regulated on a
+ per-second basis, which will cause the total transfer speed to become lower
+ than the given number. Sometimes of course substantially lower, if your
+ transfer stalls during periods.
+
+CONFIG FILE
+
+ Curl automatically tries to read the .curlrc file (or _curlrc file on win32
+ systems) from the user's home dir on startup.
+
+ The config file could be made up with normal command line switches, but you
+ can also specify the long options without the dashes to make it more
+ readable. You can separate the options and the parameter with spaces, or
+ with = or :. Comments can be used within the file. If the first letter on a
+ line is a '#'-symbol the rest of the line is treated as a comment.
+
+ If you want the parameter to contain spaces, you must enclose the entire
+ parameter within double quotes ("). Within those quotes, you specify a
+ quote as \".
+
+ NOTE: You must specify options and their arguments on the same line.
+
+ Example, set default time out and proxy in a config file:
+
+ # We want a 30 minute timeout:
+ -m 1800
+ # ... and we use a proxy for all accesses:
+ proxy = proxy.our.domain.com:8080
+
+ White spaces ARE significant at the end of lines, but all white spaces
+ leading up to the first characters of each line are ignored.
+
+ Prevent curl from reading the default file by using -q as the first command
+ line parameter, like:
+
+ curl -q www.thatsite.com
+
+ Force curl to get and display a local help page in case it is invoked
+ without URL by making a config file similar to:
+
+ # default url to get
+ url = "http://help.with.curl.com/curlhelp.html"
+
+ You can specify another config file to be read by using the -K/--config
+ flag. If you set config file name to "-" it'll read the config from stdin,
+ which can be handy if you want to hide options from being visible in process
+ tables etc:
+
+ echo "user = user:passwd" | curl -K - http://that.secret.site.com
+
+EXTRA HEADERS
+
+ When using curl in your own very special programs, you may end up needing
+ to pass on your own custom headers when getting a web page. You can do
+ this by using the -H flag.
+
+ Example, send the header "X-you-and-me: yes" to the server when getting a
+ page:
+
+ curl -H "X-you-and-me: yes" www.love.com
+
+ This can also be useful in case you want curl to send a different text in a
+ header than it normally does. The -H header you specify then replaces the
+ header curl would normally send. If you replace an internal header with an
+ empty one, you prevent that header from being sent. To prevent the Host:
+ header from being used:
+
+ curl -H "Host:" www.server.com
+
+FTP and PATH NAMES
+
+ Do note that when getting files with the ftp:// URL, the given path is
+ relative the directory you enter. To get the file 'README' from your home
+ directory at your ftp site, do:
+
+ curl ftp://user:passwd@my.site.com/README
+
+ But if you want the README file from the root directory of that very same
+ site, you need to specify the absolute file name:
+
+ curl ftp://user:passwd@my.site.com//README
+
+ (I.e with an extra slash in front of the file name.)
+
+SFTP and SCP and PATH NAMES
+
+ With sftp: and scp: URLs, the path name given is the absolute name on the
+ server. To access a file relative to the remote user's home directory,
+ prefix the file with /~/ , such as:
+
+ curl -u $USER sftp://home.example.com/~/.bashrc
+
+FTP and firewalls
+
+ The FTP protocol requires one of the involved parties to open a second
+ connection as soon as data is about to get transferred. There are two ways to
+ do this.
+
+ The default way for curl is to issue the PASV command which causes the
+ server to open another port and await another connection performed by the
+ client. This is good if the client is behind a firewall that doesn't allow
+ incoming connections.
+
+ curl ftp.download.com
+
+ If the server, for example, is behind a firewall that doesn't allow connections
+ on ports other than 21 (or if it just doesn't support the PASV command), the
+ other way to do it is to use the PORT command and instruct the server to
+ connect to the client on the given IP number and port (as parameters to the
+ PORT command).
+
+ The -P flag to curl supports a few different options. Your machine may have
+ several IP-addresses and/or network interfaces and curl allows you to select
+ which of them to use. Default address can also be used:
+
+ curl -P - ftp.download.com
+
+ Download with PORT but use the IP address of our 'le0' interface (this does
+ not work on windows):
+
+ curl -P le0 ftp.download.com
+
+ Download with PORT but use 192.168.0.10 as our IP address to use:
+
+ curl -P 192.168.0.10 ftp.download.com
+
+NETWORK INTERFACE
+
+ Get a web page from a server using a specified port for the interface:
+
+ curl --interface eth0:1 http://www.netscape.com/
+
+ or
+
+ curl --interface 192.168.1.10 http://www.netscape.com/
+
+HTTPS
+
+ Secure HTTP requires SSL libraries to be installed and used when curl is
+ built. If that is done, curl is capable of retrieving and posting documents
+ using the HTTPS protocol.
+
+ Example:
+
+ curl https://www.secure-site.com
+
+ Curl is also capable of using your personal certificates to get/post files
+ from sites that require valid certificates. The only drawback is that the
+ certificate needs to be in PEM-format. PEM is a standard and open format to
+ store certificates with, but it is not used by the most commonly used
+ browsers (Netscape and MSIE both use the so called PKCS#12 format). If you
+ want curl to use the certificates you use with your (favourite) browser, you
+ may need to download/compile a converter that can convert your browser's
+ formatted certificates to PEM formatted ones. This kind of converter is
+ included in recent versions of OpenSSL, and for older versions Dr Stephen
+ N. Henson has written a patch for SSLeay that adds this functionality. You
+ can get his patch (that requires an SSLeay installation) from his site at:
+ http://www.drh-consultancy.demon.co.uk/
+
+ Example on how to automatically retrieve a document using a certificate with
+ a personal password:
+
+ curl -E /path/to/cert.pem:password https://secure.site.com/
+
+ If you neglect to specify the password on the command line, you will be
+ prompted for the correct password before any data can be received.
+
+ Many older SSL-servers have problems with SSLv3 or TLS, which newer versions
+ of OpenSSL etc use, therefore it is sometimes useful to specify what
+ SSL-version curl should use. Use -3, -2 or -1 to specify that exact SSL
+ version to use (for SSLv3, SSLv2 or TLSv1 respectively):
+
+ curl -2 https://secure.site.com/
+
+ Otherwise, curl will first attempt to use v3 and then v2.
+
+ To use OpenSSL to convert your favourite browser's certificate into a PEM
+ formatted one that curl can use, do something like this:
+
+ In Netscape, you start with hitting the 'Security' menu button.
+
+ Select 'certificates->yours' and then pick a certificate in the list
+
+ Press the 'Export' button
+
+ enter your PIN code for the certs
+
+ select a proper place to save it
+
+ Run the 'openssl' application to convert the certificate. If you cd to the
+ openssl installation, you can do it like:
+
+ # ./apps/openssl pkcs12 -in [file you saved] -clcerts -out [PEMfile]
+
+ In Firefox, select Options, then Advanced, then the Encryption tab,
+ View Certificates. This opens the Certificate Manager, where you can
+ Export. Be sure to select PEM for the Save as type.
+
+ In Internet Explorer, select Internet Options, then the Content tab, then
+ Certificates. Then you can Export, and depending on the format you may
+ need to convert to PEM.
+
+ In Chrome, select Settings, then Show Advanced Settings. Under HTTPS/SSL
+ select Manage Certificates.
+
+RESUMING FILE TRANSFERS
+
+ To continue a file transfer where it was previously aborted, curl supports
+ resume on HTTP(S) downloads as well as FTP uploads and downloads.
+
+ Continue downloading a document:
+
+ curl -C - -o file ftp://ftp.server.com/path/file
+
+ Continue uploading a document(*1):
+
+ curl -C - -T file ftp://ftp.server.com/path/file
+
+ Continue downloading a document from a web server(*2):
+
+ curl -C - -o file http://www.server.com/
+
+ (*1) = This requires that the FTP server supports the non-standard command
+ SIZE. If it doesn't, curl will say so.
+
+ (*2) = This requires that the web server supports at least HTTP/1.1. If it
+ doesn't, curl will say so.
+
+TIME CONDITIONS
+
+ HTTP allows a client to specify a time condition for the document it
+ requests. It is If-Modified-Since or If-Unmodified-Since. Curl allows you to
+ specify them with the -z/--time-cond flag.
+
+ For example, you can easily make a download that only gets performed if the
+ remote file is newer than a local copy. It would be made like:
+
+ curl -z local.html http://remote.server.com/remote.html
+
+ Or you can download a file only if the local file is newer than the remote
+ one. Do this by prepending the date string with a '-', as in:
+
+ curl -z -local.html http://remote.server.com/remote.html
+
+ You can specify a "free text" date as condition. Tell curl to only download
+ the file if it was updated since January 12, 2012:
+
+ curl -z "Jan 12 2012" http://remote.server.com/remote.html
+
+ Curl will then accept a wide range of date formats. You always make the date
+ check the other way around by prepending it with a dash '-'.
+
+DICT
+
+ For fun try
+
+ curl dict://dict.org/m:curl
+ curl dict://dict.org/d:heisenbug:jargon
+ curl dict://dict.org/d:daniel:web1913
+
+ Aliases for 'm' are 'match' and 'find', and aliases for 'd' are 'define'
+ and 'lookup'. For example,
+
+ curl dict://dict.org/find:curl
+
+ Commands that break the URL description of the RFC (but not the DICT
+ protocol) are
+
+ curl dict://dict.org/show:db
+ curl dict://dict.org/show:strat
+
+ Authentication is still missing (but this is not required by the RFC)
+
+LDAP
+
+ If you have installed the OpenLDAP library, curl can take advantage of it
+ and offer ldap:// support.
+
+ LDAP is a complex thing and writing an LDAP query is not an easy task. I do
+ advise you to dig up the syntax description for that elsewhere. Two places
+ that might suit you are:
+
+ Netscape's "Netscape Directory SDK 3.0 for C Programmer's Guide Chapter 10:
+ Working with LDAP URLs":
+ http://developer.netscape.com/docs/manuals/dirsdk/csdk30/url.htm
+
+ RFC 2255, "The LDAP URL Format" http://curl.haxx.se/rfc/rfc2255.txt
+
+ To show you an example, this is how I can get all people from my local LDAP
+ server that has a certain sub-domain in their email address:
+
+ curl -B "ldap://ldap.frontec.se/o=frontec??sub?mail=*sth.frontec.se"
+
+ If I want the same info in HTML format, I can get it by not using the -B
+ (enforce ASCII) flag.
+
+ENVIRONMENT VARIABLES
+
+ Curl reads and understands the following environment variables:
+
+ http_proxy, HTTPS_PROXY, FTP_PROXY
+
+ They should be set for protocol-specific proxies. General proxy should be
+ set with
+
+ ALL_PROXY
+
+ A comma-separated list of host names that shouldn't go through any proxy is
+ set in (only an asterisk, '*' matches all hosts)
+
+ NO_PROXY
+
+ If the host name matches one of these strings, or the host is within the
+ domain of one of these strings, transactions with that node will not be
+ proxied.
+
+
+ The usage of the -x/--proxy flag overrides the environment variables.
+
+NETRC
+
+ Unix introduced the .netrc concept a long time ago. It is a way for a user
+ to specify name and password for commonly visited FTP sites in a file so
+ that you don't have to type them in each time you visit those sites. You
+ realize this is a big security risk if someone else gets hold of your
+ passwords, so therefore most unix programs won't read this file unless it is
+ only readable by yourself (curl doesn't care though).
+
+ Curl supports .netrc files if told to (using the -n/--netrc and
+ --netrc-optional options). This is not restricted to just FTP,
+ so curl can use it for all protocols where authentication is used.
+
+ A very simple .netrc file could look something like:
+
+ machine curl.haxx.se login iamdaniel password mysecret
+
+CUSTOM OUTPUT
+
+ To better allow script programmers to get to know about the progress of
+ curl, the -w/--write-out option was introduced. Using this, you can specify
+ what information from the previous transfer you want to extract.
+
+ To display the amount of bytes downloaded together with some text and an
+ ending newline:
+
+ curl -w 'We downloaded %{size_download} bytes\n' www.download.com
+
+KERBEROS FTP TRANSFER
+
+ Curl supports kerberos4 and kerberos5/GSSAPI for FTP transfers. You need
+ the kerberos package installed and used at curl build time for it to be
+ available.
+
+ First, get the krb-ticket the normal way, like with the kinit/kauth tool.
+ Then use curl in way similar to:
+
+ curl --krb private ftp://krb4site.com -u username:fakepwd
+
+ There's no use for a password on the -u switch, but a blank one will make
+ curl ask for one and you already entered the real password to kinit/kauth.
+
+TELNET
+
+ The curl telnet support is basic and very easy to use. Curl passes all data
+ passed to it on stdin to the remote server. Connect to a remote telnet
+ server using a command line similar to:
+
+ curl telnet://remote.server.com
+
+ And enter the data to pass to the server on stdin. The result will be sent
+ to stdout or to the file you specify with -o.
+
+ You might want the -N/--no-buffer option to switch off the buffered output
+ for slow connections or similar.
+
+ Pass options to the telnet protocol negotiation, by using the -t option. To
+ tell the server we use a vt100 terminal, try something like:
+
+ curl -tTTYPE=vt100 telnet://remote.server.com
+
+ Other interesting options for it -t include:
+
+ - XDISPLOC=<X display> Sets the X display location.
+
+ - NEW_ENV=<var,val> Sets an environment variable.
+
+ NOTE: The telnet protocol does not specify any way to login with a specified
+ user and password so curl can't do that automatically. To do that, you need
+ to track when the login prompt is received and send the username and
+ password accordingly.
+
+PERSISTENT CONNECTIONS
+
+ Specifying multiple files on a single command line will make curl transfer
+ all of them, one after the other in the specified order.
+
+ libcurl will attempt to use persistent connections for the transfers so that
+ the second transfer to the same host can use the same connection that was
+ already initiated and was left open in the previous transfer. This greatly
+ decreases connection time for all but the first transfer and it makes a far
+ better use of the network.
+
+ Note that curl cannot use persistent connections for transfers that are used
+ in subsequence curl invokes. Try to stuff as many URLs as possible on the
+ same command line if they are using the same host, as that'll make the
+ transfers faster. If you use an HTTP proxy for file transfers, practically
+ all transfers will be persistent.
+
+MULTIPLE TRANSFERS WITH A SINGLE COMMAND LINE
+
+ As is mentioned above, you can download multiple files with one command line
+ by simply adding more URLs. If you want those to get saved to a local file
+ instead of just printed to stdout, you need to add one save option for each
+ URL you specify. Note that this also goes for the -O option (but not
+ --remote-name-all).
+
+ For example: get two files and use -O for the first and a custom file
+ name for the second:
+
+ curl -O http://url.com/file.txt ftp://ftp.com/moo.exe -o moo.jpg
+
+ You can also upload multiple files in a similar fashion:
+
+ curl -T local1 ftp://ftp.com/moo.exe -T local2 ftp://ftp.com/moo2.txt
+
+IPv6
+
+ curl will connect to a server with IPv6 when a host lookup returns an IPv6
+ address and fall back to IPv4 if the connection fails. The --ipv4 and --ipv6
+ options can specify which address to use when both are available. IPv6
+ addresses can also be specified directly in URLs using the syntax:
+
+ http://[2001:1890:1112:1::20]/overview.html
+
+ When this style is used, the -g option must be given to stop curl from
+ interpreting the square brackets as special globbing characters. Link local
+ and site local addresses including a scope identifier, such as fe80::1234%1,
+ may also be used, but the scope portion must be numeric and the percent
+ character must be URL escaped. The previous example in an SFTP URL might
+ look like:
+
+ sftp://[fe80::1234%251]/
+
+ IPv6 addresses provided other than in URLs (e.g. to the --proxy, --interface
+ or --ftp-port options) should not be URL encoded.
+
+METALINK
+
+ Curl supports Metalink (both version 3 and 4 (RFC 5854) are supported), a way
+ to list multiple URIs and hashes for a file. Curl will make use of the mirrors
+ listed within for failover if there are errors (such as the file or server not
+ being available). It will also verify the hash of the file after the download
+ completes. The Metalink file itself is downloaded and processed in memory and
+ not stored in the local file system.
+
+ Example to use a remote Metalink file:
+
+ curl --metalink http://www.example.com/example.metalink
+
+ To use a Metalink file in the local file system, use FILE protocol (file://):
+
+ curl --metalink file://example.metalink
+
+ Please note that if FILE protocol is disabled, there is no way to use a local
+ Metalink file at the time of this writing. Also note that if --metalink and
+ --include are used together, --include will be ignored. This is because including
+ headers in the response will break Metalink parser and if the headers are included
+ in the file described in Metalink file, hash check will fail.
+
+MAILING LISTS
+
+ For your convenience, we have several open mailing lists to discuss curl,
+ its development and things relevant to this. Get all info at
+ http://curl.haxx.se/mail/. Some of the lists available are:
+
+ curl-users
+
+ Users of the command line tool. How to use it, what doesn't work, new
+ features, related tools, questions, news, installations, compilations,
+ running, porting etc.
+
+ curl-library
+
+ Developers using or developing libcurl. Bugs, extensions, improvements.
+
+ curl-announce
+
+ Low-traffic. Only receives announcements of new public versions. At worst,
+ that makes something like one or two mails per month, but usually only one
+ mail every second month.
+
+ curl-and-php
+
+ Using the curl functions in PHP. Everything curl with a PHP angle. Or PHP
+ with a curl angle.
+
+ curl-and-python
+
+ Python hackers using curl with or without the python binding pycurl.
+
+ Please direct curl questions, feature requests and trouble reports to one of
+ these mailing lists instead of mailing any individual.
diff --git a/docs/Makefile.am b/docs/Makefile.am
new file mode 100644
index 000000000..0701ba823
--- /dev/null
+++ b/docs/Makefile.am
@@ -0,0 +1,60 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+man_MANS = curl.1 curl-config.1 mk-ca-bundle.1
+GENHTMLPAGES = curl.html curl-config.html mk-ca-bundle.html
+PDFPAGES = curl.pdf curl-config.pdf mk-ca-bundle.pdf
+
+HTMLPAGES = $(GENHTMLPAGES) index.html
+
+SUBDIRS = examples libcurl
+
+CLEANFILES = $(GENHTMLPAGES) $(PDFPAGES)
+
+EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \
+ README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS \
+ KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \
+ $(PDFPAGES) LICENSE-MIXING README.netware DISTRO-DILEMMA INSTALL.devcpp \
+ MAIL-ETIQUETTE HTTP-COOKIES
+
+MAN2HTML= roffit < $< >$@
+
+SUFFIXES = .1 .html .pdf
+
+html: $(HTMLPAGES)
+ cd libcurl; make html
+
+pdf: $(PDFPAGES)
+ cd libcurl; make pdf
+
+.1.html:
+ $(MAN2HTML)
+
+.1.pdf:
+ @(foo=`echo $@ | sed -e 's/\.[0-9]$$//g'`; \
+ groff -Tps -man $< >$$foo.ps; \
+ ps2pdf $$foo.ps $@; \
+ rm $$foo.ps; \
+ echo "converted $< to $@")
+
diff --git a/docs/README.cmake b/docs/README.cmake
new file mode 100644
index 000000000..084c1de6d
--- /dev/null
+++ b/docs/README.cmake
@@ -0,0 +1,16 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+README.cmake
+ Read the README file first.
+
+ Curl contains CMake build files that provide a way to build Curl with the
+ CMake build tool (www.cmake.org). CMake is a cross platform meta build tool
+ that generates native makefiles and IDE project files. The CMake build
+ system can be used to build Curl on any of its supported platforms.
+
+ Read the INSTALL.cmake file for instructions on how to compile curl with
+ CMake.
diff --git a/docs/README.netware b/docs/README.netware
new file mode 100644
index 000000000..41da2e8dc
--- /dev/null
+++ b/docs/README.netware
@@ -0,0 +1,27 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+README.netware
+
+ Read the README file first.
+
+ Curl has been successfully compiled with gcc / nlmconv on different flavours
+ of Linux as well as with the official Metrowerks CodeWarrior compiler.
+ While not being the main development target, a continously growing share of
+ curl users are NetWare-based, specially also consuming the lib from PHP.
+
+ The unix-style man pages are tricky to read on windows, so therefore are all
+ those pages converted to HTML as well as pdf, and included in the release
+ archives.
+
+ The main curl.1 man page is also "built-in" in the command line tool. Use a
+ command line similar to this in order to extract a separate text file:
+
+ curl -M >manual.txt
+
+ Read the INSTALL file for instructions how to compile curl self.
+
+
diff --git a/docs/README.win32 b/docs/README.win32
new file mode 100644
index 000000000..cfd45dd25
--- /dev/null
+++ b/docs/README.win32
@@ -0,0 +1,26 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+README.win32
+
+ Read the README file first.
+
+ Curl has been compiled, built and run on all sorts of Windows and win32
+ systems. While not being the main develop target, a fair share of curl users
+ are win32-based.
+
+ The unix-style man pages are tricky to read on windows, so therefore are all
+ those pages converted to HTML as well as pdf, and included in the release
+ archives.
+
+ The main curl.1 man page is also "built-in" in the command line tool. Use a
+ command line similar to this in order to extract a separate text file:
+
+ curl -M >manual.txt
+
+ Read the INSTALL file for instructions how to compile curl self.
+
+
diff --git a/docs/RESOURCES b/docs/RESOURCES
new file mode 100644
index 000000000..760e75975
--- /dev/null
+++ b/docs/RESOURCES
@@ -0,0 +1,83 @@
+ _ _ ____ _
+ Project ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+
+This document lists documents and standards used by curl.
+
+ RFC 959 - The FTP protocol
+
+ RFC 1635 - How to Use Anonymous FTP
+
+ RFC 1738 - Uniform Resource Locators
+
+ RFC 1777 - defines the LDAP protocol
+
+ RFC 1808 - Relative Uniform Resource Locators
+
+ RFC 1867 - Form-based File Upload in HTML
+
+ RFC 1950 - ZLIB Compressed Data Format Specification
+
+ RFC 1951 - DEFLATE Compressed Data Format Specification
+
+ RFC 1952 - gzip compression format
+
+ RFC 1959 - LDAP URL syntax
+
+ RFC 2045-2049 - Everything you need to know about MIME! (needed for form
+ based upload)
+
+ RFC 2068 - HTTP 1.1 (obsoleted by RFC 2616)
+
+ RFC 2104 - Keyed-Hashing for Message Authentication
+
+ RFC 2109 - HTTP State Management Mechanism (cookie stuff)
+ - Also, read Netscape's specification at
+ http://curl.haxx.se/rfc/cookie_spec.html
+
+ RFC 2183 - The Content-Disposition Header Field
+
+ RFC 2195 - CRAM-MD5 authentication
+
+ RFC 2229 - A Dictionary Server Protocol
+
+ RFC 2255 - Newer LDAP URL syntax document.
+
+ RFC 2231 - MIME Parameter Value and Encoded Word Extensions:
+ Character Sets, Languages, and Continuations
+
+ RFC 2388 - "Returning Values from Forms: multipart/form-data"
+ Use this as an addition to the RFC1867
+
+ RFC 2396 - "Uniform Resource Identifiers: Generic Syntax and Semantics" This
+ one obsoletes RFC 1738, but since RFC 1738 is often mentioned
+ I've left it in this list.
+
+ RFC 2428 - FTP Extensions for IPv6 and NATs
+
+ RFC 2577 - FTP Security Considerations
+
+ RFC 2616 - HTTP 1.1, the latest
+
+ RFC 2617 - HTTP Authentication
+
+ RFC 2718 - Guidelines for new URL Schemes
+
+ RFC 2732 - Format for Literal IPv6 Addresses in URL's
+
+ RFC 2818 - HTTP Over TLS (TLS is the successor to SSL)
+
+ RFC 2821 - SMTP protocol
+
+ RFC 2964 - Use of HTTP State Management
+
+ RFC 2965 - HTTP State Management Mechanism. Cookies. Obsoletes RFC2109
+
+ RFC 3207 - SMTP over TLS
+
+ RFC 4616 - PLAIN authentication
+
+ RFC 4954 - SMTP Authentication
diff --git a/docs/SSLCERTS b/docs/SSLCERTS
new file mode 100644
index 000000000..0d1414cea
--- /dev/null
+++ b/docs/SSLCERTS
@@ -0,0 +1,116 @@
+ Peer SSL Certificate Verification
+ =================================
+
+libcurl performs peer SSL certificate verification by default. This is done
+by using CA cert bundle that the SSL library can use to make sure the peer's
+server certificate is valid.
+
+If you communicate with HTTPS or FTPS servers using certificates that are
+signed by CAs present in the bundle, you can be sure that the remote server
+really is the one it claims to be.
+
+Until 7.18.0, curl bundled a severely outdated ca bundle file that was
+installed by default. These days, the curl archives include no ca certs at
+all. You need to get them elsewhere. See below for example.
+
+If the remote server uses a self-signed certificate, if you don't install a CA
+cert bundle, if the server uses a certificate signed by a CA that isn't
+included in the bundle you use or if the remote host is an impostor
+impersonating your favorite site, and you want to transfer files from this
+server, do one of the following:
+
+ 1. Tell libcurl to *not* verify the peer. With libcurl you disable this with
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+
+ With the curl command line tool, you disable this with -k/--insecure.
+
+ 2. Get a CA certificate that can verify the remote server and use the proper
+ option to point out this CA cert for verification when connecting. For
+ libcurl hackers: curl_easy_setopt(curl, CURLOPT_CAPATH, capath);
+
+ With the curl command line tool: --cacert [file]
+
+ 3. Add the CA cert for your server to the existing default CA cert bundle.
+ The default path of the CA bundle used can be changed by running configure
+ with the --with-ca-bundle option pointing out the path of your choice.
+
+ To do this, you need to get the CA cert for your server in PEM format and
+ then append that to your CA cert bundle.
+
+ If you use Internet Explorer, this is one way to get extract the CA cert
+ for a particular server:
+
+ o View the certificate by double-clicking the padlock
+ o Find out where the CA certificate is kept (Certificate>
+ Authority Information Access>URL)
+ o Get a copy of the crt file using curl
+ o Convert it from crt to PEM using the openssl tool:
+ openssl x509 -inform DES -in yourdownloaded.crt \
+ -out outcert.pem -text
+ o Append the 'outcert.pem' to the CA cert bundle or use it stand-alone
+ as described below.
+
+ If you use the 'openssl' tool, this is one way to get extract the CA cert
+ for a particular server:
+
+ o openssl s_client -connect xxxxx.com:443 |tee logfile
+ o type "QUIT", followed by the "ENTER" key
+ o The certificate will have "BEGIN CERTIFICATE" and "END CERTIFICATE"
+ markers.
+ o If you want to see the data in the certificate, you can do: "openssl
+ x509 -inform PEM -in certfile -text -out certdata" where certfile is
+ the cert you extracted from logfile. Look in certdata.
+ o If you want to trust the certificate, you can append it to your
+ cert_bundle or use it stand-alone as described. Just remember that the
+ security is no better than the way you obtained the certificate.
+
+ 4. If you're using the curl command line tool, you can specify your own CA
+ cert path by setting the environment variable CURL_CA_BUNDLE to the path
+ of your choice.
+
+ If you're using the curl command line tool on Windows, curl will search
+ for a CA cert file named "curl-ca-bundle.crt" in these directories and in
+ this order:
+ 1. application's directory
+ 2. current working directory
+ 3. Windows System directory (e.g. C:\windows\system32)
+ 4. Windows Directory (e.g. C:\windows)
+ 5. all directories along %PATH%
+
+ 5. Get a better/different/newer CA cert bundle! One option is to extract the
+ one a recent Firefox browser uses by running 'make ca-bundle' in the curl
+ build tree root, or possibly download a version that was generated this
+ way for you:
+
+ http://curl.haxx.se/docs/caextract.html
+
+Neglecting to use one of the above methods when dealing with a server using a
+certificate that isn't signed by one of the certificates in the installed CA
+cert bundle, will cause SSL to report an error ("certificate verify failed")
+during the handshake and SSL will then refuse further communication with that
+server.
+
+ Peer SSL Certificate Verification with NSS
+ ==========================================
+
+If libcurl is build with NSS support then depending on the OS distribution it
+is probably required to take some additional steps to use the system-wide CA
+cert db. RedHat ships with an additional module libnsspem.so which enables NSS
+to read the OpenSSL PEM CA bundle. With OpenSuSE this lib is missing, and NSS
+can only work with its own internal formats. Also NSS got a new database
+format:
+https://wiki.mozilla.org/NSS_Shared_DB
+Starting with version 7.19.7 libcurl will check for the NSS version it runs,
+and add automatically the 'sql:' prefix to the certdb directory (either the
+hardcoded default /etc/pki/nssdb or the directory configured with SSL_DIR
+environment variable) if a version 3.12.0 or later is detected.
+To check which certdb format your distribution provides examine the default
+certdb location /etc/pki/nssdb; the new certdb format can be identified by
+the filenames cert9.db, key4.db, pkcs11.txt; filenames of older versions are
+cert8.db, key3.db, modsec.db.
+Usually these cert databases are empty; but NSS also has built-in CAs which are
+provided through a shared library libnssckbi.so; if you want to use these
+built-in CAs then create a symlink to libnssckbi.so in /etc/pki/nssdb:
+ln -s /usr/lib[64]/libnssckbi.so /etc/pki/nssdb/libnssckbi.so
+
+
diff --git a/docs/THANKS b/docs/THANKS
new file mode 100644
index 000000000..46965163b
--- /dev/null
+++ b/docs/THANKS
@@ -0,0 +1,999 @@
+ This project has been alive for many years. Countless people have provided
+ feedback that have improved curl. Here follows a list of people that have
+ contributed (a-z order).
+
+ If you have contributed but are missing here, please let us know!
+
+Aaron Oneal
+Aaron Orenstein
+Adam D. Moss
+Adam Light
+Adam Piggott
+Adam Tkac
+Adrian Schuur
+Adriano Meirelles
+Ajit Dhumale
+Akos Pasztory
+Alan Pinstein
+Albert Chin
+Albert Chin-A-Young
+Albert Choy
+Ale Vesely
+Alejandro Alvarez
+Aleksandar Milivojevic
+Alessandro Ghedini
+Alessandro Vesely
+Alex Bligh
+Alex Fishman
+Alex Gruz
+Alex Neblett
+Alex Suykov
+Alex Vinnik
+Alex aka WindEagle
+Alexander Beedie
+Alexander Kourakos
+Alexander Krasnostavsky
+Alexander Lazic
+Alexander Zhuravlev
+Alexey Borzov
+Alexey Pesternikov
+Alexey Simak
+Alexey Zakhlestin
+Alexis Carvalho
+Alfred Gebert
+Allen Pulsifer
+Amol Pattekar
+Amr Shahin
+Anatoli Tubman
+Anders Gustafsson
+Andi Jahja
+Andre Guibert de Bruet
+Andreas Damm
+Andreas Faerber
+Andreas Farber
+Andreas Ntaflos
+Andreas Olsson
+Andreas Rieke
+Andreas Schuldei
+Andreas Wurf
+Andrei Benea
+Andrei Cipu
+Andres Garcia
+Andrew Benham
+Andrew Biggs
+Andrew Bushnell
+Andrew Francis
+Andrew Fuller
+Andrew Moise
+Andrew Wansink
+Andrew de los Reyes
+Andrés García
+Andy Cedilnik
+Andy Serpa
+Andy Tsouladze
+Angus Mackay
+Anthony Bryan
+Anthony G. Basile
+Antoine Calando
+Anton Bychkov
+Anton Kalmykov
+Anton Malov
+Anton Yabchinskiy
+Arkadiusz Miskiewicz
+Armel Asselin
+Arnaud Compan
+Arnaud Ebalard
+Arthur Murray
+Arve Knudsen
+Ates Goral
+Augustus Saunders
+Avery Fay
+Axel Tillequin
+Balint Szilakszi
+Bart Whiteley
+Bas Mevissen
+Ben Darnell
+Ben Greear
+Ben Madsen
+Ben Noordhuis
+Ben Van Hof
+Ben Winslow
+Benbuck Nason
+Benjamin Gerard
+Benjamin Johnson
+Bernard Leak
+Bernhard Reutner-Fischer
+Bertrand Demiddelaer
+Bill Egert
+Bill Hoffman
+Bjoern Sikora
+Bjorn Augustsson
+Bjorn Reese
+Björn Stenberg
+Blaise Potard
+Bob Richmond
+Bob Schader
+Bogdan Nicula
+Brad Burdick
+Brad Hards
+Brad King
+Bradford Bruce
+Brandon Wang
+Brendan Jurd
+Brent Beardsley
+Brian Akins
+Brian Dessent
+Brian J. Murrell
+Brian R Duffy
+Brian Ulm
+Brock Noland
+Bruce Mitchener
+Bryan Henderson
+Bryan Kemp
+Cameron Kaiser
+Camille Moncelier
+Caolan McNamara
+Carsten Lange
+Casey O'Donnell
+Cedric Deltheil
+Chad Monroe
+Chandrakant Bagul
+Charles Kerr
+Chih-Chung Chang
+Chris "Bob Bob"
+Chris Combes
+Chris Conroy
+Chris Deidun
+Chris Flerackers
+Chris Gaukroger
+Chris Maltby
+Chris Mumford
+Chris Smowton
+Christian Grothoff
+Christian Hagele
+Christian Hägele
+Christian Krause
+Christian Kurz
+Christian Robottom Reis
+Christian Schmitz
+Christian Vogt
+Christophe Demory
+Christophe Legry
+Christopher Conroy
+Christopher Palow
+Christopher R. Palmer
+Christopher Stone
+Ciprian Badescu
+Claes Jakobsson
+Clarence Gardner
+Clifford Wolf
+Cody Jones
+Colin Hogben
+Colin Watson
+Colm Buckley
+Constantine Sapuntzakis
+Cory Nelson
+Craig A West
+Craig Davison
+Craig Markwardt
+Cris Bailiff
+Cristian Rodriguez
+Cristian Rodríguez
+Curt Bogmine
+Cyrill Osterwalder
+Dag Ekengren
+Dagobert Michelsen
+Damien Adant
+Dan Becker
+Dan C
+Dan Fandrich
+Dan Locks
+Dan Nelson
+Dan Petitt
+Dan Torop
+Dan Zitter
+Daniel Black
+Daniel Cater
+Daniel Egger
+Daniel Johnson
+Daniel Mentz
+Daniel Steinberg
+Daniel Stenberg
+Daniel Theron
+Daniel at touchtunes
+Darryl House
+Darshan Mody
+Dave Dribin
+Dave Halbakken
+Dave Hamilton
+Dave May
+Dave Reisner
+Dave Vasilevsky
+David Bau
+David Binderman
+David Blaikie
+David Byron
+David Cohen
+David Eriksson
+David Houlder
+David Hull
+David J Meyer
+David James
+David Kierznowski
+David Kimdon
+David Lang
+David LeBlanc
+David McCreedy
+David Odin
+David Phillips
+David Rosenstrauch
+David Shaw
+David Tarendash
+David Thiel
+David Wright
+David Yan
+Dengminwen
+Detlef Schmier
+Didier Brisebourg
+Diego Casorran
+Dima Barsky
+Dimitre Dimitrov
+Dimitris Sarris
+Dinar
+Dirk Eddelbuettel
+Dirk Manske
+Dmitri Shubin
+Dmitriy Sergeyev
+Dmitry Bartsevich
+Dmitry Kurochkin
+Dmitry Popov
+Dmitry Rechkin
+Dolbneff A.V
+Domenico Andreoli
+Dominick Meglio
+Dominique Leuenberger
+Doug Kaufman
+Doug Porter
+Douglas E. Wegscheid
+Douglas Kilpatrick
+Douglas R. Horner
+Douglas Steinwand
+Dov Murik
+Duane Cathey
+Duncan Mac-Vicar Prett
+Dustin Boswell
+Dylan Ellicott
+Dylan Salisbury
+Early Ehlinger
+Ebenezer Ikonne
+Edin Kadribasic
+Eduard Bloch
+Edward Sheldrake
+Eelco Dolstra
+Eetu Ojanen
+Ellis Pritchard
+Emanuele Bovisio
+Emil Romanus
+Emiliano Ida
+Enrico Scholz
+Enrik Berkhan
+Eric Cooper
+Eric Hu
+Eric Landes
+Eric Lavigne
+Eric Melville
+Eric Mertens
+Eric Rautman
+Eric Thelin
+Eric Vergnaud
+Eric Wong
+Eric Young
+Erick Nuwendam
+Erwan Legrand
+Erwin Authried
+Eugene Kotlyarov
+Evan Jordan
+Eygene Ryabinkin
+Fabian Hiernaux
+Fabian Keil
+Fabrizio Ammollo
+Fedor Karpelevitch
+Felix von Leitner
+Feng Tu
+Florian Schoppmann
+Forrest Cahoon
+Frank Hempel
+Frank Keeney
+Frank McGeough
+Frank Meier
+Frank Ticheler
+Frank Van Uffelen
+FrantiÅ¡ek KuÄera
+Fred Machado
+Fred New
+Fred Noz
+Frederic Lepied
+Gabriel Kuri
+Gabriel Sjoberg
+Garrett Holmstrom
+Gary Maxwell
+Gautam Kachroo
+Gautam Mani
+Gavrie Philipson
+Gaz Iqbal
+Georg Horn
+Georg Huettenegger
+Georg Lippitsch
+Georg Wicherski
+Gerd v. Egidy
+Gerhard Herre
+Gerrit Bruchhäuser
+Ghennadi Procopciuc
+Giancarlo Formicuccia
+Giaslas Georgios
+Gil Weber
+Gilad
+Gilbert Ramirez Jr.
+Gilles Blanc
+Gisle Vanem
+Giuseppe Attardi
+Giuseppe D'Ambrosio
+Glen Nakamura
+Glen Scott
+Gokhan Sengun
+Grant Erickson
+Greg Hewgill
+Greg Morse
+Greg Onufer
+Greg Zavertnik
+Grigory Entin
+Guenole Bescon
+Guenter Knauf
+Guido Berhoerster
+Guillaume Arluison
+Gustaf Hui
+Gwenole Beauchesne
+Götz Babin-Ebell
+Hamish Mackenzie
+Hang Kin Lau
+Hanno Kranzhoff
+Hans Steegers
+Hans-Jurgen May
+Hardeep Singh
+Harshal Pradhan
+Hauke Duden
+Heikki Korpela
+Heinrich Ko
+Hendrik Visage
+Henrik Storner
+Henry Ludemann
+Herve Amblard
+Hidemoto Nakada
+Ho-chi Chen
+Hoi-Ho Chan
+Hongli Lai
+Howard Chu
+Hzhijun
+Ian D Allen
+Ian Ford
+Ian Gulliver
+Ian Lynagh
+Ian Turner
+Ian Wilkes
+Ignacio Vazquez-Abrams
+Igor Franchuk
+Igor Novoseltsev
+Igor Polyakov
+Ilguiz Latypov
+Ilja van Sprundel
+Immanuel Gregoire
+Ingmar Runge
+Ingo Ralf Blum
+Ingo Wilken
+Jack Zhang
+Jacky Lam
+Jacob Meuser
+Jacob Moshenko
+Jad Chamcham
+James Bursa
+James Cheng
+James Clancy
+James Cone
+James Gallagher
+James Griffiths
+James Housley
+James MacMillan
+Jamie Lokier
+Jamie Newton
+Jamie Wilkinson
+Jan Ehrhardt
+Jan Koen Annot
+Jan Kunder
+Jan Schaumann
+Jan Van Boghout
+Jared Lundell
+Jari Sundell
+Jason Glasgow
+Jason Liu
+Jason McDonald
+Jason S. Priebe
+Jay Austin
+Jayesh A Shah
+Jaz Fresh
+Jean Jacques Drouin
+Jean-Claude Chauve
+Jean-Francois Bertrand
+Jean-Louis Lemaire
+Jean-Marc Ranger
+Jean-Philippe Barrette-LaPierre
+Jeff Connelly
+Jeff Johnson
+Jeff Lawson
+Jeff Phillips
+Jeff Pohlmeyer
+Jeff Weber
+Jeffrey Pohlmeyer
+Jeremy Friesner
+Jerome Muffat-Meridol
+Jerome Vouillon
+Jerry Wu
+Jes Badwal
+Jesper Jensen
+Jesse Noller
+Jie He
+Jim Drash
+Jim Freeman
+Jim Hollinger
+Jim Meyering
+Jocelyn Jaubert
+Joe Halpin
+Joe Malicki
+Joe Mason
+Joel Chen
+Jofell Gallardo
+Johan Anderson
+Johan Nilsson
+Johan van Selst
+Johannes Bauer
+John Bradshaw
+John Crow
+John Dennis
+John E. Malmberg
+John Janssen
+John Joseph Bachir
+John Kelly
+John Lask
+John Lightsey
+John Marino
+John McGowan
+John P. McCaskey
+John Suprock
+John Wilkinson
+John-Mark Bell
+Johnny Luong
+Jon Grubbs
+Jon Nelson
+Jon Sargeant
+Jon Travis
+Jon Turner
+Jonas Forsman
+Jonas Schnelli
+Jonatan Lander
+Jonathan Hseu
+Jonathan Nieder
+Jongki Suwandi
+Jose Kahan
+Josef Wolf
+Josh Kapell
+Joshua Kwan
+Josue Andrade Gomes
+Juan Barreto
+Juan F. Codagnone
+Juan Ignacio Hervás
+Judson Bishop
+Juergen Wilke
+Jukka Pihl
+Julian Noble
+Julian Taylor
+Julien Chaffraix
+Julien Royer
+Jun-ichiro itojun Hagino
+Jurij Smakov
+Justin Fletcher
+Jörg Mueller-Tolk
+Jörn Hartroth
+Kai Sommerfeld
+Kai-Uwe Rommel
+Kalle Vahlman
+Kamil Dudka
+Kang-Jin Lee
+Karl M
+Karl Moerder
+Karol Pietrzak
+Kaspar Brand
+Katie Wang
+Kees Cook
+Keith MacDonald
+Keith McGuigan
+Keith Mok
+Ken Hirsch
+Ken Rastatter
+Kenny To
+Kent Boortz
+Keshav Krity
+Kevin Baughman
+Kevin Fisk
+Kevin Lussier
+Kevin Reed
+Kevin Roth
+Kim Rinnewitz
+Kimmo Kinnunen
+Kjell Ericson
+Kjetil Jacobsen
+Klevtsov Vadim
+Kris Kennaway
+Krishnendu Majumdar
+Krister Johansen
+Kristian Gunstone
+Kristian Köhntopp
+Kyle Sallee
+Lachlan O'Dea
+Larry Campbell
+Larry Fahnoe
+Lars Buitinck
+Lars Gustafsson
+Lars J. Aas
+Lars Nilsson
+Lars Torben Wilson
+Lau Hang Kin
+Laurent Rabret
+Legoff Vincent
+Lehel Bernadt
+Len Krause
+Lenaic Lefever
+Lenny Rachitsky
+Liam Healy
+Lijo Antony
+Linas Vepstas
+Ling Thio
+Linus Nielsen Feltzing
+Lisa Xu
+Liza Alenchery
+Loic Dachary
+Loren Kirkby
+Luca Altea
+Luca Alteas
+Lucas Adamski
+Lukasz Czekierda
+Luke Amery
+Luke Call
+Luong Dinh Dung
+Maciej Karpiuk
+Maciej W. Rozycki
+Mamoru Tasaka
+Mandy Wu
+Manfred Schwarb
+Manuel Massing
+Marc Boucher
+Marc Hoersken
+Marc Kleine-Budde
+Marcel Raad
+Marcel Roelofs
+Marcelo Juchem
+Marcin Adamski
+Marcin Konicki
+Marco G. Salvagno
+Marco Maggi
+Marcus Sundberg
+Marcus Webster
+Mario Schroeder
+Mark Brand
+Mark Butler
+Mark Davies
+Mark Eichin
+Mark Incley
+Mark Karpeles
+Mark Lentczner
+Mark Salisbury
+Mark Snelling
+Mark Tully
+Markus Duft
+Markus Koetter
+Markus Moeller
+Markus Oberhumer
+Martijn Koster
+Martin C. Martin
+Martin Drasar
+Martin Hager
+Martin Hedenfalk
+Martin Lemke
+Martin Skinner
+Martin Storsjo
+Marty Kuhrt
+Maruko
+Massimiliano Ziccardi
+Massimo Callegari
+Mateusz Loskot
+Mathias Axelsson
+Mats Lidell
+Matt Kraai
+Matt Veenstra
+Matt Witherspoon
+Matt Wixson
+Matteo Rocco
+Matthew Blain
+Matthew Clarke
+Matthias Bolte
+Maurice Barnum
+Mauro Iorio
+Max Katsev
+Maxim Ivanov
+Maxim Perenesenko
+Maxim Prohorov
+Maxime Larocque
+Mehmet Bozkurt
+Mekonikum
+Mettgut Jamalla
+Michael Benedict
+Michael Calmer
+Michael Cronenworth
+Michael Curtis
+Michael Day
+Michael Goffioul
+Michael Jahn
+Michael Jerris
+Michael Mealling
+Michael Mueller
+Michael Smith
+Michael Stillwell
+Michael Wallner
+Michal Bonino
+Michal Gorny
+Michal Kowalczyk
+Michal Marek
+Michele Bini
+Mihai Ionescu
+Mikael Johansson
+Mikael Sennerholm
+Mike Bytnar
+Mike Crowe
+Mike Dobbs
+Mike Hommey
+Mike Power
+Mike Protts
+Mike Revi
+Miklos Nemeth
+Mitz Wark
+Mohamed Lrhazi
+Mohun Biswas
+Moonesamy
+Nathan Coulter
+Nathan O'Sullivan
+Nathanael Nerode
+Naveen Chandran
+Naveen Noel
+Neil Bowers
+Neil Dunbar
+Neil Spring
+Nic Roets
+Nicholas Maniscalco
+Nick Gimbrone
+Nick Humfrey
+Nick Zitzmann
+Nico Baggus
+Nicolas Berloquin
+Nicolas Croiset
+Nicolas François
+Niels van Tongeren
+Nikita Schmidt
+Nikitinskit Dmitriy
+Niklas Angebrand
+Nikolai Kondrashov
+Nikos Mavrogiannopoulos
+Ning Dong
+Nir Soffer
+Nis Jorgensen
+Nodak Sodak
+Norbert Frese
+Norbert Novotny
+Ofer
+Olaf Flebbe
+Olaf Stueben
+Olaf Stüben
+Olivier Berger
+Oren Tirosh
+Ori Avtalion
+Oscar Koeroo
+Oscar Norlander
+P R Schaffner
+Paolo Piacentini
+Pascal Terjan
+Pasha Kuznetsov
+Pat Ray
+Patrice Guerin
+Patrick Bihan-Faou
+Patrick Monnerat
+Patrick Scott
+Patrick Smith
+Patrik Thunstrom
+Pau Garcia i Quiles
+Paul Harrington
+Paul Howarth
+Paul Marquis
+Paul Moore
+Paul Nolan
+Paul Querna
+Pavel Cenek
+Pavel Orehov
+Pavel Raiskup
+Pawel A. Gajda
+Pawel Kierski
+Pedro Larroy
+Pedro Neves
+Pete Su
+Peter Bray
+Peter Forret
+Peter Heuchert
+Peter Hjalmarsson
+Peter Korsgaard
+Peter Lamberg
+Peter O'Gorman
+Peter Pentchev
+Peter Silva
+Peter Su
+Peter Sylvester
+Peter Todd
+Peter Verhas
+Peter Wullinger
+Peteris Krumins
+Phil Blundell
+Phil Karn
+Phil Lisiecki
+Phil Pellouchoud
+Philip Craig
+Philip Gladstone
+Philip Langdale
+Philippe Hameau
+Philippe Raoult
+Philippe Vaucher
+Pierre
+Pierre Brico
+Pierre Chapuis
+Pierre Joye
+Pierre Ynard
+Pooyan McSporran
+Pramod Sharma
+Puneet Pawaia
+Quagmire
+Quanah Gibson-Mount
+Quinn Slack
+Rafa Muyo
+Rafael Sagula
+Rainer Canavan
+Rainer Koenig
+Rajesh Naganathan
+Ralf S. Engelschall
+Ralph Beckmann
+Ralph Mitchell
+Ramana Mokkapati
+Randy McMurchy
+Ravi Pratap
+Ray Dassen
+Ray Pekowski
+Reinout van Schouwen
+Renato Botelho
+Renaud Chaillat
+Renaud Duhaut
+Rene Bernhardt
+Rene Rebe
+Reuven Wachtfogel
+Reza Arbab
+Ricardo Cadime
+Rich Gray
+Rich Rauenzahn
+Richard Archer
+Richard Atterer
+Richard Bramante
+Richard Clayton
+Richard Cooper
+Richard Gorton
+Richard Prescott
+Richard Silverman
+Rick Jones
+Rick Richardson
+Rob Crittenden
+Rob Jones
+Rob Stanzel
+Rob Ward
+Robert A. Monat
+Robert B. Harris
+Robert D. Young
+Robert Foreman
+Robert Iakobashvili
+Robert Olson
+Robert Schumann
+Robert Weaver
+Robin Cornelius
+Robin Johnson
+Robin Kay
+Robson Braga Araujo
+Rodney Simmons
+Rodrigo Silva
+Roland Blom
+Roland Krikava
+Roland Zimmermann
+Rolland Dudemaine
+Roman Koifman
+Roman Mamedov
+Ron Zapp
+Rosimildo da Silva
+Roy Shan
+Rune Kleveland
+Ruslan Gazizov
+Rutger Hofman
+Ryan Chan
+Ryan Nelson
+Ryan Schmidt
+S. Moonesamy
+Salvador Dávila
+Salvatore Sorrentino
+Sam Listopad
+Sampo Kellomaki
+Samuel Díaz García
+Samuel Listopad
+Samuel Thibault
+Sander Gates
+Sandor Feldi
+Santhana Todatry
+Saqib Ali
+Sara Golemon
+Saul good
+Scott Bailey
+Scott Barrett
+Scott Cantor
+Scott Davis
+Scott McCreary
+Sebastian Rasmussen
+Sebastien Willemijns
+Senthil Raja Velu
+Sergei Nikulov
+Sergio Ballestrero
+Seshubabu Pasam
+Sh Diao
+Sharad Gupta
+Shard
+Shawn Poulson
+Shmulik Regev
+Siddhartha Prakash Jain
+Sidney San Martin
+Siegfried Gyuricsko
+Simon Dick
+Simon Josefsson
+Simon Liu
+Song Ma
+Sonia Subramanian
+Spacen Jasset
+Spiridonoff A.V
+Stadler Stephan
+Stan van de Burgt
+Stefan Esser
+Stefan Krause
+Stefan Teleman
+Stefan Tomanek
+Stefan Ulrich
+Stephan Bergmann
+Stephen Collyer
+Stephen Kick
+Stephen More
+Sterling Hughes
+Steve Green
+Steve H Truong
+Steve Holme
+Steve Lhomme
+Steve Little
+Steve Marx
+Steve Oliphant
+Steve Roskowski
+Steven Bazyl
+Steven G. Johnson
+Steven M. Schweda
+Steven Parkes
+Stoned Elipot
+Sven Anders
+Sven Neuhaus
+Sven Wegener
+Sébastien Willemijns
+T. Bharath
+T. Yamada
+Taneli Vahakangas
+Tanguy Fautre
+Tatsuhiro Tsujikawa
+Temprimus
+Thomas J. Moore
+Thomas Klausner
+Thomas L. Shinnick
+Thomas Lopatic
+Thomas Schwinge
+Thomas Tonino
+Tim Ansell
+Tim Baker
+Tim Bartley
+Tim Chen
+Tim Costello
+Tim Harder
+Tim Heckman
+Tim Newsome
+Tim Sneddon
+Tinus van den Berg
+Tobias Rundström
+Toby Peterson
+Todd A Ouska
+Todd Kulesza
+Todd Ouska
+Todd Vierling
+Tom Benoist
+Tom Donovan
+Tom Lee
+Tom Mattison
+Tom Moers
+Tom Mueller
+Tom Regner
+Tom Wright
+Tom Zerucha
+Tomas Mlcoch
+Tomas Pospisek
+Tomas Szepe
+Tomasz Lacki
+Tommie Gannert
+Tommy Tam
+Ton Voon
+Toni Moreno
+Toon Verwaest
+Tor Arntsen
+Torsten Foertsch
+Toshio Kuratomi
+Toshiyuki Maezawa
+Traian Nicolescu
+Troels Walsted Hansen
+Troy Engel
+Tupone Alfredo
+Ulf Härnhammar
+Ulrich Zadow
+Venkat Akella
+Victor Snezhko
+Vikram Saxena
+Vilmos Nebehaj
+Vincent Bronner
+Vincent Le Normand
+Vincent Penquerc'h
+Vincent Sanders
+Vincent Torri
+Vlad Grachov
+Vlad Ureche
+Vladimir Grishchenko
+Vladimir Lazarenko
+Vojtech Janota
+Vojtech Minarik
+Vsevolod Novikov
+Walter J. Mack
+Ward Willats
+Wayne Haigh
+Werner Koch
+Wesley Laxton
+Wesley Miaw
+Wez Furlong
+Wilfredo Sanchez
+Wojciech Zwiefka
+Wu Yongzheng
+Xavier Bouchoux
+Yang Tse
+Yarram Sunil
+Yehoshua Hershberg
+Yukihiro Kawada
+Yuriy Sosov
+Yves Lejeune
+Zmey Petroff
+Zvi Har'El
+nk
+swalkaus at yahoo.com
+tommink[at]post.pl
diff --git a/docs/TODO b/docs/TODO
new file mode 100644
index 000000000..30c0a64ab
--- /dev/null
+++ b/docs/TODO
@@ -0,0 +1,662 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+ Things that could be nice to do in the future
+
+ Things to do in project cURL. Please tell us what you think, contribute and
+ send us patches that improve things!
+
+ All bugs documented in the KNOWN_BUGS document are subject for fixing!
+
+ 1. libcurl
+ 1.2 More data sharing
+ 1.3 struct lifreq
+ 1.4 signal-based resolver timeouts
+ 1.5 get rid of PATH_MAX
+ 1.6 progress callback without doubles
+ 1.7 Happy Eyeball dual stack connect
+
+ 2. libcurl - multi interface
+ 2.1 More non-blocking
+ 2.2 Remove easy interface internally
+ 2.4 Fix HTTP Pipelining for PUT
+
+ 3. Documentation
+ 3.1 More and better
+
+ 4. FTP
+ 4.1 HOST
+ 4.2 Alter passive/active on failure and retry
+ 4.3 Earlier bad letter detection
+ 4.4 REST for large files
+ 4.5 FTP proxy support
+ 4.6 ASCII support
+
+ 5. HTTP
+ 5.1 Better persistency for HTTP 1.0
+ 5.2 support FF3 sqlite cookie files
+ 5.3 Rearrange request header order
+
+ 6. TELNET
+ 6.1 ditch stdin
+ 6.2 ditch telnet-specific select
+ 6.3 feature negotiation debug data
+ 6.4 send data in chunks
+
+ 7. SSL
+ 7.1 Disable specific versions
+ 7.2 Provide mutex locking API
+ 7.3 Evaluate SSL patches
+ 7.4 Cache OpenSSL contexts
+ 7.5 Export session ids
+ 7.6 Provide callback for cert verification
+ 7.7 Support other SSL libraries
+ 7.9 improve configure --with-ssl
+ 7.10 Support DANE
+
+ 8. GnuTLS
+ 8.1 SSL engine stuff
+ 8.3 check connection
+
+ 9. SMTP
+ 9.1 Specify the preferred authentication mechanism
+ 9.2 Initial response
+ 9.3 Pipelining
+
+ 10. POP3
+ 10.1 auth= in URLs
+
+ 11. IMAP
+ 11.1 SASL based authentication mechanisms
+
+ 12. LDAP
+ 12.1 SASL based authentication mechanisms
+
+ 13. Other protocols
+
+ 14. New protocols
+ 14.1 RSYNC
+
+ 15. SASL
+ 15.1 Other authentication mechanisms
+
+ 16. Client
+ 16.1 sync
+ 16.2 glob posts
+ 16.3 prevent file overwriting
+ 16.4 simultaneous parallel transfers
+ 16.5 provide formpost headers
+ 16.6 url-specific options
+ 16.7 warning when setting an option
+ 16.8 IPv6 addresses with globbing
+
+ 17. Build
+ 17.1 roffit
+
+ 18. Test suite
+ 18.1 SSL tunnel
+ 18.2 nicer lacking perl message
+ 18.3 more protocols supported
+ 18.4 more platforms supported
+
+ 19. Next SONAME bump
+ 19.1 http-style HEAD output for ftp
+ 19.2 combine error codes
+ 19.3 extend CURLOPT_SOCKOPTFUNCTION prototype
+
+ 20. Next major release
+ 20.1 cleanup return codes
+ 20.2 remove obsolete defines
+ 20.3 size_t
+ 20.4 remove several functions
+ 20.5 remove CURLOPT_FAILONERROR
+ 20.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
+ 20.7 remove progress meter from libcurl
+ 20.8 remove 'curl_httppost' from public
+ 20.9 have form functions use CURL handle argument
+ 20.10 Add CURLOPT_MAIL_CLIENT option
+
+==============================================================================
+
+1. libcurl
+
+1.2 More data sharing
+
+ curl_share_* functions already exist and work, and they can be extended to
+ share more. For example, enable sharing of the ares channel and the
+ connection cache.
+
+1.3 struct lifreq
+
+ Use 'struct lifreq' and SIOCGLIFADDR instead of 'struct ifreq' and
+ SIOCGIFADDR on newer Solaris versions as they claim the latter is obsolete.
+ To support ipv6 interface addresses for network interfaces properly.
+
+1.4 signal-based resolver timeouts
+
+ libcurl built without an asynchronous resolver library uses alarm() to time
+ out DNS lookups. When a timeout occurs, this causes libcurl to jump from the
+ signal handler back into the library with a sigsetjmp, which effectively
+ causes libcurl to continue running within the signal handler. This is
+ non-portable and could cause problems on some platforms. A discussion on the
+ problem is available at http://curl.haxx.se/mail/lib-2008-09/0197.html
+
+ Also, alarm() provides timeout resolution only to the nearest second. alarm
+ ought to be replaced by setitimer on systems that support it.
+
+1.5 get rid of PATH_MAX
+
+ Having code use and rely on PATH_MAX is not nice:
+ http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
+
+ Currently the SSH based code uses it a bit, but to remove PATH_MAX from there
+ we need libssh2 to properly tell us when we pass in a too small buffer and
+ its current API (as of libssh2 1.2.7) doesn't.
+
+1.6 progress callback without doubles
+
+ The progress callback was introduced way back in the days and the choice to
+ use doubles in the arguments was possibly good at the time. Today the doubles
+ only confuse users and make the amounts less precise. We should introduce
+ another progress callback option that take precedence over the old one and
+ have both co-exist for a forseeable time until we can remove the double-using
+ one.
+
+1.7 Happy Eyeball dual stack connect
+
+ In order to make alternative technologies not suffer when transitioning, like
+ when introducing IPv6 as an alternative to IPv4 and there are more than one
+ option existing simultaneously there are reasons to reconsider internal
+ choices.
+
+ To make libcurl do blazing fast IPv6 in a dual-stack configuration, this needs
+ to be addressed:
+
+ http://tools.ietf.org/html/rfc6555
+
+
+2. libcurl - multi interface
+
+2.1 More non-blocking
+
+ Make sure we don't ever loop because of non-blocking sockets returning
+ EWOULDBLOCK or similar. Blocking cases include:
+
+ - Name resolves on non-windows unless c-ares is used
+ - NSS SSL connections
+ - HTTP proxy CONNECT operations
+ - SOCKS proxy handshakes
+ - file:// transfers
+ - TELNET transfers
+ - The "DONE" operation (post transfer protocol-specific actions) for the
+ protocols SFTP, SMTP, FTP. Fixing Curl_done() for this is a worthy task.
+
+2.2 Remove easy interface internally
+
+ Make curl_easy_perform() a wrapper-function that simply creates a multi
+ handle, adds the easy handle to it, runs curl_multi_perform() until the
+ transfer is done, then detach the easy handle, destroy the multi handle and
+ return the easy handle's return code. This will thus make everything
+ internally use and assume the multi interface. The select()-loop should use
+ curl_multi_socket().
+
+2.4 Fix HTTP Pipelining for PUT
+
+ HTTP Pipelining can be a way to greatly enhance performance for multiple
+ serial requests and currently libcurl only supports that for HEAD and GET
+ requests but it should also be possible for PUT.
+
+3. Documentation
+
+3.1 More and better
+
+ Exactly
+
+4. FTP
+
+4.1 HOST
+
+ HOST is a suggested command in the works for a client to tell which host name
+ to use, to offer FTP servers named-based virtual hosting:
+
+ http://tools.ietf.org/html/draft-hethmon-mcmurray-ftp-hosts-11
+
+4.2 Alter passive/active on failure and retry
+
+ When trying to connect passively to a server which only supports active
+ connections, libcurl returns CURLE_FTP_WEIRD_PASV_REPLY and closes the
+ connection. There could be a way to fallback to an active connection (and
+ vice versa). http://curl.haxx.se/bug/feature.cgi?id=1754793
+
+4.3 Earlier bad letter detection
+
+ Make the detection of (bad) %0d and %0a codes in FTP url parts earlier in the
+ process to avoid doing a resolve and connect in vain.
+
+4.4 REST for large files
+
+ REST fix for servers not behaving well on >2GB requests. This should fail if
+ the server doesn't set the pointer to the requested index. The tricky
+ (impossible?) part is to figure out if the server did the right thing or not.
+
+4.5 FTP proxy support
+
+ Support the most common FTP proxies, Philip Newton provided a list allegedly
+ from ncftp. This is not a subject without debate, and is probably not really
+ suitable for libcurl. http://curl.haxx.se/mail/archive-2003-04/0126.html
+
+4.6 ASCII support
+
+ FTP ASCII transfers do not follow RFC959. They don't convert the data
+ accordingly.
+
+5. HTTP
+
+5.1 Better persistency for HTTP 1.0
+
+ "Better" support for persistent connections over HTTP 1.0
+ http://curl.haxx.se/bug/feature.cgi?id=1089001
+
+5.2 support FF3 sqlite cookie files
+
+ Firefox 3 is changing from its former format to a a sqlite database instead.
+ We should consider how (lib)curl can/should support this.
+ http://curl.haxx.se/bug/feature.cgi?id=1871388
+
+5.3 Rearrange request header order
+
+ Server implementors often make an effort to detect browser and to reject
+ clients it can detect to not match. One of the last details we cannot yet
+ control in libcurl's HTTP requests, which also can be exploited to detect
+ that libcurl is in fact used even when it tries to impersonate a browser, is
+ the order of the request headers. I propose that we introduce a new option in
+ which you give headers a value, and then when the HTTP request is built it
+ sorts the headers based on that number. We could then have internally created
+ headers use a default value so only headers that need to be moved have to be
+ specified.
+
+
+6. TELNET
+
+6.1 ditch stdin
+
+Reading input (to send to the remote server) on stdin is a crappy solution for
+library purposes. We need to invent a good way for the application to be able
+to provide the data to send.
+
+6.2 ditch telnet-specific select
+
+ Move the telnet support's network select() loop go away and merge the code
+ into the main transfer loop. Until this is done, the multi interface won't
+ work for telnet.
+
+6.3 feature negotiation debug data
+
+ Add telnet feature negotiation data to the debug callback as header data.
+
+6.4 send data in chunks
+
+ Currently, telnet sends data one byte at a time. This is fine for interactive
+ use, but inefficient for any other. Sent data should be sent in larger
+ chunks.
+
+7. SSL
+
+7.1 Disable specific versions
+
+ Provide an option that allows for disabling specific SSL versions, such as
+ SSLv2 http://curl.haxx.se/bug/feature.cgi?id=1767276
+
+7.2 Provide mutex locking API
+
+ Provide a libcurl API for setting mutex callbacks in the underlying SSL
+ library, so that the same application code can use mutex-locking
+ independently of OpenSSL or GnutTLS being used.
+
+7.3 Evaluate SSL patches
+
+ Evaluate/apply Gertjan van Wingerde's SSL patches:
+ http://curl.haxx.se/mail/lib-2004-03/0087.html
+
+7.4 Cache OpenSSL contexts
+
+ "Look at SSL cafile - quick traces look to me like these are done on every
+ request as well, when they should only be necessary once per ssl context (or
+ once per handle)". The major improvement we can rather easily do is to make
+ sure we don't create and kill a new SSL "context" for every request, but
+ instead make one for every connection and re-use that SSL context in the same
+ style connections are re-used. It will make us use slightly more memory but
+ it will libcurl do less creations and deletions of SSL contexts.
+
+7.5 Export session ids
+
+ Add an interface to libcurl that enables "session IDs" to get
+ exported/imported. Cris Bailiff said: "OpenSSL has functions which can
+ serialise the current SSL state to a buffer of your choice, and recover/reset
+ the state from such a buffer at a later date - this is used by mod_ssl for
+ apache to implement and SSL session ID cache".
+
+7.6 Provide callback for cert verification
+
+ OpenSSL supports a callback for customised verification of the peer
+ certificate, but this doesn't seem to be exposed in the libcurl APIs. Could
+ it be? There's so much that could be done if it were!
+
+7.7 Support other SSL libraries
+
+ Make curl's SSL layer capable of using other free SSL libraries. Such as
+ MatrixSSL (http://www.matrixssl.org/).
+
+7.9 improve configure --with-ssl
+
+ make the configure --with-ssl option first check for OpenSSL, then GnuTLS,
+ then NSS...
+
+7.10 Support DANE
+
+ DNS-Based Authentication of Named Entities (DANE) is a way to provide SSL
+ keys and certs over DNS using DNSSEC as an alternative to the CA model.
+ http://www.rfc-editor.org/rfc/rfc6698.txt
+
+
+8. GnuTLS
+
+8.1 SSL engine stuff
+
+ Is this even possible?
+
+8.3 check connection
+
+ Add a way to check if the connection seems to be alive, to correspond to the
+ SSL_peak() way we use with OpenSSL.
+
+
+9. SMTP
+
+9.1 Specify the preferred authentication mechanism
+
+ Add the ability to specify the preferred authentication mechanism or a list
+ of mechanisms that should be used. Not only that, but the order that is
+ returned by the server during the EHLO response should be honored by curl.
+
+9.2 Initial response
+
+ Add the ability for the user to specify whether the initial response is
+ included in the AUTH command. Some email servers, such as Microsoft
+ Exchange, can work with either whilst others need to have the initial
+ response sent separately:
+
+ http://curl.haxx.se/mail/lib-2012-03/0114.html
+
+9.3 Pipelining
+
+ Add support for pipelining emails.
+
+10. POP3
+
+10.1 auth= in URLs
+
+ Being able to specify the preferred authentication mechanism in the URL as
+ per RFC2384.
+
+11. IMAP
+
+11.1 SASL based authentication mechanisms
+
+ Curl currently sends usernames and passwords as clear text whilst SASL based
+ authentication mechanisms can be more secure. As such, support should be
+ added to support these authentication mechanisms.
+
+12. LDAP
+
+12.1 SASL based authentication mechansims
+
+ Currently the LDAP module only supports ldap_simple_bind_s() in order to bind
+ to an LDAP server. However, this function sends username and password details
+ using the simple authentication mechanism (as clear text). However, it should
+ be possible to use ldap_bind_s() instead specifing the security context
+ information ourselves.
+
+13. Other protocols
+
+14. New protocols
+
+14.1 RSYNC
+
+ There's no RFC for the protocol or an URI/URL format. An implementation
+ should most probably use an existing rsync library, such as librsync.
+
+15. SASL
+
+15.1 Other authentication mechanisms
+
+ Add support for gssapi to SMTP and POP3.
+
+16. Client
+
+16.1 sync
+
+ "curl --sync http://example.com/feed[1-100].rss" or
+ "curl --sync http://example.net/{index,calendar,history}.html"
+
+ Downloads a range or set of URLs using the remote name, but only if the
+ remote file is newer than the local file. A Last-Modified HTTP date header
+ should also be used to set the mod date on the downloaded file.
+
+16.2 glob posts
+
+ Globbing support for -d and -F, as in 'curl -d "name=foo[0-9]" URL'.
+ This is easily scripted though.
+
+16.3 prevent file overwriting
+
+ Add an option that prevents cURL from overwriting existing local files. When
+ used, and there already is an existing file with the target file name
+ (either -O or -o), a number should be appended (and increased if already
+ existing). So that index.html becomes first index.html.1 and then
+ index.html.2 etc.
+
+16.4 simultaneous parallel transfers
+
+ The client could be told to use maximum N simultaneous parallel transfers and
+ then just make sure that happens. It should of course not make more than one
+ connection to the same remote host. This would require the client to use the
+ multi interface. http://curl.haxx.se/bug/feature.cgi?id=1558595
+
+16.5 provide formpost headers
+
+ Extending the capabilities of the multipart formposting. How about leaving
+ the ';type=foo' syntax as it is and adding an extra tag (headers) which
+ works like this: curl -F "coolfiles=@fil1.txt;headers=@fil1.hdr" where
+ fil1.hdr contains extra headers like
+
+ Content-Type: text/plain; charset=KOI8-R"
+ Content-Transfer-Encoding: base64
+ X-User-Comment: Please don't use browser specific HTML code
+
+ which should overwrite the program reasonable defaults (plain/text,
+ 8bit...)
+
+16.6 url-specific options
+
+ Provide a way to make options bound to a specific URL among several on the
+ command line. Possibly by letting ':' separate options between URLs,
+ similar to this:
+
+ curl --data foo --url url.com : \
+ --url url2.com : \
+ --url url3.com --data foo3
+
+ (More details: http://curl.haxx.se/mail/archive-2004-07/0133.html)
+
+ The example would do a POST-GET-POST combination on a single command line.
+
+16.7 warning when setting an option
+
+ Display a warning when libcurl returns an error when setting an option.
+ This can be useful to tell when support for a particular feature hasn't been
+ compiled into the library.
+
+16.8 IPv6 addresses with globbing
+
+ Currently the command line client needs to get url globbing disabled (with
+ -g) for it to support IPv6 numerical addresses. This is a rather silly flaw
+ that should be corrected. It probably involves a smarter detection of the
+ '[' and ']' letters.
+
+17. Build
+
+17.1 roffit
+
+ Consider extending 'roffit' to produce decent ASCII output, and use that
+ instead of (g)nroff when building src/hugehelp.c
+
+18. Test suite
+
+18.1 SSL tunnel
+
+ Make our own version of stunnel for simple port forwarding to enable HTTPS
+ and FTP-SSL tests without the stunnel dependency, and it could allow us to
+ provide test tools built with either OpenSSL or GnuTLS
+
+18.2 nicer lacking perl message
+
+ If perl wasn't found by the configure script, don't attempt to run the tests
+ but explain something nice why it doesn't.
+
+18.3 more protocols supported
+
+ Extend the test suite to include more protocols. The telnet could just do ftp
+ or http operations (for which we have test servers).
+
+18.4 more platforms supported
+
+ Make the test suite work on more platforms. OpenBSD and Mac OS. Remove
+ fork()s and it should become even more portable.
+
+19. Next SONAME bump
+
+19.1 http-style HEAD output for ftp
+
+ #undef CURL_FTP_HTTPSTYLE_HEAD in lib/ftp.c to remove the HTTP-style headers
+ from being output in NOBODY requests over ftp
+
+19.2 combine error codes
+
+ Combine some of the error codes to remove duplicates. The original
+ numbering should not be changed, and the old identifiers would be
+ macroed to the new ones in an CURL_NO_OLDIES section to help with
+ backward compatibility.
+
+ Candidates for removal and their replacements:
+
+ CURLE_FILE_COULDNT_READ_FILE => CURLE_REMOTE_FILE_NOT_FOUND
+
+ CURLE_FTP_COULDNT_RETR_FILE => CURLE_REMOTE_FILE_NOT_FOUND
+
+ CURLE_FTP_COULDNT_USE_REST => CURLE_RANGE_ERROR
+
+ CURLE_FUNCTION_NOT_FOUND => CURLE_FAILED_INIT
+
+ CURLE_LDAP_INVALID_URL => CURLE_URL_MALFORMAT
+
+ CURLE_TFTP_NOSUCHUSER => CURLE_TFTP_ILLEGAL
+
+ CURLE_TFTP_NOTFOUND => CURLE_REMOTE_FILE_NOT_FOUND
+
+ CURLE_TFTP_PERM => CURLE_REMOTE_ACCESS_DENIED
+
+19.3 extend CURLOPT_SOCKOPTFUNCTION prototype
+
+ The current prototype only provides 'purpose' that tells what the
+ connection/socket is for, but not any protocol or similar. It makes it hard
+ for applications to differentiate on TCP vs UDP and even HTTP vs FTP and
+ similar.
+
+20. Next major release
+
+20.1 cleanup return codes
+
+ curl_easy_cleanup() returns void, but curl_multi_cleanup() returns a
+ CURLMcode. These should be changed to be the same.
+
+20.2 remove obsolete defines
+
+ remove obsolete defines from curl/curl.h
+
+20.3 size_t
+
+ make several functions use size_t instead of int in their APIs
+
+20.4 remove several functions
+
+ remove the following functions from the public API:
+
+ curl_getenv
+
+ curl_mprintf (and variations)
+
+ curl_strequal
+
+ curl_strnequal
+
+ They will instead become curlx_ - alternatives. That makes the curl app
+ still capable of using them, by building with them from source.
+
+ These functions have no purpose anymore:
+
+ curl_multi_socket
+
+ curl_multi_socket_all
+
+20.5 remove CURLOPT_FAILONERROR
+
+ Remove support for CURLOPT_FAILONERROR, it has gotten too kludgy and weird
+ internally. Let the app judge success or not for itself.
+
+20.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
+
+ Remove support for a global DNS cache. Anything global is silly, and we
+ already offer the share interface for the same functionality but done
+ "right".
+
+20.7 remove progress meter from libcurl
+
+ The internally provided progress meter output doesn't belong in the library.
+ Basically no application wants it (apart from curl) but instead applications
+ can and should do their own progress meters using the progress callback.
+
+ The progress callback should then be bumped as well to get proper 64bit
+ variable types passed to it instead of doubles so that big files work
+ correctly.
+
+20.8 remove 'curl_httppost' from public
+
+ curl_formadd() was made to fill in a public struct, but the fact that the
+ struct is public is never really used by application for their own advantage
+ but instead often restricts how the form functions can or can't be modified.
+
+ Changing them to return a private handle will benefit the implementation and
+ allow us much greater freedoms while still maintining a solid API and ABI.
+
+20.9 have form functions use CURL handle argument
+
+ curl_formadd() and curl_formget() both currently have no CURL handle
+ argument, but both can use a callback that is set in the easy handle, and
+ thus curl_formget() with callback cannot function without first having
+ curl_easy_perform() (or similar) called - which is hard to grasp and a design
+ mistake.
+
+20.10 Add CURLOPT_MAIL_CLIENT option
+
+ Rather than use the URL to specify the mail client string to present in the
+ HELO and EHLO commands, libcurl should support a new CURLOPT specifically for
+ specifing this data as the URL is non-standard and to be honest a bit of a
+ hack ;-)
+
+ Please see the following thread for more information:
+ http://curl.haxx.se/mail/lib-2012-05/0178.html
+ \ No newline at end of file
diff --git a/docs/TheArtOfHttpScripting b/docs/TheArtOfHttpScripting
new file mode 100644
index 000000000..b0dab5ff2
--- /dev/null
+++ b/docs/TheArtOfHttpScripting
@@ -0,0 +1,507 @@
+Online: http://curl.haxx.se/docs/httpscripting.html
+Date: Jan 19, 2011
+
+ The Art Of Scripting HTTP Requests Using Curl
+ =============================================
+
+ This document will assume that you're familiar with HTML and general
+ networking.
+
+ The possibility to write scripts is essential to make a good computer
+ system. Unix' capability to be extended by shell scripts and various tools to
+ run various automated commands and scripts is one reason why it has succeeded
+ so well.
+
+ The increasing amount of applications moving to the web has made "HTTP
+ Scripting" more frequently requested and wanted. To be able to automatically
+ extract information from the web, to fake users, to post or upload data to
+ web servers are all important tasks today.
+
+ Curl is a command line tool for doing all sorts of URL manipulations and
+ transfers, but this particular document will focus on how to use it when
+ doing HTTP requests for fun and profit. I'll assume that you know how to
+ invoke 'curl --help' or 'curl --manual' to get basic information about it.
+
+ Curl is not written to do everything for you. It makes the requests, it gets
+ the data, it sends data and it retrieves the information. You probably need
+ to glue everything together using some kind of script language or repeated
+ manual invokes.
+
+1. The HTTP Protocol
+
+ HTTP is the protocol used to fetch data from web servers. It is a very simple
+ protocol that is built upon TCP/IP. The protocol also allows information to
+ get sent to the server from the client using a few different methods, as will
+ be shown here.
+
+ HTTP is plain ASCII text lines being sent by the client to a server to
+ request a particular action, and then the server replies a few text lines
+ before the actual requested content is sent to the client.
+
+ The client, curl, sends a HTTP request. The request contains a method (like
+ GET, POST, HEAD etc), a number of request headers and sometimes a request
+ body. The HTTP server responds with a status line (indicating if things went
+ well), response headers and most often also a response body. The "body" part
+ is the plain data you requested, like the actual HTML or the image etc.
+
+ 1.1 See the Protocol
+
+ Using curl's option --verbose (-v as a short option) will display what kind
+ of commands curl sends to the server, as well as a few other informational
+ texts.
+
+ --verbose is the single most useful option when it comes to debug or even
+ understand the curl<->server interaction.
+
+ Sometimes even --verbose is not enough. Then --trace and --trace-ascii offer
+ even more details as they show EVERYTHING curl sends and receives. Use it
+ like this:
+
+ curl --trace-ascii debugdump.txt http://www.example.com/
+
+2. URL
+
+ The Uniform Resource Locator format is how you specify the address of a
+ particular resource on the Internet. You know these, you've seen URLs like
+ http://curl.haxx.se or https://yourbank.com a million times.
+
+3. GET a page
+
+ The simplest and most common request/operation made using HTTP is to get a
+ URL. The URL could itself refer to a web page, an image or a file. The client
+ issues a GET request to the server and receives the document it asked for.
+ If you issue the command line
+
+ curl http://curl.haxx.se
+
+ you get a web page returned in your terminal window. The entire HTML document
+ that that URL holds.
+
+ All HTTP replies contain a set of response headers that are normally hidden,
+ use curl's --include (-i) option to display them as well as the rest of the
+ document. You can also ask the remote server for ONLY the headers by using
+ the --head (-I) option (which will make curl issue a HEAD request).
+
+4. Forms
+
+ Forms are the general way a web site can present a HTML page with fields for
+ the user to enter data in, and then press some kind of 'OK' or 'submit'
+ button to get that data sent to the server. The server then typically uses
+ the posted data to decide how to act. Like using the entered words to search
+ in a database, or to add the info in a bug track system, display the entered
+ address on a map or using the info as a login-prompt verifying that the user
+ is allowed to see what it is about to see.
+
+ Of course there has to be some kind of program in the server end to receive
+ the data you send. You cannot just invent something out of the air.
+
+ 4.1 GET
+
+ A GET-form uses the method GET, as specified in HTML like:
+
+ <form method="GET" action="junk.cgi">
+ <input type=text name="birthyear">
+ <input type=submit name=press value="OK">
+ </form>
+
+ In your favorite browser, this form will appear with a text box to fill in
+ and a press-button labeled "OK". If you fill in '1905' and press the OK
+ button, your browser will then create a new URL to get for you. The URL will
+ get "junk.cgi?birthyear=1905&press=OK" appended to the path part of the
+ previous URL.
+
+ If the original form was seen on the page "www.hotmail.com/when/birth.html",
+ the second page you'll get will become
+ "www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK".
+
+ Most search engines work this way.
+
+ To make curl do the GET form post for you, just enter the expected created
+ URL:
+
+ curl "http://www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK"
+
+ 4.2 POST
+
+ The GET method makes all input field names get displayed in the URL field of
+ your browser. That's generally a good thing when you want to be able to
+ bookmark that page with your given data, but it is an obvious disadvantage
+ if you entered secret information in one of the fields or if there are a
+ large amount of fields creating a very long and unreadable URL.
+
+ The HTTP protocol then offers the POST method. This way the client sends the
+ data separated from the URL and thus you won't see any of it in the URL
+ address field.
+
+ The form would look very similar to the previous one:
+
+ <form method="POST" action="junk.cgi">
+ <input type=text name="birthyear">
+ <input type=submit name=press value=" OK ">
+ </form>
+
+ And to use curl to post this form with the same data filled in as before, we
+ could do it like:
+
+ curl --data "birthyear=1905&press=%20OK%20" \
+ http://www.example.com/when.cgi
+
+ This kind of POST will use the Content-Type
+ application/x-www-form-urlencoded and is the most widely used POST kind.
+
+ The data you send to the server MUST already be properly encoded, curl will
+ not do that for you. For example, if you want the data to contain a space,
+ you need to replace that space with %20 etc. Failing to comply with this
+ will most likely cause your data to be received wrongly and messed up.
+
+ Recent curl versions can in fact url-encode POST data for you, like this:
+
+ curl --data-urlencode "name=I am Daniel" http://www.example.com
+
+ 4.3 File Upload POST
+
+ Back in late 1995 they defined an additional way to post data over HTTP. It
+ is documented in the RFC 1867, why this method sometimes is referred to as
+ RFC1867-posting.
+
+ This method is mainly designed to better support file uploads. A form that
+ allows a user to upload a file could be written like this in HTML:
+
+ <form method="POST" enctype='multipart/form-data' action="upload.cgi">
+ <input type=file name=upload>
+ <input type=submit name=press value="OK">
+ </form>
+
+ This clearly shows that the Content-Type about to be sent is
+ multipart/form-data.
+
+ To post to a form like this with curl, you enter a command line like:
+
+ curl --form upload=@localfilename --form press=OK [URL]
+
+ 4.4 Hidden Fields
+
+ A very common way for HTML based application to pass state information
+ between pages is to add hidden fields to the forms. Hidden fields are
+ already filled in, they aren't displayed to the user and they get passed
+ along just as all the other fields.
+
+ A similar example form with one visible field, one hidden field and one
+ submit button could look like:
+
+ <form method="POST" action="foobar.cgi">
+ <input type=text name="birthyear">
+ <input type=hidden name="person" value="daniel">
+ <input type=submit name="press" value="OK">
+ </form>
+
+ To post this with curl, you won't have to think about if the fields are
+ hidden or not. To curl they're all the same:
+
+ curl --data "birthyear=1905&press=OK&person=daniel" [URL]
+
+ 4.5 Figure Out What A POST Looks Like
+
+ When you're about fill in a form and send to a server by using curl instead
+ of a browser, you're of course very interested in sending a POST exactly the
+ way your browser does.
+
+ An easy way to get to see this, is to save the HTML page with the form on
+ your local disk, modify the 'method' to a GET, and press the submit button
+ (you could also change the action URL if you want to).
+
+ You will then clearly see the data get appended to the URL, separated with a
+ '?'-letter as GET forms are supposed to.
+
+5. PUT
+
+ The perhaps best way to upload data to a HTTP server is to use PUT. Then
+ again, this of course requires that someone put a program or script on the
+ server end that knows how to receive a HTTP PUT stream.
+
+ Put a file to a HTTP server with curl:
+
+ curl --upload-file uploadfile http://www.example.com/receive.cgi
+
+6. HTTP Authentication
+
+ HTTP Authentication is the ability to tell the server your username and
+ password so that it can verify that you're allowed to do the request you're
+ doing. The Basic authentication used in HTTP (which is the type curl uses by
+ default) is *plain* *text* based, which means it sends username and password
+ only slightly obfuscated, but still fully readable by anyone that sniffs on
+ the network between you and the remote server.
+
+ To tell curl to use a user and password for authentication:
+
+ curl --user name:password http://www.example.com
+
+ The site might require a different authentication method (check the headers
+ returned by the server), and then --ntlm, --digest, --negotiate or even
+ --anyauth might be options that suit you.
+
+ Sometimes your HTTP access is only available through the use of a HTTP
+ proxy. This seems to be especially common at various companies. A HTTP proxy
+ may require its own user and password to allow the client to get through to
+ the Internet. To specify those with curl, run something like:
+
+ curl --proxy-user proxyuser:proxypassword curl.haxx.se
+
+ If your proxy requires the authentication to be done using the NTLM method,
+ use --proxy-ntlm, if it requires Digest use --proxy-digest.
+
+ If you use any one these user+password options but leave out the password
+ part, curl will prompt for the password interactively.
+
+ Do note that when a program is run, its parameters might be possible to see
+ when listing the running processes of the system. Thus, other users may be
+ able to watch your passwords if you pass them as plain command line
+ options. There are ways to circumvent this.
+
+ It is worth noting that while this is how HTTP Authentication works, very
+ many web sites will not use this concept when they provide logins etc. See
+ the Web Login chapter further below for more details on that.
+
+7. Referer
+
+ A HTTP request may include a 'referer' field (yes it is misspelled), which
+ can be used to tell from which URL the client got to this particular
+ resource. Some programs/scripts check the referer field of requests to verify
+ that this wasn't arriving from an external site or an unknown page. While
+ this is a stupid way to check something so easily forged, many scripts still
+ do it. Using curl, you can put anything you want in the referer-field and
+ thus more easily be able to fool the server into serving your request.
+
+ Use curl to set the referer field with:
+
+ curl --referer http://www.example.come http://www.example.com
+
+8. User Agent
+
+ Very similar to the referer field, all HTTP requests may set the User-Agent
+ field. It names what user agent (client) that is being used. Many
+ applications use this information to decide how to display pages. Silly web
+ programmers try to make different pages for users of different browsers to
+ make them look the best possible for their particular browsers. They usually
+ also do different kinds of javascript, vbscript etc.
+
+ At times, you will see that getting a page with curl will not return the same
+ page that you see when getting the page with your browser. Then you know it
+ is time to set the User Agent field to fool the server into thinking you're
+ one of those browsers.
+
+ To make curl look like Internet Explorer 5 on a Windows 2000 box:
+
+ curl --user-agent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" [URL]
+
+ Or why not look like you're using Netscape 4.73 on an old Linux box:
+
+ curl --user-agent "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" [URL]
+
+9. Redirects
+
+ When a resource is requested from a server, the reply from the server may
+ include a hint about where the browser should go next to find this page, or a
+ new page keeping newly generated output. The header that tells the browser
+ to redirect is Location:.
+
+ Curl does not follow Location: headers by default, but will simply display
+ such pages in the same manner it display all HTTP replies. It does however
+ feature an option that will make it attempt to follow the Location: pointers.
+
+ To tell curl to follow a Location:
+
+ curl --location http://www.example.com
+
+ If you use curl to POST to a site that immediately redirects you to another
+ page, you can safely use --location (-L) and --data/--form together. Curl will
+ only use POST in the first request, and then revert to GET in the following
+ operations.
+
+10. Cookies
+
+ The way the web browsers do "client side state control" is by using
+ cookies. Cookies are just names with associated contents. The cookies are
+ sent to the client by the server. The server tells the client for what path
+ and host name it wants the cookie sent back, and it also sends an expiration
+ date and a few more properties.
+
+ When a client communicates with a server with a name and path as previously
+ specified in a received cookie, the client sends back the cookies and their
+ contents to the server, unless of course they are expired.
+
+ Many applications and servers use this method to connect a series of requests
+ into a single logical session. To be able to use curl in such occasions, we
+ must be able to record and send back cookies the way the web application
+ expects them. The same way browsers deal with them.
+
+ The simplest way to send a few cookies to the server when getting a page with
+ curl is to add them on the command line like:
+
+ curl --cookie "name=Daniel" http://www.example.com
+
+ Cookies are sent as common HTTP headers. This is practical as it allows curl
+ to record cookies simply by recording headers. Record cookies with curl by
+ using the --dump-header (-D) option like:
+
+ curl --dump-header headers_and_cookies http://www.example.com
+
+ (Take note that the --cookie-jar option described below is a better way to
+ store cookies.)
+
+ Curl has a full blown cookie parsing engine built-in that comes to use if you
+ want to reconnect to a server and use cookies that were stored from a
+ previous connection (or handicrafted manually to fool the server into
+ believing you had a previous connection). To use previously stored cookies,
+ you run curl like:
+
+ curl --cookie stored_cookies_in_file http://www.example.com
+
+ Curl's "cookie engine" gets enabled when you use the --cookie option. If you
+ only want curl to understand received cookies, use --cookie with a file that
+ doesn't exist. Example, if you want to let curl understand cookies from a
+ page and follow a location (and thus possibly send back cookies it received),
+ you can invoke it like:
+
+ curl --cookie nada --location http://www.example.com
+
+ Curl has the ability to read and write cookie files that use the same file
+ format that Netscape and Mozilla do. It is a convenient way to share cookies
+ between browsers and automatic scripts. The --cookie (-b) switch
+ automatically detects if a given file is such a cookie file and parses it,
+ and by using the --cookie-jar (-c) option you'll make curl write a new cookie
+ file at the end of an operation:
+
+ curl --cookie cookies.txt --cookie-jar newcookies.txt \
+ http://www.example.com
+
+11. HTTPS
+
+ There are a few ways to do secure HTTP transfers. The by far most common
+ protocol for doing this is what is generally known as HTTPS, HTTP over
+ SSL. SSL encrypts all the data that is sent and received over the network and
+ thus makes it harder for attackers to spy on sensitive information.
+
+ SSL (or TLS as the latest version of the standard is called) offers a
+ truckload of advanced features to allow all those encryptions and key
+ infrastructure mechanisms encrypted HTTP requires.
+
+ Curl supports encrypted fetches thanks to the freely available OpenSSL
+ libraries. To get a page from a HTTPS server, simply run curl like:
+
+ curl https://secure.example.com
+
+ 11.1 Certificates
+
+ In the HTTPS world, you use certificates to validate that you are the one
+ you claim to be, as an addition to normal passwords. Curl supports client-
+ side certificates. All certificates are locked with a pass phrase, which you
+ need to enter before the certificate can be used by curl. The pass phrase
+ can be specified on the command line or if not, entered interactively when
+ curl queries for it. Use a certificate with curl on a HTTPS server like:
+
+ curl --cert mycert.pem https://secure.example.com
+
+ curl also tries to verify that the server is who it claims to be, by
+ verifying the server's certificate against a locally stored CA cert
+ bundle. Failing the verification will cause curl to deny the connection. You
+ must then use --insecure (-k) in case you want to tell curl to ignore that
+ the server can't be verified.
+
+ More about server certificate verification and ca cert bundles can be read
+ in the SSLCERTS document, available online here:
+
+ http://curl.haxx.se/docs/sslcerts.html
+
+12. Custom Request Elements
+
+ Doing fancy stuff, you may need to add or change elements of a single curl
+ request.
+
+ For example, you can change the POST request to a PROPFIND and send the data
+ as "Content-Type: text/xml" (instead of the default Content-Type) like this:
+
+ curl --data "<xml>" --header "Content-Type: text/xml" \
+ --request PROPFIND url.com
+
+ You can delete a default header by providing one without content. Like you
+ can ruin the request by chopping off the Host: header:
+
+ curl --header "Host:" http://www.example.com
+
+ You can add headers the same way. Your server may want a "Destination:"
+ header, and you can add it:
+
+ curl --header "Destination: http://nowhere" http://example.com
+
+13. Web Login
+
+ While not strictly just HTTP related, it still cause a lot of people problems
+ so here's the executive run-down of how the vast majority of all login forms
+ work and how to login to them using curl.
+
+ It can also be noted that to do this properly in an automated fashion, you
+ will most certainly need to script things and do multiple curl invokes etc.
+
+ First, servers mostly use cookies to track the logged-in status of the
+ client, so you will need to capture the cookies you receive in the
+ responses. Then, many sites also set a special cookie on the login page (to
+ make sure you got there through their login page) so you should make a habit
+ of first getting the login-form page to capture the cookies set there.
+
+ Some web-based login systems features various amounts of javascript, and
+ sometimes they use such code to set or modify cookie contents. Possibly they
+ do that to prevent programmed logins, like this manual describes how to...
+ Anyway, if reading the code isn't enough to let you repeat the behavior
+ manually, capturing the HTTP requests done by your browers and analyzing the
+ sent cookies is usually a working method to work out how to shortcut the
+ javascript need.
+
+ In the actual <form> tag for the login, lots of sites fill-in random/session
+ or otherwise secretly generated hidden tags and you may need to first capture
+ the HTML code for the login form and extract all the hidden fields to be able
+ to do a proper login POST. Remember that the contents need to be URL encoded
+ when sent in a normal POST.
+
+14. Debug
+
+ Many times when you run curl on a site, you'll notice that the site doesn't
+ seem to respond the same way to your curl requests as it does to your
+ browser's.
+
+ Then you need to start making your curl requests more similar to your
+ browser's requests:
+
+ * Use the --trace-ascii option to store fully detailed logs of the requests
+ for easier analyzing and better understanding
+
+ * Make sure you check for and use cookies when needed (both reading with
+ --cookie and writing with --cookie-jar)
+
+ * Set user-agent to one like a recent popular browser does
+
+ * Set referer like it is set by the browser
+
+ * If you use POST, make sure you send all the fields and in the same order as
+ the browser does it. (See chapter 4.5 above)
+
+ A very good helper to make sure you do this right, is the LiveHTTPHeader tool
+ that lets you view all headers you send and receive with Mozilla/Firefox
+ (even when using HTTPS).
+
+ A more raw approach is to capture the HTTP traffic on the network with tools
+ such as ethereal or tcpdump and check what headers that were sent and
+ received by the browser. (HTTPS makes this technique inefficient.)
+
+15. References
+
+ RFC 2616 is a must to read if you want in-depth understanding of the HTTP
+ protocol.
+
+ RFC 3986 explains the URL syntax.
+
+ RFC 2109 defines how cookies are supposed to work.
+
+ RFC 1867 defines the HTTP post upload format.
+
+ http://curl.haxx.se is the home of the cURL project
diff --git a/docs/VERSIONS b/docs/VERSIONS
new file mode 100644
index 000000000..0670089bd
--- /dev/null
+++ b/docs/VERSIONS
@@ -0,0 +1,60 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+Version Numbers and Releases
+
+ Curl is not only curl. Curl is also libcurl. They're actually individually
+ versioned, but they mostly follow each other rather closely.
+
+ The version numbering is always built up using the same system:
+
+ X.Y[.Z]
+
+ Where
+ X is main version number
+ Y is release number
+ Z is patch number
+
+ One of these numbers will get bumped in each new release. The numbers to the
+ right of a bumped number will be reset to zero. If Z is zero, it may not be
+ included in the version number.
+
+ The main version number will get bumped when *really* big, world colliding
+ changes are made. The release number is bumped when changes are performed or
+ things/features are added. The patch number is bumped when the changes are
+ mere bugfixes.
+
+ It means that after release 1.2.3, we can release 2.0 if something really big
+ has been made, 1.3 if not that big changes were made or 1.2.4 if mostly bugs
+ were fixed.
+
+ Bumping, as in increasing the number with 1, is unconditionally only
+ affecting one of the numbers (except the ones to the right of it, that may be
+ set to zero). 1 becomes 2, 3 becomes 4, 9 becomes 10, 88 becomes 89 and 99
+ becomes 100. So, after 1.2.9 comes 1.2.10. After 3.99.3, 3.100 might come.
+
+ All original curl source release archives are named according to the libcurl
+ version (not according to the curl client version that, as said before, might
+ differ).
+
+ As a service to any application that might want to support new libcurl
+ features while still being able to build with older versions, all releases
+ have the libcurl version stored in the curl/curlver.h file using a static
+ numbering scheme that can be used for comparison. The version number is
+ defined as:
+
+ #define LIBCURL_VERSION_NUM 0xXXYYZZ
+
+ Where XX, YY and ZZ are the main version, release and patch numbers in
+ hexadecimal. All three number fields are always represented using two digits
+ (eight bits each). 1.2 would appear as "0x010200" while version 9.11.7
+ appears as "0x090b07".
+
+ This 6-digit hexadecimal number is always a greater number in a more recent
+ release. It makes comparisons with greater than and less than work.
+
+ This number is also available as three separate defines:
+ LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR and LIBCURL_VERSION_PATCH.
diff --git a/docs/curl-config.1 b/docs/curl-config.1
new file mode 100644
index 000000000..14a9d2ba8
--- /dev/null
+++ b/docs/curl-config.1
@@ -0,0 +1,98 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH curl-config 1 "25 Oct 2007" "Curl 7.17.1" "curl-config manual"
+.SH NAME
+curl-config \- Get information about a libcurl installation
+.SH SYNOPSIS
+.B curl-config [options]
+.SH DESCRIPTION
+.B curl-config
+displays information about the curl and libcurl installation.
+.SH OPTIONS
+.IP "--ca"
+Displays the built-in path to the CA cert bundle this libcurl uses.
+.IP "--cc"
+Displays the compiler used to build libcurl.
+.IP "--cflags"
+Set of compiler options (CFLAGS) to use when compiling files that use
+libcurl. Currently that is only the include path to the curl include files.
+.IP "--checkfor [version]"
+Specify the oldest possible libcurl version string you want, and this
+script will return 0 if the current installation is new enough or it
+returns 1 and outputs a text saying that the current version is not new
+enough. (Added in 7.15.4)
+.IP "--configure"
+Displays the arguments given to configure when building curl.
+.IP "--feature"
+Lists what particular main features the installed libcurl was built with. At
+the time of writing, this list may include SSL, KRB4 or IPv6. Do not assume
+any particular order. The keywords will be separated by newlines. There may be
+none, one, or several keywords in the list.
+.IP "--help"
+Displays the available options.
+.IP "--libs"
+Shows the complete set of libs and other linker options you will need in order
+to link your application with libcurl.
+.IP "--prefix"
+This is the prefix used when libcurl was installed. Libcurl is then installed
+in $prefix/lib and its header files are installed in $prefix/include and so
+on. The prefix is set with "configure --prefix".
+.IP "--protocols"
+Lists what particular protocols the installed libcurl was built to support. At
+the time of writing, this list may include HTTP, HTTPS, FTP, FTPS, FILE,
+TELNET, LDAP, DICT. Do not assume any particular order. The protocols will
+be listed using uppercase and are separated by newlines. There may be none,
+one, or several protocols in the list. (Added in 7.13.0)
+.IP "--static-libs"
+Shows the complete set of libs and other linker options you will need in order
+to link your application with libcurl statically. (Added in 7.17.1)
+.IP "--version"
+Outputs version information about the installed libcurl.
+.IP "--vernum"
+Outputs version information about the installed libcurl, in numerical mode.
+This outputs the version number, in hexadecimal, with 8 bits for each part;
+major, minor, patch. So that libcurl 7.7.4 would appear as 070704 and libcurl
+12.13.14 would appear as 0c0d0e... Note that the initial zero might be
+omitted. (This option was broken in the 7.15.0 release.)
+.SH "EXAMPLES"
+What linker options do I need when I link with libcurl?
+
+ $ curl-config --libs
+
+What compiler options do I need when I compile using libcurl functions?
+
+ $ curl-config --cflags
+
+How do I know if libcurl was built with SSL support?
+
+ $ curl-config --feature | grep SSL
+
+What's the installed libcurl version?
+
+ $ curl-config --version
+
+How do I build a single file with a one-line command?
+
+ $ `curl-config --cc --cflags` -o example example.c `curl-config --libs`
+.SH "SEE ALSO"
+.BR curl (1)
diff --git a/docs/curl.1 b/docs/curl.1
new file mode 100644
index 000000000..6808d07e5
--- /dev/null
+++ b/docs/curl.1
@@ -0,0 +1,1944 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH curl 1 "27 July 2012" "Curl 7.27.0" "Curl Manual"
+.SH NAME
+curl \- transfer a URL
+.SH SYNOPSIS
+.B curl [options]
+.I [URL...]
+.SH DESCRIPTION
+.B curl
+is a tool to transfer data from or to a server, using one of the supported
+protocols (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP,
+LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP). The
+command is designed to work without user interaction.
+
+curl offers a busload of useful tricks like proxy support, user
+authentication, FTP upload, HTTP post, SSL connections, cookies, file transfer
+resume, Metalink, and more. As you will see below, the number of features will
+make your head spin!
+
+curl is powered by libcurl for all transfer-related features. See
+.BR libcurl (3)
+for details.
+.SH URL
+The URL syntax is protocol-dependent. You'll find a detailed description in
+RFC 3986.
+
+You can specify multiple URLs or parts of URLs by writing part sets within
+braces as in:
+
+ http://site.{one,two,three}.com
+
+or you can get sequences of alphanumeric series by using [] as in:
+
+ ftp://ftp.numericals.com/file[1-100].txt
+ ftp://ftp.numericals.com/file[001-100].txt (with leading zeros)
+ ftp://ftp.letters.com/file[a-z].txt
+
+Nested sequences are not supported, but you can use several ones next to each
+other:
+
+ http://any.org/archive[1996-1999]/vol[1-4]/part{a,b,c}.html
+
+You can specify any amount of URLs on the command line. They will be fetched
+in a sequential manner in the specified order.
+
+You can specify a step counter for the ranges to get every Nth number or
+letter:
+
+ http://www.numericals.com/file[1-100:10].txt
+ http://www.letters.com/file[a-z:2].txt
+
+If you specify URL without protocol:// prefix, curl will attempt to guess what
+protocol you might want. It will then default to HTTP but try other protocols
+based on often-used host name prefixes. For example, for host names starting
+with "ftp." curl will assume you want to speak FTP.
+
+curl will do its best to use what you pass to it as a URL. It is not trying to
+validate it as a syntactically correct URL by any means but is instead
+\fBvery\fP liberal with what it accepts.
+
+curl will attempt to re-use connections for multiple file transfers, so that
+getting many files from the same server will not do multiple connects /
+handshakes. This improves speed. Of course this is only done on files
+specified on a single command line and cannot be used between separate curl
+invokes.
+.SH "PROGRESS METER"
+curl normally displays a progress meter during operations, indicating the
+amount of transferred data, transfer speeds and estimated time left, etc.
+
+curl displays this data to the terminal by default, so if you invoke curl to
+do an operation and it is about to write data to the terminal, it
+\fIdisables\fP the progress meter as otherwise it would mess up the output
+mixing progress meter and response data.
+
+If you want a progress meter for HTTP POST or PUT requests, you need to
+redirect the response output to a file, using shell redirect (>), -o [file] or
+similar.
+
+It is not the same case for FTP upload as that operation does not spit out
+any response data to the terminal.
+
+If you prefer a progress "bar" instead of the regular meter, \fI-#\fP is your
+friend.
+.SH OPTIONS
+In general, all boolean options are enabled with --\fBoption\fP and yet again
+disabled with --\fBno-\fPoption. That is, you use the exact same option name
+but prefix it with "no-". However, in this list we mostly only list and show
+the --option version of them. (This concept with --no options was added in
+7.19.0. Previously most options were toggled on/off on repeated use of the
+same command line option.)
+.IP "-#, --progress-bar"
+Make curl display progress as a simple progress bar instead of the standard,
+more informational, meter.
+.IP "-0, --http1.0"
+(HTTP) Forces curl to issue its requests using HTTP 1.0 instead of using its
+internally preferred: HTTP 1.1.
+.IP "-1, --tlsv1"
+(SSL)
+Forces curl to use TLS version 1 when negotiating with a remote TLS server.
+.IP "-2, --sslv2"
+(SSL)
+Forces curl to use SSL version 2 when negotiating with a remote SSL server.
+.IP "-3, --sslv3"
+(SSL)
+Forces curl to use SSL version 3 when negotiating with a remote SSL server.
+.IP "-4, --ipv4"
+If curl is capable of resolving an address to multiple IP versions (which it
+is if it is IPv6-capable), this option tells curl to resolve names to IPv4
+addresses only.
+.IP "-6, --ipv6"
+If curl is capable of resolving an address to multiple IP versions (which it
+is if it is IPv6-capable), this option tells curl to resolve names to IPv6
+addresses only.
+.IP "-a, --append"
+(FTP/SFTP) When used in an upload, this will tell curl to append to the target
+file instead of overwriting it. If the file doesn't exist, it will be created.
+Note that this flag is ignored by some SSH servers (including OpenSSH).
+.IP "-A, --user-agent <agent string>"
+(HTTP) Specify the User-Agent string to send to the HTTP server. Some badly
+done CGIs fail if this field isn't set to "Mozilla/4.0". To encode blanks in
+the string, surround the string with single quote marks. This can also be set
+with the \fI-H, --header\fP option of course.
+
+If this option is used several times, the last one will be used.
+.IP "--anyauth"
+(HTTP) Tells curl to figure out authentication method by itself, and use the
+most secure one the remote site claims to support. This is done by first
+doing a request and checking the response-headers, thus possibly inducing an
+extra network round-trip. This is used instead of setting a specific
+authentication method, which you can do with \fI--basic\fP, \fI--digest\fP,
+\fI--ntlm\fP, and \fI--negotiate\fP.
+
+Note that using --anyauth is not recommended if you do uploads from stdin,
+since it may require data to be sent twice and then the client must be able to
+rewind. If the need should arise when uploading from stdin, the upload
+operation will fail.
+.IP "-b, --cookie <name=data>"
+(HTTP)
+Pass the data to the HTTP server as a cookie. It is supposedly the
+data previously received from the server in a "Set-Cookie:" line.
+The data should be in the format "NAME1=VALUE1; NAME2=VALUE2".
+
+If no '=' symbol is used in the line, it is treated as a filename to use to
+read previously stored cookie lines from, which should be used in this session
+if they match. Using this method also activates the "cookie parser" which will
+make curl record incoming cookies too, which may be handy if you're using this
+in combination with the \fI-L, --location\fP option. The file format of the
+file to read cookies from should be plain HTTP headers or the Netscape/Mozilla
+cookie file format.
+
+\fBNOTE\fP that the file specified with \fI-b, --cookie\fP is only used as
+input. No cookies will be stored in the file. To store cookies, use the
+\fI-c, --cookie-jar\fP option or you could even save the HTTP headers to a file
+using \fI-D, --dump-header\fP!
+
+If this option is used several times, the last one will be used.
+.IP "-B, --use-ascii"
+(FTP/LDAP) Enable ASCII transfer. For FTP, this can also be
+enforced by using an URL that ends with ";type=A". This option causes data
+sent to stdout to be in text mode for win32 systems.
+.IP "--basic"
+(HTTP) Tells curl to use HTTP Basic authentication. This is the default and
+this option is usually pointless, unless you use it to override a previously
+set option that sets a different authentication method (such as \fI--ntlm\fP,
+\fI--digest\fP, or \fI--negotiate\fP).
+.IP "-c, --cookie-jar <file name>"
+(HTTP) Specify to which file you want curl to write all cookies after a
+completed operation. Curl writes all cookies previously read from a specified
+file as well as all cookies received from remote server(s). If no cookies are
+known, no file will be written. The file will be written using the Netscape
+cookie file format. If you set the file name to a single dash, "-", the
+cookies will be written to stdout.
+
+This command line option will activate the cookie engine that makes curl
+record and use cookies. Another way to activate it is to use the \fI-b,
+--cookie\fP option.
+
+If the cookie jar can't be created or written to, the whole curl operation
+won't fail or even report an error clearly. Using -v will get a warning
+displayed, but that is the only visible feedback you get about this possibly
+lethal situation.
+
+If this option is used several times, the last specified file name will be
+used.
+.IP "-C, --continue-at <offset>"
+Continue/Resume a previous file transfer at the given offset. The given offset
+is the exact number of bytes that will be skipped, counting from the beginning
+of the source file before it is transferred to the destination. If used with
+uploads, the FTP server command SIZE will not be used by curl.
+
+Use "-C -" to tell curl to automatically find out where/how to resume the
+transfer. It then uses the given output/input files to figure that out.
+
+If this option is used several times, the last one will be used.
+.IP "--ciphers <list of ciphers>"
+(SSL) Specifies which ciphers to use in the connection. The list of ciphers
+must specify valid ciphers. Read up on SSL cipher list details on this URL:
+\fIhttp://www.openssl.org/docs/apps/ciphers.html\fP
+
+NSS ciphers are done differently than OpenSSL and GnuTLS. The full list of NSS
+ciphers is in the NSSCipherSuite entry at this URL:
+\fIhttp://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html#Directives\fP
+
+If this option is used several times, the last one will be used.
+.IP "--compressed"
+(HTTP) Request a compressed response using one of the algorithms curl
+supports, and save the uncompressed document. If this option is used and the
+server sends an unsupported encoding, curl will report an error.
+.IP "--connect-timeout <seconds>"
+Maximum time in seconds that you allow the connection to the server to take.
+This only limits the connection phase, once curl has connected this option is
+of no more use. See also the \fI-m, --max-time\fP option.
+
+If this option is used several times, the last one will be used.
+.IP "--create-dirs"
+When used in conjunction with the \fI-o\fP option, curl will create the
+necessary local directory hierarchy as needed. This option creates the dirs
+mentioned with the \fI-o\fP option, nothing else. If the \fI-o\fP file name
+uses no dir or if the dirs it mentions already exist, no dir will be created.
+
+To create remote directories when using FTP or SFTP, try
+\fI--ftp-create-dirs\fP.
+.IP "--crlf"
+(FTP) Convert LF to CRLF in upload. Useful for MVS (OS/390).
+.IP "--crlfile <file>"
+(HTTPS/FTPS) Provide a file using PEM format with a Certificate Revocation
+List that may specify peer certificates that are to be considered revoked.
+
+If this option is used several times, the last one will be used.
+
+(Added in 7.19.7)
+.IP "-d, --data <data>"
+(HTTP) Sends the specified data in a POST request to the HTTP server, in the
+same way that a browser does when a user has filled in an HTML form and
+presses the submit button. This will cause curl to pass the data to the server
+using the content-type application/x-www-form-urlencoded. Compare to
+\fI-F, --form\fP.
+
+\fI-d, --data\fP is the same as \fI--data-ascii\fP. To post data purely binary,
+you should instead use the \fI--data-binary\fP option. To URL-encode the value
+of a form field you may use \fI--data-urlencode\fP.
+
+If any of these options is used more than once on the same command line, the
+data pieces specified will be merged together with a separating
+&-symbol. Thus, using '-d name=daniel -d skill=lousy' would generate a post
+chunk that looks like \&'name=daniel&skill=lousy'.
+
+If you start the data with the letter @, the rest should be a file name to
+read the data from, or - if you want curl to read the data from stdin. The
+contents of the file must already be URL-encoded. Multiple files can also be
+specified. Posting data from a file named 'foobar' would thus be done with
+\fI--data @foobar\fP.
+.IP "-D, --dump-header <file>"
+Write the protocol headers to the specified file.
+
+This option is handy to use when you want to store the headers that an HTTP
+site sends to you. Cookies from the headers could then be read in a second
+curl invocation by using the \fI-b, --cookie\fP option! The
+\fI-c, --cookie-jar\fP option is however a better way to store cookies.
+
+When used in FTP, the FTP server response lines are considered being "headers"
+and thus are saved there.
+
+If this option is used several times, the last one will be used.
+
+.IP "--data-ascii <data>"
+See \fI-d, --data\fP.
+.IP "--data-binary <data>"
+(HTTP) This posts data exactly as specified with no extra processing
+whatsoever.
+
+If you start the data with the letter @, the rest should be a filename. Data
+is posted in a similar manner as \fI--data-ascii\fP does, except that newlines
+are preserved and conversions are never done.
+
+If this option is used several times, the ones following the first will append
+data as described in \fI-d, --data\fP.
+.IP "--data-urlencode <data>"
+(HTTP) This posts data, similar to the other --data options with the exception
+that this performs URL-encoding. (Added in 7.18.0)
+
+To be CGI-compliant, the <data> part should begin with a \fIname\fP followed
+by a separator and a content specification. The <data> part can be passed to
+curl using one of the following syntaxes:
+.RS
+.IP "content"
+This will make curl URL-encode the content and pass that on. Just be careful
+so that the content doesn't contain any = or @ symbols, as that will then make
+the syntax match one of the other cases below!
+.IP "=content"
+This will make curl URL-encode the content and pass that on. The preceding =
+symbol is not included in the data.
+.IP "name=content"
+This will make curl URL-encode the content part and pass that on. Note that
+the name part is expected to be URL-encoded already.
+.IP "@filename"
+This will make curl load data from the given file (including any newlines),
+URL-encode that data and pass it on in the POST.
+.IP "name@filename"
+This will make curl load data from the given file (including any newlines),
+URL-encode that data and pass it on in the POST. The name part gets an equal
+sign appended, resulting in \fIname=urlencoded-file-content\fP. Note that the
+name is expected to be URL-encoded already.
+.RE
+.IP "--delegation LEVEL"
+Set \fILEVEL\fP to tell the server what it is allowed to delegate when it
+comes to user credentials. Used with GSS/kerberos.
+.RS
+.IP "none"
+Don't allow any delegation.
+.IP "policy"
+Delegates if and only if the OK-AS-DELEGATE flag is set in the Kerberos
+service ticket, which is a matter of realm policy.
+.IP "always"
+Unconditionally allow the server to delegate.
+.RE
+.IP "--digest"
+(HTTP) Enables HTTP Digest authentication. This is an authentication scheme
+that prevents the password from being sent over the wire in clear text. Use
+this in combination with the normal \fI-u, --user\fP option to set user name
+and password. See also \fI--ntlm\fP, \fI--negotiate\fP and \fI--anyauth\fP for
+related options.
+
+If this option is used several times, only the first one is used.
+.IP "--disable-eprt"
+(FTP) Tell curl to disable the use of the EPRT and LPRT commands when doing
+active FTP transfers. Curl will normally always first attempt to use EPRT,
+then LPRT before using PORT, but with this option, it will use PORT right
+away. EPRT and LPRT are extensions to the original FTP protocol, and may not
+work on all servers, but they enable more functionality in a better way than
+the traditional PORT command.
+
+\fB--eprt\fP can be used to explicitly enable EPRT again and \fB--no-eprt\fP
+is an alias for \fB--disable-eprt\fP.
+
+Disabling EPRT only changes the active behavior. If you want to switch to
+passive mode you need to not use \fI-P, --ftp-port\fP or force it with
+\fI--ftp-pasv\fP.
+.IP "--disable-epsv"
+(FTP) Tell curl to disable the use of the EPSV command when doing passive FTP
+transfers. Curl will normally always first attempt to use EPSV before PASV,
+but with this option, it will not try using EPSV.
+
+\fB--epsv\fP can be used to explicitly enable EPSV again and \fB--no-epsv\fP
+is an alias for \fB--disable-epsv\fP.
+
+Disabling EPSV only changes the passive behavior. If you want to switch to
+active mode you need to use \fI-P, --ftp-port\fP.
+.IP "-e, --referer <URL>"
+(HTTP) Sends the "Referer Page" information to the HTTP server. This can also
+be set with the \fI-H, --header\fP flag of course. When used with
+\fI-L, --location\fP you can append ";auto" to the --referer URL to make curl
+automatically set the previous URL when it follows a Location: header. The
+\&";auto" string can be used alone, even if you don't set an initial --referer.
+
+If this option is used several times, the last one will be used.
+.IP "-E, --cert <certificate[:password]>"
+(SSL) Tells curl to use the specified client certificate file when getting a
+file with HTTPS, FTPS or another SSL-based protocol. The certificate must be
+in PEM format. If the optional password isn't specified, it will be queried
+for on the terminal. Note that this option assumes a \&"certificate" file that
+is the private key and the private certificate concatenated! See \fI--cert\fP
+and \fI--key\fP to specify them independently.
+
+If curl is built against the NSS SSL library then this option can tell
+curl the nickname of the certificate to use within the NSS database defined
+by the environment variable SSL_DIR (or by default /etc/pki/nssdb). If the
+NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files may be
+loaded. If you want to use a file from the current directory, please precede
+it with "./" prefix, in order to avoid confusion with a nickname.
+
+If this option is used several times, the last one will be used.
+.IP "--engine <name>"
+Select the OpenSSL crypto engine to use for cipher
+operations. Use \fI--engine list\fP to print a list of build-time supported
+engines. Note that not all (or none) of the engines may be available at
+run-time.
+.IP "--environment"
+(RISC OS ONLY) Sets a range of environment variables, using the names the
+\fI-w\fP option supports, to allow easier extraction of useful information
+after having run curl.
+.IP "--egd-file <file>"
+(SSL) Specify the path name to the Entropy Gathering Daemon socket. The socket
+is used to seed the random engine for SSL connections. See also the
+\fI--random-file\fP option.
+.IP "--cert-type <type>"
+(SSL) Tells curl what certificate type the provided certificate is in. PEM,
+DER and ENG are recognized types. If not specified, PEM is assumed.
+
+If this option is used several times, the last one will be used.
+.IP "--cacert <CA certificate>"
+(SSL) Tells curl to use the specified certificate file to verify the peer. The
+file may contain multiple CA certificates. The certificate(s) must be in PEM
+format. Normally curl is built to use a default file for this, so this option
+is typically used to alter that default file.
+
+curl recognizes the environment variable named 'CURL_CA_BUNDLE' if it is
+set, and uses the given path as a path to a CA cert bundle. This option
+overrides that variable.
+
+The windows version of curl will automatically look for a CA certs file named
+\'curl-ca-bundle.crt\', either in the same directory as curl.exe, or in the
+Current Working Directory, or in any folder along your PATH.
+
+If curl is built against the NSS SSL library then this option tells
+curl the nickname of the CA certificate to use within the NSS database
+defined by the environment variable SSL_DIR (or by default /etc/pki/nssdb).
+If the NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files
+may be loaded.
+
+If this option is used several times, the last one will be used.
+.IP "--capath <CA certificate directory>"
+(SSL) Tells curl to use the specified certificate directory to verify the
+peer. Multiple paths can be provided by separating them with ":" (e.g.
+\&"path1:path2:path3"). The certificates must be in PEM format, and if curl is
+built against OpenSSL, the directory must have been processed using the
+c_rehash utility supplied with OpenSSL. Using \fI--capath\fP can allow
+OpenSSL-powered curl to make SSL-connections much more efficiently than using
+\fI--cacert\fP if the \fI--cacert\fP file contains many CA certificates.
+
+If this option is set, the default capath value will be ignored, and if it is
+used several times, the last one will be used.
+.IP "-f, --fail"
+(HTTP) Fail silently (no output at all) on server errors. This is mostly done
+to better enable scripts etc to better deal with failed attempts. In
+normal cases when an HTTP server fails to deliver a document, it returns an
+HTML document stating so (which often also describes why and more). This flag
+will prevent curl from outputting that and return error 22.
+
+This method is not fail-safe and there are occasions where non-successful
+response codes will slip through, especially when authentication is involved
+(response codes 401 and 407).
+.IP "-F, --form <name=content>"
+(HTTP) This lets curl emulate a filled-in form in which a user has pressed the
+submit button. This causes curl to POST data using the Content-Type
+multipart/form-data according to RFC 2388. This enables uploading of binary
+files etc. To force the 'content' part to be a file, prefix the file name
+with an @ sign. To just get the content part from a file, prefix the file name
+with the symbol <. The difference between @ and < is then that @ makes a file
+get attached in the post as a file upload, while the < makes a text field and
+just get the contents for that text field from a file.
+
+Example, to send your password file to the server, where
+\&'password' is the name of the form-field to which /etc/passwd will be the
+input:
+
+\fBcurl\fP -F password=@/etc/passwd www.mypasswords.com
+
+To read content from stdin instead of a file, use - as the filename. This goes
+for both @ and < constructs.
+
+You can also tell curl what Content-Type to use by using 'type=', in a manner
+similar to:
+
+\fBcurl\fP -F "web=@index.html;type=text/html" url.com
+
+or
+
+\fBcurl\fP -F "name=daniel;type=text/foo" url.com
+
+You can also explicitly change the name field of a file upload part by setting
+filename=, like this:
+
+\fBcurl\fP -F "file=@localfile;filename=nameinpost" url.com
+
+See further examples and details in the MANUAL.
+
+This option can be used multiple times.
+.IP "--ftp-account [data]"
+(FTP) When an FTP server asks for "account data" after user name and password
+has been provided, this data is sent off using the ACCT command. (Added in
+7.13.0)
+
+If this option is used several times, the last one will be used.
+.IP "--ftp-alternative-to-user <command>"
+(FTP) If authenticating with the USER and PASS commands fails, send this
+command. When connecting to Tumbleweed's Secure Transport server over FTPS
+using a client certificate, using "SITE AUTH" will tell the server to retrieve
+the username from the certificate. (Added in 7.15.5)
+.IP "--ftp-create-dirs"
+(FTP/SFTP) When an FTP or SFTP URL/operation uses a path that doesn't
+currently exist on the server, the standard behavior of curl is to
+fail. Using this option, curl will instead attempt to create missing
+directories.
+.IP "--ftp-method [method]"
+(FTP) Control what method curl should use to reach a file on an FTP(S)
+server. The method argument should be one of the following alternatives:
+.RS
+.IP multicwd
+curl does a single CWD operation for each path part in the given URL. For deep
+hierarchies this means very many commands. This is how RFC 1738 says it should
+be done. This is the default but the slowest behavior.
+.IP nocwd
+curl does no CWD at all. curl will do SIZE, RETR, STOR etc and give a full
+path to the server for all these commands. This is the fastest behavior.
+.IP singlecwd
+curl does one CWD with the full target directory and then operates on the file
+\&"normally" (like in the multicwd case). This is somewhat more standards
+compliant than 'nocwd' but without the full penalty of 'multicwd'.
+.RE
+(Added in 7.15.1)
+.IP "--ftp-pasv"
+(FTP) Use passive mode for the data connection. Passive is the internal default
+behavior, but using this option can be used to override a previous
+\fI-P/-ftp-port\fP option. (Added in 7.11.0)
+
+If this option is used several times, only the first one is used. Undoing an
+enforced passive really isn't doable but you must then instead enforce the
+correct \fI-P, --ftp-port\fP again.
+
+Passive mode means that curl will try the EPSV command first and then PASV,
+unless \fI--disable-epsv\fP is used.
+.IP "--ftp-skip-pasv-ip"
+(FTP) Tell curl to not use the IP address the server suggests in its response
+to curl's PASV command when curl connects the data connection. Instead curl
+will re-use the same IP address it already uses for the control
+connection. (Added in 7.14.2)
+
+This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
+.IP "--ftp-pret"
+(FTP) Tell curl to send a PRET command before PASV (and EPSV). Certain
+FTP servers, mainly drftpd, require this non-standard command for
+directory listings as well as up and downloads in PASV mode.
+(Added in 7.20.x)
+.IP "--ftp-ssl-ccc"
+(FTP) Use CCC (Clear Command Channel)
+Shuts down the SSL/TLS layer after authenticating. The rest of the
+control channel communication will be unencrypted. This allows
+NAT routers to follow the FTP transaction. The default mode is
+passive. See \fI--ftp-ssl-ccc-mode\fP for other modes.
+(Added in 7.16.1)
+.IP "--ftp-ssl-ccc-mode [active/passive]"
+(FTP) Use CCC (Clear Command Channel)
+Sets the CCC mode. The passive mode will not initiate the shutdown, but
+instead wait for the server to do it, and will not reply to the
+shutdown from the server. The active mode initiates the shutdown and
+waits for a reply from the server.
+(Added in 7.16.2)
+.IP "--ftp-ssl-control"
+(FTP) Require SSL/TLS for the FTP login, clear for transfer. Allows secure
+authentication, but non-encrypted data transfers for efficiency. Fails the
+transfer if the server doesn't support SSL/TLS. (Added in 7.16.0)
+that can still be used but will be removed in a future version.
+.IP "--form-string <name=string>"
+(HTTP) Similar to \fI--form\fP except that the value string for the named
+parameter is used literally. Leading \&'@' and \&'<' characters, and the
+\&';type=' string in the value have no special meaning. Use this in preference
+to \fI--form\fP if there's any possibility that the string value may
+accidentally trigger the \&'@' or \&'<' features of \fI--form\fP.
+.IP "-g, --globoff"
+This option switches off the "URL globbing parser". When you set this option,
+you can specify URLs that contain the letters {}[] without having them being
+interpreted by curl itself. Note that these letters are not normal legal URL
+contents but they should be encoded according to the URI standard.
+.IP "-G, --get"
+When used, this option will make all data specified with \fI-d, --data\fP or
+\fI--data-binary\fP to be used in an HTTP GET request instead of the POST
+request that otherwise would be used. The data will be appended to the URL
+with a '?' separator.
+
+If used in combination with -I, the POST data will instead be appended to the
+URL with a HEAD request.
+
+If this option is used several times, only the first one is used. This is
+because undoing a GET doesn't make sense, but you should then instead enforce
+the alternative method you prefer.
+.IP "-H, --header <header>"
+(HTTP) Extra header to use when getting a web page. You may specify any number
+of extra headers. Note that if you should add a custom header that has the
+same name as one of the internal ones curl would use, your externally set
+header will be used instead of the internal one. This allows you to make even
+trickier stuff than curl would normally do. You should not replace internally
+set headers without knowing perfectly well what you're doing. Remove an
+internal header by giving a replacement without content on the right side of
+the colon, as in: -H \&"Host:". If you send the custom header with no-value
+then its header must be terminated with a semicolon, such as \-H
+\&"X-Custom-Header;" to send "X-Custom-Header:".
+
+curl will make sure that each header you add/replace is sent with the proper
+end-of-line marker, you should thus \fBnot\fP add that as a part of the header
+content: do not add newlines or carriage returns, they will only mess things up
+for you.
+
+See also the \fI-A, --user-agent\fP and \fI-e, --referer\fP options.
+
+This option can be used multiple times to add/replace/remove multiple headers.
+.IP "--hostpubmd5 <md5>"
+(SCP/SFTP) Pass a string containing 32 hexadecimal digits. The string should
+be the 128 bit MD5 checksum of the remote host's public key, curl will refuse
+the connection with the host unless the md5sums match. (Added in 7.17.1)
+.IP "--ignore-content-length"
+(HTTP)
+Ignore the Content-Length header. This is particularly useful for servers
+running Apache 1.x, which will report incorrect Content-Length for files
+larger than 2 gigabytes.
+.IP "-i, --include"
+(HTTP) Include the HTTP-header in the output. The HTTP-header includes things
+like server-name, date of the document, HTTP-version and more...
+.IP "-I, --head"
+(HTTP/FTP/FILE)
+Fetch the HTTP-header only! HTTP-servers feature the command HEAD
+which this uses to get nothing but the header of a document. When used
+on an FTP or FILE file, curl displays the file size and last modification
+time only.
+.IP "--interface <name>"
+Perform an operation using a specified interface. You can enter interface
+name, IP address or host name. An example could look like:
+
+ curl --interface eth0:1 http://www.netscape.com/
+
+If this option is used several times, the last one will be used.
+.IP "-j, --junk-session-cookies"
+(HTTP) When curl is told to read cookies from a given file, this option will
+make it discard all "session cookies". This will basically have the same effect
+as if a new session is started. Typical browsers always discard session
+cookies when they're closed down.
+.IP "-J, --remote-header-name"
+(HTTP) This option tells the \fI-O, --remote-name\fP option to use the
+server-specified Content-Disposition filename instead of extracting a filename
+from the URL.
+.IP "-k, --insecure"
+(SSL) This option explicitly allows curl to perform "insecure" SSL connections
+and transfers. All SSL connections are attempted to be made secure by using
+the CA certificate bundle installed by default. This makes all connections
+considered "insecure" fail unless \fI-k, --insecure\fP is used.
+
+See this online resource for further details:
+\fBhttp://curl.haxx.se/docs/sslcerts.html\fP
+.IP "-K, --config <config file>"
+Specify which config file to read curl arguments from. The config file is a
+text file in which command line arguments can be written which then will be
+used as if they were written on the actual command line. Options and their
+parameters must be specified on the same config file line, separated by
+whitespace, colon, the equals sign or any combination thereof (however,
+the preferred separator is the equals sign). If the parameter is to contain
+whitespace, the parameter must be enclosed within quotes. Within double
+quotes, the following escape sequences are available: \\\\, \\", \\t, \\n,
+\\r and \\v. A backslash preceding any other letter is ignored. If the
+first column of a config line is a '#' character, the rest of the line will be
+treated as a comment. Only write one option per physical line in the config
+file.
+
+Specify the filename to -K, --config as '-' to make curl read the file from
+stdin.
+
+Note that to be able to specify a URL in the config file, you need to specify
+it using the \fI--url\fP option, and not by simply writing the URL on its own
+line. So, it could look similar to this:
+
+url = "http://curl.haxx.se/docs/"
+
+Long option names can optionally be given in the config file without the
+initial double dashes.
+
+When curl is invoked, it always (unless \fI-q\fP is used) checks for a default
+config file and uses it if found. The default config file is checked for in
+the following places in this order:
+
+1) curl tries to find the "home dir": It first checks for the CURL_HOME and
+then the HOME environment variables. Failing that, it uses getpwuid() on
+UNIX-like systems (which returns the home dir given the current user in your
+system). On Windows, it then checks for the APPDATA variable, or as a last
+resort the '%USERPROFILE%\\Application Data'.
+
+2) On windows, if there is no _curlrc file in the home dir, it checks for one
+in the same dir the curl executable is placed. On UNIX-like systems, it will
+simply try to load .curlrc from the determined home dir.
+
+.nf
+# --- Example file ---
+# this is a comment
+url = "curl.haxx.se"
+output = "curlhere.html"
+user-agent = "superagent/1.0"
+
+# and fetch another URL too
+url = "curl.haxx.se/docs/manpage.html"
+-O
+referer = "http://nowhereatall.com/"
+# --- End of example file ---
+.fi
+
+This option can be used multiple times to load multiple config files.
+.IP "--keepalive-time <seconds>"
+This option sets the time a connection needs to remain idle before sending
+keepalive probes and the time between individual keepalive probes. It is
+currently effective on operating systems offering the TCP_KEEPIDLE and
+TCP_KEEPINTVL socket options (meaning Linux, recent AIX, HP-UX and more). This
+option has no effect if \fI--no-keepalive\fP is used. (Added in 7.18.0)
+
+If this option is used several times, the last one will be used. If
+unspecified, the option defaults to 60 seconds.
+.IP "--key <key>"
+(SSL/SSH) Private key file name. Allows you to provide your private key in this
+separate file.
+
+If this option is used several times, the last one will be used.
+.IP "--key-type <type>"
+(SSL) Private key file type. Specify which type your \fI--key\fP provided
+private key is. DER, PEM, and ENG are supported. If not specified, PEM is
+assumed.
+
+If this option is used several times, the last one will be used.
+.IP "--krb <level>"
+(FTP) Enable Kerberos authentication and use. The level must be entered and
+should be one of 'clear', 'safe', 'confidential', or 'private'. Should you use
+a level that is not one of these, 'private' will instead be used.
+
+This option requires a library built with kerberos4 or GSSAPI
+(GSS-Negotiate) support. This is not very common. Use \fI-V, --version\fP to
+see if your curl supports it.
+
+If this option is used several times, the last one will be used.
+.IP "-l, --list-only"
+(FTP)
+When listing an FTP directory, this switch forces a name-only view.
+Especially useful if you want to machine-parse the contents of an FTP
+directory since the normal directory view doesn't use a standard look
+or format.
+
+This option causes an FTP NLST command to be sent. Some FTP servers
+list only files in their response to NLST; they do not include
+subdirectories and symbolic links.
+
+.IP "-L, --location"
+(HTTP/HTTPS) If the server reports that the requested page has moved to a
+different location (indicated with a Location: header and a 3XX response code),
+this option will make curl redo the request on the new place. If used together
+with \fI-i, --include\fP or \fI-I, --head\fP, headers from all requested pages
+will be shown. When authentication is used, curl only sends its credentials to
+the initial host. If a redirect takes curl to a different host, it won't be
+able to intercept the user+password. See also \fI--location-trusted\fP on how
+to change this. You can limit the amount of redirects to follow by using the
+\fI--max-redirs\fP option.
+
+When curl follows a redirect and the request is not a plain GET (for example
+POST or PUT), it will do the following request with a GET if the HTTP response
+was 301, 302, or 303. If the response code was any other 3xx code, curl will
+re-send the following request using the same unmodified method.
+.IP "--libcurl <file>"
+Append this option to any ordinary curl command line, and you will get a
+libcurl-using C source code written to the file that does the equivalent
+of what your command-line operation does!
+
+If this option is used several times, the last given file name will be
+used. (Added in 7.16.1)
+.IP "--limit-rate <speed>"
+Specify the maximum transfer rate you want curl to use. This feature is useful
+if you have a limited pipe and you'd like your transfer not to use your entire
+bandwidth.
+
+The given speed is measured in bytes/second, unless a suffix is appended.
+Appending 'k' or 'K' will count the number as kilobytes, 'm' or M' makes it
+megabytes, while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G.
+
+The given rate is the average speed counted during the entire transfer. It
+means that curl might use higher transfer speeds in short bursts, but over
+time it uses no more than the given rate.
+
+If you also use the \fI-Y, --speed-limit\fP option, that option will take
+precedence and might cripple the rate-limiting slightly, to help keeping the
+speed-limit logic working.
+
+If this option is used several times, the last one will be used.
+.IP "--local-port <num>[-num]"
+Set a preferred number or range of local port numbers to use for the
+connection(s). Note that port numbers by nature are a scarce resource that
+will be busy at times so setting this range to something too narrow might
+cause unnecessary connection setup failures. (Added in 7.15.2)
+.IP "--location-trusted"
+(HTTP/HTTPS) Like \fI-L, --location\fP, but will allow sending the name +
+password to all hosts that the site may redirect to. This may or may not
+introduce a security breach if the site redirects you to a site to which
+you'll send your authentication info (which is plaintext in the case of HTTP
+Basic authentication).
+.IP "-m, --max-time <seconds>"
+Maximum time in seconds that you allow the whole operation to take. This is
+useful for preventing your batch jobs from hanging for hours due to slow
+networks or links going down. See also the \fI--connect-timeout\fP option.
+
+If this option is used several times, the last one will be used.
+.IP "--mail-auth <address>"
+(SMTP) Specify a single address. This will be used to specify the
+authentication address (identity) of a submitted message that is being relayed
+to another server.
+
+(Added in 7.25.0)
+.IP "--mail-from <address>"
+(SMTP) Specify a single address that the given mail should get sent from.
+
+(Added in 7.20.0)
+.IP "--max-filesize <bytes>"
+Specify the maximum size (in bytes) of a file to download. If the file
+requested is larger than this value, the transfer will not start and curl will
+return with exit code 63.
+
+\fBNOTE:\fP The file size is not always known prior to download, and for such
+files this option has no effect even if the file transfer ends up being larger
+than this given limit. This concerns both FTP and HTTP transfers.
+.IP "--mail-rcpt <address>"
+(SMTP) Specify a single address that the given mail should get sent to. This
+option can be used multiple times to specify many recipients.
+
+(Added in 7.20.0)
+.IP "--max-redirs <num>"
+Set maximum number of redirection-followings allowed. If \fI-L, --location\fP
+is used, this option can be used to prevent curl from following redirections
+\&"in absurdum". By default, the limit is set to 50 redirections. Set this
+option to -1 to make it limitless.
+
+If this option is used several times, the last one will be used.
+.IP "--metalink"
+This option can tell curl to parse and process a given URI as Metalink file
+(both version 3 and 4 (RFC 5854) are supported) and make use of the mirrors
+listed within for failover if there are errors (such as the file or server not
+being available). It will also verify the hash of the file after the download
+completes. The Metalink file itself is downloaded and processed in memory and
+not stored in the local file system.
+
+Example to use a remote Metalink file:
+
+\fBcurl\fP --metalink http://www.example.com/example.metalink
+
+To use a Metalink file in the local file system, use FILE protocol
+(file://):
+
+\fBcurl\fP --metalink file://example.metalink
+
+Please note that if FILE protocol is disabled, there is no way to use
+a local Metalink file at the time of this writing. Also note that if
+\fI--metalink\fP and \fI--include\fP are used together, \fI--include\fP will be
+ignored. This is because including headers in the response will break
+Metalink parser and if the headers are included in the file described
+in Metalink file, hash check will fail.
+
+(Added in 7.27.0, if built against the libmetalink library.)
+.IP "-n, --netrc"
+Makes curl scan the \fI.netrc\fP (\fI_netrc\fP on Windows) file in the user's
+home directory for login name and password. This is typically used for FTP on
+UNIX. If used with HTTP, curl will enable user authentication. See
+.BR netrc(4)
+or
+.BR ftp(1)
+for details on the file format. Curl will not complain if that file
+doesn't have the right permissions (it should not be either world- or
+group-readable). The environment variable "HOME" is used to find the home
+directory.
+
+A quick and very simple example of how to setup a \fI.netrc\fP to allow curl
+to FTP to the machine host.domain.com with user name \&'myself' and password
+\&'secret' should look similar to:
+
+.B "machine host.domain.com login myself password secret"
+.IP "-N, --no-buffer"
+Disables the buffering of the output stream. In normal work situations, curl
+will use a standard buffered output stream that will have the effect that it
+will output the data in chunks, not necessarily exactly when the data arrives.
+Using this option will disable that buffering.
+
+Note that this is the negated option name documented. You can thus use
+\fI--buffer\fP to enforce the buffering.
+.IP "--netrc-file"
+This option is similar to \fI--netrc\fP, except that you provide the path
+(absolute or relative) to the netrc file that Curl should use.
+You can only specify one netrc file per invocation. If several
+\fI--netrc-file\fP options are provided, only the \fBlast one\fP will be used.
+(Added in 7.21.5)
+
+This option overrides any use of \fI--netrc\fP as they are mutually exclusive.
+It will also abide by \fI--netrc-optional\fP if specified.
+
+.IP "--netrc-optional"
+Very similar to \fI--netrc\fP, but this option makes the .netrc usage
+\fBoptional\fP and not mandatory as the \fI--netrc\fP option does.
+
+.IP "--negotiate"
+(HTTP) Enables GSS-Negotiate authentication. The GSS-Negotiate method was
+designed by Microsoft and is used in their web applications. It is primarily
+meant as a support for Kerberos5 authentication but may be also used along
+with another authentication method. For more information see IETF draft
+draft-brezak-spnego-http-04.txt.
+
+If you want to enable Negotiate for your proxy authentication, then use
+\fI--proxy-negotiate\fP.
+
+This option requires a library built with GSSAPI support. This is
+not very common. Use \fI-V, --version\fP to see if your version supports
+GSS-Negotiate.
+
+When using this option, you must also provide a fake \fI-u, --user\fP option to
+activate the authentication code properly. Sending a '-u :' is enough as the
+user name and password from the \fI-u\fP option aren't actually used.
+
+If this option is used several times, only the first one is used.
+.IP "--no-keepalive"
+Disables the use of keepalive messages on the TCP connection, as by default
+curl enables them.
+
+Note that this is the negated option name documented. You can thus use
+\fI--keepalive\fP to enforce keepalive.
+.IP "--no-sessionid"
+(SSL) Disable curl's use of SSL session-ID caching. By default all transfers
+are done using the cache. Note that while nothing should ever get hurt by
+attempting to reuse SSL session-IDs, there seem to be broken SSL
+implementations in the wild that may require you to disable this in order for
+you to succeed. (Added in 7.16.0)
+
+Note that this is the negated option name documented. You can thus use
+\fI--sessionid\fP to enforce session-ID caching.
+.IP "--noproxy <no-proxy-list>"
+Comma-separated list of hosts which do not use a proxy, if one is specified.
+The only wildcard is a single * character, which matches all hosts, and
+effectively disables the proxy. Each name in this list is matched as either
+a domain which contains the hostname, or the hostname itself. For example,
+local.com would match local.com, local.com:80, and www.local.com, but not
+www.notlocal.com. (Added in 7.19.4).
+.IP "--ntlm"
+(HTTP) Enables NTLM authentication. The NTLM authentication method was
+designed by Microsoft and is used by IIS web servers. It is a proprietary
+protocol, reverse-engineered by clever people and implemented in curl based
+on their efforts. This kind of behavior should not be endorsed, you should
+encourage everyone who uses NTLM to switch to a public and documented
+authentication method instead, such as Digest.
+
+If you want to enable NTLM for your proxy authentication, then use
+\fI--proxy-ntlm\fP.
+
+This option requires a library built with SSL support. Use
+\fI-V, --version\fP to see if your curl supports NTLM.
+
+If this option is used several times, only the first one is used.
+.IP "-o, --output <file>"
+Write output to <file> instead of stdout. If you are using {} or [] to fetch
+multiple documents, you can use '#' followed by a number in the <file>
+specifier. That variable will be replaced with the current string for the URL
+being fetched. Like in:
+
+ curl http://{one,two}.site.com -o "file_#1.txt"
+
+or use several variables like:
+
+ curl http://{site,host}.host[1-5].com -o "#1_#2"
+
+You may use this option as many times as the number of URLs you have.
+
+See also the \fI--create-dirs\fP option to create the local directories
+dynamically. Specifying the output as '-' (a single dash) will force the
+output to be done to stdout.
+.IP "-O, --remote-name"
+Write output to a local file named like the remote file we get. (Only the file
+part of the remote file is used, the path is cut off.)
+
+The remote file name to use for saving is extracted from the given URL,
+nothing else.
+
+Consequentially, the file will be saved in the current working directory. If
+you want the file saved in a different directory, make sure you change current
+working directory before you invoke curl with the \fB-O, --remote-name\fP flag!
+
+You may use this option as many times as the number of URLs you have.
+.IP "-p, --proxytunnel"
+When an HTTP proxy is used (\fI-x, --proxy\fP), this option will cause non-HTTP
+protocols to attempt to tunnel through the proxy instead of merely using it to
+do HTTP-like operations. The tunnel approach is made with the HTTP proxy
+CONNECT request and requires that the proxy allows direct connect to the
+remote port number curl wants to tunnel through to.
+.IP "-P, --ftp-port <address>"
+(FTP) Reverses the default initiator/listener roles when connecting with
+FTP. This switch makes curl use active mode. In practice, curl then tells the
+server to connect back to the client's specified address and port, while
+passive mode asks the server to setup an IP address and port for it to connect
+to. <address> should be one of:
+.RS
+.IP interface
+i.e "eth0" to specify which interface's IP address you want to use (Unix only)
+.IP "IP address"
+i.e "192.168.10.1" to specify the exact IP address
+.IP "host name"
+i.e "my.host.domain" to specify the machine
+.IP "-"
+make curl pick the same IP address that is already used for the control
+connection
+.RE
+
+If this option is used several times, the last one will be used. Disable the
+use of PORT with \fI--ftp-pasv\fP. Disable the attempt to use the EPRT command
+instead of PORT by using \fI--disable-eprt\fP. EPRT is really PORT++.
+
+Starting in 7.19.5, you can append \&":[start]-[end]\&" to the right of the
+address, to tell curl what TCP port range to use. That means you specify a
+port range, from a lower to a higher number. A single number works as well,
+but do note that it increases the risk of failure since the port may not be
+available.
+.IP "--pass <phrase>"
+(SSL/SSH) Passphrase for the private key
+
+If this option is used several times, the last one will be used.
+.IP "--post301"
+(HTTP) Tells curl to respect RFC 2616/10.3.2 and not convert POST requests
+into GET requests when following a 301 redirection. The non-RFC behaviour is
+ubiquitous in web browsers, so curl does the conversion by default to maintain
+consistency. However, a server may require a POST to remain a POST after such
+a redirection. This option is meaningful only when using \fI-L, --location\fP
+(Added in 7.17.1)
+.IP "--post302"
+(HTTP) Tells curl to respect RFC 2616/10.3.2 and not convert POST requests
+into GET requests when following a 302 redirection. The non-RFC behaviour is
+ubiquitous in web browsers, so curl does the conversion by default to maintain
+consistency. However, a server may require a POST to remain a POST after such
+a redirection. This option is meaningful only when using \fI-L, --location\fP
+(Added in 7.19.1)
+.IP "--proto <protocols>"
+Tells curl to use the listed protocols for its initial retrieval. Protocols
+are evaluated left to right, are comma separated, and are each a protocol
+name or 'all', optionally prefixed by zero or more modifiers. Available
+modifiers are:
+.RS
+.TP 3
+.B +
+Permit this protocol in addition to protocols already permitted (this is
+the default if no modifier is used).
+.TP
+.B -
+Deny this protocol, removing it from the list of protocols already permitted.
+.TP
+.B =
+Permit only this protocol (ignoring the list already permitted), though
+subject to later modification by subsequent entries in the comma separated
+list.
+.RE
+.IP
+For example:
+.RS
+.TP 15
+.B --proto -ftps
+uses the default protocols, but disables ftps
+.TP
+.B --proto -all,https,+http
+only enables http and https
+.TP
+.B --proto =http,https
+also only enables http and https
+.RE
+.IP
+Unknown protocols produce a warning. This allows scripts to safely rely on
+being able to disable potentially dangerous protocols, without relying upon
+support for that protocol being built into curl to avoid an error.
+
+This option can be used multiple times, in which case the effect is the same
+as concatenating the protocols into one instance of the option.
+
+(Added in 7.20.2)
+.IP "--proto-redir <protocols>"
+Tells curl to use the listed protocols after a redirect. See --proto for
+how protocols are represented.
+
+(Added in 7.20.2)
+.IP "--proxy-anyauth"
+Tells curl to pick a suitable authentication method when communicating with
+the given proxy. This might cause an extra request/response round-trip. (Added
+in 7.13.2)
+.IP "--proxy-basic"
+Tells curl to use HTTP Basic authentication when communicating with the given
+proxy. Use \fI--basic\fP for enabling HTTP Basic with a remote host. Basic is
+the default authentication method curl uses with proxies.
+.IP "--proxy-digest"
+Tells curl to use HTTP Digest authentication when communicating with the given
+proxy. Use \fI--digest\fP for enabling HTTP Digest with a remote host.
+.IP "--proxy-negotiate"
+Tells curl to use HTTP Negotiate authentication when communicating
+with the given proxy. Use \fI--negotiate\fP for enabling HTTP Negotiate
+with a remote host. (Added in 7.17.1)
+.IP "--proxy-ntlm"
+Tells curl to use HTTP NTLM authentication when communicating with the given
+proxy. Use \fI--ntlm\fP for enabling NTLM with a remote host.
+.IP "--proxy1.0 <proxyhost[:port]>"
+Use the specified HTTP 1.0 proxy. If the port number is not specified, it is
+assumed at port 1080.
+
+The only difference between this and the HTTP proxy option (\fI-x, --proxy\fP),
+is that attempts to use CONNECT through the proxy will specify an HTTP 1.0
+protocol instead of the default HTTP 1.1.
+.IP "--pubkey <key>"
+(SSH) Public key file name. Allows you to provide your public key in this
+separate file.
+
+If this option is used several times, the last one will be used.
+.IP "-q"
+If used as the first parameter on the command line, the \fIcurlrc\fP config
+file will not be read and used. See the \fI-K, --config\fP for details on the
+default config file search path.
+.IP "-Q, --quote <command>"
+(FTP/SFTP) Send an arbitrary command to the remote FTP or SFTP server. Quote
+commands are sent BEFORE the transfer takes place (just after the initial PWD
+command in an FTP transfer, to be exact). To make commands take place after a
+successful transfer, prefix them with a dash '-'. To make commands be sent
+after curl has changed the working directory, just before the transfer
+command(s), prefix the command with a '+' (this is only supported for
+FTP). You may specify any number of commands. If the server returns failure
+for one of the commands, the entire operation will be aborted. You must send
+syntactically correct FTP commands as RFC 959 defines to FTP servers, or one
+of the commands listed below to SFTP servers. This option can be used
+multiple times. When speaking to an FTP server, prefix the command with an
+asterisk (*) to make curl continue even if the command fails as by default
+curl will stop at first failure.
+
+SFTP is a binary protocol. Unlike for FTP, curl interprets SFTP quote commands
+itself before sending them to the server. File names may be quoted
+shell-style to embed spaces or special characters. Following is the list of
+all supported SFTP quote commands:
+.RS
+.IP "chgrp group file"
+The chgrp command sets the group ID of the file named by the file operand to
+the group ID specified by the group operand. The group operand is a decimal
+integer group ID.
+.IP "chmod mode file"
+The chmod command modifies the file mode bits of the specified file. The
+mode operand is an octal integer mode number.
+.IP "chown user file"
+The chown command sets the owner of the file named by the file operand to the
+user ID specified by the user operand. The user operand is a decimal
+integer user ID.
+.IP "ln source_file target_file"
+The ln and symlink commands create a symbolic link at the target_file location
+pointing to the source_file location.
+.IP "mkdir directory_name"
+The mkdir command creates the directory named by the directory_name operand.
+.IP "pwd"
+The pwd command returns the absolute pathname of the current working directory.
+.IP "rename source target"
+The rename command renames the file or directory named by the source
+operand to the destination path named by the target operand.
+.IP "rm file"
+The rm command removes the file specified by the file operand.
+.IP "rmdir directory"
+The rmdir command removes the directory entry specified by the directory
+operand, provided it is empty.
+.IP "symlink source_file target_file"
+See ln.
+.RE
+.IP "-r, --range <range>"
+(HTTP/FTP/SFTP/FILE) Retrieve a byte range (i.e a partial document) from a
+HTTP/1.1, FTP or SFTP server or a local FILE. Ranges can be specified
+in a number of ways.
+.RS
+.TP 10
+.B 0-499
+specifies the first 500 bytes
+.TP
+.B 500-999
+specifies the second 500 bytes
+.TP
+.B -500
+specifies the last 500 bytes
+.TP
+.B 9500-
+specifies the bytes from offset 9500 and forward
+.TP
+.B 0-0,-1
+specifies the first and last byte only(*)(H)
+.TP
+.B 500-700,600-799
+specifies 300 bytes from offset 500(H)
+.TP
+.B 100-199,500-599
+specifies two separate 100-byte ranges(*)(H)
+.RE
+
+(*) = NOTE that this will cause the server to reply with a multipart
+response!
+
+Only digit characters (0-9) are valid in the 'start' and 'stop' fields of the
+\&'start-stop' range syntax. If a non-digit character is given in the range,
+the server's response will be unspecified, depending on the server's
+configuration.
+
+You should also be aware that many HTTP/1.1 servers do not have this feature
+enabled, so that when you attempt to get a range, you'll instead get the whole
+document.
+
+FTP and SFTP range downloads only support the simple 'start-stop' syntax
+(optionally with one of the numbers omitted). FTP use depends on the extended
+FTP command SIZE.
+
+If this option is used several times, the last one will be used.
+.IP "-R, --remote-time"
+When used, this will make curl attempt to figure out the timestamp of the
+remote file, and if that is available make the local file get that same
+timestamp.
+.IP "--random-file <file>"
+(SSL) Specify the path name to file containing what will be considered as
+random data. The data is used to seed the random engine for SSL connections.
+See also the \fI--egd-file\fP option.
+.IP "--raw"
+(HTTP) When used, it disables all internal HTTP decoding of content or transfer
+encodings and instead makes them passed on unaltered, raw. (Added in 7.16.2)
+.IP "--remote-name-all"
+This option changes the default action for all given URLs to be dealt with as
+if \fI-O, --remote-name\fP were used for each one. So if you want to disable
+that for a specific URL after \fI--remote-name-all\fP has been used, you must
+use "-o -" or \fI--no-remote-name\fP. (Added in 7.19.0)
+.IP "--resolve <host:port:address>"
+Provide a custom address for a specific host and port pair. Using this, you
+can make the curl requests(s) use a specified address and prevent the
+otherwise normally resolved address to be used. Consider it a sort of
+/etc/hosts alternative provided on the command line. The port number should be
+the number used for the specific protocol the host will be used for. It means
+you need several entries if you want to provide address for the same host but
+different ports.
+
+This option can be used many times to add many host names to resolve.
+
+(Added in 7.21.3)
+.IP "--retry <num>"
+If a transient error is returned when curl tries to perform a transfer, it
+will retry this number of times before giving up. Setting the number to 0
+makes curl do no retries (which is the default). Transient error means either:
+a timeout, an FTP 4xx response code or an HTTP 5xx response code.
+
+When curl is about to retry a transfer, it will first wait one second and then
+for all forthcoming retries it will double the waiting time until it reaches
+10 minutes which then will be the delay between the rest of the retries. By
+using \fI--retry-delay\fP you disable this exponential backoff algorithm. See
+also \fI--retry-max-time\fP to limit the total time allowed for
+retries. (Added in 7.12.3)
+
+If this option is used several times, the last one will be used.
+.IP "--retry-delay <seconds>"
+Make curl sleep this amount of time before each retry when a transfer has
+failed with a transient error (it changes the default backoff time algorithm
+between retries). This option is only interesting if \fI--retry\fP is also
+used. Setting this delay to zero will make curl use the default backoff time.
+(Added in 7.12.3)
+
+If this option is used several times, the last one will be used.
+.IP "--retry-max-time <seconds>"
+The retry timer is reset before the first transfer attempt. Retries will be
+done as usual (see \fI--retry\fP) as long as the timer hasn't reached this
+given limit. Notice that if the timer hasn't reached the limit, the request
+will be made and while performing, it may take longer than this given time
+period. To limit a single request\'s maximum time, use \fI-m, --max-time\fP.
+Set this option to zero to not timeout retries. (Added in 7.12.3)
+
+If this option is used several times, the last one will be used.
+.IP "-s, --silent"
+Silent or quiet mode. Don't show progress meter or error messages. Makes
+Curl mute.
+.IP "-S, --show-error"
+When used with \fI-s\fP it makes curl show an error message if it fails.
+.IP "--ssl"
+(FTP, POP3, IMAP, SMTP) Try to use SSL/TLS for the connection. Reverts to a
+non-secure connection if the server doesn't support SSL/TLS. See also
+\fI--ftp-ssl-control\fP and \fI--ssl-reqd\fP for different levels of
+encryption required. (Added in 7.20.0)
+
+This option was formerly known as \fI--ftp-ssl\fP (Added in 7.11.0). That
+option name can still be used but will be removed in a future version.
+.IP "--ssl-reqd"
+(FTP, POP3, IMAP, SMTP) Require SSL/TLS for the connection. Terminates the
+connection if the server doesn't support SSL/TLS. (Added in 7.20.0)
+
+This option was formerly known as \fI--ftp-ssl-reqd\fP (added in 7.15.5). That
+option name can still be used but will be removed in a future version.
+.IP "--ssl-allow-beast"
+(SSL) This option tells curl to not work around a security flaw in the SSL3
+and TLS1.0 protocols known as BEAST. If this option isn't used, the SSL layer
+may use work-arounds known to cause interoperability problems with some older
+SSL implementations. WARNING: this option loosens the SSL security, and by
+using this flag you ask for exactly that. (Added in 7.25.0)
+.IP "--socks4 <host[:port]>"
+Use the specified SOCKS4 proxy. If the port number is not specified, it is
+assumed at port 1080. (Added in 7.15.2)
+
+This option overrides any previous use of \fI-x, --proxy\fP, as they are
+mutually exclusive.
+
+Since 7.21.7, this option is superfluous since you can specify a socks4 proxy
+with \fI-x, --proxy\fP using a socks4:// protocol prefix.
+
+If this option is used several times, the last one will be used.
+.IP "--socks4a <host[:port]>"
+Use the specified SOCKS4a proxy. If the port number is not specified, it is
+assumed at port 1080. (Added in 7.18.0)
+
+This option overrides any previous use of \fI-x, --proxy\fP, as they are
+mutually exclusive.
+
+Since 7.21.7, this option is superfluous since you can specify a socks4a proxy
+with \fI-x, --proxy\fP using a socks4a:// protocol prefix.
+
+If this option is used several times, the last one will be used.
+.IP "--socks5-hostname <host[:port]>"
+Use the specified SOCKS5 proxy (and let the proxy resolve the host name). If
+the port number is not specified, it is assumed at port 1080. (Added in
+7.18.0)
+
+This option overrides any previous use of \fI-x, --proxy\fP, as they are
+mutually exclusive.
+
+Since 7.21.7, this option is superfluous since you can specify a socks5
+hostname proxy with \fI-x, --proxy\fP using a socks5h:// protocol prefix.
+
+If this option is used several times, the last one will be used. (This option
+was previously wrongly documented and used as --socks without the number
+appended.)
+.IP "--socks5 <host[:port]>"
+Use the specified SOCKS5 proxy - but resolve the host name locally. If the
+port number is not specified, it is assumed at port 1080.
+
+This option overrides any previous use of \fI-x, --proxy\fP, as they are
+mutually exclusive.
+
+Since 7.21.7, this option is superfluous since you can specify a socks5 proxy
+with \fI-x, --proxy\fP using a socks5:// protocol prefix.
+
+If this option is used several times, the last one will be used. (This option
+was previously wrongly documented and used as --socks without the number
+appended.)
+
+This option (as well as \fI--socks4\fP) does not work with IPV6, FTPS or LDAP.
+.IP "--socks5-gssapi-service <servicename>"
+The default service name for a socks server is rcmd/server-fqdn. This option
+allows you to change it.
+
+Examples: --socks5 proxy-name \fI--socks5-gssapi-service\fP sockd would use
+sockd/proxy-name --socks5 proxy-name \fI--socks5-gssapi-service\fP
+sockd/real-name would use sockd/real-name for cases where the proxy-name does
+not match the principal name. (Added in 7.19.4).
+.IP "--socks5-gssapi-nec"
+As part of the gssapi negotiation a protection mode is negotiated. RFC 1961
+says in section 4.3/4.4 it should be protected, but the NEC reference
+implementation does not. The option \fI--socks5-gssapi-nec\fP allows the
+unprotected exchange of the protection mode negotiation. (Added in 7.19.4).
+.IP "--stderr <file>"
+Redirect all writes to stderr to the specified file instead. If the file name
+is a plain '-', it is instead written to stdout.
+
+If this option is used several times, the last one will be used.
+.IP "-t, --telnet-option <OPT=val>"
+Pass options to the telnet protocol. Supported options are:
+
+TTYPE=<term> Sets the terminal type.
+
+XDISPLOC=<X display> Sets the X display location.
+
+NEW_ENV=<var,val> Sets an environment variable.
+.IP "-T, --upload-file <file>"
+This transfers the specified local file to the remote URL. If there is no file
+part in the specified URL, Curl will append the local file name. NOTE that you
+must use a trailing / on the last directory to really prove to Curl that there
+is no file name or curl will think that your last directory name is the remote
+file name to use. That will most likely cause the upload operation to fail. If
+this is used on an HTTP(S) server, the PUT command will be used.
+
+Use the file name "-" (a single dash) to use stdin instead of a given file.
+Alternately, the file name "." (a single period) may be specified instead
+of "-" to use stdin in non-blocking mode to allow reading server output
+while stdin is being uploaded.
+
+You can specify one -T for each URL on the command line. Each -T + URL pair
+specifies what to upload and to where. curl also supports "globbing" of the -T
+argument, meaning that you can upload multiple files to a single URL by using
+the same URL globbing style supported in the URL, like this:
+
+curl -T "{file1,file2}" http://www.uploadtothissite.com
+
+or even
+
+curl -T "img[1-1000].png" ftp://ftp.picturemania.com/upload/
+.IP "--tcp-nodelay"
+Turn on the TCP_NODELAY option. See the \fIcurl_easy_setopt(3)\fP man page for
+details about this option. (Added in 7.11.2)
+.IP "--tftp-blksize <value>"
+(TFTP) Set TFTP BLKSIZE option (must be >512). This is the block size that
+curl will try to use when transferring data to or from a TFTP server. By
+default 512 bytes will be used.
+
+If this option is used several times, the last one will be used.
+
+(Added in 7.20.0)
+.IP "--tlsauthtype <authtype>"
+Set TLS authentication type. Currently, the only supported option is "SRP",
+for TLS-SRP (RFC 5054). If \fI--tlsuser\fP and \fI--tlspassword\fP are
+specified but \fI--tlsauthtype\fP is not, then this option defaults to "SRP".
+(Added in 7.21.4)
+.IP "--tlsuser <user>"
+Set username for use with the TLS authentication method specified with
+\fI--tlsauthtype\fP. Requires that \fI--tlspassword\fP also be set. (Added in
+7.21.4)
+.IP "--tlspassword <password>"
+Set password for use with the TLS authentication method specified with
+\fI--tlsauthtype\fP. Requires that \fI--tlsuser\fP also be set. (Added in
+7.21.4)
+.IP "--tr-encoding"
+(HTTP) Request a compressed Transfer-Encoding response using one of the
+algorithms curl supports, and uncompress the data while receiving it.
+
+(Added in 7.21.6)
+.IP "--trace <file>"
+Enables a full trace dump of all incoming and outgoing data, including
+descriptive information, to the given output file. Use "-" as filename to have
+the output sent to stdout.
+
+This option overrides previous uses of \fI-v, --verbose\fP or
+\fI--trace-ascii\fP.
+
+If this option is used several times, the last one will be used.
+.IP "--trace-ascii <file>"
+Enables a full trace dump of all incoming and outgoing data, including
+descriptive information, to the given output file. Use "-" as filename to have
+the output sent to stdout.
+
+This is very similar to \fI--trace\fP, but leaves out the hex part and only
+shows the ASCII part of the dump. It makes smaller output that might be easier
+to read for untrained humans.
+
+This option overrides previous uses of \fI-v, --verbose\fP or \fI--trace\fP.
+
+If this option is used several times, the last one will be used.
+.IP "--trace-time"
+Prepends a time stamp to each trace or verbose line that curl displays.
+(Added in 7.14.0)
+.IP "-u, --user <user:password>"
+Specify the user name and password to use for server authentication. Overrides
+\fI-n, --netrc\fP and \fI--netrc-optional\fP.
+
+If you just give the user name (without entering a colon) curl will prompt for
+a password.
+
+If you use an SSPI-enabled curl binary and do NTLM authentication, you can
+force curl to pick up the user name and password from your environment by
+simply specifying a single colon with this option: "-u :".
+
+If this option is used several times, the last one will be used.
+.IP "-U, --proxy-user <user:password>"
+Specify the user name and password to use for proxy authentication.
+
+If you use an SSPI-enabled curl binary and do NTLM authentication, you can
+force curl to pick up the user name and password from your environment by
+simply specifying a single colon with this option: "-U :".
+
+If this option is used several times, the last one will be used.
+.IP "--url <URL>"
+Specify a URL to fetch. This option is mostly handy when you want to specify
+URL(s) in a config file.
+
+This option may be used any number of times. To control where this URL is
+written, use the \fI-o, --output\fP or the \fI-O, --remote-name\fP options.
+.IP "-v, --verbose"
+Makes the fetching more verbose/talkative. Mostly useful for debugging. A line
+starting with '>' means "header data" sent by curl, '<' means "header data"
+received by curl that is hidden in normal cases, and a line starting with '*'
+means additional info provided by curl.
+
+Note that if you only want HTTP headers in the output, \fI-i, --include\fP
+might be the option you're looking for.
+
+If you think this option still doesn't give you enough details, consider using
+\fI--trace\fP or \fI--trace-ascii\fP instead.
+
+This option overrides previous uses of \fI--trace-ascii\fP or \fI--trace\fP.
+
+Use \fI-s, --silent\fP to make curl quiet.
+.IP "-w, --write-out <format>"
+Defines what to display on stdout after a completed and successful
+operation. The format is a string that may contain plain text mixed with any
+number of variables. The string can be specified as "string", to get read from
+a particular file you specify it "@filename" and to tell curl to read the
+format from stdin you write "@-".
+
+The variables present in the output format will be substituted by the value or
+text that curl thinks fit, as described below. All variables are specified
+as %{variable_name} and to output a normal % you just write them as
+%%. You can output a newline by using \\n, a carriage return with \\r and a tab
+space with \\t.
+
+.B NOTE:
+The %-symbol is a special symbol in the win32-environment, where all
+occurrences of % must be doubled when using this option.
+
+The variables available are:
+.RS
+.TP 15
+.B content_type
+The Content-Type of the requested document, if there was any.
+.TP
+.B filename_effective
+The ultimate filename that curl writes out to. This is only meaningful if curl
+is told to write to a file with the \fI--remote-name\fP or \fI--output\fP
+option. It's most useful in combination with the \fI--remote-header-name\fP
+option. (Added in 7.25.1)
+.TP
+.B ftp_entry_path
+The initial path curl ended up in when logging on to the remote FTP
+server. (Added in 7.15.4)
+.TP
+.B http_code
+The numerical response code that was found in the last retrieved HTTP(S) or
+FTP(s) transfer. In 7.18.2 the alias \fBresponse_code\fP was added to show the
+same info.
+.TP
+.B http_connect
+The numerical code that was found in the last response (from a proxy) to a
+curl CONNECT request. (Added in 7.12.4)
+.TP
+.B num_connects
+Number of new connects made in the recent transfer. (Added in 7.12.3)
+.TP
+.B num_redirects
+Number of redirects that were followed in the request. (Added in 7.12.3)
+.TP
+.B redirect_url
+When an HTTP request was made without -L to follow redirects, this variable
+will show the actual URL a redirect \fIwould\fP take you to. (Added in 7.18.2)
+.TP
+.B size_download
+The total amount of bytes that were downloaded.
+.TP
+.B size_header
+The total amount of bytes of the downloaded headers.
+.TP
+.B size_request
+The total amount of bytes that were sent in the HTTP request.
+.TP
+.B size_upload
+The total amount of bytes that were uploaded.
+.TP
+.B speed_download
+The average download speed that curl measured for the complete download. Bytes
+per second.
+.TP
+.B speed_upload
+The average upload speed that curl measured for the complete upload. Bytes per
+second.
+.TP
+.B ssl_verify_result
+The result of the SSL peer certificate verification that was requested. 0
+means the verification was successful. (Added in 7.19.0)
+.TP
+.B time_appconnect
+The time, in seconds, it took from the start until the SSL/SSH/etc
+connect/handshake to the remote host was completed. (Added in 7.19.0)
+.TP
+.B time_connect
+The time, in seconds, it took from the start until the TCP connect to the
+remote host (or proxy) was completed.
+.TP
+.B time_namelookup
+The time, in seconds, it took from the start until the name resolving was
+completed.
+.TP
+.B time_pretransfer
+The time, in seconds, it took from the start until the file transfer was just
+about to begin. This includes all pre-transfer commands and negotiations that
+are specific to the particular protocol(s) involved.
+.TP
+.B time_redirect
+The time, in seconds, it took for all redirection steps include name lookup,
+connect, pretransfer and transfer before the final transaction was
+started. time_redirect shows the complete execution time for multiple
+redirections. (Added in 7.12.3)
+.TP
+.B time_starttransfer
+The time, in seconds, it took from the start until the first byte was just
+about to be transferred. This includes time_pretransfer and also the time the
+server needed to calculate the result.
+.TP
+.B time_total
+The total time, in seconds, that the full operation lasted. The time will be
+displayed with millisecond resolution.
+.TP
+.B url_effective
+The URL that was fetched last. This is most meaningful if you've told curl
+to follow location: headers.
+.RE
+
+If this option is used several times, the last one will be used.
+.IP "-x, --proxy <[protocol://][user:password@]proxyhost[:port]>"
+Use the specified HTTP proxy. If the port number is not specified, it is
+assumed at port 1080.
+
+This option overrides existing environment variables that set the proxy to
+use. If there's an environment variable setting a proxy, you can set proxy to
+\&"" to override it.
+
+All operations that are performed over an HTTP proxy will transparently be
+converted to HTTP. It means that certain protocol specific operations might
+not be available. This is not the case if you can tunnel through the proxy, as
+one with the \fI-p, --proxytunnel\fP option.
+
+User and password that might be provided in the proxy string are URL decoded
+by curl. This allows you to pass in special characters such as @ by using %40
+or pass in a colon with %3a.
+
+The proxy host can be specified the exact same way as the proxy environment
+variables, including the protocol prefix (http://) and the embedded user +
+password.
+
+From 7.21.7, the proxy string may be specified with a protocol:// prefix to
+specify alternative proxy protocols. Use socks4://, socks4a://, socks5:// or
+socks5h:// to request the specific SOCKS version to be used. No protocol
+specified, http:// and all others will be treated as HTTP proxies.
+
+If this option is used several times, the last one will be used.
+.IP "-X, --request <command>"
+(HTTP) Specifies a custom request method to use when communicating with the
+HTTP server. The specified request will be used instead of the method
+otherwise used (which defaults to GET). Read the HTTP 1.1 specification for
+details and explanations. Common additional HTTP requests include PUT and
+DELETE, but related technologies like WebDAV offers PROPFIND, COPY, MOVE and
+more.
+
+(FTP)
+Specifies a custom FTP command to use instead of LIST when doing file lists
+with FTP.
+
+If this option is used several times, the last one will be used.
+
+.IP "--xattr"
+When saving output to a file, this option tells curl to store certain file
+metadata in extened file attributes. Currently, the URL is stored in the
+xdg.origin.url attribute and, for HTTP, the content type is stored in
+the mime_type attribute. If the file system does not support extended
+attributes, a warning is issued.
+
+.IP "-y, --speed-time <time>"
+If a download is slower than speed-limit bytes per second during a speed-time
+period, the download gets aborted. If speed-time is used, the default
+speed-limit will be 1 unless set with \fI-Y\fP.
+
+This option controls transfers and thus will not affect slow connects etc. If
+this is a concern for you, try the \fI--connect-timeout\fP option.
+
+If this option is used several times, the last one will be used.
+.IP "-Y, --speed-limit <speed>"
+If a download is slower than this given speed (in bytes per second) for
+speed-time seconds it gets aborted. speed-time is set with \fI-y\fP and is 30
+if not set.
+
+If this option is used several times, the last one will be used.
+.IP "-z/--time-cond <date expression>|<file>"
+(HTTP/FTP) Request a file that has been modified later than the given time and
+date, or one that has been modified before that time. The <date expression>
+can be all sorts of date strings or if it doesn't match any internal ones, it
+is taken as a filename and tries to get the modification date (mtime) from
+<file> instead. See the \fIcurl_getdate(3)\fP man pages for date expression
+details.
+
+Start the date expression with a dash (-) to make it request for a document
+that is older than the given date/time, default is a document that is newer
+than the specified date/time.
+
+If this option is used several times, the last one will be used.
+.IP "-h, --help"
+Usage help.
+.IP "-M, --manual"
+Manual. Display the huge help text.
+.IP "-V, --version"
+Displays information about curl and the libcurl version it uses.
+
+The first line includes the full version of curl, libcurl and other 3rd party
+libraries linked with the executable.
+
+The second line (starts with "Protocols:") shows all protocols that libcurl
+reports to support.
+
+The third line (starts with "Features:") shows specific features libcurl
+reports to offer. Available features include:
+.RS
+.IP "IPv6"
+You can use IPv6 with this.
+.IP "krb4"
+Krb4 for FTP is supported.
+.IP "SSL"
+HTTPS and FTPS are supported.
+.IP "libz"
+Automatic decompression of compressed files over HTTP is supported.
+.IP "NTLM"
+NTLM authentication is supported.
+.IP "GSS-Negotiate"
+Negotiate authentication and krb5 for FTP is supported.
+.IP "Debug"
+This curl uses a libcurl built with Debug. This enables more error-tracking
+and memory debugging etc. For curl-developers only!
+.IP "AsynchDNS"
+This curl uses asynchronous name resolves.
+.IP "SPNEGO"
+SPNEGO Negotiate authentication is supported.
+.IP "Largefile"
+This curl supports transfers of large files, files larger than 2GB.
+.IP "IDN"
+This curl supports IDN - international domain names.
+.IP "SSPI"
+SSPI is supported. If you use NTLM and set a blank user name, curl will
+authenticate with your current user and password.
+.IP "TLS-SRP"
+SRP (Secure Remote Password) authentication is supported for TLS.
+.IP "Metalink"
+This curl supports Metalink (both version 3 and 4 (RFC 5854)), which
+describes mirrors and hashes. curl will use mirrors for failover if
+there are errors (such as the file or server not being available).
+.RE
+.SH FILES
+.I ~/.curlrc
+.RS
+Default config file, see \fI-K, --config\fP for details.
+.SH ENVIRONMENT
+The environment variables can be specified in lower case or upper case. The
+lower case version has precedence. http_proxy is an exception as it is only
+available in lower case.
+
+Using an environment variable to set the proxy has the same effect as using
+the \fI--proxy\fP option.
+
+.IP "http_proxy [protocol://]<host>[:port]"
+Sets the proxy server to use for HTTP.
+.IP "HTTPS_PROXY [protocol://]<host>[:port]"
+Sets the proxy server to use for HTTPS.
+.IP "[url-protocol]_PROXY [protocol://]<host>[:port]"
+Sets the proxy server to use for [url-protocol], where the protocol is a
+protocol that curl supports and as specified in a URL. FTP, FTPS, POP3, IMAP,
+SMTP, LDAP etc.
+.IP "ALL_PROXY [protocol://]<host>[:port]"
+Sets the proxy server to use if no protocol-specific proxy is set.
+.IP "NO_PROXY <comma-separated list of hosts>"
+list of host names that shouldn't go through any proxy. If set to a asterisk
+\&'*' only, it matches all hosts.
+.SH "PROXY PROTOCOL PREFIXES"
+Since curl version 7.21.7, the proxy string may be specified with a
+protocol:// prefix to specify alternative proxy protocols.
+
+If no protocol is specified in the proxy string or if the string doesn't match
+a supported one, the proxy will be treated as an HTTP proxy.
+
+The supported proxy protocol prefixes are as follows:
+.IP "socks4://"
+Makes it the equivalent of \fI--socks4\fP
+.IP "socks4a://"
+Makes it the equivalent of \fI--socks4a\fP
+.IP "socks5://"
+Makes it the equivalent of \fI--socks5\fP
+.IP "socks5h://"
+Makes it the equivalent of \fI--socks5-hostname\fP
+.SH EXIT CODES
+There are a bunch of different error codes and their corresponding error
+messages that may appear during bad conditions. At the time of this writing,
+the exit codes are:
+.IP 1
+Unsupported protocol. This build of curl has no support for this protocol.
+.IP 2
+Failed to initialize.
+.IP 3
+URL malformed. The syntax was not correct.
+.IP 4
+A feature or option that was needed to perform the desired request was not
+enabled or was explicitly disabled at build-time. To make curl able to do
+this, you probably need another build of libcurl!
+.IP 5
+Couldn't resolve proxy. The given proxy host could not be resolved.
+.IP 6
+Couldn't resolve host. The given remote host was not resolved.
+.IP 7
+Failed to connect to host.
+.IP 8
+FTP weird server reply. The server sent data curl couldn't parse.
+.IP 9
+FTP access denied. The server denied login or denied access to the particular
+resource or directory you wanted to reach. Most often you tried to change to a
+directory that doesn't exist on the server.
+.IP 11
+FTP weird PASS reply. Curl couldn't parse the reply sent to the PASS request.
+.IP 13
+FTP weird PASV reply, Curl couldn't parse the reply sent to the PASV request.
+.IP 14
+FTP weird 227 format. Curl couldn't parse the 227-line the server sent.
+.IP 15
+FTP can't get host. Couldn't resolve the host IP we got in the 227-line.
+.IP 17
+FTP couldn't set binary. Couldn't change transfer method to binary.
+.IP 18
+Partial file. Only a part of the file was transferred.
+.IP 19
+FTP couldn't download/access the given file, the RETR (or similar) command
+failed.
+.IP 21
+FTP quote error. A quote command returned error from the server.
+.IP 22
+HTTP page not retrieved. The requested url was not found or returned another
+error with the HTTP error code being 400 or above. This return code only
+appears if \fI-f, --fail\fP is used.
+.IP 23
+Write error. Curl couldn't write data to a local filesystem or similar.
+.IP 25
+FTP couldn't STOR file. The server denied the STOR operation, used for FTP
+uploading.
+.IP 26
+Read error. Various reading problems.
+.IP 27
+Out of memory. A memory allocation request failed.
+.IP 28
+Operation timeout. The specified time-out period was reached according to the
+conditions.
+.IP 30
+FTP PORT failed. The PORT command failed. Not all FTP servers support the PORT
+command, try doing a transfer using PASV instead!
+.IP 31
+FTP couldn't use REST. The REST command failed. This command is used for
+resumed FTP transfers.
+.IP 33
+HTTP range error. The range "command" didn't work.
+.IP 34
+HTTP post error. Internal post-request generation error.
+.IP 35
+SSL connect error. The SSL handshaking failed.
+.IP 36
+FTP bad download resume. Couldn't continue an earlier aborted download.
+.IP 37
+FILE couldn't read file. Failed to open the file. Permissions?
+.IP 38
+LDAP cannot bind. LDAP bind operation failed.
+.IP 39
+LDAP search failed.
+.IP 41
+Function not found. A required LDAP function was not found.
+.IP 42
+Aborted by callback. An application told curl to abort the operation.
+.IP 43
+Internal error. A function was called with a bad parameter.
+.IP 45
+Interface error. A specified outgoing interface could not be used.
+.IP 47
+Too many redirects. When following redirects, curl hit the maximum amount.
+.IP 48
+Unknown option specified to libcurl. This indicates that you passed a weird
+option to curl that was passed on to libcurl and rejected. Read up in the
+manual!
+.IP 49
+Malformed telnet option.
+.IP 51
+The peer's SSL certificate or SSH MD5 fingerprint was not OK.
+.IP 52
+The server didn't reply anything, which here is considered an error.
+.IP 53
+SSL crypto engine not found.
+.IP 54
+Cannot set SSL crypto engine as default.
+.IP 55
+Failed sending network data.
+.IP 56
+Failure in receiving network data.
+.IP 58
+Problem with the local certificate.
+.IP 59
+Couldn't use specified SSL cipher.
+.IP 60
+Peer certificate cannot be authenticated with known CA certificates.
+.IP 61
+Unrecognized transfer encoding.
+.IP 62
+Invalid LDAP URL.
+.IP 63
+Maximum file size exceeded.
+.IP 64
+Requested FTP SSL level failed.
+.IP 65
+Sending the data requires a rewind that failed.
+.IP 66
+Failed to initialise SSL Engine.
+.IP 67
+The user name, password, or similar was not accepted and curl failed to log in.
+.IP 68
+File not found on TFTP server.
+.IP 69
+Permission problem on TFTP server.
+.IP 70
+Out of disk space on TFTP server.
+.IP 71
+Illegal TFTP operation.
+.IP 72
+Unknown TFTP transfer ID.
+.IP 73
+File already exists (TFTP).
+.IP 74
+No such user (TFTP).
+.IP 75
+Character conversion failed.
+.IP 76
+Character conversion functions required.
+.IP 77
+Problem with reading the SSL CA cert (path? access rights?).
+.IP 78
+The resource referenced in the URL does not exist.
+.IP 79
+An unspecified error occurred during the SSH session.
+.IP 80
+Failed to shut down the SSL connection.
+.IP 82
+Could not load CRL file, missing or wrong format (added in 7.19.0).
+.IP 83
+Issuer check failed (added in 7.19.0).
+.IP 84
+The FTP PRET command failed
+.IP 85
+RTSP: mismatch of CSeq numbers
+.IP 86
+RTSP: mismatch of Session Identifiers
+.IP 87
+unable to parse FTP file list
+.IP 88
+FTP chunk callback reported error
+.IP XX
+More error codes will appear here in future releases. The existing ones
+are meant to never change.
+.SH AUTHORS / CONTRIBUTORS
+Daniel Stenberg is the main author, but the whole list of contributors is
+found in the separate THANKS file.
+.SH WWW
+http://curl.haxx.se
+.SH FTP
+ftp://ftp.sunet.se/pub/www/utilities/curl/
+.SH "SEE ALSO"
+.BR ftp (1),
+.BR wget (1)
diff --git a/docs/examples/.gitignore b/docs/examples/.gitignore
new file mode 100644
index 000000000..cbe0d04d4
--- /dev/null
+++ b/docs/examples/.gitignore
@@ -0,0 +1,45 @@
+10-at-a-time
+anyauthput
+certinfo
+chkspeed
+cookie_interface
+debug
+externalsocket
+fileupload
+fopen
+ftp-wildcard
+ftpget
+ftpgetinfo
+ftpgetresp
+ftpsget
+ftpupload
+getinfo
+getinmemory
+http-post
+httpcustomheader
+httpput
+https
+imap
+multi-app
+multi-debugcallback
+multi-double
+multi-post
+multi-single
+persistant
+pop3s
+pop3slist
+post-callback
+postit2
+progressfunc
+resolve
+rtsp
+sendrecv
+sepheaders
+sftpget
+simple
+simplepost
+simplesmtp
+simplessl
+smtp-multi
+smtp-tls
+url2file
diff --git a/docs/examples/10-at-a-time.c b/docs/examples/10-at-a-time.c
new file mode 100644
index 000000000..a85fff46f
--- /dev/null
+++ b/docs/examples/10-at-a-time.c
@@ -0,0 +1,197 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* Example application source code using the multi interface to download many
+ * files, but with a capped maximum amount of simultaneous transfers.
+ *
+ * Written by Michael Wallner
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef WIN32
+# include <unistd.h>
+#endif
+#include <curl/multi.h>
+
+static const char *urls[] = {
+ "http://www.microsoft.com",
+ "http://www.opensource.org",
+ "http://www.google.com",
+ "http://www.yahoo.com",
+ "http://www.ibm.com",
+ "http://www.mysql.com",
+ "http://www.oracle.com",
+ "http://www.ripe.net",
+ "http://www.iana.org",
+ "http://www.amazon.com",
+ "http://www.netcraft.com",
+ "http://www.heise.de",
+ "http://www.chip.de",
+ "http://www.ca.com",
+ "http://www.cnet.com",
+ "http://www.news.com",
+ "http://www.cnn.com",
+ "http://www.wikipedia.org",
+ "http://www.dell.com",
+ "http://www.hp.com",
+ "http://www.cert.org",
+ "http://www.mit.edu",
+ "http://www.nist.gov",
+ "http://www.ebay.com",
+ "http://www.playstation.com",
+ "http://www.uefa.com",
+ "http://www.ieee.org",
+ "http://www.apple.com",
+ "http://www.sony.com",
+ "http://www.symantec.com",
+ "http://www.zdnet.com",
+ "http://www.fujitsu.com",
+ "http://www.supermicro.com",
+ "http://www.hotmail.com",
+ "http://www.ecma.com",
+ "http://www.bbc.co.uk",
+ "http://news.google.com",
+ "http://www.foxnews.com",
+ "http://www.msn.com",
+ "http://www.wired.com",
+ "http://www.sky.com",
+ "http://www.usatoday.com",
+ "http://www.cbs.com",
+ "http://www.nbc.com",
+ "http://slashdot.org",
+ "http://www.bloglines.com",
+ "http://www.techweb.com",
+ "http://www.newslink.org",
+ "http://www.un.org",
+};
+
+#define MAX 10 /* number of simultaneous transfers */
+#define CNT sizeof(urls)/sizeof(char*) /* total number of transfers to do */
+
+static size_t cb(char *d, size_t n, size_t l, void *p)
+{
+ /* take care of the data here, ignored in this example */
+ (void)d;
+ (void)p;
+ return n*l;
+}
+
+static void init(CURLM *cm, int i)
+{
+ CURL *eh = curl_easy_init();
+
+ curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, cb);
+ curl_easy_setopt(eh, CURLOPT_HEADER, 0L);
+ curl_easy_setopt(eh, CURLOPT_URL, urls[i]);
+ curl_easy_setopt(eh, CURLOPT_PRIVATE, urls[i]);
+ curl_easy_setopt(eh, CURLOPT_VERBOSE, 0L);
+
+ curl_multi_add_handle(cm, eh);
+}
+
+int main(void)
+{
+ CURLM *cm;
+ CURLMsg *msg;
+ long L;
+ unsigned int C=0;
+ int M, Q, U = -1;
+ fd_set R, W, E;
+ struct timeval T;
+
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ cm = curl_multi_init();
+
+ /* we can optionally limit the total amount of connections this multi handle
+ uses */
+ curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, (long)MAX);
+
+ for (C = 0; C < MAX; ++C) {
+ init(cm, C);
+ }
+
+ while (U) {
+ curl_multi_perform(cm, &U);
+
+ if (U) {
+ FD_ZERO(&R);
+ FD_ZERO(&W);
+ FD_ZERO(&E);
+
+ if (curl_multi_fdset(cm, &R, &W, &E, &M)) {
+ fprintf(stderr, "E: curl_multi_fdset\n");
+ return EXIT_FAILURE;
+ }
+
+ if (curl_multi_timeout(cm, &L)) {
+ fprintf(stderr, "E: curl_multi_timeout\n");
+ return EXIT_FAILURE;
+ }
+ if (L == -1)
+ L = 100;
+
+ if (M == -1) {
+#ifdef WIN32
+ Sleep(L);
+#else
+ sleep(L / 1000);
+#endif
+ } else {
+ T.tv_sec = L/1000;
+ T.tv_usec = (L%1000)*1000;
+
+ if (0 > select(M+1, &R, &W, &E, &T)) {
+ fprintf(stderr, "E: select(%i,,,,%li): %i: %s\n",
+ M+1, L, errno, strerror(errno));
+ return EXIT_FAILURE;
+ }
+ }
+ }
+
+ while ((msg = curl_multi_info_read(cm, &Q))) {
+ if (msg->msg == CURLMSG_DONE) {
+ char *url;
+ CURL *e = msg->easy_handle;
+ curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);
+ fprintf(stderr, "R: %d - %s <%s>\n",
+ msg->data.result, curl_easy_strerror(msg->data.result), url);
+ curl_multi_remove_handle(cm, e);
+ curl_easy_cleanup(e);
+ }
+ else {
+ fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
+ }
+ if (C < CNT) {
+ init(cm, C++);
+ U++; /* just to prevent it from remaining at 0 if there are more
+ URLs to get */
+ }
+ }
+ }
+
+ curl_multi_cleanup(cm);
+ curl_global_cleanup();
+
+ return EXIT_SUCCESS;
+}
diff --git a/docs/examples/Makefile.am b/docs/examples/Makefile.am
new file mode 100644
index 000000000..865f09371
--- /dev/null
+++ b/docs/examples/Makefile.am
@@ -0,0 +1,64 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
+AUTOMAKE_OPTIONS = foreign nostdinc
+
+EXTRA_DIST = README Makefile.example Makefile.inc Makefile.m32 \
+ Makefile.netware makefile.dj $(COMPLICATED_EXAMPLES)
+
+# Specify our include paths here, and do it relative to $(top_srcdir) and
+# $(top_builddir), to ensure that these paths which belong to the library
+# being currently built and tested are searched before the library which
+# might possibly already be installed in the system.
+#
+# $(top_builddir)/include/curl for generated curlbuild.h included from curl.h
+# $(top_builddir)/include for generated curlbuild.h included from lib/setup.h
+# $(top_srcdir)/include is for libcurl's external include files
+
+AM_CPPFLAGS = -I$(top_builddir)/include/curl \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include
+
+LIBDIR = $(top_builddir)/lib
+
+# Avoid libcurl obsolete stuff
+AM_CPPFLAGS += -DCURL_NO_OLDIES
+
+# Mostly for Windows build targets, when using static libcurl
+if USE_CPPFLAG_CURL_STATICLIB
+AM_CPPFLAGS += -DCURL_STATICLIB
+endif
+
+# Prevent LIBS from being used for all link targets
+LIBS = $(BLANK_AT_MAKETIME)
+
+# Dependencies
+if USE_EXPLICIT_LIB_DEPS
+LDADD = $(LIBDIR)/libcurl.la @LIBCURL_LIBS@
+else
+LDADD = $(LIBDIR)/libcurl.la
+endif
+
+# Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines
+include Makefile.inc
+
+all: $(check_PROGRAMS)
diff --git a/docs/examples/Makefile.example b/docs/examples/Makefile.example
new file mode 100644
index 000000000..dfd117873
--- /dev/null
+++ b/docs/examples/Makefile.example
@@ -0,0 +1,53 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
+# What to call the final executable
+TARGET = example
+
+# Which object files that the executable consists of
+OBJS= ftpget.o
+
+# What compiler to use
+CC = gcc
+
+# Compiler flags, -g for debug, -c to make an object file
+CFLAGS = -c -g
+
+# This should point to a directory that holds libcurl, if it isn't
+# in the system's standard lib dir
+# We also set a -L to include the directory where we have the openssl
+# libraries
+LDFLAGS = -L/home/dast/lib -L/usr/local/ssl/lib
+
+# We need -lcurl for the curl stuff
+# We need -lsocket and -lnsl when on Solaris
+# We need -lssl and -lcrypto when using libcurl with SSL support
+# We need -lpthread for the pthread example
+LIBS = -lcurl -lsocket -lnsl -lssl -lcrypto
+
+# Link the target with all objects and libraries
+$(TARGET) : $(OBJS)
+ $(CC) -o $(TARGET) $(OBJS) $(LDFLAGS) $(LIBS)
+
+# Compile the source files into object files
+ftpget.o : ftpget.c
+ $(CC) $(CFLAGS) $<
diff --git a/docs/examples/Makefile.inc b/docs/examples/Makefile.inc
new file mode 100644
index 000000000..9aabfcabd
--- /dev/null
+++ b/docs/examples/Makefile.inc
@@ -0,0 +1,15 @@
+# These are all libcurl example programs to be test compiled
+check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \
+ fopen ftpget ftpgetresp ftpupload getinfo getinmemory http-post httpput \
+ https multi-app multi-debugcallback multi-double multi-post multi-single \
+ persistant post-callback postit2 sepheaders simple simplepost simplessl \
+ sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \
+ smtp-multi simplesmtp smtp-tls rtsp externalsocket resolve \
+ progressfunc pop3s pop3slist imap url2file sftpget ftpsget
+
+# These examples require external dependencies that may not be commonly
+# available on POSIX systems, so don't bother attempting to compile them here.
+COMPLICATED_EXAMPLES = curlgtk.c curlx.c htmltitle.cpp cacertinmem.c \
+ ftpuploadresume.c ghiper.c hiperfifo.c htmltidy.c multithread.c \
+ opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c \
+ smooth-gtk-thread.c version-check.pl href_extractor.c asiohiper.cpp
diff --git a/docs/examples/Makefile.m32 b/docs/examples/Makefile.m32
new file mode 100644
index 000000000..c1db6207a
--- /dev/null
+++ b/docs/examples/Makefile.m32
@@ -0,0 +1,282 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+#
+## Makefile for building curl examples with MingW (GCC-3.2 or later)
+## and optionally OpenSSL (0.9.8), libssh2 (1.3), zlib (1.2.5), librtmp (2.3)
+##
+## Usage: mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...]
+## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-spi-winidn
+##
+## Hint: you can also set environment vars to control the build, f.e.:
+## set ZLIB_PATH=c:/zlib-1.2.7
+## set ZLIB=1
+#
+###########################################################################
+
+# Edit the path below to point to the base of your Zlib sources.
+ifndef ZLIB_PATH
+ZLIB_PATH = ../../../zlib-1.2.7
+endif
+# Edit the path below to point to the base of your OpenSSL package.
+ifndef OPENSSL_PATH
+OPENSSL_PATH = ../../../openssl-0.9.8x
+endif
+# Edit the path below to point to the base of your LibSSH2 package.
+ifndef LIBSSH2_PATH
+LIBSSH2_PATH = ../../../libssh2-1.4.2
+endif
+# Edit the path below to point to the base of your librtmp package.
+ifndef LIBRTMP_PATH
+LIBRTMP_PATH = ../../../librtmp-2.3
+endif
+# Edit the path below to point to the base of your libidn package.
+ifndef LIBIDN_PATH
+LIBIDN_PATH = ../../../libidn-1.18
+endif
+# Edit the path below to point to the base of your MS IDN package.
+# Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1
+# http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ad6158d7-ddba-416a-9109-07607425a815
+ifndef WINIDN_PATH
+WINIDN_PATH = ../../../Microsoft IDN Mitigation APIs
+endif
+# Edit the path below to point to the base of your Novell LDAP NDK.
+ifndef LDAP_SDK
+LDAP_SDK = c:/novell/ndk/cldapsdk/win32
+endif
+
+PROOT = ../..
+
+# Edit the path below to point to the base of your c-ares package.
+ifndef LIBCARES_PATH
+LIBCARES_PATH = $(PROOT)/ares
+endif
+
+# Edit the var below to set to your architecture or set environment var.
+ifndef ARCH
+ARCH = w32
+endif
+
+CC = $(CROSSPREFIX)gcc
+CFLAGS = -g -O2 -Wall
+CFLAGS += -fno-strict-aliasing
+ifeq ($(ARCH),w64)
+CFLAGS += -D_AMD64_
+endif
+# comment LDFLAGS below to keep debug info
+LDFLAGS = -s
+RC = $(CROSSPREFIX)windres
+RCFLAGS = --include-dir=$(PROOT)/include -O COFF -i
+
+# Platform-dependent helper tool macros
+ifeq ($(findstring /sh,$(SHELL)),/sh)
+DEL = rm -f $1
+RMDIR = rm -fr $1
+MKDIR = mkdir -p $1
+COPY = -cp -afv $1 $2
+#COPYR = -cp -afr $1/* $2
+COPYR = -rsync -aC $1/* $2
+TOUCH = touch $1
+CAT = cat
+ECHONL = echo ""
+DL = '
+else
+ifeq "$(OS)" "Windows_NT"
+DEL = -del 2>NUL /q /f $(subst /,\,$1)
+RMDIR = -rd 2>NUL /q /s $(subst /,\,$1)
+else
+DEL = -del 2>NUL $(subst /,\,$1)
+RMDIR = -deltree 2>NUL /y $(subst /,\,$1)
+endif
+MKDIR = -md 2>NUL $(subst /,\,$1)
+COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2)
+COPYR = -xcopy 2>NUL /q /y /e $(subst /,\,$1) $(subst /,\,$2)
+TOUCH = copy 2>&1>NUL /b $(subst /,\,$1) +,,
+CAT = type
+ECHONL = $(ComSpec) /c echo.
+endif
+
+########################################################
+## Nothing more to do below this line!
+
+ifeq ($(findstring -dyn,$(CFG)),-dyn)
+DYN = 1
+endif
+ifeq ($(findstring -ares,$(CFG)),-ares)
+ARES = 1
+endif
+ifeq ($(findstring -rtmp,$(CFG)),-rtmp)
+RTMP = 1
+SSL = 1
+ZLIB = 1
+endif
+ifeq ($(findstring -ssh2,$(CFG)),-ssh2)
+SSH2 = 1
+SSL = 1
+ZLIB = 1
+endif
+ifeq ($(findstring -ssl,$(CFG)),-ssl)
+SSL = 1
+endif
+ifeq ($(findstring -zlib,$(CFG)),-zlib)
+ZLIB = 1
+endif
+ifeq ($(findstring -idn,$(CFG)),-idn)
+IDN = 1
+endif
+ifeq ($(findstring -winidn,$(CFG)),-winidn)
+WINIDN = 1
+endif
+ifeq ($(findstring -sspi,$(CFG)),-sspi)
+SSPI = 1
+endif
+ifeq ($(findstring -spnego,$(CFG)),-spnego)
+SPNEGO = 1
+endif
+ifeq ($(findstring -ldaps,$(CFG)),-ldaps)
+LDAPS = 1
+endif
+ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
+IPV6 = 1
+endif
+ifeq ($(findstring -metalink,$(CFG)),-metalink)
+METALINK = 1
+endif
+ifeq ($(findstring -winssl,$(CFG)),-winssl)
+SCHANNEL = 1
+SSPI = 1
+endif
+
+INCLUDES = -I. -I$(PROOT) -I$(PROOT)/include -I$(PROOT)/lib
+
+ifdef DYN
+ curl_DEPENDENCIES = $(PROOT)/lib/libcurldll.a $(PROOT)/lib/libcurl.dll
+ curl_LDADD = -L$(PROOT)/lib -lcurldll
+else
+ curl_DEPENDENCIES = $(PROOT)/lib/libcurl.a
+ curl_LDADD = -L$(PROOT)/lib -lcurl
+ CFLAGS += -DCURL_STATICLIB
+ LDFLAGS += -static
+endif
+ifdef ARES
+ ifndef DYN
+ curl_DEPENDENCIES += $(LIBCARES_PATH)/libcares.a
+ endif
+ CFLAGS += -DUSE_ARES
+ curl_LDADD += -L"$(LIBCARES_PATH)" -lcares
+endif
+ifdef RTMP
+ CFLAGS += -DUSE_LIBRTMP
+ curl_LDADD += -L"$(LIBRTMP_PATH)/librtmp" -lrtmp -lwinmm
+endif
+ifdef SSH2
+ CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H
+ curl_LDADD += -L"$(LIBSSH2_PATH)/win32" -lssh2
+endif
+ifdef SSL
+ ifndef OPENSSL_LIBPATH
+ OPENSSL_LIBS = -lssl -lcrypto
+ ifeq "$(wildcard $(OPENSSL_PATH)/out)" "$(OPENSSL_PATH)/out"
+ OPENSSL_LIBPATH = $(OPENSSL_PATH)/out
+ ifdef DYN
+ OPENSSL_LIBS = -lssl32 -leay32
+ endif
+ endif
+ ifeq "$(wildcard $(OPENSSL_PATH)/lib)" "$(OPENSSL_PATH)/lib"
+ OPENSSL_LIBPATH = $(OPENSSL_PATH)/lib
+ endif
+ endif
+ ifndef DYN
+ OPENSSL_LIBS += -lgdi32 -lcrypt32
+ endif
+ CFLAGS += -DUSE_SSLEAY
+ curl_LDADD += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS)
+endif
+ifdef ZLIB
+ INCLUDES += -I"$(ZLIB_PATH)"
+ CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H
+ curl_LDADD += -L"$(ZLIB_PATH)" -lz
+endif
+ifdef IDN
+ CFLAGS += -DUSE_LIBIDN
+ curl_LDADD += -L"$(LIBIDN_PATH)/lib" -lidn
+else
+ifdef WINIDN
+ CFLAGS += -DUSE_WIN32_IDN
+ curl_LDADD += -L"$(WINIDN_PATH)" -lnormaliz
+endif
+endif
+ifdef SSPI
+ CFLAGS += -DUSE_WINDOWS_SSPI
+ ifdef SCHANNEL
+ CFLAGS += -DUSE_SCHANNEL
+ endif
+endif
+ifdef SPNEGO
+ CFLAGS += -DHAVE_SPNEGO
+endif
+ifdef IPV6
+ CFLAGS += -DENABLE_IPV6 -D_WIN32_WINNT=0x0501
+endif
+ifdef LDAPS
+ CFLAGS += -DHAVE_LDAP_SSL
+endif
+ifdef USE_LDAP_NOVELL
+ CFLAGS += -DCURL_HAS_NOVELL_LDAPSDK
+ curl_LDADD += -L"$(LDAP_SDK)/lib/mscvc" -lldapsdk -lldapssl -lldapx
+endif
+ifdef USE_LDAP_OPENLDAP
+ CFLAGS += -DCURL_HAS_OPENLDAP_LDAPSDK
+ curl_LDADD += -L"$(LDAP_SDK)/lib" -lldap -llber
+endif
+ifndef USE_LDAP_NOVELL
+ifndef USE_LDAP_OPENLDAP
+ curl_LDADD += -lwldap32
+endif
+endif
+curl_LDADD += -lws2_32
+
+# Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines
+include Makefile.inc
+
+check_PROGRAMS := $(patsubst %,%.exe,$(strip $(check_PROGRAMS)))
+check_PROGRAMS += ftpuploadresume.exe synctime.exe
+
+.PRECIOUS: %.o
+
+
+all: $(check_PROGRAMS)
+
+%.exe: %.o $(curl_DEPENDENCIES)
+ $(CC) $(LDFLAGS) -o $@ $< $(curl_LDADD)
+
+%.o: %.c
+ $(CC) $(INCLUDES) $(CFLAGS) -c $<
+
+%.res: %.rc
+ $(RC) $(RCFLAGS) $< -o $@
+
+clean:
+ @$(call DEL, $(check_PROGRAMS:.exe=.o))
+
+distclean vclean: clean
+ @$(call DEL, $(check_PROGRAMS))
+
diff --git a/docs/examples/Makefile.netware b/docs/examples/Makefile.netware
new file mode 100644
index 000000000..934f17aef
--- /dev/null
+++ b/docs/examples/Makefile.netware
@@ -0,0 +1,441 @@
+#################################################################
+#
+## Makefile for building curl.nlm (NetWare version - gnu make)
+## Use: make -f Makefile.netware
+##
+## Comments to: Guenter Knauf http://www.gknw.net/phpbb
+#
+#################################################################
+
+# Edit the path below to point to the base of your Novell NDK.
+ifndef NDKBASE
+NDKBASE = c:/novell
+endif
+
+# Edit the path below to point to the base of your Zlib sources.
+ifndef ZLIB_PATH
+ZLIB_PATH = ../../../zlib-1.2.7
+endif
+
+# Edit the path below to point to the base of your OpenSSL package.
+ifndef OPENSSL_PATH
+OPENSSL_PATH = ../../../openssl-0.9.8x
+endif
+
+# Edit the path below to point to the base of your LibSSH2 package.
+ifndef LIBSSH2_PATH
+LIBSSH2_PATH = ../../../libssh2-1.4.2
+endif
+
+# Edit the path below to point to the base of your axTLS package.
+ifndef AXTLS_PATH
+AXTLS_PATH = ../../../axTLS-1.2.7
+endif
+
+# Edit the path below to point to the base of your libidn package.
+ifndef LIBIDN_PATH
+LIBIDN_PATH = ../../../libidn-1.18
+endif
+
+# Edit the path below to point to the base of your librtmp package.
+ifndef LIBRTMP_PATH
+LIBRTMP_PATH = ../../../librtmp-2.3
+endif
+
+# Edit the path below to point to the base of your fbopenssl package.
+ifndef FBOPENSSL_PATH
+FBOPENSSL_PATH = ../../fbopenssl-0.4
+endif
+
+# Edit the path below to point to the base of your c-ares package.
+ifndef LIBCARES_PATH
+LIBCARES_PATH = ../../ares
+endif
+
+ifndef INSTDIR
+INSTDIR = ..$(DS)..$(DS)curl-$(LIBCURL_VERSION_STR)-bin-nw
+endif
+
+# Edit the vars below to change NLM target settings.
+TARGET = examples
+VERSION = $(LIBCURL_VERSION)
+COPYR = Copyright (C) $(LIBCURL_COPYRIGHT_STR)
+DESCR = cURL ($(LIBARCH))
+MTSAFE = YES
+STACK = 8192
+SCREEN = Example Program
+# Comment the line below if you dont want to load protected automatically.
+# LDRING = 3
+
+# Uncomment the next line to enable linking with POSIX semantics.
+# POSIXFL = 1
+
+# Edit the var below to point to your lib architecture.
+ifndef LIBARCH
+LIBARCH = LIBC
+endif
+
+# must be equal to NDEBUG or DEBUG, CURLDEBUG
+ifndef DB
+DB = NDEBUG
+endif
+# Optimization: -O<n> or debugging: -g
+ifeq ($(DB),NDEBUG)
+ OPT = -O2
+ OBJDIR = release
+else
+ OPT = -g
+ OBJDIR = debug
+endif
+
+# The following lines defines your compiler.
+ifdef CWFolder
+ METROWERKS = $(CWFolder)
+endif
+ifdef METROWERKS
+ # MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support
+ MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support/Metrowerks Support
+ CC = mwccnlm
+else
+ CC = gcc
+endif
+PERL = perl
+# Here you can find a native Win32 binary of the original awk:
+# http://www.gknw.net/development/prgtools/awk-20100523.zip
+AWK = awk
+CP = cp -afv
+MKDIR = mkdir
+# RM = rm -f
+# If you want to mark the target as MTSAFE you will need a tool for
+# generating the xdc data for the linker; here's a minimal tool:
+# http://www.gknw.net/development/prgtools/mkxdc.zip
+MPKXDC = mkxdc
+
+# LIBARCH_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH))
+LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
+
+# Include the version info retrieved from curlver.h
+-include $(OBJDIR)/version.inc
+
+# Global flags for all compilers
+CFLAGS += $(OPT) -D$(DB) -DNETWARE -DHAVE_CONFIG_H -nostdinc
+
+ifeq ($(CC),mwccnlm)
+LD = mwldnlm
+LDFLAGS = -nostdlib $< $(PRELUDE) $(LDLIBS) -o $@ -commandfile
+LIBEXT = lib
+CFLAGS += -gccinc -inline off -opt nointrinsics -proc 586
+CFLAGS += -relax_pointers
+#CFLAGS += -w on
+ifeq ($(LIBARCH),LIBC)
+ifeq ($(POSIXFL),1)
+ PRELUDE = $(NDK_LIBC)/imports/posixpre.o
+else
+ PRELUDE = $(NDK_LIBC)/imports/libcpre.o
+endif
+ CFLAGS += -align 4
+else
+ # PRELUDE = $(NDK_CLIB)/imports/clibpre.o
+ # to avoid the __init_* / __deinit_* whoes dont use prelude from NDK
+ PRELUDE = "$(MWCW_PATH)/libraries/runtime/prelude.obj"
+ # CFLAGS += -include "$(MWCW_PATH)/headers/nlm_clib_prefix.h"
+ CFLAGS += -align 1
+endif
+else
+LD = nlmconv
+LDFLAGS = -T
+LIBEXT = a
+CFLAGS += -m32
+CFLAGS += -fno-builtin -fno-strict-aliasing
+ifeq ($(findstring gcc,$(CC)),gcc)
+CFLAGS += -fpcc-struct-return
+endif
+CFLAGS += -Wall # -pedantic
+ifeq ($(LIBARCH),LIBC)
+ifeq ($(POSIXFL),1)
+ PRELUDE = $(NDK_LIBC)/imports/posixpre.gcc.o
+else
+ PRELUDE = $(NDK_LIBC)/imports/libcpre.gcc.o
+endif
+else
+ # PRELUDE = $(NDK_CLIB)/imports/clibpre.gcc.o
+ # to avoid the __init_* / __deinit_* whoes dont use prelude from NDK
+ # http://www.gknw.net/development/mk_nlm/gcc_pre.zip
+ PRELUDE = $(NDK_ROOT)/pre/prelude.o
+ CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h
+endif
+endif
+
+NDK_ROOT = $(NDKBASE)/ndk
+ifndef NDK_CLIB
+NDK_CLIB = $(NDK_ROOT)/nwsdk
+endif
+ifndef NDK_LIBC
+NDK_LIBC = $(NDK_ROOT)/libc
+endif
+ifndef NDK_LDAP
+NDK_LDAP = $(NDK_ROOT)/cldapsdk/netware
+endif
+CURL_INC = ../../include
+CURL_LIB = ../../lib
+
+INCLUDES = -I$(CURL_INC)
+
+ifeq ($(findstring -static,$(CFG)),-static)
+LINK_STATIC = 1
+endif
+ifeq ($(findstring -ares,$(CFG)),-ares)
+WITH_ARES = 1
+endif
+ifeq ($(findstring -rtmp,$(CFG)),-rtmp)
+WITH_RTMP = 1
+WITH_SSL = 1
+WITH_ZLIB = 1
+endif
+ifeq ($(findstring -ssh2,$(CFG)),-ssh2)
+WITH_SSH2 = 1
+WITH_SSL = 1
+WITH_ZLIB = 1
+endif
+ifeq ($(findstring -axtls,$(CFG)),-axtls)
+WITH_AXTLS = 1
+WITH_SSL =
+else
+ifeq ($(findstring -ssl,$(CFG)),-ssl)
+WITH_SSL = 1
+endif
+endif
+ifeq ($(findstring -zlib,$(CFG)),-zlib)
+WITH_ZLIB = 1
+endif
+ifeq ($(findstring -idn,$(CFG)),-idn)
+WITH_IDN = 1
+endif
+ifeq ($(findstring -spnego,$(CFG)),-spnego)
+WITH_SPNEGO = 1
+endif
+ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
+ENABLE_IPV6 = 1
+endif
+
+ifdef LINK_STATIC
+ LDLIBS = $(CURL_LIB)/libcurl.$(LIBEXT)
+ifdef WITH_ARES
+ LDLIBS += $(LIBCARES_PATH)/libcares.$(LIBEXT)
+endif
+else
+ MODULES = libcurl.nlm
+ IMPORTS = @$(CURL_LIB)/libcurl.imp
+endif
+ifdef WITH_SSH2
+ # INCLUDES += -I$(LIBSSH2_PATH)/include
+ifdef LINK_STATIC
+ LDLIBS += $(LIBSSH2_PATH)/nw/libssh2.$(LIBEXT)
+else
+ MODULES += libssh2.nlm
+ IMPORTS += @$(LIBSSH2_PATH)/nw/libssh2.imp
+endif
+endif
+ifdef WITH_RTMP
+ # INCLUDES += -I$(LIBRTMP_PATH)
+ifdef LINK_STATIC
+ LDLIBS += $(LIBRTMP_PATH)/librtmp/librtmp.$(LIBEXT)
+endif
+endif
+ifdef WITH_SSL
+ INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L)
+ LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/ssl.$(LIBEXT)
+ LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT)
+ IMPORTS += GetProcessSwitchCount RunningProcess
+ifdef WITH_SPNEGO
+ # INCLUDES += -I$(FBOPENSSL_PATH)/include
+ LDLIBS += $(FBOPENSSL_PATH)/nw/fbopenssl.$(LIBEXT)
+endif
+else
+ifdef WITH_AXTLS
+ INCLUDES += -I$(AXTLS_PATH)/inc
+ifdef LINK_STATIC
+ LDLIBS += $(AXTLS_PATH)/lib/libaxtls.$(LIBEXT)
+else
+ MODULES += libaxtls.nlm
+ IMPORTS += $(AXTLS_PATH)/lib/libaxtls.imp
+endif
+endif
+endif
+ifdef WITH_ZLIB
+ # INCLUDES += -I$(ZLIB_PATH)
+ifdef LINK_STATIC
+ LDLIBS += $(ZLIB_PATH)/nw/$(LIBARCH)/libz.$(LIBEXT)
+else
+ MODULES += libz.nlm
+ IMPORTS += @$(ZLIB_PATH)/nw/$(LIBARCH)/libz.imp
+endif
+endif
+ifdef WITH_IDN
+ # INCLUDES += -I$(LIBIDN_PATH)/include
+ LDLIBS += $(LIBIDN_PATH)/lib/libidn.$(LIBEXT)
+endif
+
+ifeq ($(LIBARCH),LIBC)
+ INCLUDES += -I$(NDK_LIBC)/include
+ # INCLUDES += -I$(NDK_LIBC)/include/nks
+ # INCLUDES += -I$(NDK_LIBC)/include/winsock
+ CFLAGS += -D_POSIX_SOURCE
+else
+ INCLUDES += -I$(NDK_CLIB)/include/nlm
+ # INCLUDES += -I$(NDK_CLIB)/include
+endif
+ifndef DISABLE_LDAP
+ # INCLUDES += -I$(NDK_LDAP)/$(LIBARCH_L)/inc
+endif
+CFLAGS += $(INCLUDES)
+
+ifeq ($(MTSAFE),YES)
+ XDCOPT = -n
+endif
+ifeq ($(MTSAFE),NO)
+ XDCOPT = -u
+endif
+ifdef XDCOPT
+ XDCDATA = $(OBJDIR)/$(TARGET).xdc
+endif
+
+ifeq ($(findstring /sh,$(SHELL)),/sh)
+DL = '
+DS = /
+PCT = %
+#-include $(NDKBASE)/nlmconv/ncpfs.inc
+else
+DS = \\
+PCT = %%
+endif
+
+# Makefile.inc provides the CSOURCES and HHEADERS defines
+include Makefile.inc
+
+check_PROGRAMS := $(patsubst %,%.nlm,$(strip $(check_PROGRAMS)))
+
+.PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.def $(OBJDIR)/%.xdc
+
+
+all: prebuild $(check_PROGRAMS)
+
+prebuild: $(OBJDIR) $(OBJDIR)/version.inc
+
+$(OBJDIR)/%.o: %.c
+ @echo Compiling $<
+ $(CC) $(CFLAGS) -c $< -o $@
+
+$(OBJDIR)/version.inc: $(CURL_INC)/curl/curlver.h $(OBJDIR)
+ @echo Creating $@
+ @$(AWK) -f ../../packages/NetWare/get_ver.awk $< > $@
+
+install: $(INSTDIR) all
+ @$(CP) $(check_PROGRAMS) $(INSTDIR)
+
+clean:
+ -$(RM) -r $(OBJDIR)
+
+distclean vclean: clean
+ -$(RM) $(check_PROGRAMS)
+
+$(OBJDIR) $(INSTDIR):
+ @$(MKDIR) $@
+
+%.nlm: $(OBJDIR)/%.o $(OBJDIR)/%.def $(XDCDATA)
+ @echo Linking $@
+ @-$(RM) $@
+ @$(LD) $(LDFLAGS) $(OBJDIR)/$(@:.nlm=.def)
+
+$(OBJDIR)/%.xdc: Makefile.netware
+ @echo Creating $@
+ @$(MPKXDC) $(XDCOPT) $@
+
+$(OBJDIR)/%.def: Makefile.netware
+ @echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
+ @echo $(DL)# Do not edit this file - it is created by Make!$(DL) >> $@
+ @echo $(DL)# All your changes will be lost!!$(DL) >> $@
+ @echo $(DL)#$(DL) >> $@
+ @echo $(DL)copyright "$(COPYR)"$(DL) >> $@
+ @echo $(DL)description "$(DESCR) $(notdir $(@:.def=)) Example"$(DL) >> $@
+ @echo $(DL)version $(VERSION)$(DL) >> $@
+ifdef NLMTYPE
+ @echo $(DL)type $(NLMTYPE)$(DL) >> $@
+endif
+ifdef STACK
+ @echo $(DL)stack $(STACK)$(DL) >> $@
+endif
+ifdef SCREEN
+ @echo $(DL)screenname "$(DESCR) $(notdir $(@:.def=)) $(SCREEN)"$(DL) >> $@
+else
+ @echo $(DL)screenname "DEFAULT"$(DL) >> $@
+endif
+ifneq ($(DB),NDEBUG)
+ @echo $(DL)debug$(DL) >> $@
+endif
+ @echo $(DL)threadname "_$(notdir $(@:.def=))"$(DL) >> $@
+ifdef XDCDATA
+ @echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@
+endif
+ifeq ($(LDRING),0)
+ @echo $(DL)flag_on 16$(DL) >> $@
+endif
+ifeq ($(LDRING),3)
+ @echo $(DL)flag_on 512$(DL) >> $@
+endif
+ifeq ($(LIBARCH),CLIB)
+ @echo $(DL)start _Prelude$(DL) >> $@
+ @echo $(DL)exit _Stop$(DL) >> $@
+ @echo $(DL)import @$(NDK_CLIB)/imports/clib.imp$(DL) >> $@
+ @echo $(DL)import @$(NDK_CLIB)/imports/threads.imp$(DL) >> $@
+ @echo $(DL)import @$(NDK_CLIB)/imports/nlmlib.imp$(DL) >> $@
+ @echo $(DL)import @$(NDK_CLIB)/imports/socklib.imp$(DL) >> $@
+ @echo $(DL)module clib$(DL) >> $@
+ifndef DISABLE_LDAP
+ @echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapsdk.imp$(DL) >> $@
+ @echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapssl.imp$(DL) >> $@
+# @echo $(DL)import @$(NDK_LDAP)/clib/imports/ldapx.imp$(DL) >> $@
+ @echo $(DL)module ldapsdk ldapssl$(DL) >> $@
+endif
+else
+ifeq ($(POSIXFL),1)
+ @echo $(DL)flag_on 4194304$(DL) >> $@
+endif
+ @echo $(DL)flag_on 64$(DL) >> $@
+ @echo $(DL)pseudopreemption$(DL) >> $@
+ifeq ($(findstring posixpre,$(PRELUDE)),posixpre)
+ @echo $(DL)start POSIX_Start$(DL) >> $@
+ @echo $(DL)exit POSIX_Stop$(DL) >> $@
+ @echo $(DL)check POSIX_CheckUnload$(DL) >> $@
+else
+ @echo $(DL)start _LibCPrelude$(DL) >> $@
+ @echo $(DL)exit _LibCPostlude$(DL) >> $@
+ @echo $(DL)check _LibCCheckUnload$(DL) >> $@
+endif
+ @echo $(DL)import @$(NDK_LIBC)/imports/libc.imp$(DL) >> $@
+ @echo $(DL)import @$(NDK_LIBC)/imports/netware.imp$(DL) >> $@
+ @echo $(DL)module libc$(DL) >> $@
+ifndef DISABLE_LDAP
+ @echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapsdk.imp$(DL) >> $@
+ @echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapssl.imp$(DL) >> $@
+# @echo $(DL)import @$(NDK_LDAP)/libc/imports/lldapx.imp$(DL) >> $@
+ @echo $(DL)module lldapsdk lldapssl$(DL) >> $@
+endif
+endif
+ifdef MODULES
+ @echo $(DL)module $(MODULES)$(DL) >> $@
+endif
+ifdef EXPORTS
+ @echo $(DL)export $(EXPORTS)$(DL) >> $@
+endif
+ifdef IMPORTS
+ @echo $(DL)import $(IMPORTS)$(DL) >> $@
+endif
+ifeq ($(findstring nlmconv,$(LD)),nlmconv)
+ @echo $(DL)input $(PRELUDE)$(DL) >> $@
+ @echo $(DL)input $(@:.def=.o)$(DL) >> $@
+ifdef LDLIBS
+ @echo $(DL)input $(LDLIBS)$(DL) >> $@
+endif
+ @echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@
+endif
diff --git a/docs/examples/README b/docs/examples/README
new file mode 100644
index 000000000..270048a6c
--- /dev/null
+++ b/docs/examples/README
@@ -0,0 +1,80 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+This directory is for libcurl programming examples. They are meant to show
+some simple steps on how you can build your own application to take full
+advantage of libcurl.
+
+If you end up with other small but still useful example sources, please mail
+them for submission in future packages and on the web site.
+
+BUILDING
+
+The Makefile.example is an example makefile that could be used to build these
+examples. Just edit the file according to your system and requirements first.
+
+Most examples should build fine using a command line like this:
+
+ $ `curl-config --cc --cflags --libs` -o example example.c
+
+Some compilers don't like having the arguments in this order but instead
+want you do reorganize them like:
+
+ $ `curl-config --cc` -o example example.c `curl-config --cflags --libs`
+
+*PLEASE* do not use the curl.haxx.se site as a test target for your libcurl
+applications/experiments. Even if some of the examples use that site as a URL
+at some places, it doesn't mean that the URLs work or that we expect you to
+actually torture our web site with your tests! Thanks.
+
+EXAMPLES
+
+anyauthput.c - HTTP PUT using "any" authentication method
+cacertinmem.c - Use a built-in PEM certificate to retrieve a https page
+cookie_interface.c - shows usage of simple cookie interface
+curlgtk.c - download using a GTK progress bar
+curlx.c - getting file info from the remote cert data
+debug.c - showing how to use the debug callback
+fileupload.c - uploading to a file:// URL
+fopen.c - fopen() layer that supports opening URLs and files
+ftpget.c - simple getting a file from FTP
+ftpgetresp.c - get the response strings from the FTP server
+ftpupload.c - upload a file to an FTP server
+ftpuploadresume.c - resume an upload to an FTP server
+getinfo.c - get the Content-Type from the recent transfer
+getinmemory.c - download a file to memory only
+ghiper.c - curl_multi_socket() using code with glib-2
+hiperfifo.c - downloads all URLs written to the fifo, using
+ curl_multi_socket() and libevent
+htmltidy.c - download a document and use libtidy to parse the HTML
+htmltitle.cc - download a HTML file and extract the <title> tag from a HTML
+ page using libxml
+http-post.c - HTTP POST
+httpput.c - HTTP PUT a local file
+https.c - simple HTTPS transfer
+imap.c - simple IMAP transfer
+multi-app.c - a multi-interface app
+multi-debugcallback.c - a multi-interface app using the debug callback
+multi-double.c - a multi-interface app doing two simultaneous transfers
+multi-post.c - a multi-interface app doing a multipart formpost
+multi-single.c - a multi-interface app getting a single file
+multithread.c - an example using multi-treading transferring multiple files
+opensslthreadlock.c - show how to do locking when using OpenSSL multi-threaded
+persistant.c - request two URLs with a persistent connection
+pop3s.c - POP3S transfer
+pop3slist.c - POP3S LIST
+post-callback.c - send a HTTP POST using a callback
+postit2.c - send a HTTP multipart formpost
+sampleconv.c - showing how a program on a non-ASCII platform would invoke
+ callbacks to do its own codeset conversions instead of using
+ the built-in iconv functions in libcurl
+sepheaders.c - download headers to a separate file
+simple.c - the most simple download a URL source
+simplepost.c - HTTP POST
+simplessl.c - HTTPS example with certificates many options set
+synctime.c - Sync local time by extracting date from remote HTTP servers
+url2file.c - download a document and store it in a file
+10-at-a-time.c - Download many files simultaneously, 10 at a time.
diff --git a/docs/examples/adddocsref.pl b/docs/examples/adddocsref.pl
new file mode 100755
index 000000000..2dcc24b63
--- /dev/null
+++ b/docs/examples/adddocsref.pl
@@ -0,0 +1,35 @@
+#!/usr/bin/perl
+
+# pass files as argument(s)
+
+my $docroot="http://curl.haxx.se/libcurl/c";
+
+for $f (@ARGV) {
+ open(NEW, ">$f.new");
+ open(F, "<$f");
+ while(<F>) {
+ my $l = $_;
+ if($l =~ /\/* $docroot/) {
+ # just ignore preciously added refs
+ }
+ elsif($l =~ /^( *).*curl_easy_setopt\([^,]*, *([^ ,]*) *,/) {
+ my ($prefix, $anc) = ($1, $2);
+ $anc =~ s/_//g;
+ print NEW "$prefix/* $docroot/curl_easy_setopt.html#$anc */\n";
+ print NEW $l;
+ }
+ elsif($l =~ /^( *).*(curl_([^\(]*))\(/) {
+ my ($prefix, $func) = ($1, $2);
+ print NEW "$prefix/* $docroot/$func.html */\n";
+ print NEW $l;
+ }
+ else {
+ print NEW $l;
+ }
+ }
+ close(F);
+ close(NEW);
+
+ system("mv $f $f.org");
+ system("mv $f.new $f");
+}
diff --git a/docs/examples/anyauthput.c b/docs/examples/anyauthput.c
new file mode 100644
index 000000000..b89dca2e1
--- /dev/null
+++ b/docs/examples/anyauthput.c
@@ -0,0 +1,185 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <fcntl.h>
+#ifdef WIN32
+# include <io.h>
+#else
+# ifdef __VMS
+ typedef int intptr_t;
+# endif
+# if !defined(_AIX) && !defined(__sgi) && !defined(__osf__)
+# include <stdint.h>
+# endif
+# include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef _MSC_VER
+# ifdef _WIN64
+ typedef __int64 intptr_t;
+# else
+ typedef int intptr_t;
+# endif
+#endif
+
+#include <curl/curl.h>
+
+#if LIBCURL_VERSION_NUM < 0x070c03
+#error "upgrade your libcurl to no less than 7.12.3"
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#if defined(_AIX) || defined(__sgi) || defined(__osf__)
+#ifndef intptr_t
+#define intptr_t long
+#endif
+#endif
+
+/*
+ * This example shows a HTTP PUT operation with authentiction using "any"
+ * type. It PUTs a file given as a command line argument to the URL also given
+ * on the command line.
+ *
+ * Since libcurl 7.12.3, using "any" auth and POST/PUT requires a set ioctl
+ * function.
+ *
+ * This example also uses its own read callback.
+ */
+
+/* ioctl callback function */
+static curlioerr my_ioctl(CURL *handle, curliocmd cmd, void *userp)
+{
+ intptr_t fd = (intptr_t)userp;
+
+ (void)handle; /* not used in here */
+
+ switch(cmd) {
+ case CURLIOCMD_RESTARTREAD:
+ /* mr libcurl kindly asks as to rewind the read data stream to start */
+ if(-1 == lseek(fd, 0, SEEK_SET))
+ /* couldn't rewind */
+ return CURLIOE_FAILRESTART;
+
+ break;
+
+ default: /* ignore unknown commands */
+ return CURLIOE_UNKNOWNCMD;
+ }
+ return CURLIOE_OK; /* success! */
+}
+
+/* read callback function, fread() look alike */
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ size_t retcode;
+ curl_off_t nread;
+
+ intptr_t fd = (intptr_t)stream;
+
+ retcode = read(fd, ptr, size * nmemb);
+
+ nread = (curl_off_t)retcode;
+
+ fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T
+ " bytes from file\n", nread);
+
+ return retcode;
+}
+
+int main(int argc, char **argv)
+{
+ CURL *curl;
+ CURLcode res;
+ intptr_t hd ;
+ struct stat file_info;
+
+ char *file;
+ char *url;
+
+ if(argc < 3)
+ return 1;
+
+ file= argv[1];
+ url = argv[2];
+
+ /* get the file size of the local file */
+ hd = open(file, O_RDONLY) ;
+ fstat(hd, &file_info);
+
+ /* In windows, this will init the winsock stuff */
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ /* get a curl handle */
+ curl = curl_easy_init();
+ if(curl) {
+ /* we want to use our own read function */
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
+
+ /* which file to upload */
+ curl_easy_setopt(curl, CURLOPT_READDATA, (void*)hd);
+
+ /* set the ioctl function */
+ curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, my_ioctl);
+
+ /* pass the file descriptor to the ioctl callback as well */
+ curl_easy_setopt(curl, CURLOPT_IOCTLDATA, (void*)hd);
+
+ /* enable "uploading" (which means PUT when doing HTTP) */
+ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L) ;
+
+ /* specify target URL, and note that this URL should also include a file
+ name, not only a directory (as you can do with GTP uploads) */
+ curl_easy_setopt(curl,CURLOPT_URL, url);
+
+ /* and give the size of the upload, this supports large file sizes
+ on systems that have general support for it */
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
+ (curl_off_t)file_info.st_size);
+
+ /* tell libcurl we can use "any" auth, which lets the lib pick one, but it
+ also costs one extra round-trip and possibly sending of all the PUT
+ data twice!!! */
+ curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY);
+
+ /* set user name and password for the authentication */
+ curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password");
+
+ /* Now run off and do what you've been told! */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ close(hd); /* close the local file */
+
+ curl_global_cleanup();
+ return 0;
+}
diff --git a/docs/examples/asiohiper.cpp b/docs/examples/asiohiper.cpp
new file mode 100644
index 000000000..44836fdc1
--- /dev/null
+++ b/docs/examples/asiohiper.cpp
@@ -0,0 +1,454 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * file: asiohiper.cpp
+ * Example program to demonstrate the use of multi socket interface
+ * with boost::asio
+ *
+ * This program is in c++ and uses boost::asio instead of libevent/libev.
+ * Requires boost::asio, boost::bind and boost::system
+ *
+ * This is an adaptation of libcurl's "hiperfifo.c" and "evhiperfifo.c"
+ * sample programs. This example implements a subset of the functionality from
+ * hiperfifo.c, for full functionality refer hiperfifo.c or evhiperfifo.c
+ *
+ * Written by Lijo Antony based on hiperfifo.c by Jeff Pohlmeyer
+ *
+ * When running, the program creates an easy handle for a URL and
+ * uses the curl_multi API to fetch it.
+ *
+ * Note:
+ * For the sake of simplicity, URL is hard coded to "www.google.com"
+ *
+ * This is purely a demo app, all retrieved data is simply discarded by the write
+ * callback.
+ */
+
+
+#include <curl/curl.h>
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+
+#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
+
+/* boost::asio related objects
+ * using global variables for simplicity
+ */
+boost::asio::io_service io_service;
+boost::asio::deadline_timer timer(io_service);
+std::map<curl_socket_t, boost::asio::ip::tcp::socket *> socket_map;
+
+/* Global information, common to all connections */
+typedef struct _GlobalInfo
+{
+ CURLM *multi;
+ int still_running;
+} GlobalInfo;
+
+/* Information associated with a specific easy handle */
+typedef struct _ConnInfo
+{
+ CURL *easy;
+ char *url;
+ GlobalInfo *global;
+ char error[CURL_ERROR_SIZE];
+} ConnInfo;
+
+static void timer_cb(const boost::system::error_code & error, GlobalInfo *g);
+
+/* Update the event timer after curl_multi library calls */
+static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
+{
+ fprintf(MSG_OUT, "\nmulti_timer_cb: timeout_ms %ld", timeout_ms);
+
+ /* cancel running timer */
+ timer.cancel();
+
+ if ( timeout_ms > 0 )
+ {
+ /* update timer */
+ timer.expires_from_now(boost::posix_time::millisec(timeout_ms));
+ timer.async_wait(boost::bind(&timer_cb, _1, g));
+ }
+ else
+ {
+ /* call timeout function immediately */
+ boost::system::error_code error; /*success*/
+ timer_cb(error, g);
+ }
+
+ return 0;
+}
+
+/* Die if we get a bad CURLMcode somewhere */
+static void mcode_or_die(const char *where, CURLMcode code)
+{
+ if ( CURLM_OK != code )
+ {
+ const char *s;
+ switch ( code )
+ {
+ case CURLM_CALL_MULTI_PERFORM: s="CURLM_CALL_MULTI_PERFORM"; break;
+ case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break;
+ case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
+ case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
+ case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
+ case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
+ case CURLM_LAST: s="CURLM_LAST"; break;
+ default: s="CURLM_unknown";
+ break;
+ case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET";
+ fprintf(MSG_OUT, "\nERROR: %s returns %s", where, s);
+ /* ignore this error */
+ return;
+ }
+ fprintf(MSG_OUT, "\nERROR: %s returns %s", where, s);
+ exit(code);
+ }
+}
+
+/* Check for completed transfers, and remove their easy handles */
+static void check_multi_info(GlobalInfo *g)
+{
+ char *eff_url;
+ CURLMsg *msg;
+ int msgs_left;
+ ConnInfo *conn;
+ CURL *easy;
+ CURLcode res;
+
+ fprintf(MSG_OUT, "\nREMAINING: %d", g->still_running);
+
+ while ((msg = curl_multi_info_read(g->multi, &msgs_left)))
+ {
+ if (msg->msg == CURLMSG_DONE)
+ {
+ easy = msg->easy_handle;
+ res = msg->data.result;
+ curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
+ curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
+ fprintf(MSG_OUT, "\nDONE: %s => (%d) %s", eff_url, res, conn->error);
+ curl_multi_remove_handle(g->multi, easy);
+ free(conn->url);
+ curl_easy_cleanup(easy);
+ free(conn);
+ }
+ }
+}
+
+/* Called by asio when there is an action on a socket */
+static void event_cb(GlobalInfo * g, boost::asio::ip::tcp::socket * tcp_socket, int action)
+{
+ fprintf(MSG_OUT, "\nevent_cb: action=%d", action);
+
+ CURLMcode rc;
+ rc = curl_multi_socket_action(g->multi, tcp_socket->native_handle(), action, &g->still_running);
+
+ mcode_or_die("event_cb: curl_multi_socket_action", rc);
+ check_multi_info(g);
+
+ if ( g->still_running <= 0 )
+ {
+ fprintf(MSG_OUT, "\nlast transfer done, kill timeout");
+ timer.cancel();
+ }
+}
+
+/* Called by asio when our timeout expires */
+static void timer_cb(const boost::system::error_code & error, GlobalInfo *g)
+{
+ if ( !error)
+ {
+ fprintf(MSG_OUT, "\ntimer_cb: ");
+
+ CURLMcode rc;
+ rc = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0, &g->still_running);
+
+ mcode_or_die("timer_cb: curl_multi_socket_action", rc);
+ check_multi_info(g);
+ }
+}
+
+/* Clean up any data */
+static void remsock(int *f, GlobalInfo *g)
+{
+ fprintf(MSG_OUT, "\nremsock: ");
+
+ if ( f )
+ {
+ free(f);
+ }
+}
+
+static void setsock(int *fdp, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
+{
+ fprintf(MSG_OUT, "\nsetsock: socket=%d, act=%d, fdp=%p", s, act, fdp);
+
+ std::map<curl_socket_t, boost::asio::ip::tcp::socket *>::iterator it = socket_map.find(s);
+
+ if ( it == socket_map.end() )
+ {
+ fprintf(MSG_OUT, "\nsocket %d is a c-ares socket, ignoring", s);
+ return;
+ }
+
+ boost::asio::ip::tcp::socket * tcp_socket = it->second;
+
+ *fdp = act;
+
+ if ( act == CURL_POLL_IN )
+ {
+ fprintf(MSG_OUT, "\nwatching for socket to become readable");
+
+ tcp_socket->async_read_some(boost::asio::null_buffers(),
+ boost::bind(&event_cb, g,
+ tcp_socket,
+ act));
+ }
+ else if ( act == CURL_POLL_OUT )
+ {
+ fprintf(MSG_OUT, "\nwatching for socket to become writable");
+
+ tcp_socket->async_write_some(boost::asio::null_buffers(),
+ boost::bind(&event_cb, g,
+ tcp_socket,
+ act));
+ }
+ else if ( act == CURL_POLL_INOUT )
+ {
+ fprintf(MSG_OUT, "\nwatching for socket to become readable & writable");
+
+ tcp_socket->async_read_some(boost::asio::null_buffers(),
+ boost::bind(&event_cb, g,
+ tcp_socket,
+ act));
+
+ tcp_socket->async_write_some(boost::asio::null_buffers(),
+ boost::bind(&event_cb, g,
+ tcp_socket,
+ act));
+ }
+}
+
+
+static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
+{
+ int *fdp = (int *)calloc(sizeof(int), 1); /* fdp is used to store current action */
+
+ setsock(fdp, s, easy, action, g);
+ curl_multi_assign(g->multi, s, fdp);
+}
+
+/* CURLMOPT_SOCKETFUNCTION */
+static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
+{
+ fprintf(MSG_OUT, "\nsock_cb: socket=%d, what=%d, sockp=%p", s, what, sockp);
+
+ GlobalInfo *g = (GlobalInfo*) cbp;
+ int *actionp = (int*) sockp;
+ const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE"};
+
+ fprintf(MSG_OUT,
+ "\nsocket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
+
+ if ( what == CURL_POLL_REMOVE )
+ {
+ fprintf(MSG_OUT, "\n");
+ remsock(actionp, g);
+ }
+ else
+ {
+ if ( !actionp )
+ {
+ fprintf(MSG_OUT, "\nAdding data: %s", whatstr[what]);
+ addsock(s, e, what, g);
+ }
+ else
+ {
+ fprintf(MSG_OUT,
+ "\nChanging action from %s to %s",
+ whatstr[*actionp], whatstr[what]);
+ setsock(actionp, s, e, what, g);
+ }
+ }
+ return 0;
+}
+
+
+/* CURLOPT_WRITEFUNCTION */
+static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
+{
+
+ size_t written = size * nmemb;
+ char* pBuffer = (char*)malloc(written + 1);
+
+ strncpy(pBuffer, (const char *)ptr, written);
+ pBuffer [written] = '\0';
+
+ fprintf(MSG_OUT, "%s", pBuffer);
+
+ free(pBuffer);
+
+ return written;
+}
+
+
+/* CURLOPT_PROGRESSFUNCTION */
+static int prog_cb (void *p, double dltotal, double dlnow, double ult,
+ double uln)
+{
+ ConnInfo *conn = (ConnInfo *)p;
+ (void)ult;
+ (void)uln;
+
+ fprintf(MSG_OUT, "\nProgress: %s (%g/%g)", conn->url, dlnow, dltotal);
+ fprintf(MSG_OUT, "\nProgress: %s (%g)", conn->url, ult);
+
+ return 0;
+}
+
+/* CURLOPT_OPENSOCKETFUNCTION */
+static curl_socket_t opensocket(void *clientp,
+ curlsocktype purpose,
+ struct curl_sockaddr *address)
+{
+ fprintf(MSG_OUT, "\nopensocket :");
+
+ curl_socket_t sockfd = CURL_SOCKET_BAD;
+
+ /* restrict to ipv4 */
+ if (purpose == CURLSOCKTYPE_IPCXN && address->family == AF_INET)
+ {
+ /* create a tcp socket object */
+ boost::asio::ip::tcp::socket *tcp_socket = new boost::asio::ip::tcp::socket(io_service);
+
+ /* open it and get the native handle*/
+ boost::system::error_code ec;
+ tcp_socket->open(boost::asio::ip::tcp::v4(), ec);
+
+ if (ec)
+ {
+ //An error occurred
+ std::cout << std::endl << "Couldn't open socket [" << ec << "][" << ec.message() << "]";
+ fprintf(MSG_OUT, "\nERROR: Returning CURL_SOCKET_BAD to signal error");
+ }
+ else
+ {
+ sockfd = tcp_socket->native_handle();
+ fprintf(MSG_OUT, "\nOpened socket %d", sockfd);
+
+ /* save it for monitoring */
+ socket_map.insert(std::pair<curl_socket_t, boost::asio::ip::tcp::socket *>(sockfd, tcp_socket));
+ }
+ }
+
+ return sockfd;
+}
+
+/* CURLOPT_CLOSESOCKETFUNCTION */
+static int closesocket(void *clientp, curl_socket_t item)
+{
+ fprintf(MSG_OUT, "\nclosesocket : %d", item);
+
+ std::map<curl_socket_t, boost::asio::ip::tcp::socket *>::iterator it = socket_map.find(item);
+
+ if ( it != socket_map.end() )
+ {
+ delete it->second;
+ socket_map.erase(it);
+ }
+
+ return 0;
+}
+
+/* Create a new easy handle, and add it to the global curl_multi */
+static void new_conn(char *url, GlobalInfo *g )
+{
+ ConnInfo *conn;
+ CURLMcode rc;
+
+ conn = (ConnInfo *)calloc(1, sizeof(ConnInfo));
+ memset(conn, 0, sizeof(ConnInfo));
+ conn->error[0]='\0';
+
+ conn->easy = curl_easy_init();
+
+ if ( !conn->easy )
+ {
+ fprintf(MSG_OUT, "\ncurl_easy_init() failed, exiting!");
+ exit(2);
+ }
+ conn->global = g;
+ conn->url = strdup(url);
+ curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
+ curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
+ curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
+ curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
+ curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
+ curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 1L);
+ curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
+ curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
+ curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 3L);
+ curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 10L);
+
+ /* call this function to get a socket */
+ curl_easy_setopt(conn->easy, CURLOPT_OPENSOCKETFUNCTION, opensocket);
+
+ /* call this function to close a socket */
+ curl_easy_setopt(conn->easy, CURLOPT_CLOSESOCKETFUNCTION, closesocket);
+
+ fprintf(MSG_OUT,
+ "\nAdding easy %p to multi %p (%s)", conn->easy, g->multi, url);
+ rc = curl_multi_add_handle(g->multi, conn->easy);
+ mcode_or_die("new_conn: curl_multi_add_handle", rc);
+
+ /* note that the add_handle() will set a time-out to trigger very soon so
+ that the necessary socket_action() call will be called by this app */
+}
+
+int main(int argc, char **argv)
+{
+ GlobalInfo g;
+ CURLMcode rc;
+ (void)argc;
+ (void)argv;
+
+ memset(&g, 0, sizeof(GlobalInfo));
+ g.multi = curl_multi_init();
+
+ curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
+ curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
+ curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
+ curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
+
+ new_conn((char *)"www.google.com", &g); /* add a URL */
+
+ /* enter io_service run loop */
+ io_service.run();
+
+ curl_multi_cleanup(g.multi);
+
+ fprintf(MSG_OUT, "\ndone.\n");
+ return 0;
+}
diff --git a/docs/examples/cacertinmem.c b/docs/examples/cacertinmem.c
new file mode 100644
index 000000000..051afbca9
--- /dev/null
+++ b/docs/examples/cacertinmem.c
@@ -0,0 +1,151 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* Example using a "in core" PEM certificate to retrieve a https page.
+ * Written by Theo Borm
+ */
+
+/* on a netBSD system with OPENSSL& LIBCURL installed from
+ * pkgsrc (using default paths) this program can be compiled using:
+ * gcc -I/usr/pkg/include -L/usr/pkg/lib -lcurl -Wl,-R/usr/pkg/lib -lssl
+ * -lcrypto -lz -o curlcacerttest curlcacerttest.c
+ * on other operating systems you may want to change paths to headers
+ * and libraries
+*/
+#include <openssl/ssl.h>
+#include <curl/curl.h>
+#include <stdio.h>
+
+size_t writefunction( void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ fwrite(ptr,size,nmemb,stream);
+ return(nmemb*size);
+}
+
+static CURLcode sslctx_function(CURL * curl, void * sslctx, void * parm)
+{
+ X509_STORE * store;
+ X509 * cert=NULL;
+ BIO * bio;
+ char * mypem = /* www.cacert.org */
+ "-----BEGIN CERTIFICATE-----\n"\
+ "MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n"\
+ "IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n"\
+ "IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA\n"\
+ "Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO\n"\
+ "BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi\n"\
+ "MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ\n"\
+ "ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC\n"\
+ "CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ\n"\
+ "8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6\n"\
+ "zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y\n"\
+ "fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7\n"\
+ "w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc\n"\
+ "G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k\n"\
+ "epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q\n"\
+ "laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ\n"\
+ "QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU\n"\
+ "fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826\n"\
+ "YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w\n"\
+ "ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY\n"\
+ "gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe\n"\
+ "MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0\n"\
+ "IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy\n"\
+ "dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw\n"\
+ "czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0\n"\
+ "dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl\n"\
+ "aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC\n"\
+ "AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg\n"\
+ "b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB\n"\
+ "ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc\n"\
+ "nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg\n"\
+ "18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c\n"\
+ "gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl\n"\
+ "Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY\n"\
+ "sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T\n"\
+ "SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF\n"\
+ "CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum\n"\
+ "GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk\n"\
+ "zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW\n"\
+ "omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n"\
+ "-----END CERTIFICATE-----\n";
+ /* get a BIO */
+ bio=BIO_new_mem_buf(mypem, -1);
+ /* use it to read the PEM formatted certificate from memory into an X509
+ * structure that SSL can use
+ */
+ PEM_read_bio_X509(bio, &cert, 0, NULL);
+ if (cert == NULL)
+ printf("PEM_read_bio_X509 failed...\n");
+
+ /* get a pointer to the X509 certificate store (which may be empty!) */
+ store=SSL_CTX_get_cert_store((SSL_CTX *)sslctx);
+
+ /* add our certificate to this store */
+ if (X509_STORE_add_cert(store, cert)==0)
+ printf("error adding certificate\n");
+
+ /* all set to go */
+ return CURLE_OK ;
+}
+
+int main(void)
+{
+ CURL * ch;
+ CURLcode rv;
+
+ rv=curl_global_init(CURL_GLOBAL_ALL);
+ ch=curl_easy_init();
+ rv=curl_easy_setopt(ch,CURLOPT_VERBOSE, 0L);
+ rv=curl_easy_setopt(ch,CURLOPT_HEADER, 0L);
+ rv=curl_easy_setopt(ch,CURLOPT_NOPROGRESS, 1L);
+ rv=curl_easy_setopt(ch,CURLOPT_NOSIGNAL, 1L);
+ rv=curl_easy_setopt(ch,CURLOPT_WRITEFUNCTION, *writefunction);
+ rv=curl_easy_setopt(ch,CURLOPT_WRITEDATA, stdout);
+ rv=curl_easy_setopt(ch,CURLOPT_HEADERFUNCTION, *writefunction);
+ rv=curl_easy_setopt(ch,CURLOPT_WRITEHEADER, stderr);
+ rv=curl_easy_setopt(ch,CURLOPT_SSLCERTTYPE,"PEM");
+ rv=curl_easy_setopt(ch,CURLOPT_SSL_VERIFYPEER,1L);
+ rv=curl_easy_setopt(ch, CURLOPT_URL, "https://www.example.com/");
+
+ /* first try: retrieve page without cacerts' certificate -> will fail
+ */
+ rv=curl_easy_perform(ch);
+ if (rv==CURLE_OK)
+ printf("*** transfer succeeded ***\n");
+ else
+ printf("*** transfer failed ***\n");
+
+ /* second try: retrieve page using cacerts' certificate -> will succeed
+ * load the certificate by installing a function doing the nescessary
+ * "modifications" to the SSL CONTEXT just before link init
+ */
+ rv=curl_easy_setopt(ch,CURLOPT_SSL_CTX_FUNCTION, *sslctx_function);
+ rv=curl_easy_perform(ch);
+ if (rv==CURLE_OK)
+ printf("*** transfer succeeded ***\n");
+ else
+ printf("*** transfer failed ***\n");
+
+ curl_easy_cleanup(ch);
+ curl_global_cleanup();
+ return rv;
+}
diff --git a/docs/examples/certinfo.c b/docs/examples/certinfo.c
new file mode 100644
index 000000000..ffcec6356
--- /dev/null
+++ b/docs/examples/certinfo.c
@@ -0,0 +1,81 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+
+#include <curl/curl.h>
+
+static size_t wrfu(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ (void)stream;
+ (void)ptr;
+ return size * nmemb;
+}
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+
+ curl = curl_easy_init();
+ if(curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/");
+
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, wrfu);
+
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
+ curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L);
+
+ res = curl_easy_perform(curl);
+
+ if(!res) {
+ struct curl_certinfo *ci = NULL;
+
+ res = curl_easy_getinfo(curl, CURLINFO_CERTINFO, &ci);
+
+ if(!res && ci) {
+ int i;
+ printf("%d certs!\n", ci->num_of_certs);
+
+ for(i=0; i<ci->num_of_certs; i++) {
+ struct curl_slist *slist;
+
+ for(slist = ci->certinfo[i]; slist; slist = slist->next)
+ printf("%s\n", slist->data);
+
+ }
+ }
+
+ }
+
+
+ curl_easy_cleanup(curl);
+ }
+
+ curl_global_cleanup();
+
+ return 0;
+}
diff --git a/docs/examples/chkspeed.c b/docs/examples/chkspeed.c
new file mode 100644
index 000000000..b5c397ab7
--- /dev/null
+++ b/docs/examples/chkspeed.c
@@ -0,0 +1,176 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* Example source code to show how the callback function can be used to
+ * download data into a chunk of memory instead of storing it in a file.
+ * After successful download we use curl_easy_getinfo() calls to get the
+ * amount of downloaded bytes, the time used for the whole download, and
+ * the average download speed.
+ * On Linux you can create the download test files with:
+ * dd if=/dev/urandom of=file_1M.bin bs=1M count=1
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <curl/curl.h>
+
+#define URL_BASE "http://speedtest.your.domain/"
+#define URL_1M URL_BASE "file_1M.bin"
+#define URL_2M URL_BASE "file_2M.bin"
+#define URL_5M URL_BASE "file_5M.bin"
+#define URL_10M URL_BASE "file_10M.bin"
+#define URL_20M URL_BASE "file_20M.bin"
+#define URL_50M URL_BASE "file_50M.bin"
+#define URL_100M URL_BASE "file_100M.bin"
+
+#define CHKSPEED_VERSION "1.0"
+
+static size_t WriteCallback(void *ptr, size_t size, size_t nmemb, void *data)
+{
+ /* we are not interested in the downloaded bytes itself,
+ so we only return the size we would have saved ... */
+ (void)ptr; /* unused */
+ (void)data; /* unused */
+ return (size_t)(size * nmemb);
+}
+
+int main(int argc, char *argv[])
+{
+ CURL *curl_handle;
+ CURLcode res;
+ int prtsep = 0, prttime = 0;
+ const char *url = URL_1M;
+ char *appname = argv[0];
+
+ if (argc > 1) {
+ /* parse input parameters */
+ for (argc--, argv++; *argv; argc--, argv++) {
+ if (strncasecmp(*argv, "-", 1) == 0) {
+ if (strncasecmp(*argv, "-H", 2) == 0) {
+ fprintf(stderr,
+ "\rUsage: %s [-m=1|2|5|10|20|50|100] [-t] [-x] [url]\n",
+ appname);
+ exit(1);
+ } else if (strncasecmp(*argv, "-V", 2) == 0) {
+ fprintf(stderr, "\r%s %s - %s\n",
+ appname, CHKSPEED_VERSION, curl_version());
+ exit(1);
+ } else if (strncasecmp(*argv, "-X", 2) == 0) {
+ prtsep = 1;
+ } else if (strncasecmp(*argv, "-T", 2) == 0) {
+ prttime = 1;
+ } else if (strncasecmp(*argv, "-M=", 3) == 0) {
+ long m = strtol((*argv)+3, NULL, 10);
+ switch(m) {
+ case 1: url = URL_1M;
+ break;
+ case 2: url = URL_2M;
+ break;
+ case 5: url = URL_5M;
+ break;
+ case 10: url = URL_10M;
+ break;
+ case 20: url = URL_20M;
+ break;
+ case 50: url = URL_50M;
+ break;
+ case 100: url = URL_100M;
+ break;
+ default: fprintf(stderr, "\r%s: invalid parameter %s\n",
+ appname, *argv + 3);
+ exit(1);
+ }
+ } else {
+ fprintf(stderr, "\r%s: invalid or unknown option %s\n",
+ appname, *argv);
+ exit(1);
+ }
+ } else {
+ url = *argv;
+ }
+ }
+ }
+
+ /* print separator line */
+ if (prtsep) {
+ printf("-------------------------------------------------\n");
+ }
+ /* print localtime */
+ if (prttime) {
+ time_t t = time(NULL);
+ printf("Localtime: %s", ctime(&t));
+ }
+
+ /* init libcurl */
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ /* init the curl session */
+ curl_handle = curl_easy_init();
+
+ /* specify URL to get */
+ curl_easy_setopt(curl_handle, CURLOPT_URL, url);
+
+ /* send all data to this function */
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteCallback);
+
+ /* some servers don't like requests that are made without a user-agent
+ field, so we provide one */
+ curl_easy_setopt(curl_handle, CURLOPT_USERAGENT,
+ "libcurl-speedchecker/" CHKSPEED_VERSION);
+
+ /* get it! */
+ res = curl_easy_perform(curl_handle);
+
+ if(CURLE_OK == res) {
+ double val;
+
+ /* check for bytes downloaded */
+ res = curl_easy_getinfo(curl_handle, CURLINFO_SIZE_DOWNLOAD, &val);
+ if((CURLE_OK == res) && (val>0))
+ printf("Data downloaded: %0.0f bytes.\n", val);
+
+ /* check for total download time */
+ res = curl_easy_getinfo(curl_handle, CURLINFO_TOTAL_TIME, &val);
+ if((CURLE_OK == res) && (val>0))
+ printf("Total download time: %0.3f sec.\n", val);
+
+ /* check for average download speed */
+ res = curl_easy_getinfo(curl_handle, CURLINFO_SPEED_DOWNLOAD, &val);
+ if((CURLE_OK == res) && (val>0))
+ printf("Average download speed: %0.3f kbyte/sec.\n", val / 1024);
+
+ } else {
+ fprintf(stderr, "Error while fetching '%s' : %s\n",
+ url, curl_easy_strerror(res));
+ }
+
+ /* cleanup curl stuff */
+ curl_easy_cleanup(curl_handle);
+
+ /* we're done with libcurl, so clean it up */
+ curl_global_cleanup();
+
+ return 0;
+}
diff --git a/docs/examples/cookie_interface.c b/docs/examples/cookie_interface.c
new file mode 100644
index 000000000..2e7c66db2
--- /dev/null
+++ b/docs/examples/cookie_interface.c
@@ -0,0 +1,124 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* This example shows usage of simple cookie interface. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+
+#include <curl/curl.h>
+
+static void
+print_cookies(CURL *curl)
+{
+ CURLcode res;
+ struct curl_slist *cookies;
+ struct curl_slist *nc;
+ int i;
+
+ printf("Cookies, curl knows:\n");
+ res = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies);
+ if (res != CURLE_OK) {
+ fprintf(stderr, "Curl curl_easy_getinfo failed: %s\n", curl_easy_strerror(res));
+ exit(1);
+ }
+ nc = cookies, i = 1;
+ while (nc) {
+ printf("[%d]: %s\n", i, nc->data);
+ nc = nc->next;
+ i++;
+ }
+ if (i == 1) {
+ printf("(none)\n");
+ }
+ curl_slist_free_all(cookies);
+}
+
+int
+main(void)
+{
+ CURL *curl;
+ CURLcode res;
+
+ curl_global_init(CURL_GLOBAL_ALL);
+ curl = curl_easy_init();
+ if (curl) {
+ char nline[256];
+
+ curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/");
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); /* just to start the cookie engine */
+ res = curl_easy_perform(curl);
+ if (res != CURLE_OK) {
+ fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res));
+ return 1;
+ }
+
+ print_cookies(curl);
+
+ printf("Erasing curl's knowledge of cookies!\n");
+ curl_easy_setopt(curl, CURLOPT_COOKIELIST, "ALL");
+
+ print_cookies(curl);
+
+ printf("-----------------------------------------------\n"
+ "Setting a cookie \"PREF\" via cookie interface:\n");
+#ifdef WIN32
+#define snprintf _snprintf
+#endif
+ /* Netscape format cookie */
+ snprintf(nline, sizeof(nline), "%s\t%s\t%s\t%s\t%lu\t%s\t%s",
+ ".google.com", "TRUE", "/", "FALSE", (unsigned long)time(NULL) + 31337UL, "PREF", "hello google, i like you very much!");
+ res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline);
+ if (res != CURLE_OK) {
+ fprintf(stderr, "Curl curl_easy_setopt failed: %s\n", curl_easy_strerror(res));
+ return 1;
+ }
+
+ /* HTTP-header style cookie */
+ snprintf(nline, sizeof(nline),
+ "Set-Cookie: OLD_PREF=3d141414bf4209321; "
+ "expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com");
+ res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline);
+ if (res != CURLE_OK) {
+ fprintf(stderr, "Curl curl_easy_setopt failed: %s\n", curl_easy_strerror(res));
+ return 1;
+ }
+
+ print_cookies(curl);
+
+ res = curl_easy_perform(curl);
+ if (res != CURLE_OK) {
+ fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res));
+ return 1;
+ }
+ }
+ else {
+ fprintf(stderr, "Curl init failed!\n");
+ return 1;
+ }
+
+ curl_global_cleanup();
+ return 0;
+}
diff --git a/docs/examples/curlgtk.c b/docs/examples/curlgtk.c
new file mode 100644
index 000000000..8cb9914c6
--- /dev/null
+++ b/docs/examples/curlgtk.c
@@ -0,0 +1,106 @@
+/*****************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ */
+/* Copyright (c) 2000 David Odin (aka DindinX) for MandrakeSoft */
+/* an attempt to use the curl library in concert with a gtk-threaded application */
+
+#include <stdio.h>
+#include <gtk/gtk.h>
+
+#include <curl/curl.h>
+
+GtkWidget *Bar;
+
+size_t my_write_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ return fwrite(ptr, size, nmemb, stream);
+}
+
+size_t my_read_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ return fread(ptr, size, nmemb, stream);
+}
+
+int my_progress_func(GtkWidget *bar,
+ double t, /* dltotal */
+ double d, /* dlnow */
+ double ultotal,
+ double ulnow)
+{
+/* printf("%d / %d (%g %%)\n", d, t, d*100.0/t);*/
+ gdk_threads_enter();
+ gtk_progress_set_value(GTK_PROGRESS(bar), d*100.0/t);
+ gdk_threads_leave();
+ return 0;
+}
+
+void *my_thread(void *ptr)
+{
+ CURL *curl;
+ CURLcode res;
+ FILE *outfile;
+ gchar *url = ptr;
+
+ curl = curl_easy_init();
+ if(curl)
+ {
+ outfile = fopen("test.curl", "w");
+
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_write_func);
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, my_read_func);
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
+ curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, my_progress_func);
+ curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, Bar);
+
+ res = curl_easy_perform(curl);
+
+ fclose(outfile);
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+
+ return NULL;
+}
+
+int main(int argc, char **argv)
+{
+ GtkWidget *Window, *Frame, *Frame2;
+ GtkAdjustment *adj;
+
+ /* Must initialize libcurl before any threads are started */
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ /* Init thread */
+ g_thread_init(NULL);
+
+ gtk_init(&argc, &argv);
+ Window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ Frame = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(Frame), GTK_SHADOW_OUT);
+ gtk_container_add(GTK_CONTAINER(Window), Frame);
+ Frame2 = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(Frame2), GTK_SHADOW_IN);
+ gtk_container_add(GTK_CONTAINER(Frame), Frame2);
+ gtk_container_set_border_width(GTK_CONTAINER(Frame2), 5);
+ adj = (GtkAdjustment*)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
+ Bar = gtk_progress_bar_new_with_adjustment(adj);
+ gtk_container_add(GTK_CONTAINER(Frame2), Bar);
+ gtk_widget_show_all(Window);
+
+ if (!g_thread_create(&my_thread, argv[1], FALSE, NULL) != 0)
+ g_warning("can't create the thread");
+
+
+ gdk_threads_enter();
+ gtk_main();
+ gdk_threads_leave();
+ return 0;
+}
+
diff --git a/docs/examples/curlx.c b/docs/examples/curlx.c
new file mode 100644
index 000000000..89d5f407b
--- /dev/null
+++ b/docs/examples/curlx.c
@@ -0,0 +1,513 @@
+/*
+ curlx.c Authors: Peter Sylvester, Jean-Paul Merlin
+
+ This is a little program to demonstrate the usage of
+
+ - an ssl initialisation callback setting a user key and trustbases
+ coming from a pkcs12 file
+ - using an ssl application callback to find a URI in the
+ certificate presented during ssl session establishment.
+
+*/
+
+
+/*
+ * Copyright (c) 2003 The OpenEvidence Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, the following disclaimer,
+ * and the original OpenSSL and SSLeay Licences below.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions, the following disclaimer
+ * and the original OpenSSL and SSLeay Licences below in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgments:
+ * "This product includes software developed by the Openevidence Project
+ * for use in the OpenEvidence Toolkit. (http://www.openevidence.org/)"
+ * This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com)."
+ *
+ * 4. The names "OpenEvidence Toolkit" and "OpenEvidence Project" must not be
+ * used to endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openevidence-core@openevidence.org.
+ *
+ * 5. Products derived from this software may not be called "OpenEvidence"
+ * nor may "OpenEvidence" appear in their names without prior written
+ * permission of the OpenEvidence Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgments:
+ * "This product includes software developed by the OpenEvidence Project
+ * for use in the OpenEvidence Toolkit (http://www.openevidence.org/)
+ * This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenEvidence PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenEvidence PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <curl/curl.h>
+#include <openssl/x509v3.h>
+#include <openssl/x509_vfy.h>
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include <openssl/objects.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs12.h>
+#include <openssl/bio.h>
+#include <openssl/ssl.h>
+
+static const char *curlx_usage[]={
+ "usage: curlx args\n",
+ " -p12 arg - tia file ",
+ " -envpass arg - environement variable which content the tia private key password",
+ " -out arg - output file (response)- default stdout",
+ " -in arg - input file (request)- default stdin",
+ " -connect arg - URL of the server for the connection ex: www.openevidence.org",
+ " -mimetype arg - MIME type for data in ex : application/timestamp-query or application/dvcs -default application/timestamp-query",
+ " -acceptmime arg - MIME type acceptable for the response ex : application/timestamp-response or application/dvcs -default none",
+ " -accesstype arg - an Object identifier in an AIA/SIA method, e.g. AD_DVCS or ad_timestamping",
+ NULL
+};
+
+/*
+
+./curlx -p12 psy.p12 -envpass XX -in request -verbose -accesstype AD_DVCS
+-mimetype application/dvcs -acceptmime application/dvcs -out response
+
+*/
+
+/*
+ * We use this ZERO_NULL to avoid picky compiler warnings,
+ * when assigning a NULL pointer to a function pointer var.
+ */
+
+#define ZERO_NULL 0
+
+/* This is a context that we pass to all callbacks */
+
+typedef struct sslctxparm_st {
+ unsigned char * p12file ;
+ const char * pst ;
+ PKCS12 * p12 ;
+ EVP_PKEY * pkey ;
+ X509 * usercert ;
+ STACK_OF(X509) * ca ;
+ CURL * curl;
+ BIO * errorbio;
+ int accesstype ;
+ int verbose;
+
+} sslctxparm;
+
+/* some helper function. */
+
+static char *i2s_ASN1_IA5STRING( ASN1_IA5STRING *ia5)
+{
+ char *tmp;
+ if(!ia5 || !ia5->length)
+ return NULL;
+ tmp = OPENSSL_malloc(ia5->length + 1);
+ memcpy(tmp, ia5->data, ia5->length);
+ tmp[ia5->length] = 0;
+ return tmp;
+}
+
+/* A conveniance routine to get an access URI. */
+
+static unsigned char *my_get_ext(X509 * cert, const int type, int extensiontype) {
+
+ int i;
+ STACK_OF(ACCESS_DESCRIPTION) * accessinfo ;
+ accessinfo = X509_get_ext_d2i(cert, extensiontype, NULL, NULL) ;
+
+ if (!sk_ACCESS_DESCRIPTION_num(accessinfo))
+ return NULL;
+ for (i = 0; i < sk_ACCESS_DESCRIPTION_num(accessinfo); i++) {
+ ACCESS_DESCRIPTION * ad = sk_ACCESS_DESCRIPTION_value(accessinfo, i);
+ if (OBJ_obj2nid(ad->method) == type) {
+ if (ad->location->type == GEN_URI) {
+ return i2s_ASN1_IA5STRING(ad->location->d.ia5);
+ }
+ return NULL;
+ }
+ }
+ return NULL;
+}
+
+/* This is an application verification call back, it does not
+ perform any addition verification but tries to find a URL
+ in the presented certificat. If found, this will become
+ the URL to be used in the POST.
+*/
+
+static int ssl_app_verify_callback(X509_STORE_CTX *ctx, void *arg)
+{
+ sslctxparm * p = (sslctxparm *) arg;
+ int ok;
+
+ if (p->verbose > 2)
+ BIO_printf(p->errorbio,"entering ssl_app_verify_callback\n");
+
+ if ((ok= X509_verify_cert(ctx)) && ctx->cert) {
+ unsigned char * accessinfo ;
+ if (p->verbose > 1)
+ X509_print_ex(p->errorbio,ctx->cert,0,0);
+
+ if (accessinfo = my_get_ext(ctx->cert,p->accesstype ,NID_sinfo_access)) {
+ if (p->verbose)
+ BIO_printf(p->errorbio,"Setting URL from SIA to: %s\n", accessinfo);
+
+ curl_easy_setopt(p->curl, CURLOPT_URL,accessinfo);
+ }
+ else if (accessinfo = my_get_ext(ctx->cert,p->accesstype,
+ NID_info_access)) {
+ if (p->verbose)
+ BIO_printf(p->errorbio,"Setting URL from AIA to: %s\n", accessinfo);
+
+ curl_easy_setopt(p->curl, CURLOPT_URL,accessinfo);
+ }
+ }
+ if (p->verbose > 2)
+ BIO_printf(p->errorbio,"leaving ssl_app_verify_callback with %d\n", ok);
+ return(ok);
+}
+
+
+/* This is an example of an curl SSL initialisation call back. The callback sets:
+ - a private key and certificate
+ - a trusted ca certificate
+ - a preferred cipherlist
+ - an application verification callback (the function above)
+*/
+
+static CURLcode sslctxfun(CURL * curl, void * sslctx, void * parm) {
+
+ sslctxparm * p = (sslctxparm *) parm;
+ SSL_CTX * ctx = (SSL_CTX *) sslctx ;
+
+ if (!SSL_CTX_use_certificate(ctx,p->usercert)) {
+ BIO_printf(p->errorbio, "SSL_CTX_use_certificate problem\n"); goto err;
+ }
+ if (!SSL_CTX_use_PrivateKey(ctx,p->pkey)) {
+ BIO_printf(p->errorbio, "SSL_CTX_use_PrivateKey\n"); goto err;
+ }
+
+ if (!SSL_CTX_check_private_key(ctx)) {
+ BIO_printf(p->errorbio, "SSL_CTX_check_private_key\n"); goto err;
+ }
+
+ SSL_CTX_set_quiet_shutdown(ctx,1);
+ SSL_CTX_set_cipher_list(ctx,"RC4-MD5");
+ SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
+
+ X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), sk_X509_value(p->ca, sk_X509_num(p->ca)-1));
+
+ SSL_CTX_set_verify_depth(ctx,2);
+
+ SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,ZERO_NULL);
+
+ SSL_CTX_set_cert_verify_callback(ctx, ssl_app_verify_callback, parm);
+
+
+ return CURLE_OK ;
+ err:
+ ERR_print_errors(p->errorbio);
+ return CURLE_SSL_CERTPROBLEM;
+
+}
+
+int main(int argc, char **argv) {
+
+ BIO* in=NULL;
+ BIO* out=NULL;
+
+ char * outfile = NULL;
+ char * infile = NULL ;
+
+ int tabLength=100;
+ char *binaryptr;
+ char* mimetype;
+ char* mimetypeaccept=NULL;
+ char* contenttype;
+ const char** pp;
+ unsigned char* hostporturl = NULL;
+ BIO * p12bio ;
+ char **args = argv + 1;
+ unsigned char * serverurl;
+ sslctxparm p;
+ char *response;
+
+ CURLcode res;
+ struct curl_slist * headers=NULL;
+ int badarg=0;
+
+ binaryptr = malloc(tabLength);
+
+ p.verbose = 0;
+ p.errorbio = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+
+ /* we need some more for the P12 decoding */
+
+ OpenSSL_add_all_ciphers();
+ OpenSSL_add_all_digests();
+ ERR_load_crypto_strings();
+
+
+
+ while (*args && *args[0] == '-') {
+ if (!strcmp (*args, "-in")) {
+ if (args[1]) {
+ infile=*(++args);
+ } else badarg=1;
+ } else if (!strcmp (*args, "-out")) {
+ if (args[1]) {
+ outfile=*(++args);
+ } else badarg=1;
+ } else if (!strcmp (*args, "-p12")) {
+ if (args[1]) {
+ p.p12file = *(++args);
+ } else badarg=1;
+ } else if (strcmp(*args,"-envpass") == 0) {
+ if (args[1]) {
+ p.pst = getenv(*(++args));
+ } else badarg=1;
+ } else if (strcmp(*args,"-connect") == 0) {
+ if (args[1]) {
+ hostporturl = *(++args);
+ } else badarg=1;
+ } else if (strcmp(*args,"-mimetype") == 0) {
+ if (args[1]) {
+ mimetype = *(++args);
+ } else badarg=1;
+ } else if (strcmp(*args,"-acceptmime") == 0) {
+ if (args[1]) {
+ mimetypeaccept = *(++args);
+ } else badarg=1;
+ } else if (strcmp(*args,"-accesstype") == 0) {
+ if (args[1]) {
+ if ((p.accesstype = OBJ_obj2nid(OBJ_txt2obj(*++args,0))) == 0) badarg=1;
+ } else badarg=1;
+ } else if (strcmp(*args,"-verbose") == 0) {
+ p.verbose++;
+ } else badarg=1;
+ args++;
+ }
+
+ if (mimetype==NULL || mimetypeaccept == NULL) badarg = 1;
+
+ if (badarg) {
+ for (pp=curlx_usage; (*pp != NULL); pp++)
+ BIO_printf(p.errorbio,"%s\n",*pp);
+ BIO_printf(p.errorbio,"\n");
+ goto err;
+ }
+
+
+
+ /* set input */
+
+ if ((in=BIO_new(BIO_s_file())) == NULL) {
+ BIO_printf(p.errorbio, "Error setting input bio\n");
+ goto err;
+ } else if (infile == NULL)
+ BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT);
+ else if (BIO_read_filename(in,infile) <= 0) {
+ BIO_printf(p.errorbio, "Error opening input file %s\n", infile);
+ BIO_free(in);
+ goto err;
+ }
+
+ /* set output */
+
+ if ((out=BIO_new(BIO_s_file())) == NULL) {
+ BIO_printf(p.errorbio, "Error setting output bio.\n");
+ goto err;
+ } else if (outfile == NULL)
+ BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
+ else if (BIO_write_filename(out,outfile) <= 0) {
+ BIO_printf(p.errorbio, "Error opening output file %s\n", outfile);
+ BIO_free(out);
+ goto err;
+ }
+
+
+ p.errorbio = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+ if (!(p.curl = curl_easy_init())) {
+ BIO_printf(p.errorbio, "Cannot init curl lib\n");
+ goto err;
+ }
+
+
+
+ if (!(p12bio = BIO_new_file(p.p12file , "rb"))) {
+ BIO_printf(p.errorbio, "Error opening P12 file %s\n", p.p12file); goto err;
+ }
+ if (!(p.p12 = d2i_PKCS12_bio (p12bio, NULL))) {
+ BIO_printf(p.errorbio, "Cannot decode P12 structure %s\n", p.p12file); goto err;
+ }
+
+ p.ca= NULL;
+ if (!(PKCS12_parse (p.p12, p.pst, &(p.pkey), &(p.usercert), &(p.ca) ) )) {
+ BIO_printf(p.errorbio,"Invalid P12 structure in %s\n", p.p12file); goto err;
+ }
+
+ if (sk_X509_num(p.ca) <= 0) {
+ BIO_printf(p.errorbio,"No trustworthy CA given.%s\n", p.p12file); goto err;
+ }
+
+ if (p.verbose > 1)
+ X509_print_ex(p.errorbio,p.usercert,0,0);
+
+ /* determine URL to go */
+
+ if (hostporturl) {
+ serverurl = malloc(9+strlen(hostporturl));
+ sprintf(serverurl,"https://%s",hostporturl);
+ }
+ else if (p.accesstype != 0) { /* see whether we can find an AIA or SIA for a given access type */
+ if (!(serverurl = my_get_ext(p.usercert,p.accesstype,NID_info_access))) {
+ int j=0;
+ BIO_printf(p.errorbio,"no service URL in user cert "
+ "cherching in others certificats\n");
+ for (j=0;j<sk_X509_num(p.ca);j++) {
+ if ((serverurl = my_get_ext(sk_X509_value(p.ca,j),p.accesstype,
+ NID_info_access)))
+ break;
+ if ((serverurl = my_get_ext(sk_X509_value(p.ca,j),p.accesstype,
+ NID_sinfo_access)))
+ break;
+ }
+ }
+ }
+
+ if (!serverurl) {
+ BIO_printf(p.errorbio, "no service URL in certificats,"
+ " check '-accesstype (AD_DVCS | ad_timestamping)'"
+ " or use '-connect'\n");
+ goto err;
+ }
+
+ if (p.verbose)
+ BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl);
+
+ curl_easy_setopt(p.curl, CURLOPT_URL, serverurl);
+
+ /* Now specify the POST binary data */
+
+ curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr);
+ curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE,(long)tabLength);
+
+ /* pass our list of custom made headers */
+
+ contenttype = malloc(15+strlen(mimetype));
+ sprintf(contenttype,"Content-type: %s",mimetype);
+ headers = curl_slist_append(headers,contenttype);
+ curl_easy_setopt(p.curl, CURLOPT_HTTPHEADER, headers);
+
+ if (p.verbose)
+ BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl);
+
+ {
+ FILE *outfp;
+ BIO_get_fp(out,&outfp);
+ curl_easy_setopt(p.curl, CURLOPT_WRITEDATA, outfp);
+ }
+
+ res = curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun) ;
+
+ if (res != CURLE_OK)
+ BIO_printf(p.errorbio,"%d %s=%d %d\n", __LINE__, "CURLOPT_SSL_CTX_FUNCTION",CURLOPT_SSL_CTX_FUNCTION,res);
+
+ curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_DATA, &p);
+
+ {
+ int lu; int i=0;
+ while ((lu = BIO_read (in,&binaryptr[i],tabLength-i)) >0 ) {
+ i+=lu;
+ if (i== tabLength) {
+ tabLength+=100;
+ binaryptr=realloc(binaryptr,tabLength); /* should be more careful */
+ }
+ }
+ tabLength = i;
+ }
+ /* Now specify the POST binary data */
+
+ curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr);
+ curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE,(long)tabLength);
+
+
+ /* Perform the request, res will get the return code */
+
+ BIO_printf(p.errorbio,"%d %s %d\n", __LINE__, "curl_easy_perform",
+ res = curl_easy_perform(p.curl));
+ {
+ int result =curl_easy_getinfo(p.curl,CURLINFO_CONTENT_TYPE,&response);
+ if( mimetypeaccept && p.verbose)
+ if(!strcmp(mimetypeaccept,response))
+ BIO_printf(p.errorbio,"the response has a correct mimetype : %s\n",
+ response);
+ else
+ BIO_printf(p.errorbio,"the reponse doesn\'t has an acceptable "
+ "mime type, it is %s instead of %s\n",
+ response,mimetypeaccept);
+ }
+
+ /*** code d'erreur si accept mime ***, egalement code return HTTP != 200 ***/
+
+/* free the header list*/
+
+ curl_slist_free_all(headers);
+
+ /* always cleanup */
+ curl_easy_cleanup(p.curl);
+
+ BIO_free(in);
+ BIO_free(out);
+ return (EXIT_SUCCESS);
+
+ err: BIO_printf(p.errorbio,"error");
+ exit(1);
+}
diff --git a/docs/examples/debug.c b/docs/examples/debug.c
new file mode 100644
index 000000000..3852bf2cc
--- /dev/null
+++ b/docs/examples/debug.c
@@ -0,0 +1,144 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <curl/curl.h>
+
+struct data {
+ char trace_ascii; /* 1 or 0 */
+};
+
+static
+void dump(const char *text,
+ FILE *stream, unsigned char *ptr, size_t size,
+ char nohex)
+{
+ size_t i;
+ size_t c;
+
+ unsigned int width=0x10;
+
+ if(nohex)
+ /* without the hex output, we can fit more on screen */
+ width = 0x40;
+
+ fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n",
+ text, (long)size, (long)size);
+
+ for(i=0; i<size; i+= width) {
+
+ fprintf(stream, "%4.4lx: ", (long)i);
+
+ if(!nohex) {
+ /* hex not disabled, show it */
+ for(c = 0; c < width; c++)
+ if(i+c < size)
+ fprintf(stream, "%02x ", ptr[i+c]);
+ else
+ fputs(" ", stream);
+ }
+
+ for(c = 0; (c < width) && (i+c < size); c++) {
+ /* check for 0D0A; if found, skip past and start a new line of output */
+ if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) {
+ i+=(c+2-width);
+ break;
+ }
+ fprintf(stream, "%c",
+ (ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.');
+ /* check again for 0D0A, to avoid an extra \n if it's at width */
+ if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
+ i+=(c+3-width);
+ break;
+ }
+ }
+ fputc('\n', stream); /* newline */
+ }
+ fflush(stream);
+}
+
+static
+int my_trace(CURL *handle, curl_infotype type,
+ char *data, size_t size,
+ void *userp)
+{
+ struct data *config = (struct data *)userp;
+ const char *text;
+ (void)handle; /* prevent compiler warning */
+
+ switch (type) {
+ case CURLINFO_TEXT:
+ fprintf(stderr, "== Info: %s", data);
+ default: /* in case a new one is introduced to shock us */
+ return 0;
+
+ case CURLINFO_HEADER_OUT:
+ text = "=> Send header";
+ break;
+ case CURLINFO_DATA_OUT:
+ text = "=> Send data";
+ break;
+ case CURLINFO_SSL_DATA_OUT:
+ text = "=> Send SSL data";
+ break;
+ case CURLINFO_HEADER_IN:
+ text = "<= Recv header";
+ break;
+ case CURLINFO_DATA_IN:
+ text = "<= Recv data";
+ break;
+ case CURLINFO_SSL_DATA_IN:
+ text = "<= Recv SSL data";
+ break;
+ }
+
+ dump(text, stderr, (unsigned char *)data, size, config->trace_ascii);
+ return 0;
+}
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+ struct data config;
+
+ config.trace_ascii = 1; /* enable ascii tracing */
+
+ curl = curl_easy_init();
+ if(curl) {
+ curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
+ curl_easy_setopt(curl, CURLOPT_DEBUGDATA, &config);
+
+ /* the DEBUGFUNCTION has no effect until we enable VERBOSE */
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ return 0;
+}
diff --git a/docs/examples/evhiperfifo.c b/docs/examples/evhiperfifo.c
new file mode 100644
index 000000000..c2e87fcc5
--- /dev/null
+++ b/docs/examples/evhiperfifo.c
@@ -0,0 +1,442 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* Example application source code using the multi socket interface to
+ * download many files at once.
+ *
+ * This example features the same basic functionality as hiperfifo.c does,
+ * but this uses libev instead of libevent.
+ *
+ * Written by Jeff Pohlmeyer, converted to use libev by Markus Koetter
+
+Requires libev and a (POSIX?) system that has mkfifo().
+
+This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
+sample programs.
+
+When running, the program creates the named pipe "hiper.fifo"
+
+Whenever there is input into the fifo, the program reads the input as a list
+of URL's and creates some new easy handles to fetch each URL via the
+curl_multi "hiper" API.
+
+
+Thus, you can try a single URL:
+ % echo http://www.yahoo.com > hiper.fifo
+
+Or a whole bunch of them:
+ % cat my-url-list > hiper.fifo
+
+The fifo buffer is handled almost instantly, so you can even add more URL's
+while the previous requests are still being downloaded.
+
+Note:
+ For the sake of simplicity, URL length is limited to 1023 char's !
+
+This is purely a demo app, all retrieved data is simply discarded by the write
+callback.
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include <curl/curl.h>
+#include <ev.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#define DPRINT(x...) printf(x)
+
+#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
+
+
+/* Global information, common to all connections */
+typedef struct _GlobalInfo
+{
+ struct ev_loop *loop;
+ struct ev_io fifo_event;
+ struct ev_timer timer_event;
+ CURLM *multi;
+ int still_running;
+ FILE* input;
+} GlobalInfo;
+
+
+/* Information associated with a specific easy handle */
+typedef struct _ConnInfo
+{
+ CURL *easy;
+ char *url;
+ GlobalInfo *global;
+ char error[CURL_ERROR_SIZE];
+} ConnInfo;
+
+
+/* Information associated with a specific socket */
+typedef struct _SockInfo
+{
+ curl_socket_t sockfd;
+ CURL *easy;
+ int action;
+ long timeout;
+ struct ev_io ev;
+ int evset;
+ GlobalInfo *global;
+} SockInfo;
+
+static void timer_cb(EV_P_ struct ev_timer *w, int revents);
+
+/* Update the event timer after curl_multi library calls */
+static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
+{
+ DPRINT("%s %li\n", __PRETTY_FUNCTION__, timeout_ms);
+ ev_timer_stop(g->loop, &g->timer_event);
+ if (timeout_ms > 0)
+ {
+ double t = timeout_ms / 1000;
+ ev_timer_init(&g->timer_event, timer_cb, t, 0.);
+ ev_timer_start(g->loop, &g->timer_event);
+ }else
+ timer_cb(g->loop, &g->timer_event, 0);
+ return 0;
+}
+
+/* Die if we get a bad CURLMcode somewhere */
+static void mcode_or_die(const char *where, CURLMcode code)
+{
+ if ( CURLM_OK != code )
+ {
+ const char *s;
+ switch ( code )
+ {
+ case CURLM_CALL_MULTI_PERFORM: s="CURLM_CALL_MULTI_PERFORM"; break;
+ case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break;
+ case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
+ case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
+ case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
+ case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
+ case CURLM_LAST: s="CURLM_LAST"; break;
+ default: s="CURLM_unknown";
+ break;
+ case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET";
+ fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
+ /* ignore this error */
+ return;
+ }
+ fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
+ exit(code);
+ }
+}
+
+
+
+/* Check for completed transfers, and remove their easy handles */
+static void check_multi_info(GlobalInfo *g)
+{
+ char *eff_url;
+ CURLMsg *msg;
+ int msgs_left;
+ ConnInfo *conn;
+ CURL *easy;
+ CURLcode res;
+
+ fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
+ while ((msg = curl_multi_info_read(g->multi, &msgs_left))) {
+ if (msg->msg == CURLMSG_DONE) {
+ easy = msg->easy_handle;
+ res = msg->data.result;
+ curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
+ curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
+ fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, res, conn->error);
+ curl_multi_remove_handle(g->multi, easy);
+ free(conn->url);
+ curl_easy_cleanup(easy);
+ free(conn);
+ }
+ }
+}
+
+
+
+/* Called by libevent when we get action on a multi socket */
+static void event_cb(EV_P_ struct ev_io *w, int revents)
+{
+ DPRINT("%s w %p revents %i\n", __PRETTY_FUNCTION__, w, revents);
+ GlobalInfo *g = (GlobalInfo*) w->data;
+ CURLMcode rc;
+
+ int action = (revents&EV_READ?CURL_POLL_IN:0)|
+ (revents&EV_WRITE?CURL_POLL_OUT:0);
+ rc = curl_multi_socket_action(g->multi, w->fd, action, &g->still_running);
+ mcode_or_die("event_cb: curl_multi_socket_action", rc);
+ check_multi_info(g);
+ if ( g->still_running <= 0 )
+ {
+ fprintf(MSG_OUT, "last transfer done, kill timeout\n");
+ ev_timer_stop(g->loop, &g->timer_event);
+ }
+}
+
+/* Called by libevent when our timeout expires */
+static void timer_cb(EV_P_ struct ev_timer *w, int revents)
+{
+ DPRINT("%s w %p revents %i\n", __PRETTY_FUNCTION__, w, revents);
+
+ GlobalInfo *g = (GlobalInfo *)w->data;
+ CURLMcode rc;
+
+ rc = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0, &g->still_running);
+ mcode_or_die("timer_cb: curl_multi_socket_action", rc);
+ check_multi_info(g);
+}
+
+/* Clean up the SockInfo structure */
+static void remsock(SockInfo *f, GlobalInfo *g)
+{
+ printf("%s \n", __PRETTY_FUNCTION__);
+ if ( f )
+ {
+ if ( f->evset )
+ ev_io_stop(g->loop, &f->ev);
+ free(f);
+ }
+}
+
+
+
+/* Assign information to a SockInfo structure */
+static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
+{
+ printf("%s \n", __PRETTY_FUNCTION__);
+
+ int kind = (act&CURL_POLL_IN?EV_READ:0)|(act&CURL_POLL_OUT?EV_WRITE:0);
+
+ f->sockfd = s;
+ f->action = act;
+ f->easy = e;
+ if ( f->evset )
+ ev_io_stop(g->loop, &f->ev);
+ ev_io_init(&f->ev, event_cb, f->sockfd, kind);
+ f->ev.data = g;
+ f->evset=1;
+ ev_io_start(g->loop, &f->ev);
+}
+
+
+
+/* Initialize a new SockInfo structure */
+static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
+{
+ SockInfo *fdp = calloc(sizeof(SockInfo), 1);
+
+ fdp->global = g;
+ setsock(fdp, s, easy, action, g);
+ curl_multi_assign(g->multi, s, fdp);
+}
+
+/* CURLMOPT_SOCKETFUNCTION */
+static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
+{
+ DPRINT("%s e %p s %i what %i cbp %p sockp %p\n",
+ __PRETTY_FUNCTION__, e, s, what, cbp, sockp);
+
+ GlobalInfo *g = (GlobalInfo*) cbp;
+ SockInfo *fdp = (SockInfo*) sockp;
+ const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE"};
+
+ fprintf(MSG_OUT,
+ "socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
+ if ( what == CURL_POLL_REMOVE )
+ {
+ fprintf(MSG_OUT, "\n");
+ remsock(fdp, g);
+ } else
+ {
+ if ( !fdp )
+ {
+ fprintf(MSG_OUT, "Adding data: %s\n", whatstr[what]);
+ addsock(s, e, what, g);
+ } else
+ {
+ fprintf(MSG_OUT,
+ "Changing action from %s to %s\n",
+ whatstr[fdp->action], whatstr[what]);
+ setsock(fdp, s, e, what, g);
+ }
+ }
+ return 0;
+}
+
+
+/* CURLOPT_WRITEFUNCTION */
+static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
+{
+ size_t realsize = size * nmemb;
+ ConnInfo *conn = (ConnInfo*) data;
+ (void)ptr;
+ (void)conn;
+ return realsize;
+}
+
+
+/* CURLOPT_PROGRESSFUNCTION */
+static int prog_cb (void *p, double dltotal, double dlnow, double ult,
+ double uln)
+{
+ ConnInfo *conn = (ConnInfo *)p;
+ (void)ult;
+ (void)uln;
+
+ fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
+ return 0;
+}
+
+
+/* Create a new easy handle, and add it to the global curl_multi */
+static void new_conn(char *url, GlobalInfo *g )
+{
+ ConnInfo *conn;
+ CURLMcode rc;
+
+ conn = calloc(1, sizeof(ConnInfo));
+ memset(conn, 0, sizeof(ConnInfo));
+ conn->error[0]='\0';
+
+ conn->easy = curl_easy_init();
+ if ( !conn->easy )
+ {
+ fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n");
+ exit(2);
+ }
+ conn->global = g;
+ conn->url = strdup(url);
+ curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
+ curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
+ curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, conn);
+ curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
+ curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
+ curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 0L);
+ curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
+ curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
+ curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 3L);
+ curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 10L);
+
+ fprintf(MSG_OUT,
+ "Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
+ rc = curl_multi_add_handle(g->multi, conn->easy);
+ mcode_or_die("new_conn: curl_multi_add_handle", rc);
+
+ /* note that the add_handle() will set a time-out to trigger very soon so
+ that the necessary socket_action() call will be called by this app */
+}
+
+/* This gets called whenever data is received from the fifo */
+static void fifo_cb(EV_P_ struct ev_io *w, int revents)
+{
+ char s[1024];
+ long int rv=0;
+ int n=0;
+ GlobalInfo *g = (GlobalInfo *)w->data;
+
+ do
+ {
+ s[0]='\0';
+ rv=fscanf(g->input, "%1023s%n", s, &n);
+ s[n]='\0';
+ if ( n && s[0] )
+ {
+ new_conn(s,g); /* if we read a URL, go get it! */
+ } else break;
+ } while ( rv != EOF );
+}
+
+/* Create a named pipe and tell libevent to monitor it */
+static int init_fifo (GlobalInfo *g)
+{
+ struct stat st;
+ static const char *fifo = "hiper.fifo";
+ curl_socket_t sockfd;
+
+ fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
+ if ( lstat (fifo, &st) == 0 )
+ {
+ if ( (st.st_mode & S_IFMT) == S_IFREG )
+ {
+ errno = EEXIST;
+ perror("lstat");
+ exit (1);
+ }
+ }
+ unlink(fifo);
+ if ( mkfifo (fifo, 0600) == -1 )
+ {
+ perror("mkfifo");
+ exit (1);
+ }
+ sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
+ if ( sockfd == -1 )
+ {
+ perror("open");
+ exit (1);
+ }
+ g->input = fdopen(sockfd, "r");
+
+ fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo);
+ ev_io_init(&g->fifo_event, fifo_cb, sockfd, EV_READ);
+ ev_io_start(g->loop, &g->fifo_event);
+ return(0);
+}
+
+int main(int argc, char **argv)
+{
+ GlobalInfo g;
+ CURLMcode rc;
+ (void)argc;
+ (void)argv;
+
+ memset(&g, 0, sizeof(GlobalInfo));
+ g.loop = ev_default_loop(0);
+
+ init_fifo(&g);
+ g.multi = curl_multi_init();
+
+ ev_timer_init(&g.timer_event, timer_cb, 0., 0.);
+ g.timer_event.data = &g;
+ g.fifo_event.data = &g;
+ curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
+ curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
+ curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
+ curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
+
+ /* we don't call any curl_multi_socket*() function yet as we have no handles
+ added! */
+
+ ev_loop(g.loop, 0);
+ curl_multi_cleanup(g.multi);
+ return 0;
+}
diff --git a/docs/examples/externalsocket.c b/docs/examples/externalsocket.c
new file mode 100644
index 000000000..1b326c8b2
--- /dev/null
+++ b/docs/examples/externalsocket.c
@@ -0,0 +1,153 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+ * This is an example demonstrating how an application can pass in a custom
+ * socket to libcurl to use. This example also handles the connect itself.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <curl/curl.h>
+
+#ifdef WIN32
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#define close closesocket
+#else
+#include <sys/types.h> /* socket types */
+#include <sys/socket.h> /* socket definitions */
+#include <netinet/in.h>
+#include <arpa/inet.h> /* inet (3) funtions */
+#include <unistd.h> /* misc. UNIX functions */
+#endif
+
+#include <errno.h>
+
+/* The IP address and port number to connect to */
+#define IPADDR "127.0.0.1"
+#define PORTNUM 80
+
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+
+static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ int written = fwrite(ptr, size, nmemb, (FILE *)stream);
+ return written;
+}
+
+static curl_socket_t opensocket(void *clientp,
+ curlsocktype purpose,
+ struct curl_sockaddr *address)
+{
+ curl_socket_t sockfd;
+ (void)purpose;
+ (void)address;
+ sockfd = *(curl_socket_t *)clientp;
+ /* the actual externally set socket is passed in via the OPENSOCKETDATA
+ option */
+ return sockfd;
+}
+
+static int sockopt_callback(void *clientp, curl_socket_t curlfd,
+ curlsocktype purpose)
+{
+ (void)clientp;
+ (void)curlfd;
+ (void)purpose;
+ /* This return code was added in libcurl 7.21.5 */
+ return CURL_SOCKOPT_ALREADY_CONNECTED;
+}
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+ struct sockaddr_in servaddr; /* socket address structure */
+ curl_socket_t sockfd;
+
+#ifdef WIN32
+ WSADATA wsaData;
+ int initwsa;
+
+ if((initwsa = WSAStartup(MAKEWORD(2,0), &wsaData)) != 0) {
+ printf("WSAStartup failed: %d\n", initwsa);
+ return 1;
+ }
+#endif
+
+ curl = curl_easy_init();
+ if(curl) {
+ /*
+ * Note that libcurl will internally think that you connect to the host
+ * and port that you specify in the URL option.
+ */
+ curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999");
+
+ /* Create the socket "manually" */
+ if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) == CURL_SOCKET_BAD ) {
+ printf("Error creating listening socket.\n");
+ return 3;
+ }
+
+ memset(&servaddr, 0, sizeof(servaddr));
+ servaddr.sin_family = AF_INET;
+ servaddr.sin_port = htons(PORTNUM);
+
+ if (INADDR_NONE == (servaddr.sin_addr.s_addr = inet_addr(IPADDR)))
+ return 2;
+
+ if(connect(sockfd,(struct sockaddr *) &servaddr, sizeof(servaddr)) ==
+ -1) {
+ close(sockfd);
+ printf("client error: connect: %s\n", strerror(errno));
+ return 1;
+ }
+
+ /* no progress meter please */
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
+
+ /* send all data to this function */
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
+
+ /* call this function to get a socket */
+ curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket);
+ curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd);
+
+ /* call this function to set options for the socket */
+ curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
+
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
+
+ res = curl_easy_perform(curl);
+
+ curl_easy_cleanup(curl);
+
+ if(res) {
+ printf("libcurl error: %d\n", res);
+ return 4;
+ }
+ }
+ return 0;
+}
diff --git a/docs/examples/fileupload.c b/docs/examples/fileupload.c
new file mode 100644
index 000000000..665eca0af
--- /dev/null
+++ b/docs/examples/fileupload.c
@@ -0,0 +1,86 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <curl/curl.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+ struct stat file_info;
+ double speed_upload, total_time;
+ FILE *fd;
+
+ fd = fopen("debugit", "rb"); /* open file to upload */
+ if(!fd) {
+
+ return 1; /* can't continue */
+ }
+
+ /* to get the file size */
+ if(fstat(fileno(fd), &file_info) != 0) {
+
+ return 1; /* can't continue */
+ }
+
+ curl = curl_easy_init();
+ if(curl) {
+ /* upload to this place */
+ curl_easy_setopt(curl, CURLOPT_URL,
+ "file:///home/dast/src/curl/debug/new");
+
+ /* tell it to "upload" to the URL */
+ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
+
+ /* set where to read from (on Windows you need to use READFUNCTION too) */
+ curl_easy_setopt(curl, CURLOPT_READDATA, fd);
+
+ /* and give the size of the upload (optional) */
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
+ (curl_off_t)file_info.st_size);
+
+ /* enable verbose for easier tracing */
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK) {
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ }
+ else {
+ /* now extract transfer info */
+ curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &speed_upload);
+ curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time);
+
+ fprintf(stderr, "Speed: %.3f bytes/sec during %.3f seconds\n",
+ speed_upload, total_time);
+
+ }
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ return 0;
+}
diff --git a/docs/examples/fopen.c b/docs/examples/fopen.c
new file mode 100644
index 000000000..6fe5c0f9f
--- /dev/null
+++ b/docs/examples/fopen.c
@@ -0,0 +1,527 @@
+/*****************************************************************************
+ *
+ * This example source code introduces a c library buffered I/O interface to
+ * URL reads it supports fopen(), fread(), fgets(), feof(), fclose(),
+ * rewind(). Supported functions have identical prototypes to their normal c
+ * lib namesakes and are preceaded by url_ .
+ *
+ * Using this code you can replace your program's fopen() with url_fopen()
+ * and fread() with url_fread() and it become possible to read remote streams
+ * instead of (only) local files. Local files (ie those that can be directly
+ * fopened) will drop back to using the underlying clib implementations
+ *
+ * See the main() function at the bottom that shows an app that retrives from a
+ * specified url using fgets() and fread() and saves as two output files.
+ *
+ * Copyright (c) 2003 Simtec Electronics
+ *
+ * Re-implemented by Vincent Sanders <vince@kyllikki.org> with extensive
+ * reference to original curl example code
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This example requires libcurl 7.9.7 or later.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#ifndef WIN32
+# include <sys/time.h>
+#endif
+#include <stdlib.h>
+#include <errno.h>
+
+#include <curl/curl.h>
+
+enum fcurl_type_e {
+ CFTYPE_NONE=0,
+ CFTYPE_FILE=1,
+ CFTYPE_CURL=2
+};
+
+struct fcurl_data
+{
+ enum fcurl_type_e type; /* type of handle */
+ union {
+ CURL *curl;
+ FILE *file;
+ } handle; /* handle */
+
+ char *buffer; /* buffer to store cached data*/
+ size_t buffer_len; /* currently allocated buffers length */
+ size_t buffer_pos; /* end of data in buffer*/
+ int still_running; /* Is background url fetch still in progress */
+};
+
+typedef struct fcurl_data URL_FILE;
+
+/* exported functions */
+URL_FILE *url_fopen(const char *url,const char *operation);
+int url_fclose(URL_FILE *file);
+int url_feof(URL_FILE *file);
+size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file);
+char * url_fgets(char *ptr, size_t size, URL_FILE *file);
+void url_rewind(URL_FILE *file);
+
+/* we use a global one for convenience */
+CURLM *multi_handle;
+
+/* curl calls this routine to get more data */
+static size_t write_callback(char *buffer,
+ size_t size,
+ size_t nitems,
+ void *userp)
+{
+ char *newbuff;
+ size_t rembuff;
+
+ URL_FILE *url = (URL_FILE *)userp;
+ size *= nitems;
+
+ rembuff=url->buffer_len - url->buffer_pos; /* remaining space in buffer */
+
+ if(size > rembuff) {
+ /* not enough space in buffer */
+ newbuff=realloc(url->buffer,url->buffer_len + (size - rembuff));
+ if(newbuff==NULL) {
+ fprintf(stderr,"callback buffer grow failed\n");
+ size=rembuff;
+ }
+ else {
+ /* realloc suceeded increase buffer size*/
+ url->buffer_len+=size - rembuff;
+ url->buffer=newbuff;
+ }
+ }
+
+ memcpy(&url->buffer[url->buffer_pos], buffer, size);
+ url->buffer_pos += size;
+
+ return size;
+}
+
+/* use to attempt to fill the read buffer up to requested number of bytes */
+static int fill_buffer(URL_FILE *file, size_t want)
+{
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ struct timeval timeout;
+ int rc;
+
+ /* only attempt to fill buffer if transactions still running and buffer
+ * doesnt exceed required size already
+ */
+ if((!file->still_running) || (file->buffer_pos > want))
+ return 0;
+
+ /* attempt to fill buffer */
+ do {
+ int maxfd = -1;
+ long curl_timeo = -1;
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ /* set a suitable timeout to fail on */
+ timeout.tv_sec = 60; /* 1 minute */
+ timeout.tv_usec = 0;
+
+ curl_multi_timeout(multi_handle, &curl_timeo);
+ if(curl_timeo >= 0) {
+ timeout.tv_sec = curl_timeo / 1000;
+ if(timeout.tv_sec > 1)
+ timeout.tv_sec = 1;
+ else
+ timeout.tv_usec = (curl_timeo % 1000) * 1000;
+ }
+
+ /* get file descriptors from the transfers */
+ curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* In a real-world program you OF COURSE check the return code of the
+ function calls. On success, the value of maxfd is guaranteed to be
+ greater or equal than -1. We call select(maxfd + 1, ...), specially
+ in case of (maxfd == -1), we call select(0, ...), which is basically
+ equal to sleep. */
+
+ rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ switch(rc) {
+ case -1:
+ /* select error */
+ break;
+
+ case 0:
+ default:
+ /* timeout or readable/writable sockets */
+ curl_multi_perform(multi_handle, &file->still_running);
+ break;
+ }
+ } while(file->still_running && (file->buffer_pos < want));
+ return 1;
+}
+
+/* use to remove want bytes from the front of a files buffer */
+static int use_buffer(URL_FILE *file,int want)
+{
+ /* sort out buffer */
+ if((file->buffer_pos - want) <=0) {
+ /* ditch buffer - write will recreate */
+ if(file->buffer)
+ free(file->buffer);
+
+ file->buffer=NULL;
+ file->buffer_pos=0;
+ file->buffer_len=0;
+ }
+ else {
+ /* move rest down make it available for later */
+ memmove(file->buffer,
+ &file->buffer[want],
+ (file->buffer_pos - want));
+
+ file->buffer_pos -= want;
+ }
+ return 0;
+}
+
+URL_FILE *url_fopen(const char *url,const char *operation)
+{
+ /* this code could check for URLs or types in the 'url' and
+ basicly use the real fopen() for standard files */
+
+ URL_FILE *file;
+ (void)operation;
+
+ file = malloc(sizeof(URL_FILE));
+ if(!file)
+ return NULL;
+
+ memset(file, 0, sizeof(URL_FILE));
+
+ if((file->handle.file=fopen(url,operation)))
+ file->type = CFTYPE_FILE; /* marked as URL */
+
+ else {
+ file->type = CFTYPE_CURL; /* marked as URL */
+ file->handle.curl = curl_easy_init();
+
+ curl_easy_setopt(file->handle.curl, CURLOPT_URL, url);
+ curl_easy_setopt(file->handle.curl, CURLOPT_WRITEDATA, file);
+ curl_easy_setopt(file->handle.curl, CURLOPT_VERBOSE, 0L);
+ curl_easy_setopt(file->handle.curl, CURLOPT_WRITEFUNCTION, write_callback);
+
+ if(!multi_handle)
+ multi_handle = curl_multi_init();
+
+ curl_multi_add_handle(multi_handle, file->handle.curl);
+
+ /* lets start the fetch */
+ curl_multi_perform(multi_handle, &file->still_running);
+
+ if((file->buffer_pos == 0) && (!file->still_running)) {
+ /* if still_running is 0 now, we should return NULL */
+
+ /* make sure the easy handle is not in the multi handle anymore */
+ curl_multi_remove_handle(multi_handle, file->handle.curl);
+
+ /* cleanup */
+ curl_easy_cleanup(file->handle.curl);
+
+ free(file);
+
+ file = NULL;
+ }
+ }
+ return file;
+}
+
+int url_fclose(URL_FILE *file)
+{
+ int ret=0;/* default is good return */
+
+ switch(file->type) {
+ case CFTYPE_FILE:
+ ret=fclose(file->handle.file); /* passthrough */
+ break;
+
+ case CFTYPE_CURL:
+ /* make sure the easy handle is not in the multi handle anymore */
+ curl_multi_remove_handle(multi_handle, file->handle.curl);
+
+ /* cleanup */
+ curl_easy_cleanup(file->handle.curl);
+ break;
+
+ default: /* unknown or supported type - oh dear */
+ ret=EOF;
+ errno=EBADF;
+ break;
+ }
+
+ if(file->buffer)
+ free(file->buffer);/* free any allocated buffer space */
+
+ free(file);
+
+ return ret;
+}
+
+int url_feof(URL_FILE *file)
+{
+ int ret=0;
+
+ switch(file->type) {
+ case CFTYPE_FILE:
+ ret=feof(file->handle.file);
+ break;
+
+ case CFTYPE_CURL:
+ if((file->buffer_pos == 0) && (!file->still_running))
+ ret = 1;
+ break;
+
+ default: /* unknown or supported type - oh dear */
+ ret=-1;
+ errno=EBADF;
+ break;
+ }
+ return ret;
+}
+
+size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file)
+{
+ size_t want;
+
+ switch(file->type) {
+ case CFTYPE_FILE:
+ want=fread(ptr,size,nmemb,file->handle.file);
+ break;
+
+ case CFTYPE_CURL:
+ want = nmemb * size;
+
+ fill_buffer(file,want);
+
+ /* check if theres data in the buffer - if not fill_buffer()
+ * either errored or EOF */
+ if(!file->buffer_pos)
+ return 0;
+
+ /* ensure only available data is considered */
+ if(file->buffer_pos < want)
+ want = file->buffer_pos;
+
+ /* xfer data to caller */
+ memcpy(ptr, file->buffer, want);
+
+ use_buffer(file,want);
+
+ want = want / size; /* number of items */
+ break;
+
+ default: /* unknown or supported type - oh dear */
+ want=0;
+ errno=EBADF;
+ break;
+
+ }
+ return want;
+}
+
+char *url_fgets(char *ptr, size_t size, URL_FILE *file)
+{
+ size_t want = size - 1;/* always need to leave room for zero termination */
+ size_t loop;
+
+ switch(file->type) {
+ case CFTYPE_FILE:
+ ptr = fgets(ptr,size,file->handle.file);
+ break;
+
+ case CFTYPE_CURL:
+ fill_buffer(file,want);
+
+ /* check if theres data in the buffer - if not fill either errored or
+ * EOF */
+ if(!file->buffer_pos)
+ return NULL;
+
+ /* ensure only available data is considered */
+ if(file->buffer_pos < want)
+ want = file->buffer_pos;
+
+ /*buffer contains data */
+ /* look for newline or eof */
+ for(loop=0;loop < want;loop++) {
+ if(file->buffer[loop] == '\n') {
+ want=loop+1;/* include newline */
+ break;
+ }
+ }
+
+ /* xfer data to caller */
+ memcpy(ptr, file->buffer, want);
+ ptr[want]=0;/* allways null terminate */
+
+ use_buffer(file,want);
+
+ break;
+
+ default: /* unknown or supported type - oh dear */
+ ptr=NULL;
+ errno=EBADF;
+ break;
+ }
+
+ return ptr;/*success */
+}
+
+void url_rewind(URL_FILE *file)
+{
+ switch(file->type) {
+ case CFTYPE_FILE:
+ rewind(file->handle.file); /* passthrough */
+ break;
+
+ case CFTYPE_CURL:
+ /* halt transaction */
+ curl_multi_remove_handle(multi_handle, file->handle.curl);
+
+ /* restart */
+ curl_multi_add_handle(multi_handle, file->handle.curl);
+
+ /* ditch buffer - write will recreate - resets stream pos*/
+ if(file->buffer)
+ free(file->buffer);
+
+ file->buffer=NULL;
+ file->buffer_pos=0;
+ file->buffer_len=0;
+
+ break;
+
+ default: /* unknown or supported type - oh dear */
+ break;
+ }
+}
+
+/* Small main program to retrive from a url using fgets and fread saving the
+ * output to two test files (note the fgets method will corrupt binary files if
+ * they contain 0 chars */
+int main(int argc, char *argv[])
+{
+ URL_FILE *handle;
+ FILE *outf;
+
+ int nread;
+ char buffer[256];
+ const char *url;
+
+ if(argc < 2)
+ url="http://192.168.7.3/testfile";/* default to testurl */
+ else
+ url=argv[1];/* use passed url */
+
+ /* copy from url line by line with fgets */
+ outf=fopen("fgets.test","w+");
+ if(!outf) {
+ perror("couldn't open fgets output file\n");
+ return 1;
+ }
+
+ handle = url_fopen(url, "r");
+ if(!handle) {
+ printf("couldn't url_fopen() %s\n", url);
+ fclose(outf);
+ return 2;
+ }
+
+ while(!url_feof(handle)) {
+ url_fgets(buffer,sizeof(buffer),handle);
+ fwrite(buffer,1,strlen(buffer),outf);
+ }
+
+ url_fclose(handle);
+
+ fclose(outf);
+
+
+ /* Copy from url with fread */
+ outf=fopen("fread.test","w+");
+ if(!outf) {
+ perror("couldn't open fread output file\n");
+ return 1;
+ }
+
+ handle = url_fopen("testfile", "r");
+ if(!handle) {
+ printf("couldn't url_fopen() testfile\n");
+ fclose(outf);
+ return 2;
+ }
+
+ do {
+ nread = url_fread(buffer, 1,sizeof(buffer), handle);
+ fwrite(buffer,1,nread,outf);
+ } while(nread);
+
+ url_fclose(handle);
+
+ fclose(outf);
+
+
+ /* Test rewind */
+ outf=fopen("rewind.test","w+");
+ if(!outf) {
+ perror("couldn't open fread output file\n");
+ return 1;
+ }
+
+ handle = url_fopen("testfile", "r");
+ if(!handle) {
+ printf("couldn't url_fopen() testfile\n");
+ fclose(outf);
+ return 2;
+ }
+
+ nread = url_fread(buffer, 1,sizeof(buffer), handle);
+ fwrite(buffer,1,nread,outf);
+ url_rewind(handle);
+
+ buffer[0]='\n';
+ fwrite(buffer,1,1,outf);
+
+ nread = url_fread(buffer, 1,sizeof(buffer), handle);
+ fwrite(buffer,1,nread,outf);
+
+
+ url_fclose(handle);
+
+ fclose(outf);
+
+
+ return 0;/* all done */
+}
diff --git a/docs/examples/ftp-wildcard.c b/docs/examples/ftp-wildcard.c
new file mode 100644
index 000000000..5a2a10311
--- /dev/null
+++ b/docs/examples/ftp-wildcard.c
@@ -0,0 +1,148 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <curl/curl.h>
+#include <stdio.h>
+
+struct callback_data {
+ FILE *output;
+};
+
+static long file_is_comming(struct curl_fileinfo *finfo,
+ struct callback_data *data,
+ int remains);
+
+static long file_is_downloaded(struct callback_data *data);
+
+static size_t write_it(char *buff, size_t size, size_t nmemb,
+ void *cb_data);
+
+int main(int argc, char **argv)
+{
+ int rc = CURLE_OK;
+
+ /* curl easy handle */
+ CURL *handle;
+
+ /* help data */
+ struct callback_data data = { 0 };
+
+ /* global initialization */
+ rc = curl_global_init(CURL_GLOBAL_ALL);
+ if(rc)
+ return rc;
+
+ /* initialization of easy handle */
+ handle = curl_easy_init();
+ if(!handle) {
+ curl_global_cleanup();
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* turn on wildcard matching */
+ curl_easy_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
+
+ /* callback is called before download of concrete file started */
+ curl_easy_setopt(handle, CURLOPT_CHUNK_BGN_FUNCTION, file_is_comming);
+
+ /* callback is called after data from the file have been transferred */
+ curl_easy_setopt(handle, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded);
+
+ /* this callback will write contents into files */
+ curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_it);
+
+ /* put transfer data into callbacks */
+ curl_easy_setopt(handle, CURLOPT_CHUNK_DATA, &data);
+ curl_easy_setopt(handle, CURLOPT_WRITEDATA, &data);
+
+ /* curl_easy_setopt(handle, CURLOPT_VERBOSE, 1L); */
+
+ /* set an URL containing wildcard pattern (only in the last part) */
+ if(argc == 2)
+ curl_easy_setopt(handle, CURLOPT_URL, argv[1]);
+ else
+ curl_easy_setopt(handle, CURLOPT_URL, "ftp://example.com/test/*");
+
+ /* and start transfer! */
+ rc = curl_easy_perform(handle);
+
+ curl_easy_cleanup(handle);
+ curl_global_cleanup();
+ return rc;
+}
+
+static long file_is_comming(struct curl_fileinfo *finfo,
+ struct callback_data *data,
+ int remains)
+{
+ printf("%3d %40s %10luB ", remains, finfo->filename,
+ (unsigned long)finfo->size);
+
+ switch(finfo->filetype) {
+ case CURLFILETYPE_DIRECTORY:
+ printf(" DIR\n");
+ break;
+ case CURLFILETYPE_FILE:
+ printf("FILE ");
+ break;
+ default:
+ printf("OTHER\n");
+ break;
+ }
+
+ if(finfo->filetype == CURLFILETYPE_FILE) {
+ /* do not transfer files >= 50B */
+ if(finfo->size > 50) {
+ printf("SKIPPED\n");
+ return CURL_CHUNK_BGN_FUNC_SKIP;
+ }
+
+ data->output = fopen(finfo->filename, "w");
+ if(!data->output) {
+ return CURL_CHUNK_BGN_FUNC_FAIL;
+ }
+ }
+
+ return CURL_CHUNK_BGN_FUNC_OK;
+}
+
+static long file_is_downloaded(struct callback_data *data)
+{
+ if(data->output) {
+ printf("DOWNLOADED\n");
+ fclose(data->output);
+ data->output = 0x0;
+ }
+ return CURL_CHUNK_END_FUNC_OK;
+}
+
+static size_t write_it(char *buff, size_t size, size_t nmemb,
+ void *cb_data)
+{
+ struct callback_data *data = cb_data;
+ size_t written = 0;
+ if(data->output)
+ written = fwrite(buff, size, nmemb, data->output);
+ else
+ /* listing output */
+ written = fwrite(buff, size, nmemb, stdout);
+ return written;
+}
diff --git a/docs/examples/ftpget.c b/docs/examples/ftpget.c
new file mode 100644
index 000000000..bcb42bb30
--- /dev/null
+++ b/docs/examples/ftpget.c
@@ -0,0 +1,94 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+
+#include <curl/curl.h>
+
+/*
+ * This is an example showing how to get a single file from an FTP server.
+ * It delays the actual destination file creation until the first write
+ * callback so that it won't create an empty file in case the remote file
+ * doesn't exist or something else fails.
+ */
+
+struct FtpFile {
+ const char *filename;
+ FILE *stream;
+};
+
+static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
+{
+ struct FtpFile *out=(struct FtpFile *)stream;
+ if(out && !out->stream) {
+ /* open file for writing */
+ out->stream=fopen(out->filename, "wb");
+ if(!out->stream)
+ return -1; /* failure, can't open file to write */
+ }
+ return fwrite(buffer, size, nmemb, out->stream);
+}
+
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+ struct FtpFile ftpfile={
+ "curl.tar.gz", /* name to store the file as if succesful */
+ NULL
+ };
+
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+
+ curl = curl_easy_init();
+ if(curl) {
+ /*
+ * You better replace the URL with one that works!
+ */
+ curl_easy_setopt(curl, CURLOPT_URL,
+ "ftp://ftp.example.com/pub/www/utilities/curl/curl-7.9.2.tar.gz");
+ /* Define our callback to get called when there's data to be written */
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
+ /* Set a pointer to our struct to pass to the callback */
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
+
+ /* Switch on full protocol/debug output */
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ res = curl_easy_perform(curl);
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+
+ if(CURLE_OK != res) {
+ /* we failed */
+ fprintf(stderr, "curl told us %d\n", res);
+ }
+ }
+
+ if(ftpfile.stream)
+ fclose(ftpfile.stream); /* close the local file */
+
+ curl_global_cleanup();
+
+ return 0;
+}
diff --git a/docs/examples/ftpgetinfo.c b/docs/examples/ftpgetinfo.c
new file mode 100644
index 000000000..dfdcf78b7
--- /dev/null
+++ b/docs/examples/ftpgetinfo.c
@@ -0,0 +1,89 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <string.h>
+
+#include <curl/curl.h>
+
+/*
+ * This is an example showing how to check a single file's size and mtime
+ * from an FTP server.
+ */
+
+static size_t throw_away(void *ptr, size_t size, size_t nmemb, void *data)
+{
+ (void)ptr;
+ (void)data;
+ /* we are not interested in the headers itself,
+ so we only return the size we would have saved ... */
+ return (size_t)(size * nmemb);
+}
+
+int main(void)
+{
+ char ftpurl[] = "ftp://ftp.example.com/gnu/binutils/binutils-2.19.1.tar.bz2";
+ CURL *curl;
+ CURLcode res;
+ long filetime = -1;
+ double filesize = 0.0;
+ const char *filename = strrchr(ftpurl, '/') + 1;
+
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+
+ curl = curl_easy_init();
+ if(curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, ftpurl);
+ /* No download if the file */
+ curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
+ /* Ask for filetime */
+ curl_easy_setopt(curl, CURLOPT_FILETIME, 1L);
+ /* No header output: TODO 14.1 http-style HEAD output for ftp */
+ curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, throw_away);
+ curl_easy_setopt(curl, CURLOPT_HEADER, 0L);
+ /* Switch on full protocol/debug output */
+ /* curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); */
+
+ res = curl_easy_perform(curl);
+
+ if(CURLE_OK == res) {
+ /* http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html */
+ res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
+ if((CURLE_OK == res) && (filetime >= 0)) {
+ time_t file_time = (time_t)filetime;
+ printf("filetime %s: %s", filename, ctime(&file_time));
+ }
+ res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &filesize);
+ if((CURLE_OK == res) && (filesize>0.0))
+ printf("filesize %s: %0.0f bytes\n", filename, filesize);
+ } else {
+ /* we failed */
+ fprintf(stderr, "curl told us %d\n", res);
+ }
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+
+ curl_global_cleanup();
+
+ return 0;
+}
diff --git a/docs/examples/ftpgetresp.c b/docs/examples/ftpgetresp.c
new file mode 100644
index 000000000..db96a3a13
--- /dev/null
+++ b/docs/examples/ftpgetresp.c
@@ -0,0 +1,76 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+
+#include <curl/curl.h>
+
+/*
+ * Similar to ftpget.c but this also stores the received response-lines
+ * in a separate file using our own callback!
+ *
+ * This functionality was introduced in libcurl 7.9.3.
+ */
+
+static size_t
+write_response(void *ptr, size_t size, size_t nmemb, void *data)
+{
+ FILE *writehere = (FILE *)data;
+ return fwrite(ptr, size, nmemb, writehere);
+}
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+ FILE *ftpfile;
+ FILE *respfile;
+
+ /* local file name to store the file as */
+ ftpfile = fopen("ftp-list", "wb"); /* b is binary, needed on win32 */
+
+ /* local file name to store the FTP server's response lines in */
+ respfile = fopen("ftp-responses", "wb"); /* b is binary, needed on win32 */
+
+ curl = curl_easy_init();
+ if(curl) {
+ /* Get a file listing from sunet */
+ curl_easy_setopt(curl, CURLOPT_URL, "ftp://ftp.example.com/");
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, ftpfile);
+ /* If you intend to use this on windows with a libcurl DLL, you must use
+ CURLOPT_WRITEFUNCTION as well */
+ curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_response);
+ curl_easy_setopt(curl, CURLOPT_WRITEHEADER, respfile);
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+
+ fclose(ftpfile); /* close the local file */
+ fclose(respfile); /* close the response file */
+
+ return 0;
+}
diff --git a/docs/examples/ftpsget.c b/docs/examples/ftpsget.c
new file mode 100644
index 000000000..0cfe32024
--- /dev/null
+++ b/docs/examples/ftpsget.c
@@ -0,0 +1,101 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <stdio.h>
+
+#include <curl/curl.h>
+
+/*
+ * This is an example showing how to get a single file from an FTPS server.
+ * It delays the actual destination file creation until the first write
+ * callback so that it won't create an empty file in case the remote file
+ * doesn't exist or something else fails.
+ */
+
+struct FtpFile {
+ const char *filename;
+ FILE *stream;
+};
+
+static size_t my_fwrite(void *buffer, size_t size, size_t nmemb,
+ void *stream)
+{
+ struct FtpFile *out=(struct FtpFile *)stream;
+ if(out && !out->stream) {
+ /* open file for writing */
+ out->stream=fopen(out->filename, "wb");
+ if(!out->stream)
+ return -1; /* failure, can't open file to write */
+ }
+ return fwrite(buffer, size, nmemb, out->stream);
+}
+
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+ struct FtpFile ftpfile={
+ "yourfile.bin", /* name to store the file as if succesful */
+ NULL
+ };
+
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+
+ curl = curl_easy_init();
+ if(curl) {
+ /*
+ * You better replace the URL with one that works! Note that we use an
+ * FTP:// URL with standard explicit FTPS. You can also do FTPS:// URLs if
+ * you want to do the rarer kind of transfers: implicit.
+ */
+ curl_easy_setopt(curl, CURLOPT_URL,
+ "ftp://user@server/home/user/file.txt");
+ /* Define our callback to get called when there's data to be written */
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
+ /* Set a pointer to our struct to pass to the callback */
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
+
+ /* We activate SSL and we require it for both control and data */
+ curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
+
+ /* Switch on full protocol/debug output */
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ res = curl_easy_perform(curl);
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+
+ if(CURLE_OK != res) {
+ /* we failed */
+ fprintf(stderr, "curl told us %d\n", res);
+ }
+ }
+
+ if(ftpfile.stream)
+ fclose(ftpfile.stream); /* close the local file */
+
+ curl_global_cleanup();
+
+ return 0;
+}
diff --git a/docs/examples/ftpupload.c b/docs/examples/ftpupload.c
new file mode 100644
index 000000000..e79f8d842
--- /dev/null
+++ b/docs/examples/ftpupload.c
@@ -0,0 +1,140 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <string.h>
+
+#include <curl/curl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#ifdef WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+/*
+ * This example shows an FTP upload, with a rename of the file just after
+ * a successful upload.
+ *
+ * Example based on source code provided by Erick Nuwendam. Thanks!
+ */
+
+#define LOCAL_FILE "/tmp/uploadthis.txt"
+#define UPLOAD_FILE_AS "while-uploading.txt"
+#define REMOTE_URL "ftp://example.com/" UPLOAD_FILE_AS
+#define RENAME_FILE_TO "renamed-and-fine.txt"
+
+/* NOTE: if you want this example to work on Windows with libcurl as a
+ DLL, you MUST also provide a read callback with CURLOPT_READFUNCTION.
+ Failing to do so will give you a crash since a DLL may not use the
+ variable's memory when passed in to it from an app like this. */
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ curl_off_t nread;
+ /* in real-world cases, this would probably get this data differently
+ as this fread() stuff is exactly what the library already would do
+ by default internally */
+ size_t retcode = fread(ptr, size, nmemb, stream);
+
+ nread = (curl_off_t)retcode;
+
+ fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T
+ " bytes from file\n", nread);
+ return retcode;
+}
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+ FILE *hd_src;
+ struct stat file_info;
+ curl_off_t fsize;
+
+ struct curl_slist *headerlist=NULL;
+ static const char buf_1 [] = "RNFR " UPLOAD_FILE_AS;
+ static const char buf_2 [] = "RNTO " RENAME_FILE_TO;
+
+ /* get the file size of the local file */
+ if(stat(LOCAL_FILE, &file_info)) {
+ printf("Couldnt open '%s': %s\n", LOCAL_FILE, strerror(errno));
+ return 1;
+ }
+ fsize = (curl_off_t)file_info.st_size;
+
+ printf("Local file size: %" CURL_FORMAT_CURL_OFF_T " bytes.\n", fsize);
+
+ /* get a FILE * of the same file */
+ hd_src = fopen(LOCAL_FILE, "rb");
+
+ /* In windows, this will init the winsock stuff */
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ /* get a curl handle */
+ curl = curl_easy_init();
+ if(curl) {
+ /* build a list of commands to pass to libcurl */
+ headerlist = curl_slist_append(headerlist, buf_1);
+ headerlist = curl_slist_append(headerlist, buf_2);
+
+ /* we want to use our own read function */
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
+
+ /* enable uploading */
+ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
+
+ /* specify target */
+ curl_easy_setopt(curl,CURLOPT_URL, REMOTE_URL);
+
+ /* pass in that last of FTP commands to run after the transfer */
+ curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
+
+ /* now specify which file to upload */
+ curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);
+
+ /* Set the size of the file to upload (optional). If you give a *_LARGE
+ option you MUST make sure that the type of the passed-in argument is a
+ curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must
+ make sure that to pass in a type 'long' argument. */
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
+ (curl_off_t)fsize);
+
+ /* Now run off and do what you've been told! */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* clean up the FTP commands list */
+ curl_slist_free_all (headerlist);
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ fclose(hd_src); /* close the local file */
+
+ curl_global_cleanup();
+ return 0;
+}
diff --git a/docs/examples/ftpuploadresume.c b/docs/examples/ftpuploadresume.c
new file mode 100644
index 000000000..55b8986c7
--- /dev/null
+++ b/docs/examples/ftpuploadresume.c
@@ -0,0 +1,174 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* Upload to FTP, resuming failed transfers
+ *
+ * Compile for MinGW like this:
+ * gcc -Wall -pedantic -std=c99 ftpuploadwithresume.c -o ftpuploadresume.exe
+ * -lcurl -lmsvcr70
+ *
+ * Written by Philip Bock
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <curl/curl.h>
+
+#if defined(_MSC_VER) && (_MSC_VER < 1300)
+# error _snscanf requires MSVC 7.0 or later.
+#endif
+
+/* The MinGW headers are missing a few Win32 function definitions,
+ you shouldn't need this if you use VC++ */
+#if defined(__MINGW32__) && !defined(__MINGW64__)
+int __cdecl _snscanf(const char * input, size_t length, const char * format, ...);
+#endif
+
+
+/* parse headers for Content-Length */
+size_t getcontentlengthfunc(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ int r;
+ long len = 0;
+
+ /* _snscanf() is Win32 specific */
+ r = _snscanf(ptr, size * nmemb, "Content-Length: %ld\n", &len);
+
+ if (r) /* Microsoft: we don't read the specs */
+ *((long *) stream) = len;
+
+ return size * nmemb;
+}
+
+/* discard downloaded data */
+size_t discardfunc(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ return size * nmemb;
+}
+
+/* read data to upload */
+size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ FILE *f = stream;
+ size_t n;
+
+ if (ferror(f))
+ return CURL_READFUNC_ABORT;
+
+ n = fread(ptr, size, nmemb, f) * size;
+
+ return n;
+}
+
+
+int upload(CURL *curlhandle, const char * remotepath, const char * localpath,
+ long timeout, long tries)
+{
+ FILE *f;
+ long uploaded_len = 0;
+ CURLcode r = CURLE_GOT_NOTHING;
+ int c;
+
+ f = fopen(localpath, "rb");
+ if (f == NULL) {
+ perror(NULL);
+ return 0;
+ }
+
+ curl_easy_setopt(curlhandle, CURLOPT_UPLOAD, 1L);
+
+ curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath);
+
+ if (timeout)
+ curl_easy_setopt(curlhandle, CURLOPT_FTP_RESPONSE_TIMEOUT, timeout);
+
+ curl_easy_setopt(curlhandle, CURLOPT_HEADERFUNCTION, getcontentlengthfunc);
+ curl_easy_setopt(curlhandle, CURLOPT_HEADERDATA, &uploaded_len);
+
+ curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, discardfunc);
+
+ curl_easy_setopt(curlhandle, CURLOPT_READFUNCTION, readfunc);
+ curl_easy_setopt(curlhandle, CURLOPT_READDATA, f);
+
+ curl_easy_setopt(curlhandle, CURLOPT_FTPPORT, "-"); /* disable passive mode */
+ curl_easy_setopt(curlhandle, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);
+
+ curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L);
+
+ for (c = 0; (r != CURLE_OK) && (c < tries); c++) {
+ /* are we resuming? */
+ if (c) { /* yes */
+ /* determine the length of the file already written */
+
+ /*
+ * With NOBODY and NOHEADER, libcurl will issue a SIZE
+ * command, but the only way to retrieve the result is
+ * to parse the returned Content-Length header. Thus,
+ * getcontentlengthfunc(). We need discardfunc() above
+ * because HEADER will dump the headers to stdout
+ * without it.
+ */
+ curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 1L);
+ curl_easy_setopt(curlhandle, CURLOPT_HEADER, 1L);
+
+ r = curl_easy_perform(curlhandle);
+ if (r != CURLE_OK)
+ continue;
+
+ curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 0L);
+ curl_easy_setopt(curlhandle, CURLOPT_HEADER, 0L);
+
+ fseek(f, uploaded_len, SEEK_SET);
+
+ curl_easy_setopt(curlhandle, CURLOPT_APPEND, 1L);
+ }
+ else { /* no */
+ curl_easy_setopt(curlhandle, CURLOPT_APPEND, 0L);
+ }
+
+ r = curl_easy_perform(curlhandle);
+ }
+
+ fclose(f);
+
+ if (r == CURLE_OK)
+ return 1;
+ else {
+ fprintf(stderr, "%s\n", curl_easy_strerror(r));
+ return 0;
+ }
+}
+
+int main(int c, char **argv)
+{
+ CURL *curlhandle = NULL;
+
+ curl_global_init(CURL_GLOBAL_ALL);
+ curlhandle = curl_easy_init();
+
+ upload(curlhandle, "ftp://user:pass@example.com/path/file", "C:\\file", 0, 3);
+
+ curl_easy_cleanup(curlhandle);
+ curl_global_cleanup();
+
+ return 0;
+}
diff --git a/docs/examples/getinfo.c b/docs/examples/getinfo.c
new file mode 100644
index 000000000..acbe1e1af
--- /dev/null
+++ b/docs/examples/getinfo.c
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <curl/curl.h>
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+
+ /* http://curl.haxx.se/libcurl/c/curl_easy_init.html */
+ curl = curl_easy_init();
+ if(curl) {
+ /* http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTURL */
+ curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/");
+ /* http://curl.haxx.se/libcurl/c/curl_easy_perform.html */
+ res = curl_easy_perform(curl);
+
+ if(CURLE_OK == res) {
+ char *ct;
+ /* ask for the content-type */
+ /* http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html */
+ res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
+
+ if((CURLE_OK == res) && ct)
+ printf("We received Content-Type: %s\n", ct);
+ }
+
+ /* always cleanup */
+ /* http://curl.haxx.se/libcurl/c/curl_easy_cleanup.html */
+ curl_easy_cleanup(curl);
+ }
+ return 0;
+}
diff --git a/docs/examples/getinmemory.c b/docs/examples/getinmemory.c
new file mode 100644
index 000000000..78e6deb10
--- /dev/null
+++ b/docs/examples/getinmemory.c
@@ -0,0 +1,112 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* Example source code to show how the callback function can be used to
+ * download data into a chunk of memory instead of storing it in a file.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <curl/curl.h>
+
+struct MemoryStruct {
+ char *memory;
+ size_t size;
+};
+
+
+static size_t
+WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
+{
+ size_t realsize = size * nmemb;
+ struct MemoryStruct *mem = (struct MemoryStruct *)userp;
+
+ mem->memory = realloc(mem->memory, mem->size + realsize + 1);
+ if (mem->memory == NULL) {
+ /* out of memory! */
+ printf("not enough memory (realloc returned NULL)\n");
+ exit(EXIT_FAILURE);
+ }
+
+ memcpy(&(mem->memory[mem->size]), contents, realsize);
+ mem->size += realsize;
+ mem->memory[mem->size] = 0;
+
+ return realsize;
+}
+
+
+int main(void)
+{
+ CURL *curl_handle;
+
+ struct MemoryStruct chunk;
+
+ chunk.memory = malloc(1); /* will be grown as needed by the realloc above */
+ chunk.size = 0; /* no data at this point */
+
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ /* init the curl session */
+ curl_handle = curl_easy_init();
+
+ /* specify URL to get */
+ curl_easy_setopt(curl_handle, CURLOPT_URL, "http://www.example.com/");
+
+ /* send all data to this function */
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
+
+ /* we pass our 'chunk' struct to the callback function */
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
+
+ /* some servers don't like requests that are made without a user-agent
+ field, so we provide one */
+ curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
+
+ /* get it! */
+ curl_easy_perform(curl_handle);
+
+ /* cleanup curl stuff */
+ curl_easy_cleanup(curl_handle);
+
+ /*
+ * Now, our chunk.memory points to a memory block that is chunk.size
+ * bytes big and contains the remote file.
+ *
+ * Do something nice with it!
+ *
+ * You should be aware of the fact that at this point we might have an
+ * allocated data block, and nothing has yet deallocated that data. So when
+ * you're done with it, you should free() it as a nice application.
+ */
+
+ printf("%lu bytes retrieved\n", (long)chunk.size);
+
+ if(chunk.memory)
+ free(chunk.memory);
+
+ /* we're done with libcurl, so clean it up */
+ curl_global_cleanup();
+
+ return 0;
+}
diff --git a/docs/examples/ghiper.c b/docs/examples/ghiper.c
new file mode 100644
index 000000000..9a3f46d3f
--- /dev/null
+++ b/docs/examples/ghiper.c
@@ -0,0 +1,452 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* Example application source code using the multi socket interface to
+ * download many files at once.
+ *
+ * Written by Jeff Pohlmeyer
+
+Requires glib-2.x and a (POSIX?) system that has mkfifo().
+
+This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
+sample programs, adapted to use glib's g_io_channel in place of libevent.
+
+When running, the program creates the named pipe "hiper.fifo"
+
+Whenever there is input into the fifo, the program reads the input as a list
+of URL's and creates some new easy handles to fetch each URL via the
+curl_multi "hiper" API.
+
+
+Thus, you can try a single URL:
+ % echo http://www.yahoo.com > hiper.fifo
+
+Or a whole bunch of them:
+ % cat my-url-list > hiper.fifo
+
+The fifo buffer is handled almost instantly, so you can even add more URL's
+while the previous requests are still being downloaded.
+
+This is purely a demo app, all retrieved data is simply discarded by the write
+callback.
+
+*/
+
+
+#include <glib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <curl/curl.h>
+
+
+#define MSG_OUT g_print /* Change to "g_error" to write to stderr */
+#define SHOW_VERBOSE 0 /* Set to non-zero for libcurl messages */
+#define SHOW_PROGRESS 0 /* Set to non-zero to enable progress callback */
+
+
+
+/* Global information, common to all connections */
+typedef struct _GlobalInfo {
+ CURLM *multi;
+ guint timer_event;
+ int still_running;
+} GlobalInfo;
+
+
+
+/* Information associated with a specific easy handle */
+typedef struct _ConnInfo {
+ CURL *easy;
+ char *url;
+ GlobalInfo *global;
+ char error[CURL_ERROR_SIZE];
+} ConnInfo;
+
+
+/* Information associated with a specific socket */
+typedef struct _SockInfo {
+ curl_socket_t sockfd;
+ CURL *easy;
+ int action;
+ long timeout;
+ GIOChannel *ch;
+ guint ev;
+ GlobalInfo *global;
+} SockInfo;
+
+
+
+
+/* Die if we get a bad CURLMcode somewhere */
+static void mcode_or_die(const char *where, CURLMcode code) {
+ if ( CURLM_OK != code ) {
+ const char *s;
+ switch (code) {
+ case CURLM_CALL_MULTI_PERFORM: s="CURLM_CALL_MULTI_PERFORM"; break;
+ case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break;
+ case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
+ case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
+ case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
+ case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET"; break;
+ case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
+ case CURLM_LAST: s="CURLM_LAST"; break;
+ default: s="CURLM_unknown";
+ }
+ MSG_OUT("ERROR: %s returns %s\n", where, s);
+ exit(code);
+ }
+}
+
+
+
+/* Check for completed transfers, and remove their easy handles */
+static void check_multi_info(GlobalInfo *g)
+{
+ char *eff_url;
+ CURLMsg *msg;
+ int msgs_left;
+ ConnInfo *conn;
+ CURL *easy;
+ CURLcode res;
+
+ MSG_OUT("REMAINING: %d\n", g->still_running);
+ while ((msg = curl_multi_info_read(g->multi, &msgs_left))) {
+ if (msg->msg == CURLMSG_DONE) {
+ easy = msg->easy_handle;
+ res = msg->data.result;
+ curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
+ curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
+ MSG_OUT("DONE: %s => (%d) %s\n", eff_url, res, conn->error);
+ curl_multi_remove_handle(g->multi, easy);
+ free(conn->url);
+ curl_easy_cleanup(easy);
+ free(conn);
+ }
+ }
+}
+
+
+
+/* Called by glib when our timeout expires */
+static gboolean timer_cb(gpointer data)
+{
+ GlobalInfo *g = (GlobalInfo *)data;
+ CURLMcode rc;
+
+ rc = curl_multi_socket_action(g->multi,
+ CURL_SOCKET_TIMEOUT, 0, &g->still_running);
+ mcode_or_die("timer_cb: curl_multi_socket_action", rc);
+ check_multi_info(g);
+ return FALSE;
+}
+
+
+
+/* Update the event timer after curl_multi library calls */
+static int update_timeout_cb(CURLM *multi, long timeout_ms, void *userp)
+{
+ struct timeval timeout;
+ GlobalInfo *g=(GlobalInfo *)userp;
+ timeout.tv_sec = timeout_ms/1000;
+ timeout.tv_usec = (timeout_ms%1000)*1000;
+
+ MSG_OUT("*** update_timeout_cb %ld => %ld:%ld ***\n",
+ timeout_ms, timeout.tv_sec, timeout.tv_usec);
+
+ g->timer_event = g_timeout_add(timeout_ms, timer_cb, g);
+ return 0;
+}
+
+
+
+
+/* Called by glib when we get action on a multi socket */
+static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data)
+{
+ GlobalInfo *g = (GlobalInfo*) data;
+ CURLMcode rc;
+ int fd=g_io_channel_unix_get_fd(ch);
+
+ int action =
+ (condition & G_IO_IN ? CURL_CSELECT_IN : 0) |
+ (condition & G_IO_OUT ? CURL_CSELECT_OUT : 0);
+
+ rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
+ mcode_or_die("event_cb: curl_multi_socket_action", rc);
+
+ check_multi_info(g);
+ if(g->still_running) {
+ return TRUE;
+ } else {
+ MSG_OUT("last transfer done, kill timeout\n");
+ if (g->timer_event) { g_source_remove(g->timer_event); }
+ return FALSE;
+ }
+}
+
+
+
+/* Clean up the SockInfo structure */
+static void remsock(SockInfo *f)
+{
+ if (!f) { return; }
+ if (f->ev) { g_source_remove(f->ev); }
+ g_free(f);
+}
+
+
+
+/* Assign information to a SockInfo structure */
+static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
+{
+ GIOCondition kind =
+ (act&CURL_POLL_IN?G_IO_IN:0)|(act&CURL_POLL_OUT?G_IO_OUT:0);
+
+ f->sockfd = s;
+ f->action = act;
+ f->easy = e;
+ if (f->ev) { g_source_remove(f->ev); }
+ f->ev=g_io_add_watch(f->ch, kind, event_cb,g);
+
+}
+
+
+
+/* Initialize a new SockInfo structure */
+static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
+{
+ SockInfo *fdp = g_malloc0(sizeof(SockInfo));
+
+ fdp->global = g;
+ fdp->ch=g_io_channel_unix_new(s);
+ setsock(fdp, s, easy, action, g);
+ curl_multi_assign(g->multi, s, fdp);
+}
+
+
+
+/* CURLMOPT_SOCKETFUNCTION */
+static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
+{
+ GlobalInfo *g = (GlobalInfo*) cbp;
+ SockInfo *fdp = (SockInfo*) sockp;
+ static const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" };
+
+ MSG_OUT("socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
+ if (what == CURL_POLL_REMOVE) {
+ MSG_OUT("\n");
+ remsock(fdp);
+ } else {
+ if (!fdp) {
+ MSG_OUT("Adding data: %s%s\n",
+ what&CURL_POLL_IN?"READ":"",
+ what&CURL_POLL_OUT?"WRITE":"" );
+ addsock(s, e, what, g);
+ }
+ else {
+ MSG_OUT(
+ "Changing action from %d to %d\n", fdp->action, what);
+ setsock(fdp, s, e, what, g);
+ }
+ }
+ return 0;
+}
+
+
+
+/* CURLOPT_WRITEFUNCTION */
+static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
+{
+ size_t realsize = size * nmemb;
+ ConnInfo *conn = (ConnInfo*) data;
+ (void)ptr;
+ (void)conn;
+ return realsize;
+}
+
+
+
+/* CURLOPT_PROGRESSFUNCTION */
+static int prog_cb (void *p, double dltotal, double dlnow, double ult, double uln)
+{
+ ConnInfo *conn = (ConnInfo *)p;
+ MSG_OUT("Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
+ return 0;
+}
+
+
+
+/* Create a new easy handle, and add it to the global curl_multi */
+static void new_conn(char *url, GlobalInfo *g )
+{
+ ConnInfo *conn;
+ CURLMcode rc;
+
+ conn = g_malloc0(sizeof(ConnInfo));
+
+ conn->error[0]='\0';
+
+ conn->easy = curl_easy_init();
+ if (!conn->easy) {
+ MSG_OUT("curl_easy_init() failed, exiting!\n");
+ exit(2);
+ }
+ conn->global = g;
+ conn->url = g_strdup(url);
+ curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
+ curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
+ curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
+ curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, (long)SHOW_VERBOSE);
+ curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
+ curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
+ curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, SHOW_PROGRESS?0L:1L);
+ curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
+ curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
+ curl_easy_setopt(conn->easy, CURLOPT_FOLLOWLOCATION, 1L);
+ curl_easy_setopt(conn->easy, CURLOPT_CONNECTTIMEOUT, 30L);
+ curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 1L);
+ curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 30L);
+
+ MSG_OUT("Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
+ rc =curl_multi_add_handle(g->multi, conn->easy);
+ mcode_or_die("new_conn: curl_multi_add_handle", rc);
+
+ /* note that the add_handle() will set a time-out to trigger very soon so
+ that the necessary socket_action() call will be called by this app */
+}
+
+
+/* This gets called by glib whenever data is received from the fifo */
+static gboolean fifo_cb (GIOChannel *ch, GIOCondition condition, gpointer data)
+{
+ #define BUF_SIZE 1024
+ gsize len, tp;
+ gchar *buf, *tmp, *all=NULL;
+ GIOStatus rv;
+
+ do {
+ GError *err=NULL;
+ rv = g_io_channel_read_line (ch,&buf,&len,&tp,&err);
+ if ( buf ) {
+ if (tp) { buf[tp]='\0'; }
+ new_conn(buf,(GlobalInfo*)data);
+ g_free(buf);
+ } else {
+ buf = g_malloc(BUF_SIZE+1);
+ while (TRUE) {
+ buf[BUF_SIZE]='\0';
+ g_io_channel_read_chars(ch,buf,BUF_SIZE,&len,&err);
+ if (len) {
+ buf[len]='\0';
+ if (all) {
+ tmp=all;
+ all=g_strdup_printf("%s%s", tmp, buf);
+ g_free(tmp);
+ } else {
+ all = g_strdup(buf);
+ }
+ } else {
+ break;
+ }
+ }
+ if (all) {
+ new_conn(all,(GlobalInfo*)data);
+ g_free(all);
+ }
+ g_free(buf);
+ }
+ if ( err ) {
+ g_error("fifo_cb: %s", err->message);
+ g_free(err);
+ break;
+ }
+ } while ( (len) && (rv == G_IO_STATUS_NORMAL) );
+ return TRUE;
+}
+
+
+
+
+int init_fifo(void)
+{
+ struct stat st;
+ const char *fifo = "hiper.fifo";
+ int socket;
+
+ if (lstat (fifo, &st) == 0) {
+ if ((st.st_mode & S_IFMT) == S_IFREG) {
+ errno = EEXIST;
+ perror("lstat");
+ exit (1);
+ }
+ }
+
+ unlink (fifo);
+ if (mkfifo (fifo, 0600) == -1) {
+ perror("mkfifo");
+ exit (1);
+ }
+
+ socket = open (fifo, O_RDWR | O_NONBLOCK, 0);
+
+ if (socket == -1) {
+ perror("open");
+ exit (1);
+ }
+ MSG_OUT("Now, pipe some URL's into > %s\n", fifo);
+
+ return socket;
+
+}
+
+
+
+
+int main(int argc, char **argv)
+{
+ GlobalInfo *g;
+ CURLMcode rc;
+ GMainLoop*gmain;
+ int fd;
+ GIOChannel* ch;
+ g=g_malloc0(sizeof(GlobalInfo));
+
+ fd=init_fifo();
+ ch=g_io_channel_unix_new(fd);
+ g_io_add_watch(ch,G_IO_IN,fifo_cb,g);
+ gmain=g_main_loop_new(NULL,FALSE);
+ g->multi = curl_multi_init();
+ curl_multi_setopt(g->multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
+ curl_multi_setopt(g->multi, CURLMOPT_SOCKETDATA, g);
+ curl_multi_setopt(g->multi, CURLMOPT_TIMERFUNCTION, update_timeout_cb);
+ curl_multi_setopt(g->multi, CURLMOPT_TIMERDATA, g);
+
+ /* we don't call any curl_multi_socket*() function yet as we have no handles
+ added! */
+
+ g_main_loop_run(gmain);
+ curl_multi_cleanup(g->multi);
+ return 0;
+}
diff --git a/docs/examples/hiperfifo.c b/docs/examples/hiperfifo.c
new file mode 100644
index 000000000..6036643b1
--- /dev/null
+++ b/docs/examples/hiperfifo.c
@@ -0,0 +1,418 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* Example application source code using the multi socket interface to
+ download many files at once.
+
+Written by Jeff Pohlmeyer
+
+Requires libevent and a (POSIX?) system that has mkfifo().
+
+This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
+sample programs.
+
+When running, the program creates the named pipe "hiper.fifo"
+
+Whenever there is input into the fifo, the program reads the input as a list
+of URL's and creates some new easy handles to fetch each URL via the
+curl_multi "hiper" API.
+
+
+Thus, you can try a single URL:
+ % echo http://www.yahoo.com > hiper.fifo
+
+Or a whole bunch of them:
+ % cat my-url-list > hiper.fifo
+
+The fifo buffer is handled almost instantly, so you can even add more URL's
+while the previous requests are still being downloaded.
+
+Note:
+ For the sake of simplicity, URL length is limited to 1023 char's !
+
+This is purely a demo app, all retrieved data is simply discarded by the write
+callback.
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include <curl/curl.h>
+#include <event.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+
+#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
+
+
+/* Global information, common to all connections */
+typedef struct _GlobalInfo {
+ struct event fifo_event;
+ struct event timer_event;
+ CURLM *multi;
+ int still_running;
+ FILE* input;
+} GlobalInfo;
+
+
+/* Information associated with a specific easy handle */
+typedef struct _ConnInfo {
+ CURL *easy;
+ char *url;
+ GlobalInfo *global;
+ char error[CURL_ERROR_SIZE];
+} ConnInfo;
+
+
+/* Information associated with a specific socket */
+typedef struct _SockInfo {
+ curl_socket_t sockfd;
+ CURL *easy;
+ int action;
+ long timeout;
+ struct event ev;
+ int evset;
+ GlobalInfo *global;
+} SockInfo;
+
+
+
+/* Update the event timer after curl_multi library calls */
+static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
+{
+ struct timeval timeout;
+ (void)multi; /* unused */
+
+ timeout.tv_sec = timeout_ms/1000;
+ timeout.tv_usec = (timeout_ms%1000)*1000;
+ fprintf(MSG_OUT, "multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms);
+ evtimer_add(&g->timer_event, &timeout);
+ return 0;
+}
+
+/* Die if we get a bad CURLMcode somewhere */
+static void mcode_or_die(const char *where, CURLMcode code)
+{
+ if ( CURLM_OK != code ) {
+ const char *s;
+ switch (code) {
+ case CURLM_CALL_MULTI_PERFORM: s="CURLM_CALL_MULTI_PERFORM"; break;
+ case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break;
+ case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break;
+ case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break;
+ case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break;
+ case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break;
+ case CURLM_LAST: s="CURLM_LAST"; break;
+ default: s="CURLM_unknown";
+ break;
+ case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET";
+ fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
+ /* ignore this error */
+ return;
+ }
+ fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
+ exit(code);
+ }
+}
+
+
+
+/* Check for completed transfers, and remove their easy handles */
+static void check_multi_info(GlobalInfo *g)
+{
+ char *eff_url;
+ CURLMsg *msg;
+ int msgs_left;
+ ConnInfo *conn;
+ CURL *easy;
+ CURLcode res;
+
+ fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
+ while ((msg = curl_multi_info_read(g->multi, &msgs_left))) {
+ if (msg->msg == CURLMSG_DONE) {
+ easy = msg->easy_handle;
+ res = msg->data.result;
+ curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
+ curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
+ fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, res, conn->error);
+ curl_multi_remove_handle(g->multi, easy);
+ free(conn->url);
+ curl_easy_cleanup(easy);
+ free(conn);
+ }
+ }
+}
+
+
+
+/* Called by libevent when we get action on a multi socket */
+static void event_cb(int fd, short kind, void *userp)
+{
+ GlobalInfo *g = (GlobalInfo*) userp;
+ CURLMcode rc;
+
+ int action =
+ (kind & EV_READ ? CURL_CSELECT_IN : 0) |
+ (kind & EV_WRITE ? CURL_CSELECT_OUT : 0);
+
+ rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
+ mcode_or_die("event_cb: curl_multi_socket_action", rc);
+
+ check_multi_info(g);
+ if ( g->still_running <= 0 ) {
+ fprintf(MSG_OUT, "last transfer done, kill timeout\n");
+ if (evtimer_pending(&g->timer_event, NULL)) {
+ evtimer_del(&g->timer_event);
+ }
+ }
+}
+
+
+
+/* Called by libevent when our timeout expires */
+static void timer_cb(int fd, short kind, void *userp)
+{
+ GlobalInfo *g = (GlobalInfo *)userp;
+ CURLMcode rc;
+ (void)fd;
+ (void)kind;
+
+ rc = curl_multi_socket_action(g->multi,
+ CURL_SOCKET_TIMEOUT, 0, &g->still_running);
+ mcode_or_die("timer_cb: curl_multi_socket_action", rc);
+ check_multi_info(g);
+}
+
+
+
+/* Clean up the SockInfo structure */
+static void remsock(SockInfo *f)
+{
+ if (f) {
+ if (f->evset)
+ event_del(&f->ev);
+ free(f);
+ }
+}
+
+
+
+/* Assign information to a SockInfo structure */
+static void setsock(SockInfo*f, curl_socket_t s, CURL*e, int act, GlobalInfo*g)
+{
+ int kind =
+ (act&CURL_POLL_IN?EV_READ:0)|(act&CURL_POLL_OUT?EV_WRITE:0)|EV_PERSIST;
+
+ f->sockfd = s;
+ f->action = act;
+ f->easy = e;
+ if (f->evset)
+ event_del(&f->ev);
+ event_set(&f->ev, f->sockfd, kind, event_cb, g);
+ f->evset=1;
+ event_add(&f->ev, NULL);
+}
+
+
+
+/* Initialize a new SockInfo structure */
+static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g) {
+ SockInfo *fdp = calloc(sizeof(SockInfo), 1);
+
+ fdp->global = g;
+ setsock(fdp, s, easy, action, g);
+ curl_multi_assign(g->multi, s, fdp);
+}
+
+/* CURLMOPT_SOCKETFUNCTION */
+static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
+{
+ GlobalInfo *g = (GlobalInfo*) cbp;
+ SockInfo *fdp = (SockInfo*) sockp;
+ const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" };
+
+ fprintf(MSG_OUT,
+ "socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
+ if (what == CURL_POLL_REMOVE) {
+ fprintf(MSG_OUT, "\n");
+ remsock(fdp);
+ }
+ else {
+ if (!fdp) {
+ fprintf(MSG_OUT, "Adding data: %s\n", whatstr[what]);
+ addsock(s, e, what, g);
+ }
+ else {
+ fprintf(MSG_OUT,
+ "Changing action from %s to %s\n",
+ whatstr[fdp->action], whatstr[what]);
+ setsock(fdp, s, e, what, g);
+ }
+ }
+ return 0;
+}
+
+
+
+/* CURLOPT_WRITEFUNCTION */
+static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
+{
+ size_t realsize = size * nmemb;
+ ConnInfo *conn = (ConnInfo*) data;
+ (void)ptr;
+ (void)conn;
+ return realsize;
+}
+
+
+/* CURLOPT_PROGRESSFUNCTION */
+static int prog_cb (void *p, double dltotal, double dlnow, double ult,
+ double uln)
+{
+ ConnInfo *conn = (ConnInfo *)p;
+ (void)ult;
+ (void)uln;
+
+ fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
+ return 0;
+}
+
+
+/* Create a new easy handle, and add it to the global curl_multi */
+static void new_conn(char *url, GlobalInfo *g )
+{
+ ConnInfo *conn;
+ CURLMcode rc;
+
+ conn = calloc(1, sizeof(ConnInfo));
+ memset(conn, 0, sizeof(ConnInfo));
+ conn->error[0]='\0';
+
+ conn->easy = curl_easy_init();
+ if (!conn->easy) {
+ fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n");
+ exit(2);
+ }
+ conn->global = g;
+ conn->url = strdup(url);
+ curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
+ curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
+ curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
+ curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
+ curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
+ curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 0L);
+ curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
+ curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
+ fprintf(MSG_OUT,
+ "Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
+ rc = curl_multi_add_handle(g->multi, conn->easy);
+ mcode_or_die("new_conn: curl_multi_add_handle", rc);
+
+ /* note that the add_handle() will set a time-out to trigger very soon so
+ that the necessary socket_action() call will be called by this app */
+}
+
+/* This gets called whenever data is received from the fifo */
+static void fifo_cb(int fd, short event, void *arg)
+{
+ char s[1024];
+ long int rv=0;
+ int n=0;
+ GlobalInfo *g = (GlobalInfo *)arg;
+ (void)fd; /* unused */
+ (void)event; /* unused */
+
+ do {
+ s[0]='\0';
+ rv=fscanf(g->input, "%1023s%n", s, &n);
+ s[n]='\0';
+ if ( n && s[0] ) {
+ new_conn(s,arg); /* if we read a URL, go get it! */
+ } else break;
+ } while ( rv != EOF);
+}
+
+/* Create a named pipe and tell libevent to monitor it */
+static int init_fifo (GlobalInfo *g)
+{
+ struct stat st;
+ static const char *fifo = "hiper.fifo";
+ curl_socket_t sockfd;
+
+ fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
+ if (lstat (fifo, &st) == 0) {
+ if ((st.st_mode & S_IFMT) == S_IFREG) {
+ errno = EEXIST;
+ perror("lstat");
+ exit (1);
+ }
+ }
+ unlink(fifo);
+ if (mkfifo (fifo, 0600) == -1) {
+ perror("mkfifo");
+ exit (1);
+ }
+ sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
+ if (sockfd == -1) {
+ perror("open");
+ exit (1);
+ }
+ g->input = fdopen(sockfd, "r");
+
+ fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo);
+ event_set(&g->fifo_event, sockfd, EV_READ | EV_PERSIST, fifo_cb, g);
+ event_add(&g->fifo_event, NULL);
+ return (0);
+}
+
+int main(int argc, char **argv)
+{
+ GlobalInfo g;
+ (void)argc;
+ (void)argv;
+
+ memset(&g, 0, sizeof(GlobalInfo));
+ event_init();
+ init_fifo(&g);
+ g.multi = curl_multi_init();
+ evtimer_set(&g.timer_event, timer_cb, &g);
+
+ /* setup the generic multi interface options we want */
+ curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
+ curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
+ curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
+ curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
+
+ /* we don't call any curl_multi_socket*() function yet as we have no handles
+ added! */
+
+ event_dispatch();
+ curl_multi_cleanup(g.multi);
+ return 0;
+}
diff --git a/docs/examples/href_extractor.c b/docs/examples/href_extractor.c
new file mode 100644
index 000000000..4b307a29e
--- /dev/null
+++ b/docs/examples/href_extractor.c
@@ -0,0 +1,86 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * This example uses the "Streaming HTML parser" to extract the href pieces in
+ * a streaming manner from a downloaded HTML. Kindly donated by Michał
+ * Kowalczyk.
+ *
+ * The parser is found at
+ * http://code.google.com/p/htmlstreamparser/
+ */
+
+#include <stdio.h>
+#include <curl/curl.h>
+#include <htmlstreamparser.h>
+
+
+static size_t write_callback(void *buffer, size_t size, size_t nmemb,
+ void *hsp)
+{
+ size_t realsize = size * nmemb, p;
+ for (p = 0; p < realsize; p++) {
+ html_parser_char_parse(hsp, ((char *)buffer)[p]);
+ if (html_parser_cmp_tag(hsp, "a", 1))
+ if (html_parser_cmp_attr(hsp, "href", 4))
+ if (html_parser_is_in(hsp, HTML_VALUE_ENDED)) {
+ html_parser_val(hsp)[html_parser_val_length(hsp)] = '\0';
+ printf("%s\n", html_parser_val(hsp));
+ }
+ }
+ return realsize;
+}
+
+int main(int argc, char *argv[])
+{
+ char tag[1], attr[4], val[128];
+ CURL *curl;
+ HTMLSTREAMPARSER *hsp;
+
+ if (argc != 2) {
+ printf("Usage: %s URL\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ curl = curl_easy_init();
+
+ hsp = html_parser_init();
+
+ html_parser_set_tag_to_lower(hsp, 1);
+ html_parser_set_attr_to_lower(hsp, 1);
+ html_parser_set_tag_buffer(hsp, tag, sizeof(tag));
+ html_parser_set_attr_buffer(hsp, attr, sizeof(attr));
+ html_parser_set_val_buffer(hsp, val, sizeof(val)-1);
+
+ curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, hsp);
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
+
+ curl_easy_perform(curl);
+
+ curl_easy_cleanup(curl);
+
+ html_parser_cleanup(hsp);
+
+ return EXIT_SUCCESS;
+}
diff --git a/docs/examples/htmltidy.c b/docs/examples/htmltidy.c
new file mode 100644
index 000000000..a36e331bf
--- /dev/null
+++ b/docs/examples/htmltidy.c
@@ -0,0 +1,130 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* Download a document and use libtidy to parse the HTML.
+ * Written by Jeff Pohlmeyer
+ *
+ * LibTidy => http://tidy.sourceforge.net
+ *
+ * gcc -Wall -I/usr/local/include tidycurl.c -lcurl -ltidy -o tidycurl
+ *
+ */
+
+#include <stdio.h>
+#include <tidy/tidy.h>
+#include <tidy/buffio.h>
+#include <curl/curl.h>
+
+/* curl write callback, to fill tidy's input buffer... */
+uint write_cb(char *in, uint size, uint nmemb, TidyBuffer *out)
+{
+ uint r;
+ r = size * nmemb;
+ tidyBufAppend( out, in, r );
+ return(r);
+}
+
+/* Traverse the document tree */
+void dumpNode(TidyDoc doc, TidyNode tnod, int indent )
+{
+ TidyNode child;
+ for ( child = tidyGetChild(tnod); child; child = tidyGetNext(child) )
+ {
+ ctmbstr name = tidyNodeGetName( child );
+ if ( name )
+ {
+ /* if it has a name, then it's an HTML tag ... */
+ TidyAttr attr;
+ printf( "%*.*s%s ", indent, indent, "<", name);
+ /* walk the attribute list */
+ for ( attr=tidyAttrFirst(child); attr; attr=tidyAttrNext(attr) ) {
+ printf(tidyAttrName(attr));
+ tidyAttrValue(attr)?printf("=\"%s\" ",
+ tidyAttrValue(attr)):printf(" ");
+ }
+ printf( ">\n");
+ }
+ else {
+ /* if it doesn't have a name, then it's probably text, cdata, etc... */
+ TidyBuffer buf;
+ tidyBufInit(&buf);
+ tidyNodeGetText(doc, child, &buf);
+ printf("%*.*s\n", indent, indent, buf.bp?(char *)buf.bp:"");
+ tidyBufFree(&buf);
+ }
+ dumpNode( doc, child, indent + 4 ); /* recursive */
+ }
+}
+
+
+int main(int argc, char **argv )
+{
+ CURL *curl;
+ char curl_errbuf[CURL_ERROR_SIZE];
+ TidyDoc tdoc;
+ TidyBuffer docbuf = {0};
+ TidyBuffer tidy_errbuf = {0};
+ int err;
+ if ( argc == 2) {
+ curl = curl_easy_init();
+ curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
+ curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf);
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
+
+ tdoc = tidyCreate();
+ tidyOptSetBool(tdoc, TidyForceOutput, yes); /* try harder */
+ tidyOptSetInt(tdoc, TidyWrapLen, 4096);
+ tidySetErrorBuffer( tdoc, &tidy_errbuf );
+ tidyBufInit(&docbuf);
+
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &docbuf);
+ err=curl_easy_perform(curl);
+ if ( !err ) {
+ err = tidyParseBuffer(tdoc, &docbuf); /* parse the input */
+ if ( err >= 0 ) {
+ err = tidyCleanAndRepair(tdoc); /* fix any problems */
+ if ( err >= 0 ) {
+ err = tidyRunDiagnostics(tdoc); /* load tidy error buffer */
+ if ( err >= 0 ) {
+ dumpNode( tdoc, tidyGetRoot(tdoc), 0 ); /* walk the tree */
+ fprintf(stderr, "%s\n", tidy_errbuf.bp); /* show errors */
+ }
+ }
+ }
+ }
+ else
+ fprintf(stderr, "%s\n", curl_errbuf);
+
+ /* clean-up */
+ curl_easy_cleanup(curl);
+ tidyBufFree(&docbuf);
+ tidyBufFree(&tidy_errbuf);
+ tidyRelease(tdoc);
+ return(err);
+
+ }
+ else
+ printf( "usage: %s <url>\n", argv[0] );
+
+ return(0);
+}
diff --git a/docs/examples/htmltitle.cpp b/docs/examples/htmltitle.cpp
new file mode 100644
index 000000000..55a7935ac
--- /dev/null
+++ b/docs/examples/htmltitle.cpp
@@ -0,0 +1,313 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+// Get a web page, parse it with libxml.
+//
+// Written by Lars Nilsson
+//
+// GNU C++ compile command line suggestion (edit paths accordingly):
+//
+// g++ -Wall -I/opt/curl/include -I/opt/libxml/include/libxml2 htmltitle.cc \
+// -o htmltitle -L/opt/curl/lib -L/opt/libxml/lib -lcurl -lxml2
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <string>
+#include <curl/curl.h>
+#include <libxml/HTMLparser.h>
+
+//
+// Case-insensitive string comparison
+//
+
+#ifdef _MSC_VER
+#define COMPARE(a, b) (!stricmp((a), (b)))
+#else
+#define COMPARE(a, b) (!strcasecmp((a), (b)))
+#endif
+
+//
+// libxml callback context structure
+//
+
+struct Context
+{
+ Context(): addTitle(false) { }
+
+ bool addTitle;
+ std::string title;
+};
+
+//
+// libcurl variables for error strings and returned data
+
+static char errorBuffer[CURL_ERROR_SIZE];
+static std::string buffer;
+
+//
+// libcurl write callback function
+//
+
+static int writer(char *data, size_t size, size_t nmemb,
+ std::string *writerData)
+{
+ if (writerData == NULL)
+ return 0;
+
+ writerData->append(data, size*nmemb);
+
+ return size * nmemb;
+}
+
+//
+// libcurl connection initialization
+//
+
+static bool init(CURL *&conn, char *url)
+{
+ CURLcode code;
+
+ conn = curl_easy_init();
+
+ if (conn == NULL)
+ {
+ fprintf(stderr, "Failed to create CURL connection\n");
+
+ exit(EXIT_FAILURE);
+ }
+
+ code = curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, errorBuffer);
+ if (code != CURLE_OK)
+ {
+ fprintf(stderr, "Failed to set error buffer [%d]\n", code);
+
+ return false;
+ }
+
+ code = curl_easy_setopt(conn, CURLOPT_URL, url);
+ if (code != CURLE_OK)
+ {
+ fprintf(stderr, "Failed to set URL [%s]\n", errorBuffer);
+
+ return false;
+ }
+
+ code = curl_easy_setopt(conn, CURLOPT_FOLLOWLOCATION, 1L);
+ if (code != CURLE_OK)
+ {
+ fprintf(stderr, "Failed to set redirect option [%s]\n", errorBuffer);
+
+ return false;
+ }
+
+ code = curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writer);
+ if (code != CURLE_OK)
+ {
+ fprintf(stderr, "Failed to set writer [%s]\n", errorBuffer);
+
+ return false;
+ }
+
+ code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, &buffer);
+ if (code != CURLE_OK)
+ {
+ fprintf(stderr, "Failed to set write data [%s]\n", errorBuffer);
+
+ return false;
+ }
+
+ return true;
+}
+
+//
+// libxml start element callback function
+//
+
+static void StartElement(void *voidContext,
+ const xmlChar *name,
+ const xmlChar **attributes)
+{
+ Context *context = (Context *)voidContext;
+
+ if (COMPARE((char *)name, "TITLE"))
+ {
+ context->title = "";
+ context->addTitle = true;
+ }
+ (void) attributes;
+}
+
+//
+// libxml end element callback function
+//
+
+static void EndElement(void *voidContext,
+ const xmlChar *name)
+{
+ Context *context = (Context *)voidContext;
+
+ if (COMPARE((char *)name, "TITLE"))
+ context->addTitle = false;
+}
+
+//
+// Text handling helper function
+//
+
+static void handleCharacters(Context *context,
+ const xmlChar *chars,
+ int length)
+{
+ if (context->addTitle)
+ context->title.append((char *)chars, length);
+}
+
+//
+// libxml PCDATA callback function
+//
+
+static void Characters(void *voidContext,
+ const xmlChar *chars,
+ int length)
+{
+ Context *context = (Context *)voidContext;
+
+ handleCharacters(context, chars, length);
+}
+
+//
+// libxml CDATA callback function
+//
+
+static void cdata(void *voidContext,
+ const xmlChar *chars,
+ int length)
+{
+ Context *context = (Context *)voidContext;
+
+ handleCharacters(context, chars, length);
+}
+
+//
+// libxml SAX callback structure
+//
+
+static htmlSAXHandler saxHandler =
+{
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ StartElement,
+ EndElement,
+ NULL,
+ Characters,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ cdata,
+ NULL
+};
+
+//
+// Parse given (assumed to be) HTML text and return the title
+//
+
+static void parseHtml(const std::string &html,
+ std::string &title)
+{
+ htmlParserCtxtPtr ctxt;
+ Context context;
+
+ ctxt = htmlCreatePushParserCtxt(&saxHandler, &context, "", 0, "",
+ XML_CHAR_ENCODING_NONE);
+
+ htmlParseChunk(ctxt, html.c_str(), html.size(), 0);
+ htmlParseChunk(ctxt, "", 0, 1);
+
+ htmlFreeParserCtxt(ctxt);
+
+ title = context.title;
+}
+
+int main(int argc, char *argv[])
+{
+ CURL *conn = NULL;
+ CURLcode code;
+ std::string title;
+
+ // Ensure one argument is given
+
+ if (argc != 2)
+ {
+ fprintf(stderr, "Usage: %s <url>\n", argv[0]);
+
+ exit(EXIT_FAILURE);
+ }
+
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+
+ // Initialize CURL connection
+
+ if (!init(conn, argv[1]))
+ {
+ fprintf(stderr, "Connection initializion failed\n");
+
+ exit(EXIT_FAILURE);
+ }
+
+ // Retrieve content for the URL
+
+ code = curl_easy_perform(conn);
+ curl_easy_cleanup(conn);
+
+ if (code != CURLE_OK)
+ {
+ fprintf(stderr, "Failed to get '%s' [%s]\n", argv[1], errorBuffer);
+
+ exit(EXIT_FAILURE);
+ }
+
+ // Parse the (assumed) HTML code
+
+ parseHtml(buffer, title);
+
+ // Display the extracted title
+
+ printf("Title: %s\n", title.c_str());
+
+ return EXIT_SUCCESS;
+}
diff --git a/docs/examples/http-post.c b/docs/examples/http-post.c
new file mode 100644
index 000000000..f1975b1ec
--- /dev/null
+++ b/docs/examples/http-post.c
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <curl/curl.h>
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+
+ /* In windows, this will init the winsock stuff */
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ /* get a curl handle */
+ curl = curl_easy_init();
+ if(curl) {
+ /* First set the URL that is about to receive our POST. This URL can
+ just as well be a https:// URL if that is what should receive the
+ data. */
+ curl_easy_setopt(curl, CURLOPT_URL, "http://postit.example.com/moo.cgi");
+ /* Now specify the POST data */
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=daniel&project=curl");
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ curl_global_cleanup();
+ return 0;
+}
diff --git a/docs/examples/httpcustomheader.c b/docs/examples/httpcustomheader.c
new file mode 100644
index 000000000..07ff95997
--- /dev/null
+++ b/docs/examples/httpcustomheader.c
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <curl/curl.h>
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+
+ curl = curl_easy_init();
+ if(curl) {
+ struct curl_slist *chunk = NULL;
+
+ chunk = curl_slist_append(chunk, "Accept: moo");
+ chunk = curl_slist_append(chunk, "Another: yes");
+
+ /* request with the built-in Accept: */
+ curl_easy_setopt(curl, CURLOPT_URL, "localhost");
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* redo request with our own custom Accept: */
+ res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+
+ /* free the custom headers */
+ curl_slist_free_all(chunk);
+ }
+ return 0;
+}
diff --git a/docs/examples/httpput.c b/docs/examples/httpput.c
new file mode 100644
index 000000000..fbbca9448
--- /dev/null
+++ b/docs/examples/httpput.c
@@ -0,0 +1,125 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <curl/curl.h>
+
+/*
+ * This example shows a HTTP PUT operation. PUTs a file given as a command
+ * line argument to the URL also given on the command line.
+ *
+ * This example also uses its own read callback.
+ *
+ * Here's an article on how to setup a PUT handler for Apache:
+ * http://www.apacheweek.com/features/put
+ */
+
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ size_t retcode;
+ curl_off_t nread;
+
+ /* in real-world cases, this would probably get this data differently
+ as this fread() stuff is exactly what the library already would do
+ by default internally */
+ retcode = fread(ptr, size, nmemb, stream);
+
+ nread = (curl_off_t)retcode;
+
+ fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T
+ " bytes from file\n", nread);
+
+ return retcode;
+}
+
+int main(int argc, char **argv)
+{
+ CURL *curl;
+ CURLcode res;
+ FILE * hd_src ;
+ int hd ;
+ struct stat file_info;
+
+ char *file;
+ char *url;
+
+ if(argc < 3)
+ return 1;
+
+ file= argv[1];
+ url = argv[2];
+
+ /* get the file size of the local file */
+ hd = open(file, O_RDONLY) ;
+ fstat(hd, &file_info);
+ close(hd) ;
+
+ /* get a FILE * of the same file, could also be made with
+ fdopen() from the previous descriptor, but hey this is just
+ an example! */
+ hd_src = fopen(file, "rb");
+
+ /* In windows, this will init the winsock stuff */
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ /* get a curl handle */
+ curl = curl_easy_init();
+ if(curl) {
+ /* we want to use our own read function */
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
+
+ /* enable uploading */
+ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
+
+ /* HTTP PUT please */
+ curl_easy_setopt(curl, CURLOPT_PUT, 1L);
+
+ /* specify target URL, and note that this URL should include a file
+ name, not only a directory */
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+
+ /* now specify which file to upload */
+ curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);
+
+ /* provide the size of the upload, we specicially typecast the value
+ to curl_off_t since we must be sure to use the correct data size */
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
+ (curl_off_t)file_info.st_size);
+
+ /* Now run off and do what you've been told! */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ fclose(hd_src); /* close the local file */
+
+ curl_global_cleanup();
+ return 0;
+}
diff --git a/docs/examples/https.c b/docs/examples/https.c
new file mode 100644
index 000000000..bd9a33ba6
--- /dev/null
+++ b/docs/examples/https.c
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <curl/curl.h>
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+
+ curl = curl_easy_init();
+ if(curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
+
+#ifdef SKIP_PEER_VERIFICATION
+ /*
+ * If you want to connect to a site who isn't using a certificate that is
+ * signed by one of the certs in the CA bundle you have, you can skip the
+ * verification of the server's certificate. This makes the connection
+ * A LOT LESS SECURE.
+ *
+ * If you have a CA cert for the server stored someplace else than in the
+ * default bundle, then the CURLOPT_CAPATH option might come handy for
+ * you.
+ */
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+#endif
+
+#ifdef SKIP_HOSTNAME_VERIFICATION
+ /*
+ * If the site you're connecting to uses a different host name that what
+ * they have mentioned in their server certificate's commonName (or
+ * subjectAltName) fields, libcurl will refuse to connect. You can skip
+ * this check, but this will make the connection less secure.
+ */
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+#endif
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+
+ curl_global_cleanup();
+
+ return 0;
+}
diff --git a/docs/examples/imap.c b/docs/examples/imap.c
new file mode 100644
index 000000000..ba07f022a
--- /dev/null
+++ b/docs/examples/imap.c
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <curl/curl.h>
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res = CURLE_OK;
+
+ curl = curl_easy_init();
+ if(curl) {
+ /* Set username and password */
+ curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password");
+
+ /* This will fetch the mailbox named "foobar" */
+ curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/foobar");
+
+ res = curl_easy_perform(curl);
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ return (int)res;
+}
diff --git a/docs/examples/makefile.dj b/docs/examples/makefile.dj
new file mode 100644
index 000000000..c18ef8a70
--- /dev/null
+++ b/docs/examples/makefile.dj
@@ -0,0 +1,60 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+#
+# Adapted for djgpp / Watt-32 / DOS by
+# Gisle Vanem <gvanem@broadpark.no>
+#
+
+TOPDIR = ../..
+
+include $(TOPDIR)/packages/DOS/common.dj
+
+CFLAGS += -DFALSE=0 -DTRUE=1
+
+LIBS = $(TOPDIR)/lib/libcurl.a
+
+ifeq ($(USE_SSL),1)
+ LIBS += $(OPENSSL_ROOT)/lib/libssl.a $(OPENSSL_ROOT)/lib/libcrypt.a
+endif
+
+ifeq ($(USE_IDNA),1)
+ LIBS += $(LIBIDN_ROOT)/lib/dj_obj/libidn.a -liconv
+endif
+
+LIBS += $(WATT32_ROOT)/lib/libwatt.a $(ZLIB_ROOT)/libz.a
+
+include Makefile.inc
+
+PROGRAMS = $(patsubst %,%.exe,$(check_PROGRAMS))
+
+all: $(PROGRAMS)
+ @echo Welcome to libcurl example program
+
+%.exe: %.c
+ $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+ @echo
+
+clean vclean realclean:
+ - rm -f $(PROGRAMS) depend.dj
+
+-include depend.dj
+
diff --git a/docs/examples/multi-app.c b/docs/examples/multi-app.c
new file mode 100644
index 000000000..a5f71c5ac
--- /dev/null
+++ b/docs/examples/multi-app.c
@@ -0,0 +1,153 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* This is an example application source code using the multi interface. */
+
+#include <stdio.h>
+#include <string.h>
+
+/* somewhat unix-specific */
+#include <sys/time.h>
+#include <unistd.h>
+
+/* curl stuff */
+#include <curl/curl.h>
+
+/*
+ * Download a HTTP file and upload an FTP file simultaneously.
+ */
+
+#define HANDLECOUNT 2 /* Number of simultaneous transfers */
+#define HTTP_HANDLE 0 /* Index for the HTTP transfer */
+#define FTP_HANDLE 1 /* Index for the FTP transfer */
+
+int main(void)
+{
+ CURL *handles[HANDLECOUNT];
+ CURLM *multi_handle;
+
+ int still_running; /* keep number of running handles */
+ int i;
+
+ CURLMsg *msg; /* for picking up messages with the transfer status */
+ int msgs_left; /* how many messages are left */
+
+ /* Allocate one CURL handle per transfer */
+ for (i=0; i<HANDLECOUNT; i++)
+ handles[i] = curl_easy_init();
+
+ /* set the options (I left out a few, you'll get the point anyway) */
+ curl_easy_setopt(handles[HTTP_HANDLE], CURLOPT_URL, "http://example.com");
+
+ curl_easy_setopt(handles[FTP_HANDLE], CURLOPT_URL, "ftp://example.com");
+ curl_easy_setopt(handles[FTP_HANDLE], CURLOPT_UPLOAD, 1L);
+
+ /* init a multi stack */
+ multi_handle = curl_multi_init();
+
+ /* add the individual transfers */
+ for (i=0; i<HANDLECOUNT; i++)
+ curl_multi_add_handle(multi_handle, handles[i]);
+
+ /* we start some action by calling perform right away */
+ curl_multi_perform(multi_handle, &still_running);
+
+ do {
+ struct timeval timeout;
+ int rc; /* select() return code */
+
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ int maxfd = -1;
+
+ long curl_timeo = -1;
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ /* set a suitable timeout to play around with */
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ curl_multi_timeout(multi_handle, &curl_timeo);
+ if(curl_timeo >= 0) {
+ timeout.tv_sec = curl_timeo / 1000;
+ if(timeout.tv_sec > 1)
+ timeout.tv_sec = 1;
+ else
+ timeout.tv_usec = (curl_timeo % 1000) * 1000;
+ }
+
+ /* get file descriptors from the transfers */
+ curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* In a real-world program you OF COURSE check the return code of the
+ function calls. On success, the value of maxfd is guaranteed to be
+ greater or equal than -1. We call select(maxfd + 1, ...), specially in
+ case of (maxfd == -1), we call select(0, ...), which is basically equal
+ to sleep. */
+
+ rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ switch(rc) {
+ case -1:
+ /* select error */
+ break;
+ case 0: /* timeout */
+ default: /* action */
+ curl_multi_perform(multi_handle, &still_running);
+ break;
+ }
+ } while(still_running);
+
+ /* See how the transfers went */
+ while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
+ if (msg->msg == CURLMSG_DONE) {
+ int idx, found = 0;
+
+ /* Find out which handle this message is about */
+ for (idx=0; idx<HANDLECOUNT; idx++) {
+ found = (msg->easy_handle == handles[idx]);
+ if(found)
+ break;
+ }
+
+ switch (idx) {
+ case HTTP_HANDLE:
+ printf("HTTP transfer completed with status %d\n", msg->data.result);
+ break;
+ case FTP_HANDLE:
+ printf("FTP transfer completed with status %d\n", msg->data.result);
+ break;
+ }
+ }
+ }
+
+ curl_multi_cleanup(multi_handle);
+
+ /* Free the CURL handles */
+ for (i=0; i<HANDLECOUNT; i++)
+ curl_easy_cleanup(handles[i]);
+
+ return 0;
+}
diff --git a/docs/examples/multi-debugcallback.c b/docs/examples/multi-debugcallback.c
new file mode 100644
index 000000000..8eedcee5b
--- /dev/null
+++ b/docs/examples/multi-debugcallback.c
@@ -0,0 +1,205 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* This is an example showing the multi interface and the debug callback. */
+
+#include <stdio.h>
+#include <string.h>
+
+/* somewhat unix-specific */
+#include <sys/time.h>
+#include <unistd.h>
+
+/* curl stuff */
+#include <curl/curl.h>
+
+typedef char bool;
+#define TRUE 1
+
+static
+void dump(const char *text,
+ FILE *stream, unsigned char *ptr, size_t size,
+ bool nohex)
+{
+ size_t i;
+ size_t c;
+
+ unsigned int width=0x10;
+
+ if(nohex)
+ /* without the hex output, we can fit more on screen */
+ width = 0x40;
+
+ fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n",
+ text, (long)size, (long)size);
+
+ for(i=0; i<size; i+= width) {
+
+ fprintf(stream, "%4.4lx: ", (long)i);
+
+ if(!nohex) {
+ /* hex not disabled, show it */
+ for(c = 0; c < width; c++)
+ if(i+c < size)
+ fprintf(stream, "%02x ", ptr[i+c]);
+ else
+ fputs(" ", stream);
+ }
+
+ for(c = 0; (c < width) && (i+c < size); c++) {
+ /* check for 0D0A; if found, skip past and start a new line of output */
+ if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) {
+ i+=(c+2-width);
+ break;
+ }
+ fprintf(stream, "%c",
+ (ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.');
+ /* check again for 0D0A, to avoid an extra \n if it's at width */
+ if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) {
+ i+=(c+3-width);
+ break;
+ }
+ }
+ fputc('\n', stream); /* newline */
+ }
+ fflush(stream);
+}
+
+static
+int my_trace(CURL *handle, curl_infotype type,
+ unsigned char *data, size_t size,
+ void *userp)
+{
+ const char *text;
+
+ (void)userp;
+ (void)handle; /* prevent compiler warning */
+
+ switch (type) {
+ case CURLINFO_TEXT:
+ fprintf(stderr, "== Info: %s", data);
+ default: /* in case a new one is introduced to shock us */
+ return 0;
+
+ case CURLINFO_HEADER_OUT:
+ text = "=> Send header";
+ break;
+ case CURLINFO_DATA_OUT:
+ text = "=> Send data";
+ break;
+ case CURLINFO_HEADER_IN:
+ text = "<= Recv header";
+ break;
+ case CURLINFO_DATA_IN:
+ text = "<= Recv data";
+ break;
+ }
+
+ dump(text, stderr, data, size, TRUE);
+ return 0;
+}
+
+/*
+ * Simply download a HTTP file.
+ */
+int main(void)
+{
+ CURL *http_handle;
+ CURLM *multi_handle;
+
+ int still_running; /* keep number of running handles */
+
+ http_handle = curl_easy_init();
+
+ /* set the options (I left out a few, you'll get the point anyway) */
+ curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.example.com/");
+
+ curl_easy_setopt(http_handle, CURLOPT_DEBUGFUNCTION, my_trace);
+ curl_easy_setopt(http_handle, CURLOPT_VERBOSE, 1L);
+
+ /* init a multi stack */
+ multi_handle = curl_multi_init();
+
+ /* add the individual transfers */
+ curl_multi_add_handle(multi_handle, http_handle);
+
+ /* we start some action by calling perform right away */
+ curl_multi_perform(multi_handle, &still_running);
+
+ do {
+ struct timeval timeout;
+ int rc; /* select() return code */
+
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ int maxfd = -1;
+
+ long curl_timeo = -1;
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ /* set a suitable timeout to play around with */
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ curl_multi_timeout(multi_handle, &curl_timeo);
+ if(curl_timeo >= 0) {
+ timeout.tv_sec = curl_timeo / 1000;
+ if(timeout.tv_sec > 1)
+ timeout.tv_sec = 1;
+ else
+ timeout.tv_usec = (curl_timeo % 1000) * 1000;
+ }
+
+ /* get file descriptors from the transfers */
+ curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* In a real-world program you OF COURSE check the return code of the
+ function calls. On success, the value of maxfd is guaranteed to be
+ greater or equal than -1. We call select(maxfd + 1, ...), specially in
+ case of (maxfd == -1), we call select(0, ...), which is basically equal
+ to sleep. */
+
+ rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ switch(rc) {
+ case -1:
+ /* select error */
+ still_running = 0;
+ printf("select() returns error, this is badness\n");
+ break;
+ case 0:
+ default:
+ /* timeout or readable/writable sockets */
+ curl_multi_perform(multi_handle, &still_running);
+ break;
+ }
+ } while(still_running);
+
+ curl_multi_cleanup(multi_handle);
+
+ curl_easy_cleanup(http_handle);
+
+ return 0;
+}
diff --git a/docs/examples/multi-double.c b/docs/examples/multi-double.c
new file mode 100644
index 000000000..91422e6e2
--- /dev/null
+++ b/docs/examples/multi-double.c
@@ -0,0 +1,119 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <string.h>
+
+/* somewhat unix-specific */
+#include <sys/time.h>
+#include <unistd.h>
+
+/* curl stuff */
+#include <curl/curl.h>
+
+/*
+ * Simply download two HTTP files!
+ */
+int main(void)
+{
+ CURL *http_handle;
+ CURL *http_handle2;
+ CURLM *multi_handle;
+
+ int still_running; /* keep number of running handles */
+
+ http_handle = curl_easy_init();
+ http_handle2 = curl_easy_init();
+
+ /* set options */
+ curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.example.com/");
+
+ /* set options */
+ curl_easy_setopt(http_handle2, CURLOPT_URL, "http://localhost/");
+
+ /* init a multi stack */
+ multi_handle = curl_multi_init();
+
+ /* add the individual transfers */
+ curl_multi_add_handle(multi_handle, http_handle);
+ curl_multi_add_handle(multi_handle, http_handle2);
+
+ /* we start some action by calling perform right away */
+ curl_multi_perform(multi_handle, &still_running);
+
+ do {
+ struct timeval timeout;
+ int rc; /* select() return code */
+
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ int maxfd = -1;
+
+ long curl_timeo = -1;
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ /* set a suitable timeout to play around with */
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ curl_multi_timeout(multi_handle, &curl_timeo);
+ if(curl_timeo >= 0) {
+ timeout.tv_sec = curl_timeo / 1000;
+ if(timeout.tv_sec > 1)
+ timeout.tv_sec = 1;
+ else
+ timeout.tv_usec = (curl_timeo % 1000) * 1000;
+ }
+
+ /* get file descriptors from the transfers */
+ curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* In a real-world program you OF COURSE check the return code of the
+ function calls. On success, the value of maxfd is guaranteed to be
+ greater or equal than -1. We call select(maxfd + 1, ...), specially in
+ case of (maxfd == -1), we call select(0, ...), which is basically equal
+ to sleep. */
+
+ rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ switch(rc) {
+ case -1:
+ /* select error */
+ break;
+ case 0:
+ default:
+ /* timeout or readable/writable sockets */
+ curl_multi_perform(multi_handle, &still_running);
+ break;
+ }
+ } while(still_running);
+
+ curl_multi_cleanup(multi_handle);
+
+ curl_easy_cleanup(http_handle);
+ curl_easy_cleanup(http_handle2);
+
+ return 0;
+}
diff --git a/docs/examples/multi-post.c b/docs/examples/multi-post.c
new file mode 100644
index 000000000..965a2c3f6
--- /dev/null
+++ b/docs/examples/multi-post.c
@@ -0,0 +1,148 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* This is an example application source code using the multi interface
+ * to do a multipart formpost without "blocking". */
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <curl/curl.h>
+
+int main(void)
+{
+ CURL *curl;
+
+ CURLM *multi_handle;
+ int still_running;
+
+ struct curl_httppost *formpost=NULL;
+ struct curl_httppost *lastptr=NULL;
+ struct curl_slist *headerlist=NULL;
+ static const char buf[] = "Expect:";
+
+ /* Fill in the file upload field. This makes libcurl load data from
+ the given file name when curl_easy_perform() is called. */
+ curl_formadd(&formpost,
+ &lastptr,
+ CURLFORM_COPYNAME, "sendfile",
+ CURLFORM_FILE, "postit2.c",
+ CURLFORM_END);
+
+ /* Fill in the filename field */
+ curl_formadd(&formpost,
+ &lastptr,
+ CURLFORM_COPYNAME, "filename",
+ CURLFORM_COPYCONTENTS, "postit2.c",
+ CURLFORM_END);
+
+ /* Fill in the submit field too, even if this is rarely needed */
+ curl_formadd(&formpost,
+ &lastptr,
+ CURLFORM_COPYNAME, "submit",
+ CURLFORM_COPYCONTENTS, "send",
+ CURLFORM_END);
+
+ curl = curl_easy_init();
+ multi_handle = curl_multi_init();
+
+ /* initalize custom header list (stating that Expect: 100-continue is not
+ wanted */
+ headerlist = curl_slist_append(headerlist, buf);
+ if(curl && multi_handle) {
+
+ /* what URL that receives this POST */
+ curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/upload.cgi");
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
+ curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
+
+ curl_multi_add_handle(multi_handle, curl);
+
+ curl_multi_perform(multi_handle, &still_running);
+
+ do {
+ struct timeval timeout;
+ int rc; /* select() return code */
+
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ int maxfd = -1;
+
+ long curl_timeo = -1;
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ /* set a suitable timeout to play around with */
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ curl_multi_timeout(multi_handle, &curl_timeo);
+ if(curl_timeo >= 0) {
+ timeout.tv_sec = curl_timeo / 1000;
+ if(timeout.tv_sec > 1)
+ timeout.tv_sec = 1;
+ else
+ timeout.tv_usec = (curl_timeo % 1000) * 1000;
+ }
+
+ /* get file descriptors from the transfers */
+ curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* In a real-world program you OF COURSE check the return code of the
+ function calls. On success, the value of maxfd is guaranteed to be
+ greater or equal than -1. We call select(maxfd + 1, ...), specially in
+ case of (maxfd == -1), we call select(0, ...), which is basically equal
+ to sleep. */
+
+ rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ switch(rc) {
+ case -1:
+ /* select error */
+ break;
+ case 0:
+ default:
+ /* timeout or readable/writable sockets */
+ printf("perform!\n");
+ curl_multi_perform(multi_handle, &still_running);
+ printf("running: %d!\n", still_running);
+ break;
+ }
+ } while(still_running);
+
+ curl_multi_cleanup(multi_handle);
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+
+ /* then cleanup the formpost chain */
+ curl_formfree(formpost);
+
+ /* free slist */
+ curl_slist_free_all (headerlist);
+ }
+ return 0;
+}
diff --git a/docs/examples/multi-single.c b/docs/examples/multi-single.c
new file mode 100644
index 000000000..aeda71419
--- /dev/null
+++ b/docs/examples/multi-single.c
@@ -0,0 +1,116 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* This is a very simple example using the multi interface. */
+
+#include <stdio.h>
+#include <string.h>
+
+/* somewhat unix-specific */
+#include <sys/time.h>
+#include <unistd.h>
+
+/* curl stuff */
+#include <curl/curl.h>
+
+/*
+ * Simply download a HTTP file.
+ */
+int main(void)
+{
+ CURL *http_handle;
+ CURLM *multi_handle;
+
+ int still_running; /* keep number of running handles */
+
+ http_handle = curl_easy_init();
+
+ /* set the options (I left out a few, you'll get the point anyway) */
+ curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.example.com/");
+
+ /* init a multi stack */
+ multi_handle = curl_multi_init();
+
+ /* add the individual transfers */
+ curl_multi_add_handle(multi_handle, http_handle);
+
+ /* we start some action by calling perform right away */
+ curl_multi_perform(multi_handle, &still_running);
+
+ do {
+ struct timeval timeout;
+ int rc; /* select() return code */
+
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ int maxfd = -1;
+
+ long curl_timeo = -1;
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ /* set a suitable timeout to play around with */
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ curl_multi_timeout(multi_handle, &curl_timeo);
+ if(curl_timeo >= 0) {
+ timeout.tv_sec = curl_timeo / 1000;
+ if(timeout.tv_sec > 1)
+ timeout.tv_sec = 1;
+ else
+ timeout.tv_usec = (curl_timeo % 1000) * 1000;
+ }
+
+ /* get file descriptors from the transfers */
+ curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* In a real-world program you OF COURSE check the return code of the
+ function calls. On success, the value of maxfd is guaranteed to be
+ greater or equal than -1. We call select(maxfd + 1, ...), specially in
+ case of (maxfd == -1), we call select(0, ...), which is basically equal
+ to sleep. */
+
+ rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ switch(rc) {
+ case -1:
+ /* select error */
+ still_running = 0;
+ printf("select() returns error, this is badness\n");
+ break;
+ case 0:
+ default:
+ /* timeout or readable/writable sockets */
+ curl_multi_perform(multi_handle, &still_running);
+ break;
+ }
+ } while(still_running);
+
+ curl_multi_cleanup(multi_handle);
+
+ curl_easy_cleanup(http_handle);
+
+ return 0;
+}
diff --git a/docs/examples/multithread.c b/docs/examples/multithread.c
new file mode 100644
index 000000000..831a07467
--- /dev/null
+++ b/docs/examples/multithread.c
@@ -0,0 +1,93 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* A multi-threaded example that uses pthreads extensively to fetch
+ * X remote files at once */
+
+#include <stdio.h>
+#include <pthread.h>
+#include <curl/curl.h>
+
+#define NUMT 4
+
+/*
+ List of URLs to fetch.
+
+ If you intend to use a SSL-based protocol here you MUST setup the OpenSSL
+ callback functions as described here:
+
+ http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
+
+*/
+const char * const urls[NUMT]= {
+ "http://curl.haxx.se/",
+ "ftp://cool.haxx.se/",
+ "http://www.contactor.se/",
+ "www.haxx.se"
+};
+
+static void *pull_one_url(void *url)
+{
+ CURL *curl;
+
+ curl = curl_easy_init();
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ curl_easy_perform(curl); /* ignores error */
+ curl_easy_cleanup(curl);
+
+ return NULL;
+}
+
+
+/*
+ int pthread_create(pthread_t *new_thread_ID,
+ const pthread_attr_t *attr,
+ void * (*start_func)(void *), void *arg);
+*/
+
+int main(int argc, char **argv)
+{
+ pthread_t tid[NUMT];
+ int i;
+ int error;
+
+ /* Must initialize libcurl before any threads are started */
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ for(i=0; i< NUMT; i++) {
+ error = pthread_create(&tid[i],
+ NULL, /* default attributes please */
+ pull_one_url,
+ (void *)urls[i]);
+ if(0 != error)
+ fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
+ else
+ fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
+ }
+
+ /* now wait for all threads to terminate */
+ for(i=0; i< NUMT; i++) {
+ error = pthread_join(tid[i], NULL);
+ fprintf(stderr, "Thread %d terminated\n", i);
+ }
+
+ return 0;
+}
diff --git a/docs/examples/opensslthreadlock.c b/docs/examples/opensslthreadlock.c
new file mode 100644
index 000000000..ad54f08ea
--- /dev/null
+++ b/docs/examples/opensslthreadlock.c
@@ -0,0 +1,94 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* Example source code to show one way to set the necessary OpenSSL locking
+ * callbacks if you want to do multi-threaded transfers with HTTPS/FTPS with
+ * libcurl built to use OpenSSL.
+ *
+ * This is not a complete stand-alone example.
+ *
+ * Author: Jeremy Brown
+ */
+
+
+#include <stdio.h>
+#include <pthread.h>
+#include <openssl/err.h>
+
+#define MUTEX_TYPE pthread_mutex_t
+#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
+#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
+#define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
+#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
+#define THREAD_ID pthread_self( )
+
+
+void handle_error(const char *file, int lineno, const char *msg){
+ fprintf(stderr, "** %s:%d %s\n", file, lineno, msg);
+ ERR_print_errors_fp(stderr);
+ /* exit(-1); */
+ }
+
+/* This array will store all of the mutexes available to OpenSSL. */
+static MUTEX_TYPE *mutex_buf= NULL;
+
+
+static void locking_function(int mode, int n, const char * file, int line)
+{
+ if (mode & CRYPTO_LOCK)
+ MUTEX_LOCK(mutex_buf[n]);
+ else
+ MUTEX_UNLOCK(mutex_buf[n]);
+}
+
+static unsigned long id_function(void)
+{
+ return ((unsigned long)THREAD_ID);
+}
+
+int thread_setup(void)
+{
+ int i;
+
+ mutex_buf = malloc(CRYPTO_num_locks( ) * sizeof(MUTEX_TYPE));
+ if (!mutex_buf)
+ return 0;
+ for (i = 0; i < CRYPTO_num_locks( ); i++)
+ MUTEX_SETUP(mutex_buf[i]);
+ CRYPTO_set_id_callback(id_function);
+ CRYPTO_set_locking_callback(locking_function);
+ return 1;
+}
+
+int thread_cleanup(void)
+{
+ int i;
+
+ if (!mutex_buf)
+ return 0;
+ CRYPTO_set_id_callback(NULL);
+ CRYPTO_set_locking_callback(NULL);
+ for (i = 0; i < CRYPTO_num_locks( ); i++)
+ MUTEX_CLEANUP(mutex_buf[i]);
+ free(mutex_buf);
+ mutex_buf = NULL;
+ return 1;
+}
diff --git a/docs/examples/persistant.c b/docs/examples/persistant.c
new file mode 100644
index 000000000..0917dfdb8
--- /dev/null
+++ b/docs/examples/persistant.c
@@ -0,0 +1,64 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <unistd.h>
+#include <curl/curl.h>
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ curl = curl_easy_init();
+ if(curl) {
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
+
+ /* get the first document */
+ curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* get another document from the same server using the same
+ connection */
+ curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/docs/");
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+
+ return 0;
+}
diff --git a/docs/examples/pop3s.c b/docs/examples/pop3s.c
new file mode 100644
index 000000000..44d7c80d0
--- /dev/null
+++ b/docs/examples/pop3s.c
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <curl/curl.h>
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+
+ curl = curl_easy_init();
+ if(curl) {
+ /* Set username and password */
+ curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password");
+
+ /* This will only fetch the message with ID "1" of the given mailbox */
+ curl_easy_setopt(curl, CURLOPT_URL, "pop3s://user@pop.example.com/1");
+
+#ifdef SKIP_PEER_VERIFICATION
+ /*
+ * If you want to connect to a site who isn't using a certificate that is
+ * signed by one of the certs in the CA bundle you have, you can skip the
+ * verification of the server's certificate. This makes the connection
+ * A LOT LESS SECURE.
+ *
+ * If you have a CA cert for the server stored someplace else than in the
+ * default bundle, then the CURLOPT_CAPATH option might come handy for
+ * you.
+ */
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+#endif
+
+#ifdef SKIP_HOSTNAME_VERFICATION
+ /*
+ * If the site you're connecting to uses a different host name that what
+ * they have mentioned in their server certificate's commonName (or
+ * subjectAltName) fields, libcurl will refuse to connect. You can skip
+ * this check, but this will make the connection less secure.
+ */
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+#endif
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ return 0;
+}
diff --git a/docs/examples/pop3slist.c b/docs/examples/pop3slist.c
new file mode 100644
index 000000000..9d9668fa0
--- /dev/null
+++ b/docs/examples/pop3slist.c
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <curl/curl.h>
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+
+ curl = curl_easy_init();
+ if(curl) {
+ /* Set username and password */
+ curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password");
+
+ /* This will list every message of the given mailbox */
+ curl_easy_setopt(curl, CURLOPT_URL, "pop3s://user@pop.example.com/");
+
+#ifdef SKIP_PEER_VERIFICATION
+ /*
+ * If you want to connect to a site who isn't using a certificate that is
+ * signed by one of the certs in the CA bundle you have, you can skip the
+ * verification of the server's certificate. This makes the connection
+ * A LOT LESS SECURE.
+ *
+ * If you have a CA cert for the server stored someplace else than in the
+ * default bundle, then the CURLOPT_CAPATH option might come handy for
+ * you.
+ */
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+#endif
+
+#ifdef SKIP_HOSTNAME_VERFICATION
+ /*
+ * If the site you're connecting to uses a different host name that what
+ * they have mentioned in their server certificate's commonName (or
+ * subjectAltName) fields, libcurl will refuse to connect. You can skip
+ * this check, but this will make the connection less secure.
+ */
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+#endif
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ return 0;
+}
diff --git a/docs/examples/post-callback.c b/docs/examples/post-callback.c
new file mode 100644
index 000000000..3e1cfb060
--- /dev/null
+++ b/docs/examples/post-callback.c
@@ -0,0 +1,143 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* An example source code that issues a HTTP POST and we provide the actual
+ * data through a read callback.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <curl/curl.h>
+
+const char data[]="this is what we post to the silly web server";
+
+struct WriteThis {
+ const char *readptr;
+ long sizeleft;
+};
+
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
+{
+ struct WriteThis *pooh = (struct WriteThis *)userp;
+
+ if(size*nmemb < 1)
+ return 0;
+
+ if(pooh->sizeleft) {
+ *(char *)ptr = pooh->readptr[0]; /* copy one single byte */
+ pooh->readptr++; /* advance pointer */
+ pooh->sizeleft--; /* less data left */
+ return 1; /* we return 1 byte at a time! */
+ }
+
+ return 0; /* no more data left to deliver */
+}
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+
+ struct WriteThis pooh;
+
+ pooh.readptr = data;
+ pooh.sizeleft = (long)strlen(data);
+
+ /* In windows, this will init the winsock stuff */
+ res = curl_global_init(CURL_GLOBAL_DEFAULT);
+ /* Check for errors */
+ if(res != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed: %s\n",
+ curl_easy_strerror(res));
+ return 1;
+ }
+
+ /* get a curl handle */
+ curl = curl_easy_init();
+ if(curl) {
+ /* First set the URL that is about to receive our POST. */
+ curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/index.cgi");
+
+ /* Now specify we want to POST data */
+ curl_easy_setopt(curl, CURLOPT_POST, 1L);
+
+ /* we want to use our own read function */
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
+
+ /* pointer to pass to our read function */
+ curl_easy_setopt(curl, CURLOPT_READDATA, &pooh);
+
+ /* get verbose debug output please */
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /*
+ If you use POST to a HTTP 1.1 server, you can send data without knowing
+ the size before starting the POST if you use chunked encoding. You
+ enable this by adding a header like "Transfer-Encoding: chunked" with
+ CURLOPT_HTTPHEADER. With HTTP 1.0 or without chunked transfer, you must
+ specify the size in the request.
+ */
+#ifdef USE_CHUNKED
+ {
+ struct curl_slist *chunk = NULL;
+
+ chunk = curl_slist_append(chunk, "Transfer-Encoding: chunked");
+ res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
+ /* use curl_slist_free_all() after the *perform() call to free this
+ list again */
+ }
+#else
+ /* Set the expected POST size. If you want to POST large amounts of data,
+ consider CURLOPT_POSTFIELDSIZE_LARGE */
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, pooh.sizeleft);
+#endif
+
+#ifdef DISABLE_EXPECT
+ /*
+ Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue"
+ header. You can disable this header with CURLOPT_HTTPHEADER as usual.
+ NOTE: if you want chunked transfer too, you need to combine these two
+ since you can only set one list of headers with CURLOPT_HTTPHEADER. */
+
+ /* A less good option would be to enforce HTTP 1.0, but that might also
+ have other implications. */
+ {
+ struct curl_slist *chunk = NULL;
+
+ chunk = curl_slist_append(chunk, "Expect:");
+ res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
+ /* use curl_slist_free_all() after the *perform() call to free this
+ list again */
+ }
+#endif
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ curl_global_cleanup();
+ return 0;
+}
diff --git a/docs/examples/postit2.c b/docs/examples/postit2.c
new file mode 100644
index 000000000..67dcc1330
--- /dev/null
+++ b/docs/examples/postit2.c
@@ -0,0 +1,103 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* Example code that uploads a file name 'foo' to a remote script that accepts
+ * "HTML form based" (as described in RFC1738) uploads using HTTP POST.
+ *
+ * The imaginary form we'll fill in looks like:
+ *
+ * <form method="post" enctype="multipart/form-data" action="examplepost.cgi">
+ * Enter file: <input type="file" name="sendfile" size="40">
+ * Enter file name: <input type="text" name="filename" size="30">
+ * <input type="submit" value="send" name="submit">
+ * </form>
+ *
+ * This exact source code has not been verified to work.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <curl/curl.h>
+
+int main(int argc, char *argv[])
+{
+ CURL *curl;
+ CURLcode res;
+
+ struct curl_httppost *formpost=NULL;
+ struct curl_httppost *lastptr=NULL;
+ struct curl_slist *headerlist=NULL;
+ static const char buf[] = "Expect:";
+
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ /* Fill in the file upload field */
+ curl_formadd(&formpost,
+ &lastptr,
+ CURLFORM_COPYNAME, "sendfile",
+ CURLFORM_FILE, "postit2.c",
+ CURLFORM_END);
+
+ /* Fill in the filename field */
+ curl_formadd(&formpost,
+ &lastptr,
+ CURLFORM_COPYNAME, "filename",
+ CURLFORM_COPYCONTENTS, "postit2.c",
+ CURLFORM_END);
+
+
+ /* Fill in the submit field too, even if this is rarely needed */
+ curl_formadd(&formpost,
+ &lastptr,
+ CURLFORM_COPYNAME, "submit",
+ CURLFORM_COPYCONTENTS, "send",
+ CURLFORM_END);
+
+ curl = curl_easy_init();
+ /* initalize custom header list (stating that Expect: 100-continue is not
+ wanted */
+ headerlist = curl_slist_append(headerlist, buf);
+ if(curl) {
+ /* what URL that receives this POST */
+ curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/examplepost.cgi");
+ if ( (argc == 2) && (!strcmp(argv[1], "noexpectheader")) )
+ /* only disable 100-continue header if explicitly requested */
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
+ curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+
+ /* then cleanup the formpost chain */
+ curl_formfree(formpost);
+ /* free slist */
+ curl_slist_free_all (headerlist);
+ }
+ return 0;
+}
diff --git a/docs/examples/progressfunc.c b/docs/examples/progressfunc.c
new file mode 100644
index 000000000..51a9c9b5e
--- /dev/null
+++ b/docs/examples/progressfunc.c
@@ -0,0 +1,84 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <curl/curl.h>
+
+#define STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES 6000
+#define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL 3
+
+struct myprogress {
+ double lastruntime;
+ CURL *curl;
+};
+
+static int progress(void *p,
+ double dltotal, double dlnow,
+ double ultotal, double ulnow)
+{
+ struct myprogress *myp = (struct myprogress *)p;
+ CURL *curl = myp->curl;
+ double curtime = 0;
+
+ curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &curtime);
+
+ /* under certain circumstances it may be desirable for certain functionality
+ to only run every N seconds, in order to do this the transaction time can
+ be used */
+ if((curtime - myp->lastruntime) >= MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL) {
+ myp->lastruntime = curtime;
+ fprintf(stderr, "TOTAL TIME: %f \r\n", curtime);
+ }
+
+ fprintf(stderr, "UP: %g of %g DOWN: %g of %g\r\n",
+ ulnow, ultotal, dlnow, dltotal);
+
+ if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES)
+ return 1;
+ return 0;
+}
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res = CURLE_OK;
+ struct myprogress prog;
+
+ curl = curl_easy_init();
+ if(curl) {
+ prog.lastruntime = 0;
+ prog.curl = curl;
+
+ curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
+ curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress);
+ /* pass the struct pointer into the progress function */
+ curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog);
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
+ res = curl_easy_perform(curl);
+
+ if(res != CURLE_OK)
+ fprintf(stderr, "%s\n", curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ return (int)res;
+}
diff --git a/docs/examples/resolve.c b/docs/examples/resolve.c
new file mode 100644
index 000000000..7b3e5656e
--- /dev/null
+++ b/docs/examples/resolve.c
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <curl/curl.h>
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res = CURLE_OK;
+ struct curl_slist *host = NULL;
+
+ /* Each single name resolve string should be written using the format
+ HOST:PORT:ADDRESS where HOST is the name libcurl will try to resolve,
+ PORT is the port number of the service where libcurl wants to connect to
+ the HOST and ADDRESS is the numerical IP address
+ */
+ host = curl_slist_append(NULL, "example.com:80:127.0.0.1");
+
+ curl = curl_easy_init();
+ if(curl) {
+ curl_easy_setopt(curl, CURLOPT_RESOLVE, host);
+ curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ res = curl_easy_perform(curl);
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+
+ curl_slist_free_all(host);
+
+ return (int)res;
+}
diff --git a/docs/examples/rtsp.c b/docs/examples/rtsp.c
new file mode 100644
index 000000000..669780a9b
--- /dev/null
+++ b/docs/examples/rtsp.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2011, Jim Hollinger
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Jim Hollinger nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined (WIN32)
+# include <conio.h> /* _getch() */
+#else
+# include <termios.h>
+# include <unistd.h>
+
+static int _getch(void)
+{
+ struct termios oldt, newt;
+ int ch;
+ tcgetattr( STDIN_FILENO, &oldt );
+ newt = oldt;
+ newt.c_lflag &= ~( ICANON | ECHO );
+ tcsetattr( STDIN_FILENO, TCSANOW, &newt );
+ ch = getchar();
+ tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
+ return ch;
+}
+#endif
+
+#include <curl/curl.h>
+
+#define VERSION_STR "V1.0"
+
+/* error handling macros */
+#define my_curl_easy_setopt(A, B, C) \
+ if ((res = curl_easy_setopt((A), (B), (C))) != CURLE_OK) \
+ fprintf(stderr, "curl_easy_setopt(%s, %s, %s) failed: %d\n", \
+ #A, #B, #C, res);
+
+#define my_curl_easy_perform(A) \
+ if ((res = curl_easy_perform((A))) != CURLE_OK) \
+ fprintf(stderr, "curl_easy_perform(%s) failed: %d\n", #A, res);
+
+
+/* send RTSP OPTIONS request */
+static void rtsp_options(CURL *curl, const char *uri)
+{
+ CURLcode res = CURLE_OK;
+ printf("\nRTSP: OPTIONS %s\n", uri);
+ my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri);
+ my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_OPTIONS);
+ my_curl_easy_perform(curl);
+}
+
+
+/* send RTSP DESCRIBE request and write sdp response to a file */
+static void rtsp_describe(CURL *curl, const char *uri,
+ const char *sdp_filename)
+{
+ CURLcode res = CURLE_OK;
+ FILE *sdp_fp = fopen(sdp_filename, "wt");
+ printf("\nRTSP: DESCRIBE %s\n", uri);
+ if (sdp_fp == NULL) {
+ fprintf(stderr, "Could not open '%s' for writing\n", sdp_filename);
+ sdp_fp = stdout;
+ }
+ else {
+ printf("Writing SDP to '%s'\n", sdp_filename);
+ }
+ my_curl_easy_setopt(curl, CURLOPT_WRITEDATA, sdp_fp);
+ my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_DESCRIBE);
+ my_curl_easy_perform(curl);
+ my_curl_easy_setopt(curl, CURLOPT_WRITEDATA, stdout);
+ if (sdp_fp != stdout) {
+ fclose(sdp_fp);
+ }
+}
+
+/* send RTSP SETUP request */
+static void rtsp_setup(CURL *curl, const char *uri, const char *transport)
+{
+ CURLcode res = CURLE_OK;
+ printf("\nRTSP: SETUP %s\n", uri);
+ printf(" TRANSPORT %s\n", transport);
+ my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri);
+ my_curl_easy_setopt(curl, CURLOPT_RTSP_TRANSPORT, transport);
+ my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_SETUP);
+ my_curl_easy_perform(curl);
+}
+
+
+/* send RTSP PLAY request */
+static void rtsp_play(CURL *curl, const char *uri, const char *range)
+{
+ CURLcode res = CURLE_OK;
+ printf("\nRTSP: PLAY %s\n", uri);
+ my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri);
+ my_curl_easy_setopt(curl, CURLOPT_RANGE, range);
+ my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_PLAY);
+ my_curl_easy_perform(curl);
+}
+
+
+/* send RTSP TEARDOWN request */
+static void rtsp_teardown(CURL *curl, const char *uri)
+{
+ CURLcode res = CURLE_OK;
+ printf("\nRTSP: TEARDOWN %s\n", uri);
+ my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, (long)CURL_RTSPREQ_TEARDOWN);
+ my_curl_easy_perform(curl);
+}
+
+
+/* convert url into an sdp filename */
+static void get_sdp_filename(const char *url, char *sdp_filename)
+{
+ const char *s = strrchr(url, '/');
+ strcpy(sdp_filename, "video.sdp");
+ if (s != NULL) {
+ s++;
+ if (s[0] != '\0') {
+ sprintf(sdp_filename, "%s.sdp", s);
+ }
+ }
+}
+
+
+/* scan sdp file for media control attribute */
+static void get_media_control_attribute(const char *sdp_filename,
+ char *control)
+{
+ int max_len = 256;
+ char *s = malloc(max_len);
+ FILE *sdp_fp = fopen(sdp_filename, "rt");
+ control[0] = '\0';
+ if (sdp_fp != NULL) {
+ while (fgets(s, max_len - 2, sdp_fp) != NULL) {
+ sscanf(s, " a = control: %s", control);
+ }
+ fclose(sdp_fp);
+ }
+ free(s);
+}
+
+
+/* main app */
+int main(int argc, char * const argv[])
+{
+#if 1
+ const char *transport = "RTP/AVP;unicast;client_port=1234-1235"; /* UDP */
+#else
+ const char *transport = "RTP/AVP/TCP;unicast;client_port=1234-1235"; /* TCP */
+#endif
+ const char *range = "0.000-";
+ int rc = EXIT_SUCCESS;
+ char *base_name = NULL;
+
+ printf("\nRTSP request %s\n", VERSION_STR);
+ printf(" Project web site: http://code.google.com/p/rtsprequest/\n");
+ printf(" Requires cURL V7.20 or greater\n\n");
+
+ /* check command line */
+ if ((argc != 2) && (argc != 3)) {
+ base_name = strrchr(argv[0], '/');
+ if (base_name == NULL) {
+ base_name = strrchr(argv[0], '\\');
+ }
+ if (base_name == NULL) {
+ base_name = argv[0];
+ } else {
+ base_name++;
+ }
+ printf("Usage: %s url [transport]\n", base_name);
+ printf(" url of video server\n");
+ printf(" transport (optional) specifier for media stream protocol\n");
+ printf(" default transport: %s\n", transport);
+ printf("Example: %s rtsp://192.168.0.2/media/video1\n\n", base_name);
+ rc = EXIT_FAILURE;
+ } else {
+ const char *url = argv[1];
+ char *uri = malloc(strlen(url) + 32);
+ char *sdp_filename = malloc(strlen(url) + 32);
+ char *control = malloc(strlen(url) + 32);
+ CURLcode res;
+ get_sdp_filename(url, sdp_filename);
+ if (argc == 3) {
+ transport = argv[2];
+ }
+
+ /* initialize curl */
+ res = curl_global_init(CURL_GLOBAL_ALL);
+ if (res == CURLE_OK) {
+ curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
+ CURL *curl;
+ fprintf(stderr, " cURL V%s loaded\n", data->version);
+
+ /* initialize this curl session */
+ curl = curl_easy_init();
+ if (curl != NULL) {
+ my_curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
+ my_curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
+ my_curl_easy_setopt(curl, CURLOPT_WRITEHEADER, stdout);
+ my_curl_easy_setopt(curl, CURLOPT_URL, url);
+
+ /* request server options */
+ sprintf(uri, "%s", url);
+ rtsp_options(curl, uri);
+
+ /* request session description and write response to sdp file */
+ rtsp_describe(curl, uri, sdp_filename);
+
+ /* get media control attribute from sdp file */
+ get_media_control_attribute(sdp_filename, control);
+
+ /* setup media stream */
+ sprintf(uri, "%s/%s", url, control);
+ rtsp_setup(curl, uri, transport);
+
+ /* start playing media stream */
+ sprintf(uri, "%s/", url);
+ rtsp_play(curl, uri, range);
+ printf("Playing video, press any key to stop ...");
+ _getch();
+ printf("\n");
+
+ /* teardown session */
+ rtsp_teardown(curl, uri);
+
+ /* cleanup */
+ curl_easy_cleanup(curl);
+ curl = NULL;
+ } else {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ }
+ curl_global_cleanup();
+ } else {
+ fprintf(stderr, "curl_global_init(%s) failed: %d\n",
+ "CURL_GLOBAL_ALL", res);
+ }
+ free(control);
+ free(sdp_filename);
+ free(uri);
+ }
+
+ return rc;
+}
diff --git a/docs/examples/sampleconv.c b/docs/examples/sampleconv.c
new file mode 100644
index 000000000..3db316096
--- /dev/null
+++ b/docs/examples/sampleconv.c
@@ -0,0 +1,107 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+ This is a simple example showing how a program on a non-ASCII platform
+ would invoke callbacks to do its own codeset conversions instead of
+ using the built-in iconv functions in libcurl.
+
+ The IBM-1047 EBCDIC codeset is used for this example but the code
+ would be similar for other non-ASCII codesets.
+
+ Three callback functions are created below:
+ my_conv_from_ascii_to_ebcdic,
+ my_conv_from_ebcdic_to_ascii, and
+ my_conv_from_utf8_to_ebcdic
+
+ The "platform_xxx" calls represent platform-specific conversion routines.
+
+ */
+
+#include <stdio.h>
+#include <curl/curl.h>
+
+CURLcode my_conv_from_ascii_to_ebcdic(char *buffer, size_t length)
+{
+ char *tempptrin, *tempptrout;
+ size_t bytes = length;
+ int rc;
+ tempptrin = tempptrout = buffer;
+ rc = platform_a2e(&tempptrin, &bytes, &tempptrout, &bytes);
+ if (rc == PLATFORM_CONV_OK) {
+ return(CURLE_OK);
+ } else {
+ return(CURLE_CONV_FAILED);
+ }
+}
+
+CURLcode my_conv_from_ebcdic_to_ascii(char *buffer, size_t length)
+{
+ char *tempptrin, *tempptrout;
+ size_t bytes = length;
+ int rc;
+ tempptrin = tempptrout = buffer;
+ rc = platform_e2a(&tempptrin, &bytes, &tempptrout, &bytes);
+ if (rc == PLATFORM_CONV_OK) {
+ return(CURLE_OK);
+ } else {
+ return(CURLE_CONV_FAILED);
+ }
+}
+
+CURLcode my_conv_from_utf8_to_ebcdic(char *buffer, size_t length)
+{
+ char *tempptrin, *tempptrout;
+ size_t bytes = length;
+ int rc;
+ tempptrin = tempptrout = buffer;
+ rc = platform_u2e(&tempptrin, &bytes, &tempptrout, &bytes);
+ if (rc == PLATFORM_CONV_OK) {
+ return(CURLE_OK);
+ } else {
+ return(CURLE_CONV_FAILED);
+ }
+}
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+
+ curl = curl_easy_init();
+ if(curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+
+ /* use platform-specific functions for codeset conversions */
+ curl_easy_setopt(curl, CURLOPT_CONV_FROM_NETWORK_FUNCTION,
+ my_conv_from_ascii_to_ebcdic);
+ curl_easy_setopt(curl, CURLOPT_CONV_TO_NETWORK_FUNCTION,
+ my_conv_from_ebcdic_to_ascii);
+ curl_easy_setopt(curl, CURLOPT_CONV_FROM_UTF8_FUNCTION,
+ my_conv_from_utf8_to_ebcdic);
+
+ res = curl_easy_perform(curl);
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ return 0;
+}
diff --git a/docs/examples/sendrecv.c b/docs/examples/sendrecv.c
new file mode 100644
index 000000000..88fddf59f
--- /dev/null
+++ b/docs/examples/sendrecv.c
@@ -0,0 +1,135 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* An example of curl_easy_send() and curl_easy_recv() usage. */
+
+#include <stdio.h>
+#include <string.h>
+#include <curl/curl.h>
+
+/* Auxiliary function that waits on the socket. */
+static int wait_on_socket(curl_socket_t sockfd, int for_recv, long timeout_ms)
+{
+ struct timeval tv;
+ fd_set infd, outfd, errfd;
+ int res;
+
+ tv.tv_sec = timeout_ms / 1000;
+ tv.tv_usec= (timeout_ms % 1000) * 1000;
+
+ FD_ZERO(&infd);
+ FD_ZERO(&outfd);
+ FD_ZERO(&errfd);
+
+ FD_SET(sockfd, &errfd); /* always check for error */
+
+ if(for_recv)
+ {
+ FD_SET(sockfd, &infd);
+ }
+ else
+ {
+ FD_SET(sockfd, &outfd);
+ }
+
+ /* select() returns the number of signalled sockets or -1 */
+ res = select(sockfd + 1, &infd, &outfd, &errfd, &tv);
+ return res;
+}
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+ /* Minimalistic http request */
+ const char *request = "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n";
+ curl_socket_t sockfd; /* socket */
+ long sockextr;
+ size_t iolen;
+ curl_off_t nread;
+
+ curl = curl_easy_init();
+ if(curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ /* Do not do the transfer - only connect to host */
+ curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
+ res = curl_easy_perform(curl);
+
+ if(CURLE_OK != res)
+ {
+ printf("Error: %s\n", strerror(res));
+ return 1;
+ }
+
+ /* Extract the socket from the curl handle - we'll need it for waiting.
+ * Note that this API takes a pointer to a 'long' while we use
+ * curl_socket_t for sockets otherwise.
+ */
+ res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockextr);
+
+ if(CURLE_OK != res)
+ {
+ printf("Error: %s\n", curl_easy_strerror(res));
+ return 1;
+ }
+
+ sockfd = sockextr;
+
+ /* wait for the socket to become ready for sending */
+ if(!wait_on_socket(sockfd, 0, 60000L))
+ {
+ printf("Error: timeout.\n");
+ return 1;
+ }
+
+ puts("Sending request.");
+ /* Send the request. Real applications should check the iolen
+ * to see if all the request has been sent */
+ res = curl_easy_send(curl, request, strlen(request), &iolen);
+
+ if(CURLE_OK != res)
+ {
+ printf("Error: %s\n", curl_easy_strerror(res));
+ return 1;
+ }
+ puts("Reading response.");
+
+ /* read the response */
+ for(;;)
+ {
+ char buf[1024];
+
+ wait_on_socket(sockfd, 1, 60000L);
+ res = curl_easy_recv(curl, buf, 1024, &iolen);
+
+ if(CURLE_OK != res)
+ break;
+
+ nread = (curl_off_t)iolen;
+
+ printf("Received %" CURL_FORMAT_CURL_OFF_T " bytes.\n", nread);
+ }
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ return 0;
+}
diff --git a/docs/examples/sepheaders.c b/docs/examples/sepheaders.c
new file mode 100644
index 000000000..afa14fc85
--- /dev/null
+++ b/docs/examples/sepheaders.c
@@ -0,0 +1,85 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <curl/curl.h>
+
+static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ int written = fwrite(ptr, size, nmemb, (FILE *)stream);
+ return written;
+}
+
+int main(void)
+{
+ CURL *curl_handle;
+ static const char *headerfilename = "head.out";
+ FILE *headerfile;
+ static const char *bodyfilename = "body.out";
+ FILE *bodyfile;
+
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ /* init the curl session */
+ curl_handle = curl_easy_init();
+
+ /* set URL to get */
+ curl_easy_setopt(curl_handle, CURLOPT_URL, "http://example.com");
+
+ /* no progress meter please */
+ curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);
+
+ /* send all data to this function */
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
+
+ /* open the files */
+ headerfile = fopen(headerfilename,"w");
+ if (headerfile == NULL) {
+ curl_easy_cleanup(curl_handle);
+ return -1;
+ }
+ bodyfile = fopen(bodyfilename,"w");
+ if (bodyfile == NULL) {
+ curl_easy_cleanup(curl_handle);
+ return -1;
+ }
+
+ /* we want the headers to this file handle */
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, headerfile);
+
+ /*
+ * Notice here that if you want the actual data sent anywhere else but
+ * stdout, you should consider using the CURLOPT_WRITEDATA option. */
+
+ /* get it! */
+ curl_easy_perform(curl_handle);
+
+ /* close the header file */
+ fclose(headerfile);
+
+ /* cleanup curl stuff */
+ curl_easy_cleanup(curl_handle);
+
+ return 0;
+}
diff --git a/docs/examples/sftpget.c b/docs/examples/sftpget.c
new file mode 100644
index 000000000..8317462e9
--- /dev/null
+++ b/docs/examples/sftpget.c
@@ -0,0 +1,106 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <stdio.h>
+
+#include <curl/curl.h>
+
+/* define this to switch off the use of ssh-agent in this program */
+#undef DISABLE_SSH_AGENT
+
+/*
+ * This is an example showing how to get a single file from an SFTP server.
+ * It delays the actual destination file creation until the first write
+ * callback so that it won't create an empty file in case the remote file
+ * doesn't exist or something else fails.
+ */
+
+struct FtpFile {
+ const char *filename;
+ FILE *stream;
+};
+
+static size_t my_fwrite(void *buffer, size_t size, size_t nmemb,
+ void *stream)
+{
+ struct FtpFile *out=(struct FtpFile *)stream;
+ if(out && !out->stream) {
+ /* open file for writing */
+ out->stream=fopen(out->filename, "wb");
+ if(!out->stream)
+ return -1; /* failure, can't open file to write */
+ }
+ return fwrite(buffer, size, nmemb, out->stream);
+}
+
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+ struct FtpFile ftpfile={
+ "yourfile.bin", /* name to store the file as if succesful */
+ NULL
+ };
+
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+
+ curl = curl_easy_init();
+ if(curl) {
+ /*
+ * You better replace the URL with one that works!
+ */
+ curl_easy_setopt(curl, CURLOPT_URL,
+ "sftp://user@server/home/user/file.txt");
+ /* Define our callback to get called when there's data to be written */
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
+ /* Set a pointer to our struct to pass to the callback */
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
+
+#ifndef DISABLE_SSH_AGENT
+ /* We activate ssh agent. For this to work you need
+ to have ssh-agent running (type set | grep SSH_AGENT to check) or
+ pageant on Windows (there is an icon in systray if so) */
+ curl_easy_setopt(curl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_AGENT);
+#endif
+
+ /* Switch on full protocol/debug output */
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ res = curl_easy_perform(curl);
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+
+ if(CURLE_OK != res) {
+ /* we failed */
+ fprintf(stderr, "curl told us %d\n", res);
+ }
+ }
+
+ if(ftpfile.stream)
+ fclose(ftpfile.stream); /* close the local file */
+
+ curl_global_cleanup();
+
+ return 0;
+}
diff --git a/docs/examples/simple.c b/docs/examples/simple.c
new file mode 100644
index 000000000..cb23b7ae3
--- /dev/null
+++ b/docs/examples/simple.c
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <curl/curl.h>
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+
+ curl = curl_easy_init();
+ if(curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ return 0;
+}
diff --git a/docs/examples/simplepost.c b/docs/examples/simplepost.c
new file mode 100644
index 000000000..8657771f4
--- /dev/null
+++ b/docs/examples/simplepost.c
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <curl/curl.h>
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+
+ static const char *postthis="moo mooo moo moo";
+
+ curl = curl_easy_init();
+ if(curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postthis);
+
+ /* if we don't provide POSTFIELDSIZE, libcurl will strlen() by
+ itself */
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(postthis));
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ return 0;
+}
diff --git a/docs/examples/simplesmtp.c b/docs/examples/simplesmtp.c
new file mode 100644
index 000000000..df8516242
--- /dev/null
+++ b/docs/examples/simplesmtp.c
@@ -0,0 +1,87 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <curl/curl.h>
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+ struct curl_slist *recipients = NULL;
+
+ /* value for envelope reverse-path */
+ static const char *from = "<bradh@example.com>";
+
+ /* this becomes the envelope forward-path */
+ static const char *to = "<bradh@example.net>";
+
+ curl = curl_easy_init();
+ if(curl) {
+ /* this is the URL for your mailserver - you can also use an smtps:// URL
+ * here */
+ curl_easy_setopt(curl, CURLOPT_URL, "smtp://mail.example.net.");
+
+ /* Note that this option isn't strictly required, omitting it will result in
+ * libcurl will sent the MAIL FROM command with no sender data. All
+ * autoresponses should have an empty reverse-path, and should be directed
+ * to the address in the reverse-path which triggered them. Otherwise, they
+ * could cause an endless loop. See RFC 5321 Section 4.5.5 for more details.
+ */
+ curl_easy_setopt(curl, CURLOPT_MAIL_FROM, from);
+
+ /* Note that the CURLOPT_MAIL_RCPT takes a list, not a char array. */
+ recipients = curl_slist_append(recipients, to);
+ curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
+
+ /* You provide the payload (headers and the body of the message) as the
+ * "data" element. There are two choices, either:
+ * - provide a callback function and specify the function name using the
+ * CURLOPT_READFUNCTION option; or
+ * - just provide a FILE pointer that can be used to read the data from.
+ * The easiest case is just to read from standard input, (which is available
+ * as a FILE pointer) as shown here.
+ */
+ curl_easy_setopt(curl, CURLOPT_READDATA, stdin);
+
+ /* send the message (including headers) */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* free the list of recipients */
+ curl_slist_free_all(recipients);
+
+ /* curl won't send the QUIT command until you call cleanup, so you should be
+ * able to re-use this connection for additional messages (setting
+ * CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT as required, and calling
+ * curl_easy_perform() again. It may not be a good idea to keep the
+ * connection open for a very long time though (more than a few minutes may
+ * result in the server timing out the connection), and you do want to clean
+ * up in the end.
+ */
+ curl_easy_cleanup(curl);
+ }
+ return 0;
+}
diff --git a/docs/examples/simplessl.c b/docs/examples/simplessl.c
new file mode 100644
index 000000000..74c58461a
--- /dev/null
+++ b/docs/examples/simplessl.c
@@ -0,0 +1,138 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+
+#include <curl/curl.h>
+
+/* some requirements for this to work:
+ 1. set pCertFile to the file with the client certificate
+ 2. if the key is passphrase protected, set pPassphrase to the
+ passphrase you use
+ 3. if you are using a crypto engine:
+ 3.1. set a #define USE_ENGINE
+ 3.2. set pEngine to the name of the crypto engine you use
+ 3.3. set pKeyName to the key identifier you want to use
+ 4. if you don't use a crypto engine:
+ 4.1. set pKeyName to the file name of your client key
+ 4.2. if the format of the key file is DER, set pKeyType to "DER"
+
+ !! verify of the server certificate is not implemented here !!
+
+ **** This example only works with libcurl 7.9.3 and later! ****
+
+*/
+
+int main(void)
+{
+ int i;
+ CURL *curl;
+ CURLcode res;
+ FILE *headerfile;
+ const char *pPassphrase = NULL;
+
+ static const char *pCertFile = "testcert.pem";
+ static const char *pCACertFile="cacert.pem";
+
+ const char *pKeyName;
+ const char *pKeyType;
+
+ const char *pEngine;
+
+#ifdef USE_ENGINE
+ pKeyName = "rsa_test";
+ pKeyType = "ENG";
+ pEngine = "chil"; /* for nChiper HSM... */
+#else
+ pKeyName = "testkey.pem";
+ pKeyType = "PEM";
+ pEngine = NULL;
+#endif
+
+ headerfile = fopen("dumpit", "w");
+
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+
+ curl = curl_easy_init();
+ if(curl) {
+ /* what call to write: */
+ curl_easy_setopt(curl, CURLOPT_URL, "HTTPS://your.favourite.ssl.site");
+ curl_easy_setopt(curl, CURLOPT_WRITEHEADER, headerfile);
+
+ for(i = 0; i < 1; i++) /* single-iteration loop, just to break out from */
+ {
+ if (pEngine) /* use crypto engine */
+ {
+ if (curl_easy_setopt(curl, CURLOPT_SSLENGINE,pEngine) != CURLE_OK)
+ { /* load the crypto engine */
+ fprintf(stderr,"can't set crypto engine\n");
+ break;
+ }
+ if (curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT,1L) != CURLE_OK)
+ { /* set the crypto engine as default */
+ /* only needed for the first time you load
+ a engine in a curl object... */
+ fprintf(stderr,"can't set crypto engine as default\n");
+ break;
+ }
+ }
+ /* cert is stored PEM coded in file... */
+ /* since PEM is default, we needn't set it for PEM */
+ curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
+
+ /* set the cert for client authentication */
+ curl_easy_setopt(curl,CURLOPT_SSLCERT,pCertFile);
+
+ /* sorry, for engine we must set the passphrase
+ (if the key has one...) */
+ if (pPassphrase)
+ curl_easy_setopt(curl,CURLOPT_KEYPASSWD,pPassphrase);
+
+ /* if we use a key stored in a crypto engine,
+ we must set the key type to "ENG" */
+ curl_easy_setopt(curl,CURLOPT_SSLKEYTYPE,pKeyType);
+
+ /* set the private key (file or ID in engine) */
+ curl_easy_setopt(curl,CURLOPT_SSLKEY,pKeyName);
+
+ /* set the file with the certs vaildating the server */
+ curl_easy_setopt(curl,CURLOPT_CAINFO,pCACertFile);
+
+ /* disconnect if we can't validate server's cert */
+ curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,1L);
+
+ /* Perform the request, res will get the return code */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* we are done... */
+ }
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+
+ curl_global_cleanup();
+
+ return 0;
+}
diff --git a/docs/examples/smooth-gtk-thread.c b/docs/examples/smooth-gtk-thread.c
new file mode 100644
index 000000000..932f6e396
--- /dev/null
+++ b/docs/examples/smooth-gtk-thread.c
@@ -0,0 +1,228 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* This is a multi threaded application that uses a progress bar to show
+ * status. It uses Gtk+ to make a smooth pulse.
+ *
+ * Written by Jud Bishop after studying the other examples provided with
+ * libcurl.
+ *
+ * To compile (on a single line):
+ * gcc -ggdb `pkg-config --cflags --libs gtk+-2.0` -lcurl -lssl -lcrypto
+ * -lgthread-2.0 -dl smooth-gtk-thread.c -o smooth-gtk-thread
+ */
+
+#include <stdio.h>
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include <curl/curl.h>
+
+#define NUMT 4
+
+pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+int j = 0;
+gint num_urls = 9; /* Just make sure this is less than urls[]*/
+const char * const urls[]= {
+ "90022",
+ "90023",
+ "90024",
+ "90025",
+ "90026",
+ "90027",
+ "90028",
+ "90029",
+ "90030"
+};
+
+size_t write_file(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ /* printf("write_file\n"); */
+ return fwrite(ptr, size, nmemb, stream);
+}
+
+/* http://xoap.weather.com/weather/local/46214?cc=*&dayf=5&unit=i */
+void *pull_one_url(void *NaN)
+{
+ CURL *curl;
+ CURLcode res;
+ gchar *http;
+ FILE *outfile;
+
+ /* Stop threads from entering unless j is incremented */
+ pthread_mutex_lock(&lock);
+ while ( j < num_urls )
+ {
+ printf("j = %d\n", j);
+
+ http =
+ g_strdup_printf("xoap.weather.com/weather/local/%s?cc=*&dayf=5&unit=i\n",
+ urls[j]);
+
+ printf( "http %s", http );
+
+ curl = curl_easy_init();
+ if(curl)
+ {
+
+ outfile = fopen(urls[j], "w");
+ /* printf("fopen\n"); */
+
+ /* Set the URL and transfer type */
+ curl_easy_setopt(curl, CURLOPT_URL, http);
+
+ /* Write to the file */
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_file);
+
+ j++; /* critical line */
+ pthread_mutex_unlock(&lock);
+
+ res = curl_easy_perform(curl);
+
+ fclose(outfile);
+ printf("fclose\n");
+
+ curl_easy_cleanup(curl);
+ }
+ g_free (http);
+
+ /* Adds more latency, testing the mutex.*/
+ sleep(1);
+
+ } /* end while */
+ return NULL;
+}
+
+
+gboolean pulse_bar(gpointer data)
+{
+ gdk_threads_enter();
+ gtk_progress_bar_pulse (GTK_PROGRESS_BAR (data));
+ gdk_threads_leave();
+
+ /* Return true so the function will be called again;
+ * returning false removes this timeout function.
+ */
+ return TRUE;
+}
+
+void *create_thread(void *progress_bar)
+{
+ pthread_t tid[NUMT];
+ int i;
+ int error;
+
+ /* Make sure I don't create more threads than urls. */
+ for(i=0; i < NUMT && i < num_urls ; i++) {
+ error = pthread_create(&tid[i],
+ NULL, /* default attributes please */
+ pull_one_url,
+ NULL);
+ if(0 != error)
+ fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
+ else
+ fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
+ }
+
+ /* Wait for all threads to terminate. */
+ for(i=0; i < NUMT && i < num_urls; i++) {
+ error = pthread_join(tid[i], NULL);
+ fprintf(stderr, "Thread %d terminated\n", i);
+ }
+
+ /* This stops the pulsing if you have it turned on in the progress bar
+ section */
+ g_source_remove(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(progress_bar),
+ "pulse_id")));
+
+ /* This destroys the progress bar */
+ gtk_widget_destroy(progress_bar);
+
+ /* [Un]Comment this out to kill the program rather than pushing close. */
+ /* gtk_main_quit(); */
+
+
+ return NULL;
+
+}
+
+static gboolean cb_delete(GtkWidget *window, gpointer data)
+{
+ gtk_main_quit();
+ return FALSE;
+}
+
+int main(int argc, char **argv)
+{
+ GtkWidget *top_window, *outside_frame, *inside_frame, *progress_bar;
+
+ /* Must initialize libcurl before any threads are started */
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ /* Init thread */
+ g_thread_init(NULL);
+ gdk_threads_init ();
+ gdk_threads_enter ();
+
+ gtk_init(&argc, &argv);
+
+ /* Base window */
+ top_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+ /* Frame */
+ outside_frame = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(outside_frame), GTK_SHADOW_OUT);
+ gtk_container_add(GTK_CONTAINER(top_window), outside_frame);
+
+ /* Frame */
+ inside_frame = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(inside_frame), GTK_SHADOW_IN);
+ gtk_container_set_border_width(GTK_CONTAINER(inside_frame), 5);
+ gtk_container_add(GTK_CONTAINER(outside_frame), inside_frame);
+
+ /* Progress bar */
+ progress_bar = gtk_progress_bar_new();
+ gtk_progress_bar_pulse (GTK_PROGRESS_BAR (progress_bar));
+ /* Make uniform pulsing */
+ gint pulse_ref = g_timeout_add (300, pulse_bar, progress_bar);
+ g_object_set_data(G_OBJECT(progress_bar), "pulse_id",
+ GINT_TO_POINTER(pulse_ref));
+ gtk_container_add(GTK_CONTAINER(inside_frame), progress_bar);
+
+ gtk_widget_show_all(top_window);
+ printf("gtk_widget_show_all\n");
+
+ g_signal_connect(G_OBJECT (top_window), "delete-event",
+ G_CALLBACK(cb_delete), NULL);
+
+ if (!g_thread_create(&create_thread, progress_bar, FALSE, NULL) != 0)
+ g_warning("can't create the thread");
+
+ gtk_main();
+ gdk_threads_leave();
+ printf("gdk_threads_leave\n");
+
+ return 0;
+}
+
diff --git a/docs/examples/smtp-multi.c b/docs/examples/smtp-multi.c
new file mode 100644
index 000000000..6462aff2d
--- /dev/null
+++ b/docs/examples/smtp-multi.c
@@ -0,0 +1,203 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* This is an example application source code sending SMTP mail using the
+ * multi interface.
+ */
+
+#include <string.h>
+#include <curl/curl.h>
+
+/*
+ * This is the list of basic details you need to tweak to get things right.
+ */
+#define USERNAME "user@example.com"
+#define PASSWORD "123qwerty"
+#define SMTPSERVER "smtp.example.com"
+#define SMTPPORT ":587" /* it is a colon+port string, but you can set it
+ to "" to use the default port */
+#define RECIPIENT "<recipient@example.com>"
+#define MAILFROM "<realuser@example.com>"
+
+#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
+
+/* Note that you should include the actual meta data headers here as well if
+ you want the mail to have a Subject, another From:, show a To: or whatever
+ you think your mail should feature! */
+static const char *text[]={
+ "one\n",
+ "two\n",
+ "three\n",
+ " Hello, this is CURL email SMTP\n",
+ NULL
+};
+
+struct WriteThis {
+ int counter;
+};
+
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
+{
+ struct WriteThis *pooh = (struct WriteThis *)userp;
+ const char *data;
+
+ if(size*nmemb < 1)
+ return 0;
+
+ data = text[pooh->counter];
+
+ if(data) {
+ size_t len = strlen(data);
+ memcpy(ptr, data, len);
+ pooh->counter++; /* advance pointer */
+ return len;
+ }
+ return 0; /* no more data left to deliver */
+}
+
+static struct timeval tvnow(void)
+{
+ /*
+ ** time() returns the value of time in seconds since the Epoch.
+ */
+ struct timeval now;
+ now.tv_sec = (long)time(NULL);
+ now.tv_usec = 0;
+ return now;
+}
+
+static long tvdiff(struct timeval newer, struct timeval older)
+{
+ return (newer.tv_sec-older.tv_sec)*1000+
+ (newer.tv_usec-older.tv_usec)/1000;
+}
+
+int main(void)
+{
+ CURL *curl;
+ CURLM *mcurl;
+ int still_running = 1;
+ struct timeval mp_start;
+ struct WriteThis pooh;
+ struct curl_slist* rcpt_list = NULL;
+
+ pooh.counter = 0;
+
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+
+ curl = curl_easy_init();
+ if(!curl)
+ return 1;
+
+ mcurl = curl_multi_init();
+ if(!mcurl)
+ return 2;
+
+ rcpt_list = curl_slist_append(rcpt_list, RECIPIENT);
+ /* more addresses can be added here
+ rcpt_list = curl_slist_append(rcpt_list, "<others@example.com>");
+ */
+
+ curl_easy_setopt(curl, CURLOPT_URL, "smtp://" SMTPSERVER SMTPPORT);
+ curl_easy_setopt(curl, CURLOPT_USERNAME, USERNAME);
+ curl_easy_setopt(curl, CURLOPT_PASSWORD, PASSWORD);
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
+ curl_easy_setopt(curl, CURLOPT_MAIL_FROM, MAILFROM);
+ curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt_list);
+ curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+ curl_easy_setopt(curl, CURLOPT_READDATA, &pooh);
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(curl, CURLOPT_SSLVERSION, 0L);
+ curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0L);
+ curl_multi_add_handle(mcurl, curl);
+
+ mp_start = tvnow();
+
+ /* we start some action by calling perform right away */
+ curl_multi_perform(mcurl, &still_running);
+
+ while(still_running) {
+ struct timeval timeout;
+ int rc; /* select() return code */
+
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ int maxfd = -1;
+
+ long curl_timeo = -1;
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ /* set a suitable timeout to play around with */
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ curl_multi_timeout(mcurl, &curl_timeo);
+ if(curl_timeo >= 0) {
+ timeout.tv_sec = curl_timeo / 1000;
+ if(timeout.tv_sec > 1)
+ timeout.tv_sec = 1;
+ else
+ timeout.tv_usec = (curl_timeo % 1000) * 1000;
+ }
+
+ /* get file descriptors from the transfers */
+ curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* In a real-world program you OF COURSE check the return code of the
+ function calls. On success, the value of maxfd is guaranteed to be
+ greater or equal than -1. We call select(maxfd + 1, ...), specially in
+ case of (maxfd == -1), we call select(0, ...), which is basically equal
+ to sleep. */
+
+ rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ if (tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
+ fprintf(stderr, "ABORTING TEST, since it seems "
+ "that it would have run forever.\n");
+ break;
+ }
+
+ switch(rc) {
+ case -1:
+ /* select error */
+ break;
+ case 0: /* timeout */
+ default: /* action */
+ curl_multi_perform(mcurl, &still_running);
+ break;
+ }
+ }
+
+ curl_slist_free_all(rcpt_list);
+ curl_multi_remove_handle(mcurl, curl);
+ curl_multi_cleanup(mcurl);
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+ return 0;
+}
+
+
diff --git a/docs/examples/smtp-tls.c b/docs/examples/smtp-tls.c
new file mode 100644
index 000000000..3635c103f
--- /dev/null
+++ b/docs/examples/smtp-tls.c
@@ -0,0 +1,152 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <curl/curl.h>
+
+/* This is a simple example showing how to send mail using libcurl's SMTP
+ * capabilities. It builds on the simplesmtp.c example, adding some
+ * authentication and transport security.
+ */
+
+#define FROM "<sender@example.org>"
+#define TO "<addressee@example.net>"
+#define CC "<info@example.org>"
+
+static const char *payload_text[]={
+ "Date: Mon, 29 Nov 2010 21:54:29 +1100\n",
+ "To: " TO "\n",
+ "From: " FROM "(Example User)\n",
+ "Cc: " CC "(Another example User)\n",
+ "Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@rfcpedant.example.org>\n",
+ "Subject: SMTP TLS example message\n",
+ "\n", /* empty line to divide headers from body, see RFC5322 */
+ "The body of the message starts here.\n",
+ "\n",
+ "It could be a lot of lines, could be MIME encoded, whatever.\n",
+ "Check RFC5322.\n",
+ NULL
+};
+
+struct upload_status {
+ int lines_read;
+};
+
+static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp)
+{
+ struct upload_status *upload_ctx = (struct upload_status *)userp;
+ const char *data;
+
+ if ((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
+ return 0;
+ }
+
+ data = payload_text[upload_ctx->lines_read];
+
+ if (data) {
+ size_t len = strlen(data);
+ memcpy(ptr, data, len);
+ upload_ctx->lines_read ++;
+ return len;
+ }
+ return 0;
+}
+
+
+int main(void)
+{
+ CURL *curl;
+ CURLcode res;
+ struct curl_slist *recipients = NULL;
+ struct upload_status upload_ctx;
+
+ upload_ctx.lines_read = 0;
+
+ curl = curl_easy_init();
+ if (curl) {
+ /* This is the URL for your mailserver. Note the use of port 587 here,
+ * instead of the normal SMTP port (25). Port 587 is commonly used for
+ * secure mail submission (see RFC4403), but you should use whatever
+ * matches your server configuration. */
+ curl_easy_setopt(curl, CURLOPT_URL, "smtp://mainserver.example.net:587");
+
+ /* In this example, we'll start with a plain text connection, and upgrade
+ * to Transport Layer Security (TLS) using the STARTTLS command. Be careful
+ * of using CURLUSESSL_TRY here, because if TLS upgrade fails, the transfer
+ * will continue anyway - see the security discussion in the libcurl
+ * tutorial for more details. */
+ curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
+
+ /* If your server doesn't have a valid certificate, then you can disable
+ * part of the Transport Layer Security protection by setting the
+ * CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options to 0 (false).
+ * curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+ * curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+ * That is, in general, a bad idea. It is still better than sending your
+ * authentication details in plain text though.
+ * Instead, you should get the issuer certificate (or the host certificate
+ * if the certificate is self-signed) and add it to the set of certificates
+ * that are known to libcurl using CURLOPT_CAINFO and/or CURLOPT_CAPATH. See
+ * docs/SSLCERTS for more information.
+ */
+ curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/certificate.pem");
+
+ /* A common reason for requiring transport security is to protect
+ * authentication details (user names and passwords) from being "snooped"
+ * on the network. Here is how the user name and password are provided: */
+ curl_easy_setopt(curl, CURLOPT_USERNAME, "user@example.net");
+ curl_easy_setopt(curl, CURLOPT_PASSWORD, "P@ssw0rd");
+
+ /* value for envelope reverse-path */
+ curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);
+ /* Add two recipients, in this particular case they correspond to the
+ * To: and Cc: addressees in the header, but they could be any kind of
+ * recipient. */
+ recipients = curl_slist_append(recipients, TO);
+ recipients = curl_slist_append(recipients, CC);
+ curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
+
+ /* In this case, we're using a callback function to specify the data. You
+ * could just use the CURLOPT_READDATA option to specify a FILE pointer to
+ * read from.
+ */
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
+ curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
+
+ /* Since the traffic will be encrypted, it is very useful to turn on debug
+ * information within libcurl to see what is happening during the transfer.
+ */
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+
+ /* send the message (including headers) */
+ res = curl_easy_perform(curl);
+ /* Check for errors */
+ if(res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+
+ /* free the list of recipients and clean up */
+ curl_slist_free_all(recipients);
+ curl_easy_cleanup(curl);
+ }
+ return 0;
+}
diff --git a/docs/examples/synctime.c b/docs/examples/synctime.c
new file mode 100644
index 000000000..14d77de27
--- /dev/null
+++ b/docs/examples/synctime.c
@@ -0,0 +1,366 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* This example code only builds as-is on Windows.
+ *
+ * While Unix/Linux user, you do not need this software.
+ * You can achieve the same result as synctime using curl, awk and date.
+ * Set proxy as according to your network, but beware of proxy Cache-Control.
+ *
+ * To set your system clock, root access is required.
+ * # date -s "`curl -sI http://nist.time.gov/timezone.cgi?UTC/s/0 \
+ * | awk -F': ' '/Date: / {print $2}'`"
+ *
+ * To view remote webserver date and time.
+ * $ curl -sI http://nist.time.gov/timezone.cgi?UTC/s/0 \
+ * | awk -F': ' '/Date: / {print $2}'
+ *
+ * Synchronising your computer clock via Internet time server usually relies
+ * on DAYTIME, TIME, or NTP protocols. These protocols provide good accurate
+ * time synchronisation but it does not work very well through a
+ * firewall/proxy. Some adjustment has to be made to the firewall/proxy for
+ * these protocols to work properly.
+ *
+ * There is an indirect method. Since most webserver provide server time in
+ * their HTTP header, therefore you could synchronise your computer clock
+ * using HTTP protocol which has no problem with firewall/proxy.
+ *
+ * For this software to work, you should take note of these items.
+ * 1. Your firewall/proxy must allow your computer to surf internet.
+ * 2. Webserver system time must in sync with the NTP time server,
+ * or at least provide an accurate time keeping.
+ * 3. Webserver HTTP header does not provide the milliseconds units,
+ * so there is no way to get very accurate time.
+ * 4. This software could only provide an accuracy of +- a few seconds,
+ * as Round-Trip delay time is not taken into consideration.
+ * Compensation of network, firewall/proxy delay cannot be simply divide
+ * the Round-Trip delay time by half.
+ * 5. Win32 SetSystemTime() API will set your computer clock according to
+ * GMT/UTC time. Therefore your computer timezone must be properly set.
+ * 6. Webserver data should not be cached by the proxy server. Some
+ * webserver provide Cache-Control to prevent caching.
+ *
+ * References:
+ * http://tf.nist.gov/timefreq/service/its.htm
+ * http://tf.nist.gov/timefreq/service/firewall.htm
+ *
+ * Usage:
+ * This software will synchronise your computer clock only when you issue
+ * it with --synctime. By default, it only display the webserver's clock.
+ *
+ * Written by: Frank (contributed to libcurl)
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL THE AUTHOR OF THIS SOFTWARE BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include <time.h>
+#ifndef __CYGWIN__
+#include <windows.h>
+#endif
+#include <curl/curl.h>
+
+
+#define MAX_STRING 256
+#define MAX_STRING1 MAX_STRING+1
+
+typedef struct
+{
+ char http_proxy[MAX_STRING1];
+ char proxy_user[MAX_STRING1];
+ char timeserver[MAX_STRING1];
+} conf_t;
+
+const char DefaultTimeServer[4][MAX_STRING1] =
+{
+ "http://nist.time.gov/timezone.cgi?UTC/s/0",
+ "http://www.google.com/",
+ "http://www.worldtimeserver.com/current_time_in_UTC.aspx",
+ "http://www.worldtime.com/cgi-bin/wt.cgi"
+};
+
+const char *DayStr[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+const char *MthStr[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+int ShowAllHeader;
+int AutoSyncTime;
+SYSTEMTIME SYSTime;
+SYSTEMTIME LOCALTime;
+
+#define HTTP_COMMAND_HEAD 0
+#define HTTP_COMMAND_GET 1
+
+
+size_t SyncTime_CURL_WriteOutput(void *ptr, size_t size, size_t nmemb,
+ void *stream)
+{
+ fwrite(ptr, size, nmemb, stream);
+ return(nmemb*size);
+}
+
+size_t SyncTime_CURL_WriteHeader(void *ptr, size_t size, size_t nmemb,
+ void *stream)
+{
+ int i, RetVal;
+ char TmpStr1[26], TmpStr2[26];
+
+ if (ShowAllHeader == 1)
+ fprintf(stderr, "%s", (char *)(ptr));
+
+ if (strncmp((char *)(ptr), "Date:", 5) == 0) {
+ if (ShowAllHeader == 0)
+ fprintf(stderr, "HTTP Server. %s", (char *)(ptr));
+
+ if (AutoSyncTime == 1) {
+ *TmpStr1 = 0;
+ *TmpStr2 = 0;
+ if (strlen((char *)(ptr)) > 50) /* Can prevent buffer overflow to
+ TmpStr1 & 2? */
+ AutoSyncTime = 0;
+ else {
+ RetVal = sscanf ((char *)(ptr), "Date: %s %hu %s %hu %hu:%hu:%hu",
+ TmpStr1, &SYSTime.wDay, TmpStr2, &SYSTime.wYear,
+ &SYSTime.wHour, &SYSTime.wMinute, &SYSTime.wSecond);
+
+ if (RetVal == 7) {
+
+ SYSTime.wMilliseconds = 500; /* adjust to midpoint, 0.5 sec */
+ for (i=0; i<12; i++) {
+ if (strcmp(MthStr[i], TmpStr2) == 0) {
+ SYSTime.wMonth = i+1;
+ break;
+ }
+ }
+ AutoSyncTime = 3; /* Computer clock will be adjusted */
+ }
+ else {
+ AutoSyncTime = 0; /* Error in sscanf() fields conversion */
+ }
+ }
+ }
+ }
+
+ if (strncmp((char *)(ptr), "X-Cache: HIT", 12) == 0) {
+ fprintf(stderr, "ERROR: HTTP Server data is cached."
+ " Server Date is no longer valid.\n");
+ AutoSyncTime = 0;
+ }
+ return(nmemb*size);
+}
+
+void SyncTime_CURL_Init(CURL *curl, char *proxy_port,
+ char *proxy_user_password)
+{
+ if (strlen(proxy_port) > 0)
+ curl_easy_setopt(curl, CURLOPT_PROXY, proxy_port);
+
+ if (strlen(proxy_user_password) > 0)
+ curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, proxy_user_password);
+
+ /* Trick Webserver by claiming that you are using Microsoft WinXP SP2, IE6 */
+ curl_easy_setopt(curl, CURLOPT_USERAGENT,
+ "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, *SyncTime_CURL_WriteOutput);
+ curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, *SyncTime_CURL_WriteHeader);
+}
+
+int SyncTime_CURL_Fetch(CURL *curl, char *URL_Str, char *OutFileName,
+ int HttpGetBody)
+{
+ FILE *outfile;
+ CURLcode res;
+
+ outfile = NULL;
+ if (HttpGetBody == HTTP_COMMAND_HEAD)
+ curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
+ else {
+ outfile = fopen(OutFileName, "wb");
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
+ }
+
+ curl_easy_setopt(curl, CURLOPT_URL, URL_Str);
+ res = curl_easy_perform(curl);
+ if (outfile != NULL)
+ fclose(outfile);
+ return res; /* (CURLE_OK) */
+}
+
+void showUsage(void)
+{
+ fprintf(stderr, "SYNCTIME: Synchronising computer clock with time server"
+ " using HTTP protocol.\n");
+ fprintf(stderr, "Usage : SYNCTIME [Option]\n");
+ fprintf(stderr, "Options :\n");
+ fprintf(stderr, " --server=WEBSERVER Use this time server instead"
+ " of default.\n");
+ fprintf(stderr, " --showall Show all HTTP header.\n");
+ fprintf(stderr, " --synctime Synchronising computer clock"
+ " with time server.\n");
+ fprintf(stderr, " --proxy-user=USER[:PASS] Set proxy username and"
+ " password.\n");
+ fprintf(stderr, " --proxy=HOST[:PORT] Use HTTP proxy on given"
+ " port.\n");
+ fprintf(stderr, " --help Print this help.\n");
+ fprintf(stderr, "\n");
+ return;
+}
+
+int conf_init(conf_t *conf)
+{
+ int i;
+
+ *conf->http_proxy = 0;
+ for (i=0; i<MAX_STRING1; i++)
+ conf->proxy_user[i] = 0; /* Clean up password from memory */
+ *conf->timeserver = 0;
+ return 1;
+}
+
+int main(int argc, char *argv[])
+{
+ CURL *curl;
+ conf_t conf[1];
+ int OptionIndex;
+ struct tm *lt;
+ struct tm *gmt;
+ time_t tt;
+ time_t tt_local;
+ time_t tt_gmt;
+ double tzonediffFloat;
+ int tzonediffWord;
+ char timeBuf[61];
+ char tzoneBuf[16];
+ int RetValue;
+
+ OptionIndex = 0;
+ ShowAllHeader = 0; /* Do not show HTTP Header */
+ AutoSyncTime = 0; /* Do not synchronise computer clock */
+ RetValue = 0; /* Successful Exit */
+ conf_init(conf);
+
+ if (argc > 1) {
+ while (OptionIndex < argc) {
+ if (strncmp(argv[OptionIndex], "--server=", 9) == 0)
+ snprintf(conf->timeserver, MAX_STRING, "%s", &argv[OptionIndex][9]);
+
+ if (strcmp(argv[OptionIndex], "--showall") == 0)
+ ShowAllHeader = 1;
+
+ if (strcmp(argv[OptionIndex], "--synctime") == 0)
+ AutoSyncTime = 1;
+
+ if (strncmp(argv[OptionIndex], "--proxy-user=", 13) == 0)
+ snprintf(conf->proxy_user, MAX_STRING, "%s", &argv[OptionIndex][13]);
+
+ if (strncmp(argv[OptionIndex], "--proxy=", 8) == 0)
+ snprintf(conf->http_proxy, MAX_STRING, "%s", &argv[OptionIndex][8]);
+
+ if ((strcmp(argv[OptionIndex], "--help") == 0) ||
+ (strcmp(argv[OptionIndex], "/?") == 0)) {
+ showUsage();
+ return 0;
+ }
+ OptionIndex++;
+ }
+ }
+
+ if (*conf->timeserver == 0) /* Use default server for time information */
+ snprintf(conf->timeserver, MAX_STRING, "%s", DefaultTimeServer[0]);
+
+ /* Init CURL before usage */
+ curl_global_init(CURL_GLOBAL_ALL);
+ curl = curl_easy_init();
+ if (curl) {
+ SyncTime_CURL_Init(curl, conf->http_proxy, conf->proxy_user);
+
+ /* Calculating time diff between GMT and localtime */
+ tt = time(0);
+ lt = localtime(&tt);
+ tt_local = mktime(lt);
+ gmt = gmtime(&tt);
+ tt_gmt = mktime(gmt);
+ tzonediffFloat = difftime(tt_local, tt_gmt);
+ tzonediffWord = (int)(tzonediffFloat/3600.0);
+
+ if ((double)(tzonediffWord * 3600) == tzonediffFloat)
+ snprintf(tzoneBuf, 15, "%+03d'00'", tzonediffWord);
+ else
+ snprintf(tzoneBuf, 15, "%+03d'30'", tzonediffWord);
+
+ /* Get current system time and local time */
+ GetSystemTime(&SYSTime);
+ GetLocalTime(&LOCALTime);
+ snprintf(timeBuf, 60, "%s, %02d %s %04d %02d:%02d:%02d.%03d, ",
+ DayStr[LOCALTime.wDayOfWeek], LOCALTime.wDay,
+ MthStr[LOCALTime.wMonth-1], LOCALTime.wYear,
+ LOCALTime.wHour, LOCALTime.wMinute, LOCALTime.wSecond,
+ LOCALTime.wMilliseconds);
+
+ fprintf(stderr, "Fetch: %s\n\n", conf->timeserver);
+ fprintf(stderr, "Before HTTP. Date: %s%s\n\n", timeBuf, tzoneBuf);
+
+ /* HTTP HEAD command to the Webserver */
+ SyncTime_CURL_Fetch(curl, conf->timeserver, "index.htm",
+ HTTP_COMMAND_HEAD);
+
+ GetLocalTime(&LOCALTime);
+ snprintf(timeBuf, 60, "%s, %02d %s %04d %02d:%02d:%02d.%03d, ",
+ DayStr[LOCALTime.wDayOfWeek], LOCALTime.wDay,
+ MthStr[LOCALTime.wMonth-1], LOCALTime.wYear,
+ LOCALTime.wHour, LOCALTime.wMinute, LOCALTime.wSecond,
+ LOCALTime.wMilliseconds);
+ fprintf(stderr, "\nAfter HTTP. Date: %s%s\n", timeBuf, tzoneBuf);
+
+ if (AutoSyncTime == 3) {
+ /* Synchronising computer clock */
+ if (!SetSystemTime(&SYSTime)) { /* Set system time */
+ fprintf(stderr, "ERROR: Unable to set system time.\n");
+ RetValue = 1;
+ }
+ else {
+ /* Successfully re-adjusted computer clock */
+ GetLocalTime(&LOCALTime);
+ snprintf(timeBuf, 60, "%s, %02d %s %04d %02d:%02d:%02d.%03d, ",
+ DayStr[LOCALTime.wDayOfWeek], LOCALTime.wDay,
+ MthStr[LOCALTime.wMonth-1], LOCALTime.wYear,
+ LOCALTime.wHour, LOCALTime.wMinute, LOCALTime.wSecond,
+ LOCALTime.wMilliseconds);
+ fprintf(stderr, "\nNew System's Date: %s%s\n", timeBuf, tzoneBuf);
+ }
+ }
+
+ /* Cleanup before exit */
+ conf_init(conf);
+ curl_easy_cleanup(curl);
+ }
+ return RetValue;
+}
diff --git a/docs/examples/threaded-ssl.c b/docs/examples/threaded-ssl.c
new file mode 100644
index 000000000..a7e9c2de1
--- /dev/null
+++ b/docs/examples/threaded-ssl.c
@@ -0,0 +1,162 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* A multi-threaded example that uses pthreads and fetches 4 remote files at
+ * once over HTTPS. The lock callbacks and stuff assume OpenSSL or GnuTLS
+ * (libgcrypt) so far.
+ *
+ * OpenSSL docs for this:
+ * http://www.openssl.org/docs/crypto/threads.html
+ * gcrypt docs for this:
+ * http://gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html
+ */
+
+#define USE_OPENSSL /* or USE_GNUTLS accordingly */
+
+#include <stdio.h>
+#include <pthread.h>
+#include <curl/curl.h>
+
+#define NUMT 4
+
+/* we have this global to let the callback get easy access to it */
+static pthread_mutex_t *lockarray;
+
+#ifdef USE_OPENSSL
+#include <openssl/crypto.h>
+static void lock_callback(int mode, int type, char *file, int line)
+{
+ (void)file;
+ (void)line;
+ if (mode & CRYPTO_LOCK) {
+ pthread_mutex_lock(&(lockarray[type]));
+ }
+ else {
+ pthread_mutex_unlock(&(lockarray[type]));
+ }
+}
+
+static unsigned long thread_id(void)
+{
+ unsigned long ret;
+
+ ret=(unsigned long)pthread_self();
+ return(ret);
+}
+
+static void init_locks(void)
+{
+ int i;
+
+ lockarray=(pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() *
+ sizeof(pthread_mutex_t));
+ for (i=0; i<CRYPTO_num_locks(); i++) {
+ pthread_mutex_init(&(lockarray[i]),NULL);
+ }
+
+ CRYPTO_set_id_callback((unsigned long (*)())thread_id);
+ CRYPTO_set_locking_callback((void (*)())lock_callback);
+}
+
+static void kill_locks(void)
+{
+ int i;
+
+ CRYPTO_set_locking_callback(NULL);
+ for (i=0; i<CRYPTO_num_locks(); i++)
+ pthread_mutex_destroy(&(lockarray[i]));
+
+ OPENSSL_free(lockarray);
+}
+#endif
+
+#ifdef USE_GNUTLS
+#include <gcrypt.h>
+#include <errno.h>
+
+GCRY_THREAD_OPTION_PTHREAD_IMPL;
+
+void init_locks(void)
+{
+ gcry_control(GCRYCTL_SET_THREAD_CBS);
+}
+
+#define kill_locks()
+#endif
+
+/* List of URLs to fetch.*/
+const char * const urls[]= {
+ "https://www.example.com/",
+ "https://www2.example.com/",
+ "https://www3.example.com/",
+ "https://www4.example.com/",
+};
+
+static void *pull_one_url(void *url)
+{
+ CURL *curl;
+
+ curl = curl_easy_init();
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ /* this example doesn't verify the server's certificate, which means we
+ might be downloading stuff from an impostor */
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+ curl_easy_perform(curl); /* ignores error */
+ curl_easy_cleanup(curl);
+
+ return NULL;
+}
+
+int main(int argc, char **argv)
+{
+ pthread_t tid[NUMT];
+ int i;
+ int error;
+ (void)argc; /* we don't use any arguments in this example */
+ (void)argv;
+
+ /* Must initialize libcurl before any threads are started */
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ init_locks();
+
+ for(i=0; i< NUMT; i++) {
+ error = pthread_create(&tid[i],
+ NULL, /* default attributes please */
+ pull_one_url,
+ (void *)urls[i]);
+ if(0 != error)
+ fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
+ else
+ fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
+ }
+
+ /* now wait for all threads to terminate */
+ for(i=0; i< NUMT; i++) {
+ error = pthread_join(tid[i], NULL);
+ fprintf(stderr, "Thread %d terminated\n", i);
+ }
+
+ kill_locks();
+
+ return 0;
+}
diff --git a/docs/examples/url2file.c b/docs/examples/url2file.c
new file mode 100644
index 000000000..64d27c88f
--- /dev/null
+++ b/docs/examples/url2file.c
@@ -0,0 +1,81 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <curl/curl.h>
+
+static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
+ return written;
+}
+
+int main(int argc, char *argv[])
+{
+ CURL *curl_handle;
+ static const char *pagefilename = "page.out";
+ FILE *pagefile;
+
+ if(argc < 2 ) {
+ printf("Usage: %s <URL>\n", argv[0]);
+ return 1;
+ }
+
+ curl_global_init(CURL_GLOBAL_ALL);
+
+ /* init the curl session */
+ curl_handle = curl_easy_init();
+
+ /* set URL to get here */
+ curl_easy_setopt(curl_handle, CURLOPT_URL, argv[1]);
+
+ /* Switch on full protocol/debug output while testing */
+ curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
+
+ /* disable progress meter, set to 0L to enable and disable debug output */
+ curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);
+
+ /* send all data to this function */
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
+
+ /* open the file */
+ pagefile = fopen(pagefilename, "wb");
+ if (pagefile) {
+
+ /* write the page body to this file handle. CURLOPT_FILE is also known as
+ CURLOPT_WRITEDATA*/
+ curl_easy_setopt(curl_handle, CURLOPT_FILE, pagefile);
+
+ /* get it! */
+ curl_easy_perform(curl_handle);
+
+ /* close the header file */
+ fclose(pagefile);
+ }
+
+ /* cleanup curl stuff */
+ curl_easy_cleanup(curl_handle);
+
+ return 0;
+}
diff --git a/docs/examples/version-check.pl b/docs/examples/version-check.pl
new file mode 100755
index 000000000..92f0808d6
--- /dev/null
+++ b/docs/examples/version-check.pl
@@ -0,0 +1,105 @@
+#!/usr/bin/env perl
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
+# This script accepts a source file as input on the command line.
+#
+# It first loads the 'symbols-in-versions' document and stores a lookup
+# table for all known symbols for which version they were introduced.
+#
+# It then scans the given source file to dig up all symbols starting with CURL.
+# Finally, it sorts the internal list of found symbols (using the version
+# number as sort key) and then it outputs the most recent version number and
+# the symbols from that version that are used.
+#
+# Usage:
+#
+# version-check.pl [source file]
+#
+
+open(S, "<../libcurl/symbols-in-versions") || die;
+
+my %doc;
+my %rem;
+while(<S>) {
+ if(/(^CURL[^ \n]*) *(.*)/) {
+ my ($sym, $rest)=($1, $2);
+ my @a=split(/ +/, $rest);
+
+ $doc{$sym}=$a[0]; # when it was introduced
+
+ if($a[2]) {
+ # this symbol is documented to have been present the last time
+ # in this release
+ $rem{$sym}=$a[2];
+ }
+ }
+
+}
+
+close(S);
+
+sub age {
+ my ($ver)=@_;
+
+ my @s=split(/\./, $ver);
+ return $s[0]*10000+$s[1]*100+$s[2];
+}
+
+my %used;
+open(C, "<$ARGV[0]") || die;
+
+while(<C>) {
+ if(/\W(CURL[_A-Z0-9v]+)\W/) {
+ #print "$1\n";
+ $used{$1}++;
+ }
+}
+
+close(C);
+
+sub sortversions {
+ my $r = age($doc{$a}) <=> age($doc{$b});
+ if(!$r) {
+ $r = $a cmp $b;
+ }
+ return $r;
+}
+
+my @recent = reverse sort sortversions keys %used;
+
+# the most recent symbol
+my $newsym = $recent[0];
+# the most recent version
+my $newver = $doc{$newsym};
+
+print "The scanned source uses these symbols introduced in $newver:\n";
+
+for my $w (@recent) {
+ if($doc{$w} eq $newver) {
+ printf " $w\n";
+ next;
+ }
+ last;
+}
+
+
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 000000000..4390378af
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html><head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<title>Index to Curl documentation</title>
+</head>
+
+<body>
+<h1 align="center">Index to Curl documentation</h1>
+
+<h2>Programs</h2>
+<a href="curl-config.html">curl-config</A>
+<br><a href="curl.html">curl</A>
+
+<h2>Tutorial</h2>
+<a href="TheArtOfHttpScripting">The Art Of Scripting HTTP Requests Using Curl</a> (plain text)
+
+<h2>libcurl</h2>
+See the <a href="libcurl/index.html">libcurl section</a>
+
+</body></html>
diff --git a/docs/libcurl/.gitignore b/docs/libcurl/.gitignore
new file mode 100644
index 000000000..23f832b73
--- /dev/null
+++ b/docs/libcurl/.gitignore
@@ -0,0 +1,2 @@
+*.html
+*.pdf
diff --git a/docs/libcurl/ABI b/docs/libcurl/ABI
new file mode 100644
index 000000000..3ec0e04de
--- /dev/null
+++ b/docs/libcurl/ABI
@@ -0,0 +1,69 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+ libcurl's binary interface
+
+ABI - Application Binary Interface
+
+ First, allow me to define the word for this context: ABI describes the
+ low-level interface between an application program and a library. Calling
+ conventions, function arguments, return values, struct sizes/defines and
+ more.
+
+ For a longer description, see
+ http://en.wikipedia.org/wiki/Application_binary_interface
+
+Upgrades
+
+ In the vast majority of all cases, a typical libcurl upgrade does not break
+ the ABI at all. Your application can remain using libcurl just as before,
+ only with less bugs and possibly with added new features. You need to read
+ the release notes, and if they mention an ABI break/soname bump, you may
+ have to verify that your application still builds fine and uses libcurl as
+ it now is defined to work.
+
+Version Numbers
+
+ In libcurl land, you really can't tell by the libcurl version number if that
+ libcurl is binary compatible or not with another libcurl version.
+
+Soname Bumps
+
+ Whenever there are changes done to the library that will cause an ABI
+ breakage, that may require your application to get attention or possibly be
+ changed to adhere to new things, we will bump the soname. Then the library
+ will get a different output name and thus can in fact be installed in
+ parallel with an older installed lib (on most systems). Thus, old
+ applications built against the previous ABI version will remain working and
+ using the older lib, while newer applications build and use the newer one.
+
+ During the first seven years of libcurl releases, there have only been four
+ ABI breakages.
+
+Downgrades
+
+ Going to an older libcurl version from one you're currently using can be a
+ tricky thing. Mostly we add features and options to newer libcurls as that
+ won't break ABI or hamper existing applications. This has the implication
+ that going backwards may get you in a situation where you pick a libcurl
+ that doesn't support the options your application needs. Or possibly you
+ even downgrade so far so you cross an ABI break border and thus a different
+ soname, and then your application may need to adapt to the modified ABI.
+
+History
+
+ The previous major library soname number bumps (breaking backwards
+ compatibility) have happened the following times:
+
+ 0 - libcurl 7.1, August 2000
+
+ 1 - libcurl 7.5 December 2000
+
+ 2 - libcurl 7.7 March 2001
+
+ 3 - libcurl 7.12.0 June 2004
+
+ 4 - libcurl 7.16.0 October 2006
diff --git a/docs/libcurl/Makefile.am b/docs/libcurl/Makefile.am
new file mode 100644
index 000000000..3114e2b3b
--- /dev/null
+++ b/docs/libcurl/Makefile.am
@@ -0,0 +1,102 @@
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \
+ curl_easy_perform.3 curl_easy_setopt.3 curl_easy_duphandle.3 \
+ curl_formadd.3 curl_formfree.3 curl_getdate.3 curl_getenv.3 \
+ curl_slist_append.3 curl_slist_free_all.3 curl_version.3 \
+ curl_version_info.3 curl_escape.3 curl_unescape.3 curl_free.3 \
+ curl_strequal.3 curl_mprintf.3 curl_global_init.3 curl_global_cleanup.3 \
+ curl_multi_add_handle.3 curl_multi_cleanup.3 curl_multi_fdset.3 \
+ curl_multi_info_read.3 curl_multi_init.3 curl_multi_perform.3 \
+ curl_multi_remove_handle.3 curl_share_cleanup.3 curl_share_init.3 \
+ curl_share_setopt.3 libcurl.3 libcurl-easy.3 libcurl-multi.3 \
+ libcurl-share.3 libcurl-errors.3 curl_easy_strerror.3 \
+ curl_multi_strerror.3 curl_share_strerror.3 curl_global_init_mem.3 \
+ libcurl-tutorial.3 curl_easy_reset.3 curl_easy_escape.3 \
+ curl_easy_unescape.3 curl_multi_setopt.3 curl_multi_socket.3 \
+ curl_multi_timeout.3 curl_formget.3 curl_multi_assign.3 \
+ curl_easy_pause.3 curl_easy_recv.3 curl_easy_send.3 \
+ curl_multi_socket_action.3 curl_multi_wait.3
+
+HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
+ curl_easy_init.html curl_easy_perform.html curl_easy_setopt.html \
+ curl_easy_duphandle.html curl_formadd.html curl_formfree.html \
+ curl_getdate.html curl_getenv.html curl_slist_append.html \
+ curl_slist_free_all.html curl_version.html curl_version_info.html \
+ curl_escape.html curl_unescape.html curl_free.html curl_strequal.html \
+ curl_mprintf.html curl_global_init.html curl_global_cleanup.html \
+ curl_multi_add_handle.html curl_multi_cleanup.html \
+ curl_multi_fdset.html curl_multi_info_read.html curl_multi_init.html \
+ curl_multi_perform.html curl_multi_remove_handle.html \
+ curl_share_cleanup.html curl_share_init.html curl_share_setopt.html \
+ libcurl.html libcurl-multi.html libcurl-easy.html libcurl-share.html \
+ libcurl-errors.html curl_easy_strerror.html curl_multi_strerror.html \
+ curl_share_strerror.html curl_global_init_mem.html \
+ libcurl-tutorial.html curl_easy_reset.html curl_easy_escape.html \
+ curl_easy_unescape.html curl_multi_setopt.html curl_multi_socket.html \
+ curl_multi_timeout.html curl_formget.html curl_multi_assign.html \
+ curl_easy_pause.html curl_easy_recv.html curl_easy_send.html \
+ curl_multi_socket_action.html curl_multi_wait.html
+
+PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
+ curl_easy_init.pdf curl_easy_perform.pdf curl_easy_setopt.pdf \
+ curl_easy_duphandle.pdf curl_formadd.pdf curl_formfree.pdf \
+ curl_getdate.pdf curl_getenv.pdf curl_slist_append.pdf \
+ curl_slist_free_all.pdf curl_version.pdf curl_version_info.pdf \
+ curl_escape.pdf curl_unescape.pdf curl_free.pdf curl_strequal.pdf \
+ curl_mprintf.pdf curl_global_init.pdf curl_global_cleanup.pdf \
+ curl_multi_add_handle.pdf curl_multi_cleanup.pdf curl_multi_fdset.pdf \
+ curl_multi_info_read.pdf curl_multi_init.pdf curl_multi_perform.pdf \
+ curl_multi_remove_handle.pdf curl_share_cleanup.pdf curl_share_init.pdf \
+ curl_share_setopt.pdf libcurl.pdf libcurl-multi.pdf libcurl-easy.pdf \
+ libcurl-share.pdf libcurl-errors.pdf curl_easy_strerror.pdf \
+ curl_multi_strerror.pdf curl_share_strerror.pdf \
+ curl_global_init_mem.pdf libcurl-tutorial.pdf curl_easy_reset.pdf \
+ curl_easy_escape.pdf curl_easy_unescape.pdf curl_multi_setopt.pdf \
+ curl_multi_socket.pdf curl_multi_timeout.pdf curl_formget.pdf \
+ curl_multi_assign.pdf curl_easy_pause.pdf curl_easy_recv.pdf \
+ curl_easy_send.pdf curl_multi_socket_action.pdf curl_multi_wait.pdf
+
+CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
+
+EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) libcurl.m4 ABI \
+ symbols-in-versions symbols.pl
+MAN2HTML= roffit --mandir=. < $< >$@
+
+SUFFIXES = .3 .html
+
+html: $(HTMLPAGES)
+
+.3.html:
+ $(MAN2HTML)
+
+pdf: $(PDFPAGES)
+
+.3.pdf:
+ @(foo=`echo $@ | sed -e 's/\.[0-9]$$//g'`; \
+ groff -Tps -man $< >$$foo.ps; \
+ ps2pdf $$foo.ps $@; \
+ rm $$foo.ps; \
+ echo "converted $< to $@")
diff --git a/docs/libcurl/curl_easy_cleanup.3 b/docs/libcurl/curl_easy_cleanup.3
new file mode 100644
index 000000000..d8a3f9fcf
--- /dev/null
+++ b/docs/libcurl/curl_easy_cleanup.3
@@ -0,0 +1,57 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH curl_easy_cleanup 3 "22 aug 2007" "libcurl 7.17.0" "libcurl Manual"
+.SH NAME
+curl_easy_cleanup - End a libcurl easy session
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+
+.BI "void curl_easy_cleanup(CURL *" handle ");"
+
+.SH DESCRIPTION
+This function must be the last function to call for an easy session. It is the
+opposite of the \fIcurl_easy_init(3)\fP function and must be called with the
+same \fIhandle\fP as input that the curl_easy_init call returned.
+
+This will effectively close all connections this handle has used and possibly
+has kept open until now. Don't call this function if you intend to transfer
+more files.
+
+Occasionally you may get your progress callback or header callback called from
+within \fIcurl_easy_cleanup(3)\fP (if previously set for the handle using
+\fIcurl_easy_setopt(3)\fP). Like if libcurl decides to shut down the
+connection and the protocol is of a kind that requires a command/response
+sequence before disconnect. Examples of such protocols are FTP, POP3 and IMAP.
+
+Any uses of the \fBhandle\fP after this function has been called and have
+returned, are illegal. This kills the handle and all memory associated with
+it!
+
+With libcurl versions prior to 7.17.: when you've called this, you can safely
+remove all the strings you've previously told libcurl to use, as it won't use
+them anymore now.
+.SH RETURN VALUE
+None
+.SH "SEE ALSO"
+.BR curl_easy_init "(3), "
+
diff --git a/docs/libcurl/curl_easy_duphandle.3 b/docs/libcurl/curl_easy_duphandle.3
new file mode 100644
index 000000000..e53ced48b
--- /dev/null
+++ b/docs/libcurl/curl_easy_duphandle.3
@@ -0,0 +1,51 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_easy_duphandle 3 "18 September 2001" "libcurl 7.9" "libcurl Manual"
+.SH NAME
+curl_easy_duphandle - Clone a libcurl session handle
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+
+.BI "CURL *curl_easy_duphandle(CURL *"handle ");"
+
+.SH DESCRIPTION
+This function will return a new curl handle, a duplicate, using all the
+options previously set in the input curl \fIhandle\fP. Both handles can
+subsequently be used independently and they must both be freed with
+\fIcurl_easy_cleanup(3)\fP.
+
+All strings that the input handle has been told to point to (as opposed to
+copy) with previous calls to \fIcurl_easy_setopt(3)\fP using char * inputs,
+will be pointed to by the new handle as well. You must therefore make sure to
+keep the data around until both handles have been cleaned up.
+
+The new handle will \fBnot\fP inherit any state information, no connections,
+no SSL sessions and no cookies.
+
+\fBNote\fP that even in multi-threaded programs, this function must be called
+in a synchronous way, the input handle may not be in use when cloned.
+.SH RETURN VALUE
+If this function returns NULL, something went wrong and no valid handle was
+returned.
+.SH "SEE ALSO"
+.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_global_init "(3)
+
diff --git a/docs/libcurl/curl_easy_escape.3 b/docs/libcurl/curl_easy_escape.3
new file mode 100644
index 000000000..3a98e6fe8
--- /dev/null
+++ b/docs/libcurl/curl_easy_escape.3
@@ -0,0 +1,46 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH curl_easy_escape 3 "7 April 2006" "libcurl 7.15.4" "libcurl Manual"
+.SH NAME
+curl_easy_escape - URL encodes the given string
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "char *curl_easy_escape( CURL *" curl ", char *" url ", int "length " );"
+.ad
+.SH DESCRIPTION
+This function converts the given input string to an URL encoded string and
+returns that as a new allocated string. All input characters that are not a-z,
+A-Z, 0-9, '-', '.', '_' or '~' are converted to their "URL escaped" version
+(%NN where NN is a two-digit hexadecimal number).
+
+If the \fBlength\fP argument is set to 0 (zero), \fIcurl_easy_escape(3)\fP
+uses strlen() on the input \fBurl\fP to find out the size.
+
+You must \fIcurl_free(3)\fP the returned string when you're done with it.
+.SH AVAILABILITY
+Added in 7.15.4 and replaces the old \fIcurl_escape(3)\fP function.
+.SH RETURN VALUE
+A pointer to a zero terminated string or NULL if it failed.
+.SH "SEE ALSO"
+.BR curl_easy_unescape "(3), " curl_free "(3), " RFC 2396
diff --git a/docs/libcurl/curl_easy_getinfo.3 b/docs/libcurl/curl_easy_getinfo.3
new file mode 100644
index 000000000..096813609
--- /dev/null
+++ b/docs/libcurl/curl_easy_getinfo.3
@@ -0,0 +1,292 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH curl_easy_getinfo 3 "11 Feb 2009" "libcurl 7.19.4" "libcurl Manual"
+.SH NAME
+curl_easy_getinfo - extract information from a curl handle
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+
+.B "CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ... );"
+
+.SH DESCRIPTION
+Request internal information from the curl session with this function. The
+third argument \fBMUST\fP be a pointer to a long, a pointer to a char *, a
+pointer to a struct curl_slist * or a pointer to a double (as this
+documentation describes further down). The data pointed-to will be filled in
+accordingly and can be relied upon only if the function returns CURLE_OK. Use
+this function AFTER a performed transfer if you want to get transfer- oriented
+data.
+
+You should not free the memory returned by this function unless it is
+explicitly mentioned below.
+.SH AVAILABLE INFORMATION
+The following information can be extracted:
+.IP CURLINFO_EFFECTIVE_URL
+Pass a pointer to a char pointer to receive the last used effective URL.
+.IP CURLINFO_RESPONSE_CODE
+Pass a pointer to a long to receive the last received HTTP, FTP or SMTP
+response code. This option was previously known as CURLINFO_HTTP_CODE in
+libcurl 7.10.7 and earlier. The value will be zero if no server response code
+has been received. Note that a proxy's CONNECT response should be read with
+\fICURLINFO_HTTP_CONNECTCODE\fP and not this.
+
+Support for SMTP responses added in 7.25.0.
+.IP CURLINFO_HTTP_CONNECTCODE
+Pass a pointer to a long to receive the last received proxy response code to a
+CONNECT request.
+.IP CURLINFO_FILETIME
+Pass a pointer to a long to receive the remote time of the retrieved document
+(in number of seconds since 1 jan 1970 in the GMT/UTC time zone). If you get
+-1, it can be because of many reasons (unknown, the server hides it or the
+server doesn't support the command that tells document time etc) and the time
+of the document is unknown. Note that you must tell the server to collect this
+information before the transfer is made, by using the CURLOPT_FILETIME option
+to \fIcurl_easy_setopt(3)\fP or you will unconditionally get a -1 back. (Added
+in 7.5)
+.IP CURLINFO_TOTAL_TIME
+Pass a pointer to a double to receive the total time in seconds for the
+previous transfer, including name resolving, TCP connect etc.
+.IP CURLINFO_NAMELOOKUP_TIME
+Pass a pointer to a double to receive the time, in seconds, it took from the
+start until the name resolving was completed.
+.IP CURLINFO_CONNECT_TIME
+Pass a pointer to a double to receive the time, in seconds, it took from the
+start until the connect to the remote host (or proxy) was completed.
+.IP CURLINFO_APPCONNECT_TIME
+Pass a pointer to a double to receive the time, in seconds, it took from the
+start until the SSL/SSH connect/handshake to the remote host was completed.
+This time is most often very near to the PRETRANSFER time, except for cases
+such as HTTP pippelining where the pretransfer time can be delayed due to
+waits in line for the pipeline and more. (Added in 7.19.0)
+.IP CURLINFO_PRETRANSFER_TIME
+Pass a pointer to a double to receive the time, in seconds, it took from the
+start until the file transfer is just about to begin. This includes all
+pre-transfer commands and negotiations that are specific to the particular
+protocol(s) involved. It does \fInot\fP involve the sending of the protocol-
+specific request that triggers a transfer.
+.IP CURLINFO_STARTTRANSFER_TIME
+Pass a pointer to a double to receive the time, in seconds, it took from the
+start until the first byte is received by libcurl. This includes
+CURLINFO_PRETRANSFER_TIME and also the time the server needs to calculate the
+result.
+.IP CURLINFO_REDIRECT_TIME
+Pass a pointer to a double to receive the total time, in seconds, it took for
+all redirection steps include name lookup, connect, pretransfer and transfer
+before final transaction was started. CURLINFO_REDIRECT_TIME contains the
+complete execution time for multiple redirections. (Added in 7.9.7)
+.IP CURLINFO_REDIRECT_COUNT
+Pass a pointer to a long to receive the total number of redirections that were
+actually followed. (Added in 7.9.7)
+.IP CURLINFO_REDIRECT_URL
+Pass a pointer to a char pointer to receive the URL a redirect \fIwould\fP
+take you to if you would enable CURLOPT_FOLLOWLOCATION. This can come very
+handy if you think using the built-in libcurl redirect logic isn't good enough
+for you but you would still prefer to avoid implementing all the magic of
+figuring out the new URL. (Added in 7.18.2)
+.IP CURLINFO_SIZE_UPLOAD
+Pass a pointer to a double to receive the total amount of bytes that were
+uploaded.
+.IP CURLINFO_SIZE_DOWNLOAD
+Pass a pointer to a double to receive the total amount of bytes that were
+downloaded. The amount is only for the latest transfer and will be reset again
+for each new transfer.
+.IP CURLINFO_SPEED_DOWNLOAD
+Pass a pointer to a double to receive the average download speed that curl
+measured for the complete download. Measured in bytes/second.
+.IP CURLINFO_SPEED_UPLOAD
+Pass a pointer to a double to receive the average upload speed that curl
+measured for the complete upload. Measured in bytes/second.
+.IP CURLINFO_HEADER_SIZE
+Pass a pointer to a long to receive the total size of all the headers
+received. Measured in number of bytes.
+.IP CURLINFO_REQUEST_SIZE
+Pass a pointer to a long to receive the total size of the issued
+requests. This is so far only for HTTP requests. Note that this may be more
+than one request if FOLLOWLOCATION is true.
+.IP CURLINFO_SSL_VERIFYRESULT
+Pass a pointer to a long to receive the result of the certification
+verification that was requested (using the CURLOPT_SSL_VERIFYPEER option to
+\fIcurl_easy_setopt(3)\fP).
+.IP CURLINFO_SSL_ENGINES
+Pass the address of a 'struct curl_slist *' to receive a linked-list of
+OpenSSL crypto-engines supported. Note that engines are normally implemented
+in separate dynamic libraries. Hence not all the returned engines may be
+available at run-time. \fBNOTE:\fP you must call \fIcurl_slist_free_all(3)\fP
+on the list pointer once you're done with it, as libcurl will not free the
+data for you. (Added in 7.12.3)
+.IP CURLINFO_CONTENT_LENGTH_DOWNLOAD
+Pass a pointer to a double to receive the content-length of the download. This
+is the value read from the Content-Length: field. Since 7.19.4, this returns -1
+if the size isn't known.
+.IP CURLINFO_CONTENT_LENGTH_UPLOAD
+Pass a pointer to a double to receive the specified size of the upload. Since
+7.19.4, this returns -1 if the size isn't known.
+.IP CURLINFO_CONTENT_TYPE
+Pass a pointer to a char pointer to receive the content-type of the downloaded
+object. This is the value read from the Content-Type: field. If you get NULL,
+it means that the server didn't send a valid Content-Type header or that the
+protocol used doesn't support this.
+.IP CURLINFO_PRIVATE
+Pass a pointer to a char pointer to receive the pointer to the private data
+associated with the curl handle (set with the CURLOPT_PRIVATE option to
+\fIcurl_easy_setopt(3)\fP). Please note that for internal reasons, the
+value is returned as a char pointer, although effectively being a 'void *'.
+(Added in 7.10.3)
+.IP CURLINFO_HTTPAUTH_AVAIL
+Pass a pointer to a long to receive a bitmask indicating the authentication
+method(s) available. The meaning of the bits is explained in the
+CURLOPT_HTTPAUTH option for \fIcurl_easy_setopt(3)\fP. (Added in 7.10.8)
+.IP CURLINFO_PROXYAUTH_AVAIL
+Pass a pointer to a long to receive a bitmask indicating the authentication
+method(s) available for your proxy authentication. (Added in 7.10.8)
+.IP CURLINFO_OS_ERRNO
+Pass a pointer to a long to receive the errno variable from a connect failure.
+Note that the value is only set on failure, it is not reset upon a
+successfull operation. (Added in 7.12.2)
+.IP CURLINFO_NUM_CONNECTS
+Pass a pointer to a long to receive how many new connections libcurl had to
+create to achieve the previous transfer (only the successful connects are
+counted). Combined with \fICURLINFO_REDIRECT_COUNT\fP you are able to know
+how many times libcurl successfully reused existing connection(s) or not. See
+the Connection Options of \fIcurl_easy_setopt(3)\fP to see how libcurl tries
+to make persistent connections to save time. (Added in 7.12.3)
+.IP CURLINFO_PRIMARY_IP
+Pass a pointer to a char pointer to receive the pointer to a zero-terminated
+string holding the IP address of the most recent connection done with this
+\fBcurl\fP handle. This string may be IPv6 if that's enabled. Note that you
+get a pointer to a memory area that will be re-used at next request so you
+need to copy the string if you want to keep the information. (Added in 7.19.0)
+.IP CURLINFO_PRIMARY_PORT
+Pass a pointer to a long to receive the destination port of the most recent
+connection done with this \fBcurl\fP handle. (Added in 7.21.0)
+.IP CURLINFO_LOCAL_IP
+Pass a pointer to a char pointer to receive the pointer to a zero-terminated
+string holding the local (source) IP address of the most recent connection done
+with this \fBcurl\fP handle. This string may be IPv6 if that's enabled. The
+same restrictions apply as to \fICURLINFO_PRIMARY_IP\fP. (Added in 7.21.0)
+.IP CURLINFO_LOCAL_PORT
+Pass a pointer to a long to receive the local (source) port of the most recent
+connection done with this \fBcurl\fP handle. (Added in 7.21.0)
+.IP CURLINFO_COOKIELIST
+Pass a pointer to a 'struct curl_slist *' to receive a linked-list of all
+cookies cURL knows (expired ones, too). Don't forget to
+\fIcurl_slist_free_all(3)\fP the list after it has been used. If there are no
+cookies (cookies for the handle have not been enabled or simply none have been
+received) 'struct curl_slist *' will be set to point to NULL. (Added in
+7.14.1)
+.IP CURLINFO_LASTSOCKET
+Pass a pointer to a long to receive the last socket used by this curl
+session. If the socket is no longer valid, -1 is returned. When you finish
+working with the socket, you must call curl_easy_cleanup() as usual and let
+libcurl close the socket and cleanup other resources associated with the
+handle. This is typically used in combination with \fICURLOPT_CONNECT_ONLY\fP.
+(Added in 7.15.2)
+
+NOTE: this API is not really working on win64, since the SOCKET type on win64
+is 64 bit large while its 'long' is only 32 bits.
+.IP CURLINFO_FTP_ENTRY_PATH
+Pass a pointer to a char pointer to receive a pointer to a string holding the
+path of the entry path. That is the initial path libcurl ended up in when
+logging on to the remote FTP server. This stores a NULL as pointer if
+something is wrong. (Added in 7.15.4)
+
+Also works for SFTP since 7.21.4
+.IP CURLINFO_CERTINFO
+Pass a pointer to a 'struct curl_certinfo *' and you'll get it set to point to
+struct that holds a number of linked lists with info about the certificate
+chain, assuming you had CURLOPT_CERTINFO enabled when the previous request was
+done. The struct reports how many certs it found and then you can extract info
+for each of those certs by following the linked lists. The info chain is
+provided in a series of data in the format "name:content" where the content is
+for the specific named data. See also the certinfo.c example. NOTE: this
+option is only available in libcurl built with OpenSSL support. (Added in
+7.19.1)
+.IP CURLINFO_CONDITION_UNMET
+Pass a pointer to a long to receive the number 1 if the condition provided in
+the previous request didn't match (see \fICURLOPT_TIMECONDITION\fP). Alas, if
+this returns a 1 you know that the reason you didn't get data in return is
+because it didn't fulfill the condition. The long ths argument points to will
+get a zero stored if the condition instead was met. (Added in 7.19.4)
+.IP CURLINFO_RTSP_SESSION_ID
+Pass a pointer to a char pointer to receive a pointer to a string holding the
+most recent RTSP Session ID.
+
+Applications wishing to resume an RTSP session on another connection should
+retreive this info before closing the active connection.
+.IP CURLINFO_RTSP_CLIENT_CSEQ
+Pass a pointer to a long to receive the next CSeq that will be used by the
+application.
+.IP CURLINFO_RTSP_SERVER_CSEQ
+Pass a pointer to a long to receive the next server CSeq that will be expected
+by the application.
+
+\fI(NOTE: listening for server initiated requests is currently
+unimplemented).\fP
+
+Applications wishing to resume an RTSP session on another connection should
+retreive this info before closing the active connection.
+.IP CURLINFO_RTSP_CSEQ_RECV
+Pass a pointer to a long to receive the most recently received CSeq from the
+server. If your application encounters a \fICURLE_RTSP_CSEQ_ERROR\fP then you
+may wish to troubleshoot and/or fix the CSeq mismatch by peeking at this value.
+.SH TIMES
+.nf
+An overview of the six time values available from curl_easy_getinfo()
+
+curl_easy_perform()
+ |
+ |--NAMELOOKUP
+ |--|--CONNECT
+ |--|--|--APPCONNECT
+ |--|--|--|--PRETRANSFER
+ |--|--|--|--|--STARTTRANSFER
+ |--|--|--|--|--|--TOTAL
+ |--|--|--|--|--|--REDIRECT
+.fi
+.IP NAMELOOKUP
+\fICURLINFO_NAMELOOKUP_TIME\fP. The time it took from the start until the name
+resolving was completed.
+.IP CONNECT
+\fICURLINFO_CONNECT_TIME\fP. The time it took from the start until the connect
+to the remote host (or proxy) was completed.
+.IP APPCONNECT
+\fICURLINFO_APPCONNECT_TIME\fP. The time it took from the start until the SSL
+connect/handshake with the remote host was completed. (Added in in 7.19.0)
+.IP PRETRANSFER
+\fICURLINFO_PRETRANSFER_TIME\fP. The time it took from the start until the
+file transfer is just about to begin. This includes all pre-transfer commands
+and negotiations that are specific to the particular protocol(s) involved.
+.IP STARTTRANSFER
+\fICURLINFO_STARTTRANSFER_TIME\fP. The time it took from the start until the
+first byte is received by libcurl.
+.IP TOTAL
+\fICURLINFO_TOTAL_TIME\fP. Total time of the previous request.
+.IP REDIRECT
+\fICURLINFO_REDIRECT_TIME\fP. The time it took for all redirection steps
+include name lookup, connect, pretransfer and transfer before final
+transaction was started. So, this is zero if no redirection took place.
+.SH RETURN VALUE
+If the operation was successful, CURLE_OK is returned. Otherwise an
+appropriate error code will be returned.
+.SH "SEE ALSO"
+.BR curl_easy_setopt "(3)"
diff --git a/docs/libcurl/curl_easy_init.3 b/docs/libcurl/curl_easy_init.3
new file mode 100644
index 000000000..837ba32a5
--- /dev/null
+++ b/docs/libcurl/curl_easy_init.3
@@ -0,0 +1,51 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_easy_init 3 "4 March 2002" "libcurl 7.8.1" "libcurl Manual"
+.SH NAME
+curl_easy_init - Start a libcurl easy session
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+
+.BI "CURL *curl_easy_init( );"
+
+.SH DESCRIPTION
+This function must be the first function to call, and it returns a CURL easy
+handle that you must use as input to other easy-functions. curl_easy_init
+initializes curl and this call \fBMUST\fP have a corresponding call to
+\fIcurl_easy_cleanup(3)\fP when the operation is complete.
+
+If you did not already call \fIcurl_global_init(3)\fP,
+\fIcurl_easy_init(3)\fP does it automatically.
+This may be lethal in multi-threaded cases, since \fIcurl_global_init(3)\fP is
+not thread-safe, and it may result in resource problems because there is
+no corresponding cleanup.
+
+You are strongly advised to not allow this automatic behaviour, by
+calling \fIcurl_global_init(3)\fP yourself properly.
+See the description in \fBlibcurl\fP(3) of global environment
+requirements for details of how to use this function.
+
+.SH RETURN VALUE
+If this function returns NULL, something went wrong and you cannot use the
+other curl functions.
+.SH "SEE ALSO"
+.BR curl_easy_cleanup "(3), " curl_global_init "(3), " curl_easy_reset "(3)"
diff --git a/docs/libcurl/curl_easy_pause.3 b/docs/libcurl/curl_easy_pause.3
new file mode 100644
index 000000000..25d67bfbb
--- /dev/null
+++ b/docs/libcurl/curl_easy_pause.3
@@ -0,0 +1,85 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_easy_pause 3 "17 Dec 2007" "libcurl 7.18.0" "libcurl Manual"
+.SH NAME
+curl_easy_pause - pause and unpause a connection
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+
+.BI "CURLcode curl_easy_pause(CURL *"handle ", int "bitmask " );"
+
+.SH DESCRIPTION
+Using this function, you can explicitly mark a running connection to get
+paused, and you can unpause a connection that was previously paused.
+
+A connection can be paused by using this function or by letting the read
+or the write callbacks return the proper magic return code
+(\fICURL_READFUNC_PAUSE\fP and \fICURL_WRITEFUNC_PAUSE\fP). A write callback
+that returns pause signals to the library that it couldn't take care of any
+data at all, and that data will then be delivered again to the callback when
+the writing is later unpaused.
+
+NOTE: while it may feel tempting, take care and notice that you cannot call
+this function from another thread.
+
+When this function is called to unpause reading, the chance is high that you
+will get your write callback called before this function returns.
+
+The \fBhandle\fP argument is of course identifying the handle that operates on
+the connection you want to pause or unpause.
+
+The \fBbitmask\fP argument is a set of bits that sets the new state of the
+connection. The following bits can be used:
+.IP CURLPAUSE_RECV
+Pause receiving data. There will be no data received on this connection until
+this function is called again without this bit set. Thus, the write callback
+(\fICURLOPT_WRITEFUNCTION\fP) won't be called.
+.IP CURLPAUSE_SEND
+Pause sending data. There will be no data sent on this connection until this
+function is called again without this bit set. Thus, the read callback
+(\fICURLOPT_READFUNCTION\fP) won't be called.
+.IP CURLPAUSE_ALL
+Convenience define that pauses both directions.
+.IP CURLPAUSE_CONT
+Convenience define that unpauses both directions
+.SH RETURN VALUE
+CURLE_OK (zero) means that the option was set properly, and a non-zero return
+code means something wrong occurred after the new state was set. See the
+\fIlibcurl-errors(3)\fP man page for the full list with descriptions.
+.SH AVAILABILITY
+This function was added in libcurl 7.18.0. Before this version, there was no
+explicit support for pausing transfers.
+.SH "MEMORY USE"
+When pausing a read by returning the magic return code from a write callback,
+the read data is already in libcurl's internal buffers so it'll have to keep
+it in an allocated buffer until the reading is again unpaused using this
+function.
+
+If the downloaded data is compressed and is asked to get uncompressed
+automatically on download, libcurl will continue to uncompress the entire
+downloaded chunk and it will cache the data uncompressed. This has the side-
+effect that if you download something that is compressed a lot, it can result
+in a very large data amount needing to be allocated to save the data during
+the pause. This said, you should probably consider not using paused reading if
+you allow libcurl to uncompress data automatically.
+.SH "SEE ALSO"
+.BR curl_easy_cleanup "(3), " curl_easy_reset "(3)"
diff --git a/docs/libcurl/curl_easy_perform.3 b/docs/libcurl/curl_easy_perform.3
new file mode 100644
index 000000000..8f8517f22
--- /dev/null
+++ b/docs/libcurl/curl_easy_perform.3
@@ -0,0 +1,57 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_easy_perform 3 "5 Mar 2001" "libcurl 7.7" "libcurl Manual"
+.SH NAME
+curl_easy_perform - Perform a file transfer
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "CURLcode curl_easy_perform(CURL *" handle ");"
+.ad
+.SH DESCRIPTION
+This function is called after the init and all the \fIcurl_easy_setopt(3)\fP
+calls are made, and will perform the transfer as described in the options. It
+must be called with the same
+.I handle
+as input as the curl_easy_init call returned.
+
+You can do any amount of calls to \fIcurl_easy_perform(3)\fP while using the
+same handle. If you intend to transfer more than one file, you are even
+encouraged to do so. libcurl will then attempt to re-use the same connection
+for the following transfers, thus making the operations faster, less CPU
+intense and using less network resources. Just note that you will have to use
+\fIcurl_easy_setopt(3)\fP between the invokes to set options for the following
+curl_easy_perform.
+
+You must never call this function simultaneously from two places using the
+same handle. Let the function return first before invoking it another time. If
+you want parallel transfers, you must use several curl handles.
+.SH RETURN VALUE
+0 means everything was ok, non-zero means an error occurred as
+.I <curl/curl.h>
+defines. If the CURLOPT_ERRORBUFFER was set with
+.I curl_easy_setopt
+there will be a readable error message in the error buffer when non-zero is
+returned.
+.SH "SEE ALSO"
+.BR curl_easy_init "(3), " curl_easy_setopt "(3), "
+
diff --git a/docs/libcurl/curl_easy_recv.3 b/docs/libcurl/curl_easy_recv.3
new file mode 100644
index 000000000..1ede58944
--- /dev/null
+++ b/docs/libcurl/curl_easy_recv.3
@@ -0,0 +1,69 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH curl_easy_recv 3 "29 April 2008" "libcurl 7.18.2" "libcurl Manual"
+.SH NAME
+curl_easy_recv - receives raw data on an "easy" connection
+.SH SYNOPSIS
+.B #include <curl/easy.h>
+.sp
+.BI "CURLcode curl_easy_recv( CURL *" curl ", void *" buffer ","
+.BI "size_t " buflen ", size_t *" n ");"
+.ad
+.SH DESCRIPTION
+This function receives raw data from the established connection. You may use
+it together with \fIcurl_easy_send(3)\fP to implement custom protocols using
+libcurl. This functionality can be particularly useful if you use proxies
+and/or SSL encryption: libcurl will take care of proxy negotiation and
+connection set-up.
+
+\fBbuffer\fP is a pointer to your buffer that will get the received
+data. \fBbuflen\fP is the maximum amount of data you can get in that
+buffer. The variable \fBn\fP points to will receive the number of received
+bytes.
+
+To establish the connection, set \fBCURLOPT_CONNECT_ONLY\fP option before
+calling \fIcurl_easy_perform(3)\fP. Note that \fIcurl_easy_recv(3)\fP does not
+work on connections that were created without this option.
+
+You must ensure that the socket has data to read before calling
+\fIcurl_easy_recv(3)\fP, otherwise the call will return \fBCURLE_AGAIN\fP -
+the socket is used in non-blocking mode internally. Use
+\fIcurl_easy_getinfo(3)\fP with \fBCURLINFO_LASTSOCKET\fP to obtain the
+socket; use your operating system facilities like \fIselect(2)\fP to check if
+it has any data you can read.
+.SH AVAILABILITY
+Added in 7.18.2.
+.SH RETURN VALUE
+On success, returns \fBCURLE_OK\fP, stores the received data into
+\fBbuffer\fP, and the number of bytes it actually read into \fB*n\fP.
+
+On failure, returns the appropriate error code.
+
+If there is no data to read, the function returns \fBCURLE_AGAIN\fP. Use
+your operating system facilities to wait until the data is ready, and retry.
+.SH EXAMPLE
+See \fBsendrecv.c\fP in \fBdocs/examples\fP directory for usage example.
+.SH "SEE ALSO"
+.BR curl_easy_setopt "(3), " curl_easy_perform "(3), "
+.BR curl_easy_getinfo "(3), "
+.BR curl_easy_send "(3) "
diff --git a/docs/libcurl/curl_easy_reset.3 b/docs/libcurl/curl_easy_reset.3
new file mode 100644
index 000000000..592d3ed5c
--- /dev/null
+++ b/docs/libcurl/curl_easy_reset.3
@@ -0,0 +1,43 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_easy_reset 3 "31 July 2004" "libcurl 7.12.1" "libcurl Manual"
+.SH NAME
+curl_easy_reset - reset all options of a libcurl session handle
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+
+.BI "void curl_easy_reset(CURL *"handle ");"
+
+.SH DESCRIPTION
+Re-initializes all options previously set on a specified CURL handle to the
+default values. This puts back the handle to the same state as it was in when
+it was just created with \fIcurl_easy_init(3)\fP.
+
+It does not change the following information kept in the handle: live
+connections, the Session ID cache, the DNS cache, the cookies and shares.
+.SH AVAILABILITY
+This function was added in libcurl 7.12.1
+.SH RETURN VALUE
+Nothing
+.SH "SEE ALSO"
+.BR curl_easy_init "(3)," curl_easy_cleanup "(3)," curl_easy_setopt "(3)
+
diff --git a/docs/libcurl/curl_easy_send.3 b/docs/libcurl/curl_easy_send.3
new file mode 100644
index 000000000..17c4c1f54
--- /dev/null
+++ b/docs/libcurl/curl_easy_send.3
@@ -0,0 +1,64 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH curl_easy_send 3 "29 April 2008" "libcurl 7.18.2" "libcurl Manual"
+.SH NAME
+curl_easy_send - sends raw data over an "easy" connection
+.SH SYNOPSIS
+.B #include <curl/easy.h>
+.sp
+.BI "CURLcode curl_easy_send( CURL *" curl ", const void *" buffer ","
+.BI " size_t " buflen ", size_t *" n ");"
+.ad
+.SH DESCRIPTION
+This function sends arbitrary data over the established connection. You may
+use it together with \fIcurl_easy_recv(3)\fP to implement custom protocols
+using libcurl. This functionality can be particularly useful if you use
+proxies and/or SSL encryption: libcurl will take care of proxy negotiation and
+connection set-up.
+
+\fBbuffer\fP is a pointer to the data of length \fBbuflen\fP that you want sent.
+The variable \fBn\fP points to will receive the number of sent bytes.
+
+To establish the connection, set \fBCURLOPT_CONNECT_ONLY\fP option before
+calling \fIcurl_easy_perform(3)\fP. Note that \fIcurl_easy_send(3)\fP will not
+work on connections that were created without this option.
+
+You must ensure that the socket is writable before calling
+\fIcurl_easy_send(3)\fP, otherwise the call will return \fBCURLE_AGAIN\fP -
+the socket is used in non-blocking mode internally. Use
+\fIcurl_easy_getinfo(3)\fP with \fBCURLINFO_LASTSOCKET\fP to obtain the
+socket; use your operating system facilities like \fIselect(2)\fP to check if
+it can be written to.
+.SH AVAILABILITY
+Added in 7.18.2.
+.SH RETURN VALUE
+On success, returns \fBCURLE_OK\fP and stores the number of bytes actually
+sent into \fB*n\fP. Note that this may very well be less than the amount you
+wanted to send.
+
+On failure, returns the appropriate error code.
+.SH EXAMPLE
+See \fBsendrecv.c\fP in \fBdocs/examples\fP directory for usage example.
+.SH "SEE ALSO"
+.BR curl_easy_setopt "(3), " curl_easy_perform "(3), " curl_easy_getinfo "(3), "
+.BR curl_easy_recv "(3) "
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
new file mode 100644
index 000000000..9d712a45e
--- /dev/null
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -0,0 +1,2527 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH curl_easy_setopt 3 "1 Jan 2010" "libcurl 7.20.0" "libcurl Manual"
+.SH NAME
+curl_easy_setopt \- set options for a curl easy handle
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
+.SH DESCRIPTION
+curl_easy_setopt() is used to tell libcurl how to behave. By using the
+appropriate options to \fIcurl_easy_setopt\fP, you can change libcurl's
+behavior. All options are set with the \fIoption\fP followed by a
+\fIparameter\fP. That parameter can be a \fBlong\fP, a \fBfunction pointer\fP,
+an \fBobject pointer\fP or a \fBcurl_off_t\fP, depending on what the specific
+option expects. Read this manual carefully as bad input values may cause
+libcurl to behave badly! You can only set one option in each function call. A
+typical application uses many curl_easy_setopt() calls in the setup phase.
+
+Options set with this function call are valid for all forthcoming transfers
+performed using this \fIhandle\fP. The options are not in any way reset
+between transfers, so if you want subsequent transfers with different options,
+you must change them between the transfers. You can optionally reset all
+options back to internal default with \fIcurl_easy_reset(3)\fP.
+
+Strings passed to libcurl as 'char *' arguments, are copied by the library;
+thus the string storage associated to the pointer argument may be overwritten
+after curl_easy_setopt() returns. Exceptions to this rule are described in
+the option details below.
+
+Before version 7.17.0, strings were not copied. Instead the user was forced
+keep them available until libcurl no longer needed them.
+
+The \fIhandle\fP is the return code from a \fIcurl_easy_init(3)\fP or
+\fIcurl_easy_duphandle(3)\fP call.
+.SH BEHAVIOR OPTIONS
+.IP CURLOPT_VERBOSE
+Set the parameter to 1 to get the library to display a lot of verbose
+information about its operations. Very useful for libcurl and/or protocol
+debugging and understanding. The verbose information will be sent to stderr,
+or the stream set with \fICURLOPT_STDERR\fP.
+
+You hardly ever want this set in production use, you will almost always want
+this when you debug/report problems. Another neat option for debugging is the
+\fICURLOPT_DEBUGFUNCTION\fP.
+.IP CURLOPT_HEADER
+A parameter set to 1 tells the library to include the header in the body
+output. This is only relevant for protocols that actually have headers
+preceding the data (like HTTP).
+.IP CURLOPT_NOPROGRESS
+Pass a long. If set to 1, it tells the library to shut off the progress meter
+completely. It will also prevent the \fICURLOPT_PROGRESSFUNCTION\fP from
+getting called.
+
+Future versions of libcurl are likely to not have any built-in progress meter
+at all.
+.IP CURLOPT_NOSIGNAL
+Pass a long. If it is 1, libcurl will not use any functions that
+install signal handlers or any functions that cause signals to be sent to the
+process. This option is mainly here to allow multi-threaded unix applications
+to still set/use all timeout options etc, without risking getting signals.
+(Added in 7.10)
+
+If this option is set and libcurl has been built with the standard name
+resolver, timeouts will not occur while the name resolve takes place.
+Consider building libcurl with c-ares support to enable asynchronous DNS
+lookups, which enables nice timeouts for name resolves without signals.
+
+Setting \fICURLOPT_NOSIGNAL\fP to 1 makes libcurl NOT ask the system to ignore
+SIGPIPE signals, which otherwise are sent by the system when trying to send
+data to a socket which is closed in the other end. libcurl makes an effort to
+never cause such SIGPIPEs to trigger, but some operating systems have no way
+to avoid them and even on those that have there are some corner cases when
+they may still happen, contrary to our desire. In addition, using
+\fICURLAUTH_NTLM_WB\fP authentication could cause a SIGCHLD signal to be
+raised.
+.IP CURLOPT_WILDCARDMATCH
+Set this option to 1 if you want to transfer multiple files according to a
+file name pattern. The pattern can be specified as part of the
+\fICURLOPT_URL\fP option, using an fnmatch-like pattern (Shell Pattern
+Matching) in the last part of URL (file name).
+
+By default, libcurl uses its internal wildcard matching implementation. You
+can provide your own matching function by the \fICURLOPT_FNMATCH_FUNCTION\fP
+option.
+
+This feature is only supported by the FTP download for now.
+
+A brief introduction of its syntax follows:
+.RS
+.IP "* - ASTERISK"
+\&ftp://example.com/some/path/\fB*.txt\fP (for all txt's from the root
+directory)
+.RE
+.RS
+.IP "? - QUESTION MARK"
+Question mark matches any (exactly one) character.
+
+\&ftp://example.com/some/path/\fBphoto?.jpeg\fP
+.RE
+.RS
+.IP "[ - BRACKET EXPRESSION"
+The left bracket opens a bracket expression. The question mark and asterisk have
+no special meaning in a bracket expression. Each bracket expression ends by the
+right bracket and matches exactly one character. Some examples follow:
+
+\fB[a-zA-Z0\-9]\fP or \fB[f\-gF\-G]\fP \- character interval
+
+\fB[abc]\fP - character enumeration
+
+\fB[^abc]\fP or \fB[!abc]\fP - negation
+
+\fB[[:\fP\fIname\fP\fB:]]\fP class expression. Supported classes are
+\fBalnum\fP,\fBlower\fP, \fBspace\fP, \fBalpha\fP, \fBdigit\fP, \fBprint\fP,
+\fBupper\fP, \fBblank\fP, \fBgraph\fP, \fBxdigit\fP.
+
+\fB[][-!^]\fP - special case \- matches only '\-', ']', '[', '!' or '^'. These
+characters have no special purpose.
+
+\fB[\\[\\]\\\\]\fP - escape syntax. Matches '[', ']' or '\\'.
+
+Using the rules above, a file name pattern can be constructed:
+
+\&ftp://example.com/some/path/\fB[a-z[:upper:]\\\\].jpeg\fP
+.RE
+.PP
+(This was added in 7.21.0)
+.SH CALLBACK OPTIONS
+.IP CURLOPT_WRITEFUNCTION
+Pass a pointer to a function that matches the following prototype:
+\fBsize_t function( char *ptr, size_t size, size_t nmemb, void *userdata);\fP
+This function gets called by libcurl as soon as there is data received that
+needs to be saved. The size of the data pointed to by \fIptr\fP is \fIsize\fP
+multiplied with \fInmemb\fP, it will not be zero terminated. Return the number
+of bytes actually taken care of. If that amount differs from the amount passed
+to your function, it'll signal an error to the library. This will abort the
+transfer and return \fICURLE_WRITE_ERROR\fP.
+
+From 7.18.0, the function can return CURL_WRITEFUNC_PAUSE which then will
+cause writing to this connection to become paused. See
+\fIcurl_easy_pause(3)\fP for further details.
+
+This function may be called with zero bytes data if the transferred file is
+empty.
+
+Set this option to NULL to get the internal default function. The internal
+default function will write the data to the FILE * given with
+\fICURLOPT_WRITEDATA\fP.
+
+Set the \fIuserdata\fP argument with the \fICURLOPT_WRITEDATA\fP option.
+
+The callback function will be passed as much data as possible in all invokes,
+but you cannot possibly make any assumptions. It may be one byte, it may be
+thousands. The maximum amount of body data that can be passed to the write
+callback is defined in the curl.h header file: CURL_MAX_WRITE_SIZE (the usual
+default is 16K). If you however have \fICURLOPT_HEADER\fP set, which sends
+header data to the write callback, you can get up to
+\fICURL_MAX_HTTP_HEADER\fP bytes of header data passed into it. This usually
+means 100K.
+.IP CURLOPT_WRITEDATA
+Data pointer to pass to the file write function. If you use the
+\fICURLOPT_WRITEFUNCTION\fP option, this is the pointer you'll get as
+input. If you don't use a callback, you must pass a 'FILE *' as libcurl will
+pass this to fwrite() when writing data.
+
+The internal \fICURLOPT_WRITEFUNCTION\fP will write the data to the FILE *
+given with this option, or to stdout if this option hasn't been set.
+
+If you're using libcurl as a win32 DLL, you \fBMUST\fP use the
+\fICURLOPT_WRITEFUNCTION\fP if you set this option or you will experience
+crashes.
+
+This option is also known with the older name \fICURLOPT_FILE\fP, the name
+\fICURLOPT_WRITEDATA\fP was introduced in 7.9.7.
+.IP CURLOPT_READFUNCTION
+Pass a pointer to a function that matches the following prototype:
+\fBsize_t function( void *ptr, size_t size, size_t nmemb, void *userdata);\fP
+This function gets called by libcurl as soon as it needs to read data in order
+to send it to the peer. The data area pointed at by the pointer \fIptr\fP may
+be filled with at most \fIsize\fP multiplied with \fInmemb\fP number of
+bytes. Your function must return the actual number of bytes that you stored in
+that memory area. Returning 0 will signal end-of-file to the library and cause
+it to stop the current transfer.
+
+If you stop the current transfer by returning 0 "pre-maturely" (i.e before the
+server expected it, like when you've said you will upload N bytes and you
+upload less than N bytes), you may experience that the server "hangs" waiting
+for the rest of the data that won't come.
+
+The read callback may return \fICURL_READFUNC_ABORT\fP to stop the current
+operation immediately, resulting in a \fICURLE_ABORTED_BY_CALLBACK\fP error
+code from the transfer (Added in 7.12.1)
+
+From 7.18.0, the function can return CURL_READFUNC_PAUSE which then will cause
+reading from this connection to become paused. See \fIcurl_easy_pause(3)\fP
+for further details.
+
+\fBBugs\fP: when doing TFTP uploads, you must return the exact amount of data
+that the callback wants, or it will be considered the final packet by the
+server end and the transfer will end there.
+
+If you set this callback pointer to NULL, or don't set it at all, the default
+internal read function will be used. It is doing an fread() on the FILE *
+userdata set with \fICURLOPT_READDATA\fP.
+.IP CURLOPT_READDATA
+Data pointer to pass to the file read function. If you use the
+\fICURLOPT_READFUNCTION\fP option, this is the pointer you'll get as input. If
+you don't specify a read callback but instead rely on the default internal
+read function, this data must be a valid readable FILE *.
+
+If you're using libcurl as a win32 DLL, you MUST use a
+\fICURLOPT_READFUNCTION\fP if you set this option.
+
+This option was also known by the older name \fICURLOPT_INFILE\fP, the name
+\fICURLOPT_READDATA\fP was introduced in 7.9.7.
+.IP CURLOPT_IOCTLFUNCTION
+Pass a pointer to a function that matches the following prototype:
+\fBcurlioerr function(CURL *handle, int cmd, void *clientp);\fP. This function
+gets called by libcurl when something special I/O-related needs to be done
+that the library can't do by itself. For now, rewinding the read data stream
+is the only action it can request. The rewinding of the read data stream may
+be necessary when doing a HTTP PUT or POST with a multi-pass authentication
+method. (Option added in 7.12.3).
+
+Use \fICURLOPT_SEEKFUNCTION\fP instead to provide seeking!
+.IP CURLOPT_IOCTLDATA
+Pass a pointer that will be untouched by libcurl and passed as the 3rd
+argument in the ioctl callback set with \fICURLOPT_IOCTLFUNCTION\fP. (Option
+added in 7.12.3)
+.IP CURLOPT_SEEKFUNCTION
+Pass a pointer to a function that matches the following prototype: \fBint
+function(void *instream, curl_off_t offset, int origin);\fP This function gets
+called by libcurl to seek to a certain position in the input stream and can be
+used to fast forward a file in a resumed upload (instead of reading all
+uploaded bytes with the normal read function/callback). It is also called to
+rewind a stream when doing a HTTP PUT or POST with a multi-pass authentication
+method. The function shall work like "fseek" or "lseek" and accepted SEEK_SET,
+SEEK_CUR and SEEK_END as argument for origin, although (in 7.18.0) libcurl
+only passes SEEK_SET. The callback must return 0 (CURL_SEEKFUNC_OK) on
+success, 1 (CURL_SEEKFUNC_FAIL) to cause the upload operation to fail or 2
+(CURL_SEEKFUNC_CANTSEEK) to indicate that while the seek failed, libcurl is
+free to work around the problem if possible. The latter can sometimes be done
+by instead reading from the input or similar.
+
+If you forward the input arguments directly to "fseek" or "lseek", note that
+the data type for \fIoffset\fP is not the same as defined for curl_off_t on
+many systems! (Option added in 7.18.0)
+.IP CURLOPT_SEEKDATA
+Data pointer to pass to the file seek function. If you use the
+\fICURLOPT_SEEKFUNCTION\fP option, this is the pointer you'll get as input. If
+you don't specify a seek callback, NULL is passed. (Option added in 7.18.0)
+.IP CURLOPT_SOCKOPTFUNCTION
+Pass a pointer to a function that matches the following prototype: \fBint
+function(void *clientp, curl_socket_t curlfd, curlsocktype purpose);\fP. This
+function gets called by libcurl after the socket() call but before the
+connect() call. The callback's \fIpurpose\fP argument identifies the exact
+purpose for this particular socket:
+
+\fICURLSOCKTYPE_IPCXN\fP for actively created connections or since 7.28.0
+\fICURLSOCKTYPE_ACCEPT\fP for FTP when the connection was setup with PORT/EPSV
+(in earlier versions these sockets weren't passed to this callback).
+
+Future versions of libcurl may support more purposes. It passes the newly
+created socket descriptor so additional setsockopt() calls can be done at the
+user's discretion. Return 0 (zero) from the callback on success. Return 1
+from the callback function to signal an unrecoverable error to the library and
+it will close the socket and return \fICURLE_COULDNT_CONNECT\fP. (Option
+added in 7.16.0)
+
+Added in 7.21.5, the callback function may return
+\fICURL_SOCKOPT_ALREADY_CONNECTED\fP, which tells libcurl that the socket is
+in fact already connected and then libcurl will not attempt to connect it.
+.IP CURLOPT_SOCKOPTDATA
+Pass a pointer that will be untouched by libcurl and passed as the first
+argument in the sockopt callback set with \fICURLOPT_SOCKOPTFUNCTION\fP.
+(Option added in 7.16.0)
+.IP CURLOPT_OPENSOCKETFUNCTION
+Pass a pointer to a function that matches the following prototype:
+\fBcurl_socket_t function(void *clientp, curlsocktype purpose, struct
+curl_sockaddr *address);\fP. This function gets called by libcurl instead of
+the \fIsocket(2)\fP call. The callback's \fIpurpose\fP argument identifies the
+exact purpose for this particular socket: \fICURLSOCKTYPE_IPCXN\fP is for IP
+based connections. Future versions of libcurl may support more purposes. It
+passes the resolved peer address as a \fIaddress\fP argument so the callback
+can modify the address or refuse to connect at all. The callback function
+should return the socket or \fICURL_SOCKET_BAD\fP in case no connection could
+be established or another error was detected. Any additional
+\fIsetsockopt(2)\fP calls can be done on the socket at the user's discretion.
+\fICURL_SOCKET_BAD\fP return value from the callback function will signal an
+unrecoverable error to the library and it will return
+\fICURLE_COULDNT_CONNECT\fP. This return code can be used for IP address
+blacklisting. The default behavior is:
+.nf
+ return socket(addr->family, addr->socktype, addr->protocol);
+.fi
+(Option added in 7.17.1.)
+.IP CURLOPT_OPENSOCKETDATA
+Pass a pointer that will be untouched by libcurl and passed as the first
+argument in the opensocket callback set with \fICURLOPT_OPENSOCKETFUNCTION\fP.
+(Option added in 7.17.1.)
+.IP CURLOPT_CLOSESOCKETFUNCTION
+Pass a pointer to a function that matches the following prototype: \fBint
+function(void *clientp, curl_socket_t item);\fP. This function gets called by
+libcurl instead of the \fIclose(3)\fP or \fIclosesocket(3)\fP call when
+sockets are closed (not for any other file descriptors). This is pretty much
+the reverse to the \fICURLOPT_OPENSOCKETFUNCTION\fP option. Return 0 to signal
+success and 1 if there was an error. (Option added in 7.21.7)
+.IP CURLOPT_CLOSESOCKETDATA
+Pass a pointer that will be untouched by libcurl and passed as the first
+argument in the closesocket callback set with
+\fICURLOPT_CLOSESOCKETFUNCTION\fP. (Option added in 7.21.7)
+.IP CURLOPT_PROGRESSFUNCTION
+Pass a pointer to a function that matches the following prototype: \fBint
+function(void *clientp, double dltotal, double dlnow, double ultotal, double
+ulnow); \fP. This function gets called by libcurl instead of its internal
+equivalent with a frequent interval during operation (roughly once per second
+or sooner) no matter if data is being transferred or not. Unknown/unused
+argument values passed to the callback will be set to zero (like if you only
+download data, the upload size will remain 0). Returning a non-zero value from
+this callback will cause libcurl to abort the transfer and return
+\fICURLE_ABORTED_BY_CALLBACK\fP.
+
+If you transfer data with the multi interface, this function will not be
+called during periods of idleness unless you call the appropriate libcurl
+function that performs transfers.
+
+\fICURLOPT_NOPROGRESS\fP must be set to 0 to make this function actually
+get called.
+.IP CURLOPT_PROGRESSDATA
+Pass a pointer that will be untouched by libcurl and passed as the first
+argument in the progress callback set with \fICURLOPT_PROGRESSFUNCTION\fP.
+.IP CURLOPT_HEADERFUNCTION
+Pass a pointer to a function that matches the following prototype:
+\fBsize_t function( void *ptr, size_t size, size_t nmemb, void
+*userdata);\fP. This function gets called by libcurl as soon as it has
+received header data. The header callback will be called once for each header
+and only complete header lines are passed on to the callback. Parsing headers
+is very easy using this. The size of the data pointed to by \fIptr\fP is
+\fIsize\fP multiplied with \fInmemb\fP. Do not assume that the header line is
+zero terminated! The pointer named \fIuserdata\fP is the one you set with the
+\fICURLOPT_WRITEHEADER\fP option. The callback function must return the number
+of bytes actually taken care of. If that amount differs from the amount passed
+to your function, it'll signal an error to the library. This will abort the
+transfer and return \fICURL_WRITE_ERROR\fP.
+
+A complete HTTP header that is passed to this function can be up to
+\fICURL_MAX_HTTP_HEADER\fP (100K) bytes.
+
+If this option is not set, or if it is set to NULL, but
+\fICURLOPT_HEADERDATA\fP (\fICURLOPT_WRITEHEADER\fP) is set to anything but
+NULL, the function used to accept response data will be used instead. That is,
+it will be the function specified with \fICURLOPT_WRITEFUNCTION\fP, or if it
+is not specified or NULL - the default, stream-writing function.
+
+It's important to note that the callback will be invoked for the headers of
+all responses received after initiating a request and not just the final
+response. This includes all responses which occur during authentication
+negotiation. If you need to operate on only the headers from the final
+response, you will need to collect headers in the callback yourself and use
+HTTP status lines, for example, to delimit response boundaries.
+
+When a server sends a chunked encoded transfer, it may contain a trailer. That
+trailer is identical to a HTTP header and if such a trailer is received it is
+passed to the application using this callback as well. There are several ways
+to detect it being a trailer and not an ordinary header: 1) it comes after the
+response-body. 2) it comes after the final header line (CR LF) 3) a Trailer:
+header among the regular response-headers mention what header(s) to expect in
+the trailer.
+
+For non-HTTP protocols like FTP, POP3, IMAP and SMTP this function will get
+called with the server responses to the commands that libcurl sends.
+.IP CURLOPT_WRITEHEADER
+(This option is also known as \fBCURLOPT_HEADERDATA\fP) Pass a pointer to be
+used to write the header part of the received data to. If you don't use
+\fICURLOPT_WRITEFUNCTION\fP or \fICURLOPT_HEADERFUNCTION\fP to take care of
+the writing, this must be a valid FILE * as the internal default will then be
+a plain fwrite(). See also the \fICURLOPT_HEADERFUNCTION\fP option above on
+how to set a custom get-all-headers callback.
+.IP CURLOPT_DEBUGFUNCTION
+Pass a pointer to a function that matches the following prototype: \fBint
+curl_debug_callback (CURL *, curl_infotype, char *, size_t, void *);\fP
+\fICURLOPT_DEBUGFUNCTION\fP replaces the standard debug function used when
+\fICURLOPT_VERBOSE \fP is in effect. This callback receives debug information,
+as specified with the \fBcurl_infotype\fP argument. This function must return
+0. The data pointed to by the char * passed to this function WILL NOT be zero
+terminated, but will be exactly of the size as told by the size_t argument.
+
+Available curl_infotype values:
+.RS
+.IP CURLINFO_TEXT
+The data is informational text.
+.IP CURLINFO_HEADER_IN
+The data is header (or header-like) data received from the peer.
+.IP CURLINFO_HEADER_OUT
+The data is header (or header-like) data sent to the peer.
+.IP CURLINFO_DATA_IN
+The data is protocol data received from the peer.
+.IP CURLINFO_DATA_OUT
+The data is protocol data sent to the peer.
+.RE
+.IP CURLOPT_DEBUGDATA
+Pass a pointer to whatever you want passed in to your
+\fICURLOPT_DEBUGFUNCTION\fP in the last void * argument. This pointer is not
+used by libcurl, it is only passed to the callback.
+.IP CURLOPT_SSL_CTX_FUNCTION
+This option does only function for libcurl powered by OpenSSL. If libcurl was
+built against another SSL library, this functionality is absent.
+
+Pass a pointer to a function that matches the following prototype:
+\fBCURLcode sslctxfun(CURL *curl, void *sslctx, void *parm);\fP This function
+gets called by libcurl just before the initialization of a SSL connection
+after having processed all other SSL related options to give a last chance to
+an application to modify the behaviour of openssl's ssl initialization. The
+\fIsslctx\fP parameter is actually a pointer to an openssl \fISSL_CTX\fP. If
+an error is returned no attempt to establish a connection is made and the
+perform operation will return the error code from this callback function. Set
+the \fIparm\fP argument with the \fICURLOPT_SSL_CTX_DATA\fP option. This
+option was introduced in 7.11.0.
+
+This function will get called on all new connections made to a server, during
+the SSL negotiation. The SSL_CTX pointer will be a new one every time.
+
+To use this properly, a non-trivial amount of knowledge of the openssl
+libraries is necessary. For example, using this function allows you to use
+openssl callbacks to add additional validation code for certificates, and even
+to change the actual URI of a HTTPS request (example used in the lib509 test
+case). See also the example section for a replacement of the key, certificate
+and trust file settings.
+.IP CURLOPT_SSL_CTX_DATA
+Data pointer to pass to the ssl context callback set by the option
+\fICURLOPT_SSL_CTX_FUNCTION\fP, this is the pointer you'll get as third
+parameter, otherwise \fBNULL\fP. (Added in 7.11.0)
+.IP CURLOPT_CONV_TO_NETWORK_FUNCTION
+.IP CURLOPT_CONV_FROM_NETWORK_FUNCTION
+.IP CURLOPT_CONV_FROM_UTF8_FUNCTION
+Pass a pointer to a function that matches the following prototype:
+\fBCURLcode function(char *ptr, size_t length);\fP
+
+These three options apply to non-ASCII platforms only. They are available
+only if \fBCURL_DOES_CONVERSIONS\fP was defined when libcurl was built. When
+this is the case, \fIcurl_version_info(3)\fP will return the CURL_VERSION_CONV
+feature bit set.
+
+The data to be converted is in a buffer pointed to by the ptr parameter. The
+amount of data to convert is indicated by the length parameter. The converted
+data overlays the input data in the buffer pointed to by the ptr parameter.
+CURLE_OK should be returned upon successful conversion. A CURLcode return
+value defined by curl.h, such as CURLE_CONV_FAILED, should be returned if an
+error was encountered.
+
+\fBCURLOPT_CONV_TO_NETWORK_FUNCTION\fP and
+\fBCURLOPT_CONV_FROM_NETWORK_FUNCTION\fP convert between the host encoding and
+the network encoding. They are used when commands or ASCII data are
+sent/received over the network.
+
+\fBCURLOPT_CONV_FROM_UTF8_FUNCTION\fP is called to convert from UTF8 into the
+host encoding. It is required only for SSL processing.
+
+If you set a callback pointer to NULL, or don't set it at all, the built-in
+libcurl iconv functions will be used. If HAVE_ICONV was not defined when
+libcurl was built, and no callback has been established, conversion will
+return the CURLE_CONV_REQD error code.
+
+If HAVE_ICONV is defined, CURL_ICONV_CODESET_OF_HOST must also be defined.
+For example:
+
+ \&#define CURL_ICONV_CODESET_OF_HOST "IBM-1047"
+
+The iconv code in libcurl will default the network and UTF8 codeset names as
+follows:
+
+ \&#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
+
+ \&#define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8"
+
+You will need to override these definitions if they are different on your
+system.
+.IP CURLOPT_INTERLEAVEFUNCTION
+Pass a pointer to a function that matches the following prototype:
+\fBsize_t function( void *ptr, size_t size, size_t nmemb, void
+*userdata)\fP. This function gets called by libcurl as soon as it has received
+interleaved RTP data. This function gets called for each $ block and therefore
+contains exactly one upper-layer protocol unit (e.g. one RTP packet). Curl
+writes the interleaved header as well as the included data for each call. The
+first byte is always an ASCII dollar sign. The dollar sign is followed by a
+one byte channel identifier and then a 2 byte integer length in network byte
+order. See \fIRFC2326 Section 10.12\fP for more information on how RTP
+interleaving behaves. If unset or set to NULL, curl will use the default write
+function.
+
+Interleaved RTP poses some challenges for the client application. Since the
+stream data is sharing the RTSP control connection, it is critical to service
+the RTP in a timely fashion. If the RTP data is not handled quickly,
+subsequent response processing may become unreasonably delayed and the
+connection may close. The application may use \fICURL_RTSPREQ_RECEIVE\fP to
+service RTP data when no requests are desired. If the application makes a
+request, (e.g. \fICURL_RTSPREQ_PAUSE\fP) then the response handler will
+process any pending RTP data before marking the request as finished. (Added
+in 7.20.0)
+.IP CURLOPT_INTERLEAVEDATA
+This is the userdata pointer that will be passed to
+\fICURLOPT_INTERLEAVEFUNCTION\fP when interleaved RTP data is received. (Added
+in 7.20.0)
+.IP CURLOPT_CHUNK_BGN_FUNCTION
+Pass a pointer to a function that matches the following prototype:
+\fBlong function (const void *transfer_info, void *ptr, int remains)\fP. This
+function gets called by libcurl before a part of the stream is going to be
+transferred (if the transfer supports chunks).
+
+This callback makes sense only when using the \fICURLOPT_WILDCARDMATCH\fP
+option for now.
+
+The target of transfer_info parameter is a "feature depended" structure. For
+the FTP wildcard download, the target is curl_fileinfo structure (see
+\fIcurl/curl.h\fP). The parameter ptr is a pointer given by
+\fICURLOPT_CHUNK_DATA\fP. The parameter remains contains number of chunks
+remaining per the transfer. If the feature is not available, the parameter has
+zero value.
+
+Return \fICURL_CHUNK_BGN_FUNC_OK\fP if everything is fine,
+\fICURL_CHUNK_BGN_FUNC_SKIP\fP if you want to skip the concrete chunk or
+\fICURL_CHUNK_BGN_FUNC_FAIL\fP to tell libcurl to stop if some error occurred.
+(This was added in 7.21.0)
+.IP CURLOPT_CHUNK_END_FUNCTION
+Pass a pointer to a function that matches the following prototype:
+\fBlong function(void *ptr)\fP. This function gets called by libcurl as soon
+as a part of the stream has been transferred (or skipped).
+
+Return \fICURL_CHUNK_END_FUNC_OK\fP if everything is fine or
+\fBCURL_CHUNK_END_FUNC_FAIL\fP to tell the lib to stop if some error occurred.
+(This was added in 7.21.0)
+.IP CURLOPT_CHUNK_DATA
+Pass a pointer that will be untouched by libcurl and passed as the ptr
+argument to the \fICURL_CHUNK_BGN_FUNTION\fP and \fICURL_CHUNK_END_FUNTION\fP.
+(This was added in 7.21.0)
+.IP CURLOPT_FNMATCH_FUNCTION
+Pass a pointer to a function that matches the following prototype: \fBint
+function(void *ptr, const char *pattern, const char *string)\fP prototype (see
+\fIcurl/curl.h\fP). It is used internally for the wildcard matching feature.
+
+Return \fICURL_FNMATCHFUNC_MATCH\fP if pattern matches the string,
+\fICURL_FNMATCHFUNC_NOMATCH\fP if not or \fICURL_FNMATCHFUNC_FAIL\fP if an
+error occurred. (This was added in 7.21.0)
+.IP CURLOPT_FNMATCH_DATA
+Pass a pointer that will be untouched by libcurl and passed as the ptr argument
+to the \fICURL_FNMATCH_FUNCTION\fP. (This was added in 7.21.0)
+.SH ERROR OPTIONS
+.IP CURLOPT_ERRORBUFFER
+Pass a char * to a buffer that the libcurl may store human readable error
+messages in. This may be more helpful than just the return code from
+\fIcurl_easy_perform\fP. The buffer must be at least CURL_ERROR_SIZE big.
+Although this argument is a 'char *', it does not describe an input string.
+Therefore the (probably undefined) contents of the buffer is NOT copied by the
+library. You must keep the associated storage available until libcurl no
+longer needs it. Failing to do so will cause very odd behavior or even
+crashes. libcurl will need it until you call \fIcurl_easy_cleanup(3)\fP or you
+set the same option again to use a different pointer.
+
+Use \fICURLOPT_VERBOSE\fP and \fICURLOPT_DEBUGFUNCTION\fP to better
+debug/trace why errors happen.
+
+If the library does not return an error, the buffer may not have been
+touched. Do not rely on the contents in those cases.
+
+.IP CURLOPT_STDERR
+Pass a FILE * as parameter. Tell libcurl to use this stream instead of stderr
+when showing the progress meter and displaying \fICURLOPT_VERBOSE\fP data.
+.IP CURLOPT_FAILONERROR
+A parameter set to 1 tells the library to fail silently if the HTTP code
+returned is equal to or larger than 400. The default action would be to return
+the page normally, ignoring that code.
+
+This method is not fail-safe and there are occasions where non-successful
+response codes will slip through, especially when authentication is involved
+(response codes 401 and 407).
+
+You might get some amounts of headers transferred before this situation is
+detected, like when a "100-continue" is received as a response to a
+POST/PUT and a 401 or 407 is received immediately afterwards.
+.SH NETWORK OPTIONS
+.IP CURLOPT_URL
+Pass in a pointer to the actual URL to deal with. The parameter should be a
+char * to a zero terminated string which must be URL-encoded in the following
+format:
+
+scheme://host:port/path
+
+For a greater explanation of the format please see RFC3986.
+
+If the given URL lacks the scheme, or protocol, part ("http://" or "ftp://"
+etc), libcurl will attempt to resolve which protocol to use based on the
+given host mame. If the protocol is not supported, libcurl will return
+(\fICURLE_UNSUPPORTED_PROTOCOL\fP) when you call \fIcurl_easy_perform(3)\fP
+or \fIcurl_multi_perform(3)\fP. Use \fIcurl_version_info(3)\fP for detailed
+information on which protocols are supported.
+
+The host part of the URL contains the address of the server that you want to
+connect to. This can be the fully qualified domain name of the server, the
+local network name of the machine on your network or the IP address of the
+server or machine represented by either an IPv4 or IPv6 address. For example:
+
+http://www.example.com/
+
+http://hostname/
+
+http://192.168.0.1/
+
+http://[2001:1890:1112:1::20]/
+
+It is also possible to specify the user name and password as part of the
+host, for some protocols, when connecting to servers that require
+authentication.
+
+For example the following types of authentication support this:
+
+http://user:password@www.example.com
+
+ftp://user:password@ftp.example.com
+
+pop3://user:password@mail.example.com
+
+The port is optional and when not specified libcurl will use the default port
+based on the determined or specified protocol: 80 for HTTP, 21 for FTP and 25
+for SMTP, etc. The following examples show how to specify the port:
+
+http://www.example.com:8080/ - This will connect to a web server using port
+8080 rather than 80.
+
+smtp://mail.example.com:587/ - This will connect to a SMTP server on the
+alternative mail port.
+
+The path part of the URL is protocol specific and whilst some examples are
+given below this list is not conclusive:
+
+.B HTTP
+
+The path part of a HTTP request specifies the file to retrieve and from what
+directory. If the directory is not specified then the web server's root
+directory is used. If the file is omitted then the default document will be
+retrieved for either the directory specified or the root directory. The
+exact resource returned for each URL is entirely dependent on the server's
+configuration.
+
+http://www.example.com - This gets the main page from the web server.
+
+http://www.example.com/index.html - This returns the main page by explicitly
+requesting it.
+
+http://www.example.com/contactus/ - This returns the default document from
+the contactus directory.
+
+.B FTP
+
+The path part of an FTP request specifies the file to retrieve and from what
+directory. If the file part is omitted then libcurl downloads the directory
+listing for the directory specified. If the directory is omitted then
+the directory listing for the root / home directory will be returned.
+
+ftp://ftp.example.com - This retrieves the directory listing for the root
+directory.
+
+ftp://ftp.example.com/readme.txt - This downloads the file readme.txt from the
+root directory.
+
+ftp://ftp.example.com/libcurl/readme.txt - This downloads readme.txt from the
+libcurl directory.
+
+ftp://user:password@ftp.example.com/readme.txt - This retrieves the readme.txt
+file from the user's home directory. When a username and password is
+specified, everything that is specified in the path part is relative to the
+user's home directory. To retrieve files from the root directory or a
+directory underneath the root directory then the absolute path must be
+specified by prepending an additional forward slash to the beginning of the
+path.
+
+ftp://user:password@ftp.example.com//readme.txt - This retrieves the readme.txt
+from the root directory when logging in as a specified user.
+
+.B SMTP
+
+The path part of a SMTP request specifies the host name to present during
+communication with the mail server. If the path is omitted then libcurl will
+attempt to resolve the local computer's host name. However, this may not
+return the fully qualified domain name that is required by some mail servers
+and specifying this path allows you to set an alternative name, such as
+your machine's fully qualified domain name, which you might have obtained
+from an external function such as gethostname or getaddrinfo.
+
+smtp://mail.example.com - This connects to the mail server at example.com and
+sends your local computer's host name in the HELO / EHLO command.
+
+smtp://mail.example.com/client.example.com - This will send client.example.com in
+the HELO / EHLO command to the mail server at example.com.
+
+.B POP3
+
+The path part of a POP3 request specifies the mailbox (message) to retrieve.
+If the mailbox is not specified then a list of waiting messages is returned
+instead.
+
+pop3://user:password@mail.example.com - This lists the available messages
+pop3://user:password@mail.example.com/1 - This retrieves the first message
+
+.B SCP
+
+The path part of a SCP request specifies the file to retrieve and from what
+directory. The file part may not be omitted. The file is taken as an absolute
+path from the root directory on the server. To specify a path relative to
+the user's home directory on the server, prepend ~/ to the path portion.
+If the user name is not embedded in the URL, it can be set with the
+\fICURLOPT_USERPWD\fP or \fBCURLOPT_USERNAME\fP option.
+
+scp://user@example.com/etc/issue - This specifies the file /etc/issue
+
+scp://example.com/~/my-file - This specifies the file my-file in the
+user's home directory on the server
+
+.B SFTP
+
+The path part of a SFTP request specifies the file to retrieve and from what
+directory. If the file part is omitted then libcurl downloads the directory
+listing for the directory specified. If the path ends in a / then a directory
+listing is returned instead of a file. If the path is omitted entirely then
+the directory listing for the root / home directory will be returned.
+If the user name is not embedded in the URL, it can be set with the
+\fICURLOPT_USERPWD\fP or \fBCURLOPT_USERNAME\fP option.
+
+sftp://user:password@example.com/etc/issue - This specifies the file
+/etc/issue
+
+sftp://user@example.com/~/my-file - This specifies the file my-file in the
+user's home directory
+
+sftp://ssh.example.com/~/Documents/ - This requests a directory listing
+of the Documents directory under the user's home directory
+
+.B LDAP
+
+The path part of a LDAP request can be used to specify the: Distinguished
+Name, Attributes, Scope, Filter and Extension for a LDAP search. Each field
+is separated by a question mark and when that field is not required an empty
+string with the question mark separator should be included.
+
+ldap://ldap.example.com/o=My%20Organisation - This will perform a LDAP search
+with the DN as My Organisation.
+
+ldap://ldap.example.com/o=My%20Organisation?postalAddress - This will perform
+the same search but will only return postalAddress attributes.
+
+ldap://ldap.example.com/?rootDomainNamingContext - This specifies an empty DN
+and requests information about the rootDomainNamingContext attribute for an
+Active Directory server.
+
+For more information about the individual components of a LDAP URL please
+see RFC4516.
+
+.B NOTES
+
+Starting with version 7.20.0, the fragment part of the URI will not be sent as
+part of the path, which was previously the case.
+
+\fICURLOPT_URL\fP is the only option that \fBmust\fP be set before
+\fIcurl_easy_perform(3)\fP is called.
+
+\fICURLOPT_PROTOCOLS\fP can be used to limit what protocols libcurl will use
+for this transfer, independent of what libcurl has been compiled to
+support. That may be useful if you accept the URL from an external source and
+want to limit the accessibility.
+.IP CURLOPT_PROTOCOLS
+Pass a long that holds a bitmask of CURLPROTO_* defines. If used, this bitmask
+limits what protocols libcurl may use in the transfer. This allows you to have
+a libcurl built to support a wide range of protocols but still limit specific
+transfers to only be allowed to use a subset of them. By default libcurl will
+accept all protocols it supports. See also
+\fICURLOPT_REDIR_PROTOCOLS\fP. (Added in 7.19.4)
+.IP CURLOPT_REDIR_PROTOCOLS
+Pass a long that holds a bitmask of CURLPROTO_* defines. If used, this bitmask
+limits what protocols libcurl may use in a transfer that it follows to in a
+redirect when \fICURLOPT_FOLLOWLOCATION\fP is enabled. This allows you to
+limit specific transfers to only be allowed to use a subset of protocols in
+redirections. By default libcurl will allow all protocols except for FILE and
+SCP. This is a difference compared to pre-7.19.4 versions which
+unconditionally would follow to all protocols supported. (Added in 7.19.4)
+.IP CURLOPT_PROXY
+Set HTTP proxy to use. The parameter should be a char * to a zero terminated
+string holding the host name or dotted IP address. To specify port number in
+this string, append :[port] to the end of the host name. The proxy string may
+be prefixed with [protocol]:// since any such prefix will be ignored. The
+proxy's port number may optionally be specified with the separate option. If
+not specified, libcurl will default to using port 1080 for proxies.
+\fICURLOPT_PROXYPORT\fP.
+
+When you tell the library to use a HTTP proxy, libcurl will transparently
+convert operations to HTTP even if you specify an FTP URL etc. This may have
+an impact on what other features of the library you can use, such as
+\fICURLOPT_QUOTE\fP and similar FTP specifics that don't work unless you
+tunnel through the HTTP proxy. Such tunneling is activated with
+\fICURLOPT_HTTPPROXYTUNNEL\fP.
+
+libcurl respects the environment variables \fBhttp_proxy\fP, \fBftp_proxy\fP,
+\fBall_proxy\fP etc, if any of those are set. The \fICURLOPT_PROXY\fP option
+does however override any possibly set environment variables.
+
+Setting the proxy string to "" (an empty string) will explicitly disable the
+use of a proxy, even if there is an environment variable set for it.
+
+Since 7.14.1, the proxy host string given in environment variables can be
+specified the exact same way as the proxy can be set with \fICURLOPT_PROXY\fP,
+include protocol prefix (http://) and embedded user + password.
+
+Since 7.21.7, the proxy string may be specified with a protocol:// prefix to
+specify alternative proxy protocols. Use socks4://, socks4a://, socks5:// or
+socks5h:// (the last one to enable socks5 and asking the proxy to do the
+resolving, also known as CURLPROXY_SOCKS5_HOSTNAME type) to request the
+specific SOCKS version to be used. No protocol specified, http:// and all
+others will be treated as HTTP proxies.
+.IP CURLOPT_PROXYPORT
+Pass a long with this option to set the proxy port to connect to unless it is
+specified in the proxy string \fICURLOPT_PROXY\fP.
+.IP CURLOPT_PROXYTYPE
+Pass a long with this option to set type of the proxy. Available options for
+this are \fICURLPROXY_HTTP\fP, \fICURLPROXY_HTTP_1_0\fP (added in 7.19.4),
+\fICURLPROXY_SOCKS4\fP (added in 7.10), \fICURLPROXY_SOCKS5\fP,
+\fICURLPROXY_SOCKS4A\fP (added in 7.18.0) and \fICURLPROXY_SOCKS5_HOSTNAME\fP
+(added in 7.18.0). The HTTP type is default. (Added in 7.10)
+
+If you set \fBCURLOPT_PROXYTYPE\fP to \fICURLPROXY_HTTP_1_0\fP, it will only
+affect how libcurl speaks to a proxy when CONNECT is used. The HTTP version
+used for "regular" HTTP requests is instead controlled with
+\fICURLOPT_HTTP_VERSION\fP.
+.IP CURLOPT_NOPROXY
+Pass a pointer to a zero terminated string. The string consists of a comma
+separated list of host names that do not require a proxy to get reached, even
+if one is specified. The only wildcard available is a single * character,
+which matches all hosts, and effectively disables the proxy. Each name in this
+list is matched as either a domain which contains the hostname, or the
+hostname itself. For example, example.com would match example.com,
+example.com:80, and www.example.com, but not www.notanexample.com. (Added in
+7.19.4)
+.IP CURLOPT_HTTPPROXYTUNNEL
+Set the parameter to 1 to make the library tunnel all operations through a
+given HTTP proxy. There is a big difference between using a proxy and to
+tunnel through it. If you don't know what this means, you probably don't want
+this tunneling option.
+.IP CURLOPT_SOCKS5_GSSAPI_SERVICE
+Pass a char * as parameter to a string holding the name of the service. The
+default service name for a SOCKS5 server is rcmd/server-fqdn. This option
+allows you to change it. (Added in 7.19.4)
+.IP CURLOPT_SOCKS5_GSSAPI_NEC
+Pass a long set to 1 to enable or 0 to disable. As part of the gssapi
+negotiation a protection mode is negotiated. The RFC1961 says in section
+4.3/4.4 it should be protected, but the NEC reference implementation does not.
+If enabled, this option allows the unprotected exchange of the protection mode
+negotiation. (Added in 7.19.4).
+.IP CURLOPT_INTERFACE
+Pass a char * as parameter. This sets the interface name to use as outgoing
+network interface. The name can be an interface name, an IP address, or a host
+name.
+
+Starting with 7.24.0: If the parameter starts with "if!" then it is treated as
+only as interface name and no attempt will ever be named to do treat it as an
+IP address or to do name resolution on it. If the parameter starts with
+\&"host!" it is treated as either an IP address or a hostname. Hostnames are
+resolved synchronously. Using the if! format is highly recommended when using
+the multi interfaces to avoid allowing the code to block. If "if!" is
+specified but the parameter does not match an existing interface,
+CURLE_INTERFACE_FAILED is returned.
+.IP CURLOPT_LOCALPORT
+Pass a long. This sets the local port number of the socket used for
+connection. This can be used in combination with \fICURLOPT_INTERFACE\fP and
+you are recommended to use \fICURLOPT_LOCALPORTRANGE\fP as well when this is
+set. Valid port numbers are 1 - 65535. (Added in 7.15.2)
+.IP CURLOPT_LOCALPORTRANGE
+Pass a long. This is the number of attempts libcurl will make to find a
+working local port number. It starts with the given \fICURLOPT_LOCALPORT\fP
+and adds one to the number for each retry. Setting this to 1 or below will
+make libcurl do only one try for the exact port number. Port numbers by nature
+are scarce resources that will be busy at times so setting this value to
+something too low might cause unnecessary connection setup failures. (Added in
+7.15.2)
+.IP CURLOPT_DNS_CACHE_TIMEOUT
+Pass a long, this sets the timeout in seconds. Name resolves will be kept in
+memory for this number of seconds. Set to zero to completely disable
+caching, or set to -1 to make the cached entries remain forever. By default,
+libcurl caches this info for 60 seconds.
+
+The name resolve functions of various libc implementations don't re-read name
+server information unless explicitly told so (for example, by calling
+\fIres_init(3)\fP). This may cause libcurl to keep using the older server even
+if DHCP has updated the server info, and this may look like a DNS cache issue
+to the casual libcurl-app user.
+.IP CURLOPT_DNS_USE_GLOBAL_CACHE
+Pass a long. If the value is 1, it tells curl to use a global DNS cache
+that will survive between easy handle creations and deletions. This is not
+thread-safe and this will use a global variable.
+
+\fBWARNING:\fP this option is considered obsolete. Stop using it. Switch over
+to using the share interface instead! See \fICURLOPT_SHARE\fP and
+\fIcurl_share_init(3)\fP.
+.IP CURLOPT_BUFFERSIZE
+Pass a long specifying your preferred size (in bytes) for the receive buffer
+in libcurl. The main point of this would be that the write callback gets
+called more often and with smaller chunks. This is just treated as a request,
+not an order. You cannot be guaranteed to actually get the given size. (Added
+in 7.10)
+
+This size is by default set as big as possible (CURL_MAX_WRITE_SIZE), so it
+only makes sense to use this option if you want it smaller.
+.IP CURLOPT_PORT
+Pass a long specifying what remote port number to connect to, instead of the
+one specified in the URL or the default port for the used protocol.
+.IP CURLOPT_TCP_NODELAY
+Pass a long specifying whether the TCP_NODELAY option is to be set or cleared
+(1 = set, 0 = clear). The option is cleared by default. This will have no
+effect after the connection has been established.
+
+Setting this option will disable TCP's Nagle algorithm. The purpose of this
+algorithm is to try to minimize the number of small packets on the network
+(where "small packets" means TCP segments less than the Maximum Segment Size
+(MSS) for the network).
+
+Maximizing the amount of data sent per TCP segment is good because it
+amortizes the overhead of the send. However, in some cases (most notably
+telnet or rlogin) small segments may need to be sent without delay. This is
+less efficient than sending larger amounts of data at a time, and can
+contribute to congestion on the network if overdone.
+.IP CURLOPT_ADDRESS_SCOPE
+Pass a long specifying the scope_id value to use when connecting to IPv6
+link-local or site-local addresses. (Added in 7.19.0)
+.IP CURLOPT_TCP_KEEPALIVE
+Pass a long. If set to 1, TCP keepalive probes will be sent. The delay and
+frequency of these probes can be controlled by the \fICURLOPT_TCP_KEEPIDLE\fP
+and \fICURLOPT_TCP_KEEPINTVL\fP options, provided the operating system supports
+them. Set to 0 (default behavior) to disable keepalive probes (Added in
+7.25.0).
+.IP CURLOPT_TCP_KEEPIDLE
+Pass a long. Sets the delay, in seconds, that the operating system will wait
+while the connection is idle before sending keepalive probes. Not all operating
+systems support this option. (Added in 7.25.0)
+.IP CURLOPT_TCP_KEEPINTVL
+Pass a long. Sets the interval, in seconds, that the operating system will wait
+between sending keepalive probes. Not all operating systems support this
+option. (Added in 7.25.0)
+.SH NAMES and PASSWORDS OPTIONS (Authentication)
+.IP CURLOPT_NETRC
+This parameter controls the preference of libcurl between using user names and
+passwords from your \fI~/.netrc\fP file, relative to user names and passwords
+in the URL supplied with \fICURLOPT_URL\fP.
+
+libcurl uses a user name (and supplied or prompted password) supplied with
+\fICURLOPT_USERPWD\fP in preference to any of the options controlled by this
+parameter.
+
+Pass a long, set to one of the values described below.
+.RS
+.IP CURL_NETRC_OPTIONAL
+The use of your \fI~/.netrc\fP file is optional, and information in the URL is
+to be preferred. The file will be scanned for the host and user name (to
+find the password only) or for the host only, to find the first user name and
+password after that \fImachine\fP, which ever information is not specified in
+the URL.
+
+Undefined values of the option will have this effect.
+.IP CURL_NETRC_IGNORED
+The library will ignore the file and use only the information in the URL.
+
+This is the default.
+.IP CURL_NETRC_REQUIRED
+This value tells the library that use of the file is required, to ignore the
+information in the URL, and to search the file for the host only.
+.RE
+Only machine name, user name and password are taken into account
+(init macros and similar things aren't supported).
+
+libcurl does not verify that the file has the correct properties set (as the
+standard Unix ftp client does). It should only be readable by user.
+.IP CURLOPT_NETRC_FILE
+Pass a char * as parameter, pointing to a zero terminated string containing
+the full path name to the file you want libcurl to use as .netrc file. If this
+option is omitted, and \fICURLOPT_NETRC\fP is set, libcurl will attempt to
+find a .netrc file in the current user's home directory. (Added in 7.10.9)
+.IP CURLOPT_USERPWD
+Pass a char * as parameter, which should be [user name]:[password] to use for
+the connection. Use \fICURLOPT_HTTPAUTH\fP to decide the authentication method.
+
+When using NTLM, you can set the domain by prepending it to the user name and
+separating the domain and name with a forward (/) or backward slash (\\). Like
+this: "domain/user:password" or "domain\\user:password". Some HTTP servers (on
+Windows) support this style even for Basic authentication.
+
+When using HTTP and \fICURLOPT_FOLLOWLOCATION\fP, libcurl might perform
+several requests to possibly different hosts. libcurl will only send this user
+and password information to hosts using the initial host name (unless
+\fICURLOPT_UNRESTRICTED_AUTH\fP is set), so if libcurl follows locations to
+other hosts it will not send the user and password to those. This is enforced
+to prevent accidental information leakage.
+.IP CURLOPT_PROXYUSERPWD
+Pass a char * as parameter, which should be [user name]:[password] to use for
+the connection to the HTTP proxy. Use \fICURLOPT_PROXYAUTH\fP to decide
+the authentication method.
+.IP CURLOPT_USERNAME
+Pass a char * as parameter, which should be pointing to the zero terminated
+user name to use for the transfer.
+
+\fBCURLOPT_USERNAME\fP sets the user name to be used in protocol
+authentication. You should not use this option together with the (older)
+CURLOPT_USERPWD option.
+
+In order to specify the password to be used in conjunction with the user name
+use the \fICURLOPT_PASSWORD\fP option. (Added in 7.19.1)
+.IP CURLOPT_PASSWORD
+Pass a char * as parameter, which should be pointing to the zero terminated
+password to use for the transfer.
+
+The CURLOPT_PASSWORD option should be used in conjunction with
+the \fICURLOPT_USERNAME\fP option. (Added in 7.19.1)
+.IP CURLOPT_PROXYUSERNAME
+Pass a char * as parameter, which should be pointing to the zero terminated
+user name to use for the transfer while connecting to Proxy.
+
+The CURLOPT_PROXYUSERNAME option should be used in same way as the
+\fICURLOPT_PROXYUSERPWD\fP is used. In comparison to
+\fICURLOPT_PROXYUSERPWD\fP the CURLOPT_PROXYUSERNAME allows the username to
+contain a colon, like in the following example: "sip:user@example.com". The
+CURLOPT_PROXYUSERNAME option is an alternative way to set the user name while
+connecting to Proxy. There is no meaning to use it together with the
+\fICURLOPT_PROXYUSERPWD\fP option.
+
+In order to specify the password to be used in conjunction with the user name
+use the \fICURLOPT_PROXYPASSWORD\fP option. (Added in 7.19.1)
+.IP CURLOPT_PROXYPASSWORD
+Pass a char * as parameter, which should be pointing to the zero terminated
+password to use for the transfer while connecting to Proxy.
+
+The CURLOPT_PROXYPASSWORD option should be used in conjunction with
+the \fICURLOPT_PROXYUSERNAME\fP option. (Added in 7.19.1)
+.IP CURLOPT_HTTPAUTH
+Pass a long as parameter, which is set to a bitmask, to tell libcurl which
+authentication method(s) you want it to use. The available bits are listed
+below. If more than one bit is set, libcurl will first query the site to see
+which authentication methods it supports and then pick the best one you allow
+it to use. For some methods, this will induce an extra network round-trip. Set
+the actual name and password with the \fICURLOPT_USERPWD\fP option or
+with the \fICURLOPT_USERNAME\fP and the \fICURLOPT_PASSWORD\fP options.
+(Added in 7.10.6)
+.RS
+.IP CURLAUTH_BASIC
+HTTP Basic authentication. This is the default choice, and the only method
+that is in wide-spread use and supported virtually everywhere. This sends
+the user name and password over the network in plain text, easily captured by
+others.
+.IP CURLAUTH_DIGEST
+HTTP Digest authentication. Digest authentication is defined in RFC2617 and
+is a more secure way to do authentication over public networks than the
+regular old-fashioned Basic method.
+.IP CURLAUTH_DIGEST_IE
+HTTP Digest authentication with an IE flavor. Digest authentication is
+defined in RFC2617 and is a more secure way to do authentication over public
+networks than the regular old-fashioned Basic method. The IE flavor is simply
+that libcurl will use a special "quirk" that IE is known to have used before
+version 7 and that some servers require the client to use. (This define was
+added in 7.19.3)
+.IP CURLAUTH_GSSNEGOTIATE
+HTTP GSS-Negotiate authentication. The GSS-Negotiate (also known as plain
+\&"Negotiate") method was designed by Microsoft and is used in their web
+applications. It is primarily meant as a support for Kerberos5 authentication
+but may also be used along with other authentication methods. For more
+information see IETF draft draft-brezak-spnego-http-04.txt.
+
+You need to build libcurl with a suitable GSS-API library for this to work.
+.IP CURLAUTH_NTLM
+HTTP NTLM authentication. A proprietary protocol invented and used by
+Microsoft. It uses a challenge-response and hash concept similar to Digest, to
+prevent the password from being eavesdropped.
+
+You need to build libcurl with either OpenSSL, GnuTLS or NSS support for this
+option to work, or build libcurl on Windows.
+.IP CURLAUTH_NTLM_WB
+NTLM delegating to winbind helper. Authentication is performed by a separate
+binary application that is executed when needed. The name of the application
+is specified at compile time but is typically /usr/bin/ntlm_auth
+(Added in 7.22.0)
+
+Note that libcurl will fork when necessary to run the winbind application and
+kill it when complete, calling waitpid() to await its exit when done. On POSIX
+operating systems, killing the process will cause a SIGCHLD signal to be
+raised (regardless of whether \fICURLOPT_NOSIGNAL\fP is set), which must be
+handled intelligently by the application. In particular, the application must
+not unconditionally call wait() in its SIGCHLD signal handler to avoid being
+subject to a race condition. This behavior is subject to change in future
+versions of libcurl.
+.IP CURLAUTH_ANY
+This is a convenience macro that sets all bits and thus makes libcurl pick any
+it finds suitable. libcurl will automatically select the one it finds most
+secure.
+.IP CURLAUTH_ANYSAFE
+This is a convenience macro that sets all bits except Basic and thus makes
+libcurl pick any it finds suitable. libcurl will automatically select the one
+it finds most secure.
+.IP CURLAUTH_ONLY
+This is a meta symbol. Or this value together with a single specific auth
+value to force libcurl to probe for un-restricted auth and if not, only that
+single auth algorithm is acceptable. (Added in 7.21.3)
+.RE
+.IP CURLOPT_TLSAUTH_TYPE
+Pass a long as parameter, which is set to a bitmask, to tell libcurl which
+authentication method(s) you want it to use for TLS authentication.
+.RS
+.IP CURLOPT_TLSAUTH_SRP
+TLS-SRP authentication. Secure Remote Password authentication for TLS is
+defined in RFC5054 and provides mutual authentication if both sides have a
+shared secret. To use TLS-SRP, you must also set the
+\fICURLOPT_TLSAUTH_USERNAME\fP and \fICURLOPT_TLSAUTH_PASSWORD\fP options.
+
+You need to build libcurl with GnuTLS or OpenSSL with TLS-SRP support for this
+to work. (Added in 7.21.4)
+.RE
+.IP CURLOPT_TLSAUTH_USERNAME
+Pass a char * as parameter, which should point to the zero terminated username
+to use for the TLS authentication method specified with the
+\fICURLOPT_TLSAUTH_TYPE\fP option. Requires that the
+\fICURLOPT_TLS_PASSWORD\fP option also be set. (Added in 7.21.4)
+.IP CURLOPT_TLSAUTH_PASSWORD
+Pass a char * as parameter, which should point to the zero terminated password
+to use for the TLS authentication method specified with the
+\fICURLOPT_TLSAUTH_TYPE\fP option. Requires that the
+\fICURLOPT_TLS_USERNAME\fP option also be set. (Added in 7.21.4)
+.IP CURLOPT_PROXYAUTH
+Pass a long as parameter, which is set to a bitmask, to tell libcurl which
+authentication method(s) you want it to use for your proxy authentication. If
+more than one bit is set, libcurl will first query the site to see what
+authentication methods it supports and then pick the best one you allow it to
+use. For some methods, this will induce an extra network round-trip. Set the
+actual name and password with the \fICURLOPT_PROXYUSERPWD\fP option. The
+bitmask can be constructed by or'ing together the bits listed above for the
+\fICURLOPT_HTTPAUTH\fP option. As of this writing, only Basic, Digest and NTLM
+work. (Added in 7.10.7)
+.SH HTTP OPTIONS
+.IP CURLOPT_AUTOREFERER
+Pass a parameter set to 1 to enable this. When enabled, libcurl will
+automatically set the Referer: field in requests where it follows a Location:
+redirect.
+.IP CURLOPT_ACCEPT_ENCODING
+Sets the contents of the Accept-Encoding: header sent in a HTTP request, and
+enables decoding of a response when a Content-Encoding: header is received.
+Three encodings are supported: \fIidentity\fP, which does nothing,
+\fIdeflate\fP which requests the server to compress its response using the
+zlib algorithm, and \fIgzip\fP which requests the gzip algorithm. If a
+zero-length string is set, then an Accept-Encoding: header containing all
+supported encodings is sent.
+
+This is a request, not an order; the server may or may not do it. This option
+must be set (to any non-NULL value) or else any unsolicited encoding done by
+the server is ignored. See the special file lib/README.encoding for details.
+
+(This option was called CURLOPT_ENCODING before 7.21.6)
+.IP CURLOPT_TRANSFER_ENCODING
+Adds a request for compressed Transfer Encoding in the outgoing HTTP
+request. If the server supports this and so desires, it can respond with the
+HTTP response sent using a compressed Transfer-Encoding that will be
+automatically uncompressed by libcurl on reception.
+
+Transfer-Encoding differs slightly from the Content-Encoding you ask for with
+\fBCURLOPT_ACCEPT_ENCODING\fP in that a Transfer-Encoding is strictly meant to
+be for the transfer and thus MUST be decoded before the data arrives in the
+client. Traditionally, Transfer-Encoding has been much less used and supported
+by both HTTP clients and HTTP servers.
+
+(Added in 7.21.6)
+.IP CURLOPT_FOLLOWLOCATION
+A parameter set to 1 tells the library to follow any Location: header that the
+server sends as part of a HTTP header.
+
+This means that the library will re-send the same request on the new location
+and follow new Location: headers all the way until no more such headers are
+returned. \fICURLOPT_MAXREDIRS\fP can be used to limit the number of redirects
+libcurl will follow.
+
+Since 7.19.4, libcurl can limit what protocols it will automatically
+follow. The accepted protocols are set with \fICURLOPT_REDIR_PROTOCOLS\fP and
+it excludes the FILE protocol by default.
+.IP CURLOPT_UNRESTRICTED_AUTH
+A parameter set to 1 tells the library it can continue to send authentication
+(user+password) when following locations, even when hostname changed. This
+option is meaningful only when setting \fICURLOPT_FOLLOWLOCATION\fP.
+.IP CURLOPT_MAXREDIRS
+Pass a long. The set number will be the redirection limit. If that many
+redirections have been followed, the next redirect will cause an error
+(\fICURLE_TOO_MANY_REDIRECTS\fP). This option only makes sense if the
+\fICURLOPT_FOLLOWLOCATION\fP is used at the same time. Added in 7.15.1:
+Setting the limit to 0 will make libcurl refuse any redirect. Set it to -1 for
+an infinite number of redirects (which is the default)
+.IP CURLOPT_POSTREDIR
+Pass a bitmask to control how libcurl acts on redirects after POSTs that get a
+301, 302 or 303 response back. A parameter with bit 0 set (value
+\fBCURL_REDIR_POST_301\fP) tells the library to respect RFC2616/10.3.2 and not
+convert POST requests into GET requests when following a 301 redirection.
+Setting bit 1 (value \fBCURL_REDIR_POST_302\fP) makes libcurl maintain the
+request method after a 302 redirect whilst setting bit 2 (value
+\fBCURL_REDIR_POST_303\fP) makes libcurl maintain the request method after a
+303 redirect. The value \fBCURL_REDIR_POST_ALL\fP is a convenience define that
+sets all three bits.
+
+The non-RFC behaviour is ubiquitous in web browsers, so the library does the
+conversion by default to maintain consistency. However, a server may require a
+POST to remain a POST after such a redirection. This option is meaningful only
+when setting \fICURLOPT_FOLLOWLOCATION\fP. (Added in 7.17.1) (This option was
+known as CURLOPT_POST301 up to 7.19.0 as it only supported the 301 then)
+.IP CURLOPT_PUT
+A parameter set to 1 tells the library to use HTTP PUT to transfer data. The
+data should be set with \fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZE\fP.
+
+This option is deprecated and starting with version 7.12.1 you should instead
+use \fICURLOPT_UPLOAD\fP.
+.IP CURLOPT_POST
+A parameter set to 1 tells the library to do a regular HTTP post. This will
+also make the library use a "Content-Type:
+application/x-www-form-urlencoded" header. (This is by far the most commonly
+used POST method).
+
+Use one of \fICURLOPT_POSTFIELDS\fP or \fICURLOPT_COPYPOSTFIELDS\fP options to
+specify what data to post and \fICURLOPT_POSTFIELDSIZE\fP or
+\fICURLOPT_POSTFIELDSIZE_LARGE\fP to set the data size.
+
+Optionally, you can provide data to POST using the \fICURLOPT_READFUNCTION\fP
+and \fICURLOPT_READDATA\fP options but then you must make sure to not set
+\fICURLOPT_POSTFIELDS\fP to anything but NULL. When providing data with a
+callback, you must transmit it using chunked transfer-encoding or you must set
+the size of the data with the \fICURLOPT_POSTFIELDSIZE\fP or
+\fICURLOPT_POSTFIELDSIZE_LARGE\fP option. To enable chunked encoding, you
+simply pass in the appropriate Transfer-Encoding header, see the
+post-callback.c example.
+
+You can override the default POST Content-Type: header by setting your own
+with \fICURLOPT_HTTPHEADER\fP.
+
+Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header.
+You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual.
+
+If you use POST to a HTTP 1.1 server, you can send data without knowing the
+size before starting the POST if you use chunked encoding. You enable this by
+adding a header like "Transfer-Encoding: chunked" with
+\fICURLOPT_HTTPHEADER\fP. With HTTP 1.0 or without chunked transfer, you must
+specify the size in the request.
+
+When setting \fICURLOPT_POST\fP to 1, it will automatically set
+\fICURLOPT_NOBODY\fP to 0 (since 7.14.1).
+
+If you issue a POST request and then want to make a HEAD or GET using the same
+re-used handle, you must explicitly set the new request type using
+\fICURLOPT_NOBODY\fP or \fICURLOPT_HTTPGET\fP or similar.
+.IP CURLOPT_POSTFIELDS
+Pass a void * as parameter, which should be the full data to post in a HTTP
+POST operation. You must make sure that the data is formatted the way you want
+the server to receive it. libcurl will not convert or encode it for you. Most
+web servers will assume this data to be url-encoded.
+
+The pointed data are NOT copied by the library: as a consequence, they must
+be preserved by the calling application until the transfer finishes.
+
+This POST is a normal application/x-www-form-urlencoded kind (and libcurl will
+set that Content-Type by default when this option is used), which is the most
+commonly used one by HTML forms. See also the \fICURLOPT_POST\fP. Using
+\fICURLOPT_POSTFIELDS\fP implies \fICURLOPT_POST\fP.
+
+If you want to do a zero-byte POST, you need to set
+\fICURLOPT_POSTFIELDSIZE\fP explicitly to zero, as simply setting
+\fICURLOPT_POSTFIELDS\fP to NULL or "" just effectively disables the sending
+of the specified string. libcurl will instead assume that you'll send the POST
+data using the read callback!
+
+Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header.
+You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual.
+
+To make multipart/formdata posts (aka RFC2388-posts), check out the
+\fICURLOPT_HTTPPOST\fP option.
+.IP CURLOPT_POSTFIELDSIZE
+If you want to post data to the server without letting libcurl do a strlen()
+to measure the data size, this option must be used. When this option is used
+you can post fully binary data, which otherwise is likely to fail. If this
+size is set to -1, the library will use strlen() to get the size.
+.IP CURLOPT_POSTFIELDSIZE_LARGE
+Pass a curl_off_t as parameter. Use this to set the size of the
+\fICURLOPT_POSTFIELDS\fP data to prevent libcurl from doing strlen() on the
+data to figure out the size. This is the large file version of the
+\fICURLOPT_POSTFIELDSIZE\fP option. (Added in 7.11.1)
+.IP CURLOPT_COPYPOSTFIELDS
+Pass a char * as parameter, which should be the full data to post in a HTTP
+POST operation. It behaves as the \fICURLOPT_POSTFIELDS\fP option, but the
+original data are copied by the library, allowing the application to overwrite
+the original data after setting this option.
+
+Because data are copied, care must be taken when using this option in
+conjunction with \fICURLOPT_POSTFIELDSIZE\fP or
+\fICURLOPT_POSTFIELDSIZE_LARGE\fP: If the size has not been set prior to
+\fICURLOPT_COPYPOSTFIELDS\fP, the data are assumed to be a NUL-terminated
+string; else the stored size informs the library about the data byte count to
+copy. In any case, the size must not be changed after
+\fICURLOPT_COPYPOSTFIELDS\fP, unless another \fICURLOPT_POSTFIELDS\fP or
+\fICURLOPT_COPYPOSTFIELDS\fP option is issued.
+(Added in 7.17.1)
+.IP CURLOPT_HTTPPOST
+Tells libcurl you want a multipart/formdata HTTP POST to be made and you
+instruct what data to pass on to the server. Pass a pointer to a linked list
+of curl_httppost structs as parameter. The easiest way to create such a
+list, is to use \fIcurl_formadd(3)\fP as documented. The data in this list
+must remain intact until you close this curl handle again with
+\fIcurl_easy_cleanup(3)\fP.
+
+Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header.
+You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual.
+
+When setting \fICURLOPT_HTTPPOST\fP, it will automatically set
+\fICURLOPT_NOBODY\fP to 0 (since 7.14.1).
+.IP CURLOPT_REFERER
+Pass a pointer to a zero terminated string as parameter. It will be used to
+set the Referer: header in the http request sent to the remote server. This
+can be used to fool servers or scripts. You can also set any custom header
+with \fICURLOPT_HTTPHEADER\fP.
+.IP CURLOPT_USERAGENT
+Pass a pointer to a zero terminated string as parameter. It will be used to
+set the User-Agent: header in the http request sent to the remote server. This
+can be used to fool servers or scripts. You can also set any custom header
+with \fICURLOPT_HTTPHEADER\fP.
+.IP CURLOPT_HTTPHEADER
+Pass a pointer to a linked list of HTTP headers to pass to the server in your
+HTTP request. The linked list should be a fully valid list of \fBstruct
+curl_slist\fP structs properly filled in. Use \fIcurl_slist_append(3)\fP to
+create the list and \fIcurl_slist_free_all(3)\fP to clean up an entire
+list. If you add a header that is otherwise generated and used by libcurl
+internally, your added one will be used instead. If you add a header with no
+content as in 'Accept:' (no data on the right side of the colon), the
+internally used header will get disabled. Thus, using this option you can add
+new headers, replace internal headers and remove internal headers. To add a
+header with no content, make the content be two quotes: \&"". The headers
+included in the linked list must not be CRLF-terminated, because curl adds
+CRLF after each header item. Failure to comply with this will result in
+strange bugs because the server will most likely ignore part of the headers
+you specified.
+
+The first line in a request (containing the method, usually a GET or POST) is
+not a header and cannot be replaced using this option. Only the lines
+following the request-line are headers. Adding this method line in this list
+of headers will only cause your request to send an invalid header.
+
+Pass a NULL to this to reset back to no custom headers.
+
+The most commonly replaced headers have "shortcuts" in the options
+\fICURLOPT_COOKIE\fP, \fICURLOPT_USERAGENT\fP and \fICURLOPT_REFERER\fP.
+.IP CURLOPT_HTTP200ALIASES
+Pass a pointer to a linked list of aliases to be treated as valid HTTP 200
+responses. Some servers respond with a custom header response line. For
+example, IceCast servers respond with "ICY 200 OK". By including this string
+in your list of aliases, the response will be treated as a valid HTTP header
+line such as "HTTP/1.0 200 OK". (Added in 7.10.3)
+
+The linked list should be a fully valid list of struct curl_slist structs, and
+be properly filled in. Use \fIcurl_slist_append(3)\fP to create the list and
+\fIcurl_slist_free_all(3)\fP to clean up an entire list.
+
+The alias itself is not parsed for any version strings. Before libcurl 7.16.3,
+Libcurl used the value set by option \fICURLOPT_HTTP_VERSION\fP, but starting
+with 7.16.3 the protocol is assumed to match HTTP 1.0 when an alias matched.
+.IP CURLOPT_COOKIE
+Pass a pointer to a zero terminated string as parameter. It will be used to
+set a cookie in the http request. The format of the string should be
+NAME=CONTENTS, where NAME is the cookie name and CONTENTS is what the cookie
+should contain.
+
+If you need to set multiple cookies, you need to set them all using a single
+option and thus you need to concatenate them all in one single string. Set
+multiple cookies in one string like this: "name1=content1; name2=content2;"
+etc.
+
+This option sets the cookie header explicitly in the outgoing request(s). If
+multiple requests are done due to authentication, followed redirections or
+similar, they will all get this cookie passed on.
+
+Using this option multiple times will only make the latest string override the
+previous ones.
+.IP CURLOPT_COOKIEFILE
+Pass a pointer to a zero terminated string as parameter. It should contain the
+name of your file holding cookie data to read. The cookie data may be in
+Netscape / Mozilla cookie data format or just regular HTTP-style headers
+dumped to a file.
+
+Given an empty or non-existing file or by passing the empty string (""), this
+option will enable cookies for this curl handle, making it understand and
+parse received cookies and then use matching cookies in future requests.
+
+If you use this option multiple times, you just add more files to read.
+Subsequent files will add more cookies.
+.IP CURLOPT_COOKIEJAR
+Pass a file name as char *, zero terminated. This will make libcurl write all
+internally known cookies to the specified file when \fIcurl_easy_cleanup(3)\fP
+is called. If no cookies are known, no file will be created. Specify "-" to
+instead have the cookies written to stdout. Using this option also enables
+cookies for this session, so if you for example follow a location it will make
+matching cookies get sent accordingly.
+
+If the cookie jar file can't be created or written to (when the
+\fIcurl_easy_cleanup(3)\fP is called), libcurl will not and cannot report an
+error for this. Using \fICURLOPT_VERBOSE\fP or \fICURLOPT_DEBUGFUNCTION\fP
+will get a warning to display, but that is the only visible feedback you get
+about this possibly lethal situation.
+.IP CURLOPT_COOKIESESSION
+Pass a long set to 1 to mark this as a new cookie "session". It will force
+libcurl to ignore all cookies it is about to load that are "session cookies"
+from the previous session. By default, libcurl always stores and loads all
+cookies, independent if they are session cookies or not. Session cookies are
+cookies without expiry date and they are meant to be alive and existing for
+this "session" only.
+.IP CURLOPT_COOKIELIST
+Pass a char * to a cookie string. Cookie can be either in Netscape / Mozilla
+format or just regular HTTP-style header (Set-Cookie: ...) format. If cURL
+cookie engine was not enabled it will enable its cookie engine. Passing a
+magic string \&"ALL" will erase all cookies known by cURL. (Added in 7.14.1)
+Passing the special string \&"SESS" will only erase all session cookies known
+by cURL. (Added in 7.15.4) Passing the special string \&"FLUSH" will write
+all cookies known by cURL to the file specified by \fICURLOPT_COOKIEJAR\fP.
+(Added in 7.17.1)
+.IP CURLOPT_HTTPGET
+Pass a long. If the long is 1, this forces the HTTP request to get back
+to GET. Usable if a POST, HEAD, PUT, or a custom request has been used
+previously using the same curl handle.
+
+When setting \fICURLOPT_HTTPGET\fP to 1, it will automatically set
+\fICURLOPT_NOBODY\fP to 0 (since 7.14.1).
+.IP CURLOPT_HTTP_VERSION
+Pass a long, set to one of the values described below. They force libcurl to
+use the specific HTTP versions. This is not sensible to do unless you have a
+good reason.
+.RS
+.IP CURL_HTTP_VERSION_NONE
+We don't care about what version the library uses. libcurl will use whatever
+it thinks fit.
+.IP CURL_HTTP_VERSION_1_0
+Enforce HTTP 1.0 requests.
+.IP CURL_HTTP_VERSION_1_1
+Enforce HTTP 1.1 requests.
+.RE
+.IP CURLOPT_IGNORE_CONTENT_LENGTH
+Ignore the Content-Length header. This is useful for Apache 1.x (and similar
+servers) which will report incorrect content length for files over 2
+gigabytes. If this option is used, curl will not be able to accurately report
+progress, and will simply stop the download when the server ends the
+connection. (added in 7.14.1)
+.IP CURLOPT_HTTP_CONTENT_DECODING
+Pass a long to tell libcurl how to act on content decoding. If set to zero,
+content decoding will be disabled. If set to 1 it is enabled. Libcurl has no
+default content decoding but requires you to use \fICURLOPT_ENCODING\fP for
+that. (added in 7.16.2)
+.IP CURLOPT_HTTP_TRANSFER_DECODING
+Pass a long to tell libcurl how to act on transfer decoding. If set to zero,
+transfer decoding will be disabled, if set to 1 it is enabled
+(default). libcurl does chunked transfer decoding by default unless this
+option is set to zero. (added in 7.16.2)
+.SH SMTP OPTIONS
+.IP CURLOPT_MAIL_FROM
+Pass a pointer to a zero terminated string as parameter. This should be used
+to specify the sender's email address when sending SMTP mail with libcurl.
+
+An originator email address should be specified with angled brackets (<>)
+around it, which if not specified, will be added by libcurl from version
+7.21.4 onwards. Failing to provide such brackets may cause the server to
+reject the email.
+
+If this parameter is not specified then an empty address will be sent to the
+mail server which may or may not cause the email to be rejected.
+
+(Added in 7.20.0)
+.IP CURLOPT_MAIL_RCPT
+Pass a pointer to a linked list of recipients to pass to the server in your
+SMTP mail request. The linked list should be a fully valid list of \fBstruct
+curl_slist\fP structs properly filled in. Use \fIcurl_slist_append(3)\fP to
+create the list and \fIcurl_slist_free_all(3)\fP to clean up an entire list.
+
+Each recipient should be specified within a pair of angled brackets (<>),
+however, should you not use an angled bracket as the first character libcurl
+will assume you provided a single email address and enclose that address
+within brackets for you.
+
+(Added in 7.20.0)
+.IP CURLOPT_MAIL_AUTH
+Pass a pointer to a zero terminated string as parameter. This will be used
+to specify the authentication address (identity) of a submitted message that
+is being relayed to another server.
+
+This optional parameter allows co-operating agents in a trusted environment to
+communicate the authentication of individual messages and should only be used
+by the application program, using libcurl, if the application is itself a
+mail server acting in such an environment. If the application is operating as
+such and the AUTH address is not known or is invalid, then an empty string
+should be used for this parameter.
+
+Unlike CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT, the address should not be
+specified within a pair of angled brackets (<>). However, if an empty string
+is used then a pair of brackets will be sent by libcurl as required by
+RFC2554.
+
+(Added in 7.25.0)
+.SH TFTP OPTIONS
+.IP CURLOPT_TFTP_BLKSIZE
+Specify block size to use for TFTP data transmission. Valid range as per
+RFC2348 is 8-65464 bytes. The default of 512 bytes will be used if this option
+is not specified. The specified block size will only be used pending support
+by the remote server. If the server does not return an option acknowledgement
+or returns an option acknowledgement with no blksize, the default of 512 bytes
+will be used. (added in 7.19.4)
+.SH FTP OPTIONS
+.IP CURLOPT_FTPPORT
+Pass a pointer to a zero terminated string as parameter. It will be used to
+get the IP address to use for the FTP PORT instruction. The PORT instruction
+tells the remote server to connect to our specified IP address. The string may
+be a plain IP address, a host name, a network interface name (under Unix) or
+just a '-' symbol to let the library use your system's default IP
+address. Default FTP operations are passive, and thus won't use PORT.
+
+The address can be followed by a ':' to specify a port, optionally followed by
+a '-' to specify a port range. If the port specified is 0, the operating
+system will pick a free port. If a range is provided and all ports in the
+range are not available, libcurl will report CURLE_FTP_PORT_FAILED for the
+handle. Invalid port/range settings are ignored. IPv6 addresses followed by
+a port or portrange have to be in brackets. IPv6 addresses without port/range
+specifier can be in brackets. (added in 7.19.5)
+
+Examples with specified ports:
+
+.nf
+ eth0:0
+ 192.168.1.2:32000-33000
+ curl.se:32123
+ [::1]:1234-4567
+.fi
+
+You disable PORT again and go back to using the passive version by setting
+this option to NULL.
+.IP CURLOPT_QUOTE
+Pass a pointer to a linked list of FTP or SFTP commands to pass to the server
+prior to your FTP request. This will be done before any other commands are
+issued (even before the CWD command for FTP). The linked list should be a
+fully valid list of 'struct curl_slist' structs properly filled in with text
+strings. Use \fIcurl_slist_append(3)\fP to append strings (commands) to the
+list, and clear the entire list afterwards with
+\fIcurl_slist_free_all(3)\fP. Disable this operation again by setting a NULL
+to this option. When speaking to a FTP (or SFTP since 7.24.0) server, prefix
+the command with an asterisk (*) to make libcurl continue even if the command
+fails as by default libcurl will stop at first failure.
+
+The set of valid FTP commands depends on the server (see RFC959 for a list of
+mandatory commands).
+
+The valid SFTP commands are: chgrp, chmod, chown, ln, mkdir, pwd, rename, rm,
+rmdir, symlink (see
+.BR curl (1))
+(SFTP support added in 7.16.3)
+.IP CURLOPT_POSTQUOTE
+Pass a pointer to a linked list of FTP or SFTP commands to pass to the server
+after your FTP transfer request. The commands will only be run if no error
+occurred. The linked list should be a fully valid list of struct curl_slist
+structs properly filled in as described for \fICURLOPT_QUOTE\fP. Disable this
+operation again by setting a NULL to this option.
+.IP CURLOPT_PREQUOTE
+Pass a pointer to a linked list of FTP commands to pass to the server after
+the transfer type is set. The linked list should be a fully valid list of
+struct curl_slist structs properly filled in as described for
+\fICURLOPT_QUOTE\fP. Disable this operation again by setting a NULL to this
+option. Before version 7.16.0, if you also set \fICURLOPT_NOBODY\fP to 1, this
+option didn't work.
+.IP CURLOPT_DIRLISTONLY
+A parameter set to 1 tells the library to just list the names of files in a
+directory, instead of doing a full directory listing that would include file
+sizes, dates etc. This works for FTP and SFTP URLs.
+
+This causes an FTP NLST command to be sent on an FTP server. Beware that some
+FTP servers list only files in their response to NLST; they might not include
+subdirectories and symbolic links.
+
+Setting this option to 1 also implies a directory listing even if the URL
+doesn't end with a slash, which otherwise is necessary.
+
+Do NOT use this option if you also use \fICURLOPT_WILDCARDMATCH\fP as it will
+effectively break that feature then.
+
+(This option was known as CURLOPT_FTPLISTONLY up to 7.16.4)
+.IP CURLOPT_APPEND
+A parameter set to 1 tells the library to append to the remote file instead of
+overwrite it. This is only useful when uploading to an FTP site.
+
+(This option was known as CURLOPT_FTPAPPEND up to 7.16.4)
+.IP CURLOPT_FTP_USE_EPRT
+Pass a long. If the value is 1, it tells curl to use the EPRT (and
+LPRT) command when doing active FTP downloads (which is enabled by
+\fICURLOPT_FTPPORT\fP). Using EPRT means that it will first attempt to use
+EPRT and then LPRT before using PORT, but if you pass zero to this
+option, it will not try using EPRT or LPRT, only plain PORT. (Added in 7.10.5)
+
+If the server is an IPv6 host, this option will have no effect as of 7.12.3.
+.IP CURLOPT_FTP_USE_EPSV
+Pass a long. If the value is 1, it tells curl to use the EPSV command
+when doing passive FTP downloads (which it always does by default). Using EPSV
+means that it will first attempt to use EPSV before using PASV, but if you
+pass zero to this option, it will not try using EPSV, only plain PASV.
+
+If the server is an IPv6 host, this option will have no effect as of 7.12.3.
+.IP CURLOPT_FTP_USE_PRET
+Pass a long. If the value is 1, it tells curl to send a PRET command before
+PASV (and EPSV). Certain FTP servers, mainly drftpd, require this non-standard
+command for directory listings as well as up and downloads in PASV mode. Has
+no effect when using the active FTP transfers mode. (Added in 7.20.0)
+.IP CURLOPT_FTP_CREATE_MISSING_DIRS
+Pass a long. If the value is 1, curl will attempt to create any remote
+directory that it fails to CWD into. CWD is the command that changes working
+directory. (Added in 7.10.7)
+
+This setting also applies to SFTP-connections. curl will attempt to create
+the remote directory if it can't obtain a handle to the target-location. The
+creation will fail if a file of the same name as the directory to create
+already exists or lack of permissions prevents creation. (Added in 7.16.3)
+
+Starting with 7.19.4, you can also set this value to 2, which will make
+libcurl retry the CWD command again if the subsequent MKD command fails. This
+is especially useful if you're doing many simultaneous connections against the
+same server and they all have this option enabled, as then CWD may first fail
+but then another connection does MKD before this connection and thus MKD fails
+but trying CWD works! 7.19.4 also introduced the \fICURLFTP_CREATE_DIR\fP and
+\fICURLFTP_CREATE_DIR_RETRY\fP enum names for these arguments.
+
+Before version 7.19.4, libcurl will simply ignore arguments set to 2 and act
+as if 1 was selected.
+.IP CURLOPT_FTP_RESPONSE_TIMEOUT
+Pass a long. Causes curl to set a timeout period (in seconds) on the amount
+of time that the server is allowed to take in order to generate a response
+message for a command before the session is considered hung. While curl is
+waiting for a response, this value overrides \fICURLOPT_TIMEOUT\fP. It is
+recommended that if used in conjunction with \fICURLOPT_TIMEOUT\fP, you set
+\fICURLOPT_FTP_RESPONSE_TIMEOUT\fP to a value smaller than
+\fICURLOPT_TIMEOUT\fP. (Added in 7.10.8)
+.IP CURLOPT_FTP_ALTERNATIVE_TO_USER
+Pass a char * as parameter, pointing to a string which will be used to
+authenticate if the usual FTP "USER user" and "PASS password" negotiation
+fails. This is currently only known to be required when connecting to
+Tumbleweed's Secure Transport FTPS server using client certificates for
+authentication. (Added in 7.15.5)
+.IP CURLOPT_FTP_SKIP_PASV_IP
+Pass a long. If set to 1, it instructs libcurl to not use the IP address the
+server suggests in its 227-response to libcurl's PASV command when libcurl
+connects the data connection. Instead libcurl will re-use the same IP address
+it already uses for the control connection. But it will use the port number
+from the 227-response. (Added in 7.14.2)
+
+This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
+.IP CURLOPT_FTPSSLAUTH
+Pass a long using one of the values from below, to alter how libcurl issues
+\&"AUTH TLS" or "AUTH SSL" when FTP over SSL is activated (see
+\fICURLOPT_USE_SSL\fP). (Added in 7.12.2)
+.RS
+.IP CURLFTPAUTH_DEFAULT
+Allow libcurl to decide.
+.IP CURLFTPAUTH_SSL
+Try "AUTH SSL" first, and only if that fails try "AUTH TLS".
+.IP CURLFTPAUTH_TLS
+Try "AUTH TLS" first, and only if that fails try "AUTH SSL".
+.RE
+.IP CURLOPT_FTP_SSL_CCC
+If enabled, this option makes libcurl use CCC (Clear Command Channel). It
+shuts down the SSL/TLS layer after authenticating. The rest of the
+control channel communication will be unencrypted. This allows NAT routers
+to follow the FTP transaction. Pass a long using one of the values below.
+(Added in 7.16.1)
+.RS
+.IP CURLFTPSSL_CCC_NONE
+Don't attempt to use CCC.
+.IP CURLFTPSSL_CCC_PASSIVE
+Do not initiate the shutdown, but wait for the server to do it. Do not send
+a reply.
+.IP CURLFTPSSL_CCC_ACTIVE
+Initiate the shutdown and wait for a reply.
+.RE
+.IP CURLOPT_FTP_ACCOUNT
+Pass a pointer to a zero terminated string (or NULL to disable). When an FTP
+server asks for "account data" after user name and password has been provided,
+this data is sent off using the ACCT command. (Added in 7.13.0)
+.IP CURLOPT_FTP_FILEMETHOD
+Pass a long that should have one of the following values. This option controls
+what method libcurl should use to reach a file on a FTP(S) server. The
+argument should be one of the following alternatives:
+.RS
+.IP CURLFTPMETHOD_MULTICWD
+libcurl does a single CWD operation for each path part in the given URL. For
+deep hierarchies this means many commands. This is how RFC1738 says it
+should be done. This is the default but the slowest behavior.
+.IP CURLFTPMETHOD_NOCWD
+libcurl does no CWD at all. libcurl will do SIZE, RETR, STOR etc and give a
+full path to the server for all these commands. This is the fastest behavior.
+.IP CURLFTPMETHOD_SINGLECWD
+libcurl does one CWD with the full target directory and then operates on the
+file \&"normally" (like in the multicwd case). This is somewhat more standards
+compliant than 'nocwd' but without the full penalty of 'multicwd'.
+.RE
+(Added in 7.15.1)
+.SH RTSP OPTIONS
+.IP CURLOPT_RTSP_REQUEST
+Tell libcurl what kind of RTSP request to make. Pass one of the following RTSP
+enum values. Unless noted otherwise, commands require the Session ID to be
+initialized. (Added in 7.20.0)
+.RS
+.IP CURL_RTSPREQ_OPTIONS
+Used to retrieve the available methods of the server. The application is
+responsible for parsing and obeying the response. \fB(The session ID is not
+needed for this method.)\fP (Added in 7.20.0)
+.IP CURL_RTSPREQ_DESCRIBE
+Used to get the low level description of a stream. The application should note
+what formats it understands in the \fI'Accept:'\fP header. Unless set
+manually, libcurl will automatically fill in \fI'Accept:
+application/sdp'\fP. Time-condition headers will be added to Describe requests
+if the \fICURLOPT_TIMECONDITION\fP option is active. \fB(The session ID is not
+needed for this method)\fP (Added in 7.20.0)
+.IP CURL_RTSPREQ_ANNOUNCE
+When sent by a client, this method changes the description of the session. For
+example, if a client is using the server to record a meeting, the client can
+use Announce to inform the server of all the meta-information about the
+session. ANNOUNCE acts like a HTTP PUT or POST just like
+\fICURL_RTSPREQ_SET_PARAMETER\fP (Added in 7.20.0)
+.IP CURL_RTSPREQ_SETUP
+Setup is used to initialize the transport layer for the session. The
+application must set the desired Transport options for a session by using the
+\fICURLOPT_RTSP_TRANSPORT\fP option prior to calling setup. If no session ID
+is currently set with \fICURLOPT_RTSP_SESSION_ID\fP, libcurl will extract and
+use the session ID in the response to this request. \fB(The session ID is not
+needed for this method).\fP (Added in 7.20.0)
+.IP CURL_RTSPREQ_PLAY
+Send a Play command to the server. Use the \fICURLOPT_RANGE\fP option to
+modify the playback time (e.g. 'npt=10-15'). (Added in 7.20.0)
+.IP CURL_RTSPREQ_PAUSE
+Send a Pause command to the server. Use the \fICURLOPT_RANGE\fP option with a
+single value to indicate when the stream should be halted. (e.g. npt='25')
+(Added in 7.20.0)
+.IP CURL_RTSPREQ_TEARDOWN
+This command terminates an RTSP session. Simply closing a connection does not
+terminate the RTSP session since it is valid to control an RTSP session over
+different connections. (Added in 7.20.0)
+.IP CURL_RTSPREQ_GET_PARAMETER
+Retrieve a parameter from the server. By default, libcurl will automatically
+include a \fIContent-Type: text/parameters\fP header on all non-empty requests
+unless a custom one is set. GET_PARAMETER acts just like a HTTP PUT or POST
+(see \fICURL_RTSPREQ_SET_PARAMETER\fP).
+Applications wishing to send a heartbeat message (e.g. in the presence of a
+server-specified timeout) should send use an empty GET_PARAMETER request.
+(Added in 7.20.0)
+.IP CURL_RTSPREQ_SET_PARAMETER
+Set a parameter on the server. By default, libcurl will automatically include
+a \fIContent-Type: text/parameters\fP header unless a custom one is set. The
+interaction with SET_PARAMTER is much like a HTTP PUT or POST. An application
+may either use \fICURLOPT_UPLOAD\fP with \fICURLOPT_READDATA\fP like a HTTP
+PUT, or it may use \fICURLOPT_POSTFIELDS\fP like a HTTP POST. No chunked
+transfers are allowed, so the application must set the
+\fICURLOPT_INFILESIZE\fP in the former and \fICURLOPT_POSTFIELDSIZE\fP in the
+latter. Also, there is no use of multi-part POSTs within RTSP. (Added in
+7.20.0)
+.IP CURL_RTSPREQ_RECORD
+Used to tell the server to record a session. Use the \fICURLOPT_RANGE\fP
+option to modify the record time. (Added in 7.20.0)
+.IP CURL_RTSPREQ_RECEIVE
+This is a special request because it does not send any data to the server. The
+application may call this function in order to receive interleaved RTP
+data. It will return after processing one read buffer of data in order to give
+the application a chance to run. (Added in 7.20.0)
+.RE
+.IP CURLOPT_RTSP_SESSION_ID
+Pass a char * as a parameter to set the value of the current RTSP Session ID
+for the handle. Useful for resuming an in-progress session. Once this value is
+set to any non-NULL value, libcurl will return \fICURLE_RTSP_SESSION_ERROR\fP
+if ID received from the server does not match. If unset (or set to NULL),
+libcurl will automatically set the ID the first time the server sets it in a
+response. (Added in 7.20.0)
+.IP CURLOPT_RTSP_STREAM_URI
+Set the stream URI to operate on by passing a char * . For example, a single
+session may be controlling \fIrtsp://foo/twister/audio\fP and
+\fIrtsp://foo/twister/video\fP and the application can switch to the
+appropriate stream using this option. If unset, libcurl will default to
+operating on generic server options by passing '*' in the place of the RTSP
+Stream URI. This option is distinct from \fICURLOPT_URL\fP. When working with
+RTSP, the \fICURLOPT_STREAM_URI\fP indicates what URL to send to the server in
+the request header while the \fICURLOPT_URL\fP indicates where to make the
+connection to. (e.g. the \fICURLOPT_URL\fP for the above examples might be
+set to \fIrtsp://foo/twister\fP (Added in 7.20.0)
+.IP CURLOPT_RTSP_TRANSPORT
+Pass a char * to tell libcurl what to pass for the Transport: header for this
+RTSP session. This is mainly a convenience method to avoid needing to set a
+custom Transport: header for every SETUP request. The application must set a
+Transport: header before issuing a SETUP request. (Added in 7.20.0)
+.IP CURLOPT_RTSP_HEADER
+This option is simply an alias for \fICURLOPT_HTTP_HEADER\fP. Use this to
+replace the standard headers that RTSP and HTTP share. It is also valid to use
+the shortcuts such as \fICURLOPT_USERAGENT\fP. (Added in 7.20.0)
+.IP CURLOPT_RTSP_CLIENT_CSEQ
+Manually set the the CSEQ number to issue for the next RTSP request. Useful if
+the application is resuming a previously broken connection. The CSEQ will
+increment from this new number henceforth. (Added in 7.20.0)
+.IP CURLOPT_RTSP_SERVER_CSEQ
+Manually set the CSEQ number to expect for the next RTSP Server->Client
+request. At the moment, this feature (listening for Server requests) is
+unimplemented. (Added in 7.20.0)
+.SH PROTOCOL OPTIONS
+.IP CURLOPT_TRANSFERTEXT
+A parameter set to 1 tells the library to use ASCII mode for FTP transfers,
+instead of the default binary transfer. For win32 systems it does not set the
+stdout to binary mode. This option can be usable when transferring text data
+between systems with different views on certain characters, such as newlines
+or similar.
+
+libcurl does not do a complete ASCII conversion when doing ASCII transfers
+over FTP. This is a known limitation/flaw that nobody has rectified. libcurl
+simply sets the mode to ASCII and performs a standard transfer.
+.IP CURLOPT_PROXY_TRANSFER_MODE
+Pass a long. If the value is set to 1 (one), it tells libcurl to set the
+transfer mode (binary or ASCII) for FTP transfers done via a HTTP proxy, by
+appending ;type=a or ;type=i to the URL. Without this setting, or it being set
+to 0 (zero, the default), \fICURLOPT_TRANSFERTEXT\fP has no effect when doing
+FTP via a proxy. Beware that not all proxies support this feature. (Added in
+7.18.0)
+.IP CURLOPT_CRLF
+Pass a long. If the value is set to 1 (one), libcurl converts Unix newlines to
+CRLF newlines on transfers. Disable this option again by setting the value to
+0 (zero).
+.IP CURLOPT_RANGE
+Pass a char * as parameter, which should contain the specified range you
+want. It should be in the format "X-Y", where X or Y may be left out. HTTP
+transfers also support several intervals, separated with commas as in
+\fI"X-Y,N-M"\fP. Using this kind of multiple intervals will cause the HTTP
+server to send the response document in pieces (using standard MIME separation
+techniques). For RTSP, the formatting of a range should follow RFC2326
+Section 12.29. For RTSP, byte ranges are \fBnot\fP permitted. Instead, ranges
+should be given in npt, utc, or smpte formats.
+
+Pass a NULL to this option to disable the use of ranges.
+
+Ranges work on HTTP, FTP, FILE (since 7.18.0), and RTSP (since 7.20.0)
+transfers only.
+.IP CURLOPT_RESUME_FROM
+Pass a long as parameter. It contains the offset in number of bytes that you
+want the transfer to start from. Set this option to 0 to make the transfer
+start from the beginning (effectively disabling resume). For FTP, set this
+option to -1 to make the transfer start from the end of the target file
+(useful to continue an interrupted upload).
+
+When doing uploads with FTP, the resume position is where in the local/source
+file libcurl should try to resume the upload from and it will then append the
+source file to the remote target file.
+.IP CURLOPT_RESUME_FROM_LARGE
+Pass a curl_off_t as parameter. It contains the offset in number of bytes that
+you want the transfer to start from. (Added in 7.11.0)
+.IP CURLOPT_CUSTOMREQUEST
+Pass a pointer to a zero terminated string as parameter. It can be used to
+specify the request instead of GET or HEAD when performing HTTP based
+requests, instead of LIST and NLST when performing FTP directory listings and
+instead of LIST and RETR when issuing POP3 based commands. This is
+particularly useful, for example, for performing a HTTP DELETE request or a
+POP3 DELE command.
+
+Please don't perform this at will, on HTTP based requests, by making sure
+your server supports the command you are sending first.
+
+When you change the request method by setting \fBCURLOPT_CUSTOMREQUEST\fP to
+something, you don't actually change how libcurl behaves or acts in regards
+to the particular request method, it will only change the actual string sent
+in the request.
+
+For example:
+
+With the HTTP protocol when you tell libcurl to do a HEAD request, but then
+specify a GET though a custom request libcurl will still act as if it sent a
+HEAD. To switch to a proper HEAD use \fICURLOPT_NOBODY\fP, to switch to a
+proper POST use \fICURLOPT_POST\fP or \fICURLOPT_POSTFIELDS\fP and to switch
+to a proper GET use CURLOPT_HTTPGET.
+
+With the POP3 protocol when you tell libcurl to use a custom request it will
+behave like a LIST or RETR command was sent where it expects data to be
+returned by the server. As such \fICURLOPT_NOBODY\fP should be used when
+specifying commands such as DELE and NOOP for example.
+
+Restore to the internal default by setting this to NULL.
+
+Many people have wrongly used this option to replace the entire request with
+their own, including multiple headers and POST contents. While that might
+work in many cases, it will cause libcurl to send invalid requests and it
+could possibly confuse the remote server badly. Use \fICURLOPT_POST\fP and
+\fICURLOPT_POSTFIELDS\fP to set POST data. Use \fICURLOPT_HTTPHEADER\fP to
+replace or extend the set of headers sent by libcurl. Use
+\fICURLOPT_HTTP_VERSION\fP to change HTTP version.
+
+(Support for POP3 added in 7.26.0)
+.IP CURLOPT_FILETIME
+Pass a long. If it is 1, libcurl will attempt to get the modification date of
+the remote document in this operation. This requires that the remote server
+sends the time or replies to a time querying command. The
+\fIcurl_easy_getinfo(3)\fP function with the \fICURLINFO_FILETIME\fP argument
+can be used after a transfer to extract the received time (if any).
+.IP CURLOPT_NOBODY
+A parameter set to 1 tells the library to not include the body-part in the
+output. This is only relevant for protocols that have separate header and
+body parts. On HTTP(S) servers, this will make libcurl do a HEAD request.
+
+To change request to GET, you should use \fICURLOPT_HTTPGET\fP. Change
+request to POST with \fICURLOPT_POST\fP etc.
+.IP CURLOPT_INFILESIZE
+When uploading a file to a remote site, this option should be used to tell
+libcurl what the expected size of the infile is. This value should be passed
+as a long. See also \fICURLOPT_INFILESIZE_LARGE\fP.
+
+For uploading using SCP, this option or \fICURLOPT_INFILESIZE_LARGE\fP is
+mandatory.
+
+When sending emails using SMTP, this command can be used to specify the
+optional SIZE parameter for the MAIL FROM command. (Added in 7.23.0)
+
+This option does not limit how much data libcurl will actually send, as that
+is controlled entirely by what the read callback returns.
+.IP CURLOPT_INFILESIZE_LARGE
+When uploading a file to a remote site, this option should be used to tell
+libcurl what the expected size of the infile is. This value should be passed
+as a curl_off_t. (Added in 7.11.0)
+
+For uploading using SCP, this option or \fICURLOPT_INFILESIZE\fP is mandatory.
+
+This option does not limit how much data libcurl will actually send, as that
+is controlled entirely by what the read callback returns.
+.IP CURLOPT_UPLOAD
+A parameter set to 1 tells the library to prepare for an upload. The
+\fICURLOPT_READDATA\fP and \fICURLOPT_INFILESIZE\fP or
+\fICURLOPT_INFILESIZE_LARGE\fP options are also interesting for uploads. If
+the protocol is HTTP, uploading means using the PUT request unless you tell
+libcurl otherwise.
+
+Using PUT with HTTP 1.1 implies the use of a "Expect: 100-continue" header.
+You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual.
+
+If you use PUT to a HTTP 1.1 server, you can upload data without knowing the
+size before starting the transfer if you use chunked encoding. You enable this
+by adding a header like "Transfer-Encoding: chunked" with
+\fICURLOPT_HTTPHEADER\fP. With HTTP 1.0 or without chunked transfer, you must
+specify the size.
+.IP CURLOPT_MAXFILESIZE
+Pass a long as parameter. This allows you to specify the maximum size (in
+bytes) of a file to download. If the file requested is larger than this value,
+the transfer will not start and CURLE_FILESIZE_EXCEEDED will be returned.
+
+The file size is not always known prior to download, and for such files this
+option has no effect even if the file transfer ends up being larger than this
+given limit. This concerns both FTP and HTTP transfers.
+.IP CURLOPT_MAXFILESIZE_LARGE
+Pass a curl_off_t as parameter. This allows you to specify the maximum size
+(in bytes) of a file to download. If the file requested is larger than this
+value, the transfer will not start and \fICURLE_FILESIZE_EXCEEDED\fP will be
+returned. (Added in 7.11.0)
+
+The file size is not always known prior to download, and for such files this
+option has no effect even if the file transfer ends up being larger than this
+given limit. This concerns both FTP and HTTP transfers.
+.IP CURLOPT_TIMECONDITION
+Pass a long as parameter. This defines how the \fICURLOPT_TIMEVALUE\fP time
+value is treated. You can set this parameter to \fICURL_TIMECOND_IFMODSINCE\fP
+or \fICURL_TIMECOND_IFUNMODSINCE\fP. This feature applies to HTTP, FTP, RTSP,
+and FILE.
+
+The last modification time of a file is not always known and in such instances
+this feature will have no effect even if the given time condition would not
+have been met. \fIcurl_easy_getinfo(3)\fP with the
+\fICURLINFO_CONDITION_UNMET\fP option can be used after a transfer to learn if
+a zero-byte successful "transfer" was due to this condition not matching.
+.IP CURLOPT_TIMEVALUE
+Pass a long as parameter. This should be the time in seconds since 1 Jan 1970,
+and the time will be used in a condition as specified with
+\fICURLOPT_TIMECONDITION\fP.
+.SH CONNECTION OPTIONS
+.IP CURLOPT_TIMEOUT
+Pass a long as parameter containing the maximum time in seconds that you allow
+the libcurl transfer operation to take. Normally, name lookups can take a
+considerable time and limiting operations to less than a few minutes risk
+aborting perfectly normal operations. This option will cause curl to use the
+SIGALRM to enable time-outing system calls.
+
+In unix-like systems, this might cause signals to be used unless
+\fICURLOPT_NOSIGNAL\fP is set.
+
+Default timeout is 0 (zero) which means it never times out.
+.IP CURLOPT_TIMEOUT_MS
+Like \fICURLOPT_TIMEOUT\fP but takes number of milliseconds instead. If
+libcurl is built to use the standard system name resolver, that portion
+of the transfer will still use full-second resolution for timeouts with
+a minimum timeout allowed of one second.
+(Added in 7.16.2)
+.IP CURLOPT_LOW_SPEED_LIMIT
+Pass a long as parameter. It contains the transfer speed in bytes per second
+that the transfer should be below during \fICURLOPT_LOW_SPEED_TIME\fP seconds
+for the library to consider it too slow and abort.
+.IP CURLOPT_LOW_SPEED_TIME
+Pass a long as parameter. It contains the time in seconds that the transfer
+should be below the \fICURLOPT_LOW_SPEED_LIMIT\fP for the library to consider
+it too slow and abort.
+.IP CURLOPT_MAX_SEND_SPEED_LARGE
+Pass a curl_off_t as parameter. If an upload exceeds this speed (counted in
+bytes per second) on cumulative average during the transfer, the transfer will
+pause to keep the average rate less than or equal to the parameter value.
+Defaults to unlimited speed. (Added in 7.15.5)
+.IP CURLOPT_MAX_RECV_SPEED_LARGE
+Pass a curl_off_t as parameter. If a download exceeds this speed (counted in
+bytes per second) on cumulative average during the transfer, the transfer will
+pause to keep the average rate less than or equal to the parameter
+value. Defaults to unlimited speed. (Added in 7.15.5)
+.IP CURLOPT_MAXCONNECTS
+Pass a long. The set number will be the persistent connection cache size. The
+set amount will be the maximum amount of simultaneously open connections that
+libcurl may cache in this easy handle. Default is 5, and there isn't much
+point in changing this value unless you are perfectly aware of how this works
+and changes libcurl's behaviour. This concerns connections using any of the
+protocols that support persistent connections.
+
+When reaching the maximum limit, curl closes the oldest one in the cache to
+prevent increasing the number of open connections.
+
+If you already have performed transfers with this curl handle, setting a
+smaller MAXCONNECTS than before may cause open connections to get closed
+unnecessarily.
+
+If you add this easy handle to a multi handle, this setting is not
+acknowledged, and you must instead use \fIcurl_multi_setopt(3)\fP and the
+\fICURLMOPT_MAXCONNECTS\fP option.
+.IP CURLOPT_CLOSEPOLICY
+(Obsolete) This option does nothing.
+.IP CURLOPT_FRESH_CONNECT
+Pass a long. Set to 1 to make the next transfer use a new (fresh) connection
+by force. If the connection cache is full before this connection, one of the
+existing connections will be closed as according to the selected or default
+policy. This option should be used with caution and only if you understand
+what it does. Set this to 0 to have libcurl attempt re-using an existing
+connection (default behavior).
+.IP CURLOPT_FORBID_REUSE
+Pass a long. Set to 1 to make the next transfer explicitly close the
+connection when done. Normally, libcurl keeps all connections alive when done
+with one transfer in case a succeeding one follows that can re-use them.
+This option should be used with caution and only if you understand what it
+does. Set to 0 to have libcurl keep the connection open for possible later
+re-use (default behavior).
+.IP CURLOPT_CONNECTTIMEOUT
+Pass a long. It should contain the maximum time in seconds that you allow the
+connection to the server to take. This only limits the connection phase, once
+it has connected, this option is of no more use. Set to zero to switch to the
+default built-in connection timeout - 300 seconds. See also the
+\fICURLOPT_TIMEOUT\fP option.
+
+In unix-like systems, this might cause signals to be used unless
+\fICURLOPT_NOSIGNAL\fP is set.
+.IP CURLOPT_CONNECTTIMEOUT_MS
+Like \fICURLOPT_CONNECTTIMEOUT\fP but takes the number of milliseconds
+instead. If libcurl is built to use the standard system name resolver,
+that portion of the connect will still use full-second resolution for
+timeouts with a minimum timeout allowed of one second.
+(Added in 7.16.2)
+.IP CURLOPT_IPRESOLVE
+Allows an application to select what kind of IP addresses to use when
+resolving host names. This is only interesting when using host names that
+resolve addresses using more than one version of IP. The allowed values are:
+.RS
+.IP CURL_IPRESOLVE_WHATEVER
+Default, resolves addresses to all IP versions that your system allows.
+.IP CURL_IPRESOLVE_V4
+Resolve to IPv4 addresses.
+.IP CURL_IPRESOLVE_V6
+Resolve to IPv6 addresses.
+.RE
+.IP CURLOPT_CONNECT_ONLY
+Pass a long. If the parameter equals 1, it tells the library to perform all
+the required proxy authentication and connection setup, but no data transfer.
+This option is implemented for HTTP, SMTP and POP3.
+
+The option can be used to simply test a connection to a server, but is more
+useful when used with the \fICURLINFO_LASTSOCKET\fP option to
+\fIcurl_easy_getinfo(3)\fP as the library can set up the connection and then
+the application can obtain the most recently used socket for special data
+transfers. (Added in 7.15.2)
+.IP CURLOPT_USE_SSL
+Pass a long using one of the values from below, to make libcurl use your
+desired level of SSL for the transfer. (Added in 7.11.0)
+
+This is for enabling SSL/TLS when you use FTP, SMTP, POP3, IMAP etc.
+
+(This option was known as CURLOPT_FTP_SSL up to 7.16.4, and the constants
+were known as CURLFTPSSL_*)
+.RS
+.IP CURLUSESSL_NONE
+Don't attempt to use SSL.
+.IP CURLUSESSL_TRY
+Try using SSL, proceed as normal otherwise.
+.IP CURLUSESSL_CONTROL
+Require SSL for the control connection or fail with \fICURLE_USE_SSL_FAILED\fP.
+.IP CURLUSESSL_ALL
+Require SSL for all communication or fail with \fICURLE_USE_SSL_FAILED\fP.
+.RE
+.IP CURLOPT_RESOLVE
+Pass a pointer to a linked list of strings with host name resolve information
+to use for requests with this handle. The linked list should be a fully valid
+list of \fBstruct curl_slist\fP structs properly filled in. Use
+\fIcurl_slist_append(3)\fP to create the list and \fIcurl_slist_free_all(3)\fP
+to clean up an entire list.
+
+Each single name resolve string should be written using the format
+HOST:PORT:ADDRESS where HOST is the name libcurl will try to resolve, PORT is
+the port number of the service where libcurl wants to connect to the HOST and
+ADDRESS is the numerical IP address. If libcurl is built to support IPv6,
+ADDRESS can of course be either IPv4 or IPv6 style addressing.
+
+This option effectively pre-populates the DNS cache with entries for the
+host+port pair so redirects and everything that operations against the
+HOST+PORT will instead use your provided ADDRESS.
+
+You can remove names from the DNS cache again, to stop providing these fake
+resolves, by including a string in the linked list that uses the format
+\&"-HOST:PORT". The host name must be prefixed with a dash, and the host name
+and port number must exactly match what was already added previously.
+
+(Added in 7.21.3)
+.IP CURLOPT_DNS_SERVERS
+Set the list of DNS servers to be used instead of the system default.
+The format of the dns servers option is:
+
+host[:port][,host[:port]]...
+
+For example:
+
+192.168.1.100,192.168.1.101,3.4.5.6
+
+This option requires that libcurl was built with a resolver backend that
+supports this operation. The c-ares backend is the only such one.
+
+(Added in 7.24.0)
+.IP CURLOPT_ACCEPTTIMEOUT_MS
+Pass a long telling libcurl the maximum number of milliseconds to wait for a
+server to connect back to libcurl when an active FTP connection is used. If no
+timeout is set, the internal default of 60000 will be used. (Added in 7.24.0)
+.SH SSL and SECURITY OPTIONS
+.IP CURLOPT_SSLCERT
+Pass a pointer to a zero terminated string as parameter. The string should be
+the file name of your certificate. The default format is "PEM" and can be
+changed with \fICURLOPT_SSLCERTTYPE\fP.
+
+With NSS this can also be the nickname of the certificate you wish to
+authenticate with. If you want to use a file from the current directory, please
+precede it with "./" prefix, in order to avoid confusion with a nickname.
+.IP CURLOPT_SSLCERTTYPE
+Pass a pointer to a zero terminated string as parameter. The string should be
+the format of your certificate. Supported formats are "PEM" and "DER". (Added
+in 7.9.3)
+.IP CURLOPT_SSLKEY
+Pass a pointer to a zero terminated string as parameter. The string should be
+the file name of your private key. The default format is "PEM" and can be
+changed with \fICURLOPT_SSLKEYTYPE\fP.
+.IP CURLOPT_SSLKEYTYPE
+Pass a pointer to a zero terminated string as parameter. The string should be
+the format of your private key. Supported formats are "PEM", "DER" and "ENG".
+
+The format "ENG" enables you to load the private key from a crypto engine. In
+this case \fICURLOPT_SSLKEY\fP is used as an identifier passed to the
+engine. You have to set the crypto engine with \fICURLOPT_SSLENGINE\fP.
+\&"DER" format key file currently does not work because of a bug in OpenSSL.
+.IP CURLOPT_KEYPASSWD
+Pass a pointer to a zero terminated string as parameter. It will be used as
+the password required to use the \fICURLOPT_SSLKEY\fP or
+\fICURLOPT_SSH_PRIVATE_KEYFILE\fP private key.
+You never needed a pass phrase to load a certificate but you need one to
+load your private key.
+
+(This option was known as CURLOPT_SSLKEYPASSWD up to 7.16.4 and
+CURLOPT_SSLCERTPASSWD up to 7.9.2)
+.IP CURLOPT_SSLENGINE
+Pass a pointer to a zero terminated string as parameter. It will be used as
+the identifier for the crypto engine you want to use for your private
+key.
+
+If the crypto device cannot be loaded, \fICURLE_SSL_ENGINE_NOTFOUND\fP is
+returned.
+.IP CURLOPT_SSLENGINE_DEFAULT
+Sets the actual crypto engine as the default for (asymmetric) crypto
+operations.
+
+If the crypto device cannot be set, \fICURLE_SSL_ENGINE_SETFAILED\fP is
+returned.
+
+Even though this option doesn't need any parameter, in some configurations
+\fIcurl_easy_setopt\fP might be defined as a macro taking exactly three
+arguments. Therefore, it's recommended to pass 1 as parameter to this option.
+.IP CURLOPT_SSLVERSION
+Pass a long as parameter to control what version of SSL/TLS to attempt to use.
+The available options are:
+.RS
+.IP CURL_SSLVERSION_DEFAULT
+The default action. This will attempt to figure out the remote SSL protocol
+version, i.e. either SSLv3 or TLSv1 (but not SSLv2, which became disabled
+by default with 7.18.1).
+.IP CURL_SSLVERSION_TLSv1
+Force TLSv1
+.IP CURL_SSLVERSION_SSLv2
+Force SSLv2
+.IP CURL_SSLVERSION_SSLv3
+Force SSLv3
+.RE
+.IP CURLOPT_SSL_VERIFYPEER
+Pass a long as parameter. By default, curl assumes a value of 1.
+
+This option determines whether curl verifies the authenticity of the peer's
+certificate. A value of 1 means curl verifies; 0 (zero) means it doesn't.
+
+When negotiating a SSL connection, the server sends a certificate indicating
+its identity. Curl verifies whether the certificate is authentic, i.e. that
+you can trust that the server is who the certificate says it is. This trust
+is based on a chain of digital signatures, rooted in certification authority
+(CA) certificates you supply. curl uses a default bundle of CA certificates
+(the path for that is determined at build time) and you can specify alternate
+certificates with the \fICURLOPT_CAINFO\fP option or the \fICURLOPT_CAPATH\fP
+option.
+
+When \fICURLOPT_SSL_VERIFYPEER\fP is nonzero, and the verification fails to
+prove that the certificate is authentic, the connection fails. When the
+option is zero, the peer certificate verification succeeds regardless.
+
+Authenticating the certificate is not by itself very useful. You typically
+want to ensure that the server, as authentically identified by its
+certificate, is the server you mean to be talking to. Use
+\fICURLOPT_SSL_VERIFYHOST\fP to control that. The check that the host name in
+the certificate is valid for the host name you're connecting to is done
+independently of the \fICURLOPT_SSL_VERIFYPEER\fP option.
+.IP CURLOPT_CAINFO
+Pass a char * to a zero terminated string naming a file holding one or more
+certificates to verify the peer with. This makes sense only when used in
+combination with the \fICURLOPT_SSL_VERIFYPEER\fP option. If
+\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAINFO\fP need not
+even indicate an accessible file.
+
+This option is by default set to the system path where libcurl's cacert bundle
+is assumed to be stored, as established at build time.
+
+When built against NSS, this is the directory that the NSS certificate
+database resides in.
+.IP CURLOPT_ISSUERCERT
+Pass a char * to a zero terminated string naming a file holding a CA
+certificate in PEM format. If the option is set, an additional check against
+the peer certificate is performed to verify the issuer is indeed the one
+associated with the certificate provided by the option. This additional check
+is useful in multi-level PKI where one needs to enforce that the peer
+certificate is from a specific branch of the tree.
+
+This option makes sense only when used in combination with the
+\fICURLOPT_SSL_VERIFYPEER\fP option. Otherwise, the result of the check is not
+considered as failure.
+
+A specific error code (CURLE_SSL_ISSUER_ERROR) is defined with the option,
+which is returned if the setup of the SSL/TLS session has failed due to a
+mismatch with the issuer of peer certificate (\fICURLOPT_SSL_VERIFYPEER\fP has
+to be set too for the check to fail). (Added in 7.19.0)
+.IP CURLOPT_CAPATH
+Pass a char * to a zero terminated string naming a directory holding multiple
+CA certificates to verify the peer with. If libcurl is built against OpenSSL,
+the certificate directory must be prepared using the openssl c_rehash utility.
+This makes sense only when used in combination with the
+\fICURLOPT_SSL_VERIFYPEER\fP option. If \fICURLOPT_SSL_VERIFYPEER\fP is zero,
+\fICURLOPT_CAPATH\fP need not even indicate an accessible path. The
+\fICURLOPT_CAPATH\fP function apparently does not work in Windows due to some
+limitation in openssl. This option is OpenSSL-specific and does nothing if
+libcurl is built to use GnuTLS. NSS-powered libcurl provides the option only
+for backward compatibility.
+.IP CURLOPT_CRLFILE
+Pass a char * to a zero terminated string naming a file with the concatenation
+of CRL (in PEM format) to use in the certificate validation that occurs during
+the SSL exchange.
+
+When curl is built to use NSS or GnuTLS, there is no way to influence the use
+of CRL passed to help in the verification process. When libcurl is built with
+OpenSSL support, X509_V_FLAG_CRL_CHECK and X509_V_FLAG_CRL_CHECK_ALL are both
+set, requiring CRL check against all the elements of the certificate chain if
+a CRL file is passed.
+
+This option makes sense only when used in combination with the
+\fICURLOPT_SSL_VERIFYPEER\fP option.
+
+A specific error code (CURLE_SSL_CRL_BADFILE) is defined with the option. It
+is returned when the SSL exchange fails because the CRL file cannot be loaded.
+A failure in certificate verification due to a revocation information found in
+the CRL does not trigger this specific error. (Added in 7.19.0)
+.IP CURLOPT_SSL_VERIFYHOST
+Pass a long as parameter.
+
+This option determines whether libcurl verifies that the server cert is for
+the server it is known as.
+
+When negotiating a SSL connection, the server sends a certificate indicating
+its identity.
+
+When \fICURLOPT_SSL_VERIFYHOST\fP is 2, that certificate must indicate that
+the server is the server to which you meant to connect, or the connection
+fails.
+
+Curl considers the server the intended one when the Common Name field or a
+Subject Alternate Name field in the certificate matches the host name in the
+URL to which you told Curl to connect.
+
+When the value is 1, libcurl will return a failure. It was previously (in
+7.28.0 and earlier) a debug option of some sorts, but it is no longer
+supported due to frequently leading to programmer mistakes.
+
+When the value is 0, the connection succeeds regardless of the names in the
+certificate.
+
+The default value for this option is 2.
+
+This option controls checking the server's certificate's claimed identity.
+The server could be lying. To control lying, see
+\fICURLOPT_SSL_VERIFYPEER\fP. If libcurl is built against NSS and
+\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_SSL_VERIFYHOST\fP
+is ignored.
+
+.IP CURLOPT_CERTINFO
+Pass a long set to 1 to enable libcurl's certificate chain info gatherer. With
+this enabled, libcurl (if built with OpenSSL) will extract lots of information
+and data about the certificates in the certificate chain used in the SSL
+connection. This data is then possible to extract after a transfer using
+\fIcurl_easy_getinfo(3)\fP and its option \fICURLINFO_CERTINFO\fP. (Added in
+7.19.1)
+.IP CURLOPT_RANDOM_FILE
+Pass a char * to a zero terminated file name. The file will be used to read
+from to seed the random engine for SSL. The more random the specified file is,
+the more secure the SSL connection will become.
+.IP CURLOPT_EGDSOCKET
+Pass a char * to the zero terminated path name to the Entropy Gathering Daemon
+socket. It will be used to seed the random engine for SSL.
+.IP CURLOPT_SSL_CIPHER_LIST
+Pass a char *, pointing to a zero terminated string holding the list of
+ciphers to use for the SSL connection. The list must be syntactically correct,
+it consists of one or more cipher strings separated by colons. Commas or
+spaces are also acceptable separators but colons are normally used, \&!, \&-
+and \&+ can be used as operators.
+
+For OpenSSL and GnuTLS valid examples of cipher lists include 'RC4-SHA',
+\'SHA1+DES\', 'TLSv1' and 'DEFAULT'. The default list is normally set when you
+compile OpenSSL.
+
+You'll find more details about cipher lists on this URL:
+\fIhttp://www.openssl.org/docs/apps/ciphers.html\fP
+
+For NSS, valid examples of cipher lists include 'rsa_rc4_128_md5',
+\'rsa_aes_128_sha\', etc. With NSS you don't add/remove ciphers. If one uses
+this option then all known ciphers are disabled and only those passed in
+are enabled.
+
+You'll find more details about the NSS cipher lists on this URL:
+\fIhttp://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html#Directives\fP
+
+.IP CURLOPT_SSL_SESSIONID_CACHE
+Pass a long set to 0 to disable libcurl's use of SSL session-ID caching. Set
+this to 1 to enable it. By default all transfers are done using the
+cache. While nothing ever should get hurt by attempting to reuse SSL
+session-IDs, there seem to be broken SSL implementations in the wild that may
+require you to disable this in order for you to succeed. (Added in 7.16.0)
+.IP CURLOPT_SSL_OPTIONS
+Pass a long with a bitmask to tell libcurl about specific SSL behaviors.
+
+CURLSSLOPT_ALLOW_BEAST is the only supported bit and by setting this the user
+will tell libcurl to not attempt to use any workarounds for a security flaw
+in the SSL3 and TLS1.0 protocols. If this option isn't used or this bit is
+set to 0, the SSL layer libcurl uses may use a work-around for this flaw
+although it might cause interoperability problems with some (older) SSL
+implementations. WARNING: avoiding this work-around loosens the security, and
+by setting this option to 1 you ask for exactly that. (Added in 7.25.0)
+.IP CURLOPT_KRBLEVEL
+Pass a char * as parameter. Set the kerberos security level for FTP; this also
+enables kerberos awareness. This is a string, \&'clear', \&'safe',
+\&'confidential' or \&'private'. If the string is set but doesn't match one
+of these, 'private' will be used. Set the string to NULL to disable kerberos
+support for FTP.
+
+(This option was known as CURLOPT_KRB4LEVEL up to 7.16.3)
+.IP CURLOPT_GSSAPI_DELEGATION
+Set the parameter to CURLGSSAPI_DELEGATION_FLAG to allow unconditional GSSAPI
+credential delegation. The delegation is disabled by default since 7.21.7.
+Set the parameter to CURLGSSAPI_DELEGATION_POLICY_FLAG to delegate only if
+the OK-AS-DELEGATE flag is set in the service ticket in case this feature is
+supported by the GSSAPI implementation and the definition of
+GSS_C_DELEG_POLICY_FLAG was available at compile-time.
+(Added in 7.22.0)
+.SH SSH OPTIONS
+.IP CURLOPT_SSH_AUTH_TYPES
+Pass a long set to a bitmask consisting of one or more of
+CURLSSH_AUTH_PUBLICKEY, CURLSSH_AUTH_PASSWORD, CURLSSH_AUTH_HOST,
+CURLSSH_AUTH_KEYBOARD and CURLSSH_AUTH_AGENT. Set CURLSSH_AUTH_ANY to let
+libcurl pick a suitable one. Currently CURLSSH_AUTH_HOST has no effect. (Added
+in 7.16.1) If CURLSSH_AUTH_AGENT is used, libcurl attempts to connect to
+ssh-agent or pageant and let the agent attempt the authentication. (Added in
+7.28.0)
+.IP CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
+Pass a char * pointing to a string containing 32 hexadecimal digits. The
+string should be the 128 bit MD5 checksum of the remote host's public key, and
+libcurl will reject the connection to the host unless the md5sums match. This
+option is only for SCP and SFTP transfers. (Added in 7.17.1)
+.IP CURLOPT_SSH_PUBLIC_KEYFILE
+Pass a char * pointing to a file name for your public key. If not used,
+libcurl defaults to \fB$HOME/.ssh/id_dsa.pub\fP if the HOME environment
+variable is set, and just "id_dsa.pub" in the current directory if HOME is not
+set. (Added in 7.16.1)
+If an empty string is passed, libcurl will pass no public key to libssh2
+which then tries to compute it from the private key, this is known to work
+when libssh2 1.4.0+ is linked against OpenSSL. (Added in 7.26.0)
+.IP CURLOPT_SSH_PRIVATE_KEYFILE
+Pass a char * pointing to a file name for your private key. If not used,
+libcurl defaults to \fB$HOME/.ssh/id_dsa\fP if the HOME environment variable
+is set, and just "id_dsa" in the current directory if HOME is not set. If the
+file is password-protected, set the password with
+\fICURLOPT_KEYPASSWD\fP. (Added in 7.16.1)
+.IP CURLOPT_SSH_KNOWNHOSTS
+Pass a pointer to a zero terminated string holding the file name of the
+known_host file to use. The known_hosts file should use the OpenSSH file
+format as supported by libssh2. If this file is specified, libcurl will only
+accept connections with hosts that are known and present in that file, with a
+matching public key. Use \fICURLOPT_SSH_KEYFUNCTION\fP to alter the default
+behavior on host and key (mis)matching. (Added in 7.19.6)
+.IP CURLOPT_SSH_KEYFUNCTION
+Pass a pointer to a curl_sshkeycallback function. It gets called when the
+known_host matching has been done, to allow the application to act and decide
+for libcurl how to proceed. The callback will only be called if
+\fICURLOPT_SSH_KNOWNHOSTS\fP is also set.
+
+The curl_sshkeycallback function gets passed the CURL handle, the key from the
+known_hosts file, the key from the remote site, info from libcurl on the
+matching status and a custom pointer (set with \fICURLOPT_SSH_KEYDATA\fP). It
+MUST return one of the following return codes to tell libcurl how to act:
+.RS
+.IP CURLKHSTAT_FINE_ADD_TO_FILE
+The host+key is accepted and libcurl will append it to the known_hosts file
+before continuing with the connection. This will also add the host+key combo
+to the known_host pool kept in memory if it wasn't already present there. The
+adding of data to the file is done by completely replacing the file with a new
+copy, so the permissions of the file must allow this.
+.IP CURLKHSTAT_FINE
+The host+key is accepted libcurl will continue with the connection. This will
+also add the host+key combo to the known_host pool kept in memory if it wasn't
+already present there.
+.IP CURLKHSTAT_REJECT
+The host+key is rejected. libcurl will deny the connection to continue and it
+will be closed.
+.IP CURLKHSTAT_DEFER
+The host+key is rejected, but the SSH connection is asked to be kept alive.
+This feature could be used when the app wants to somehow return back and act
+on the host+key situation and then retry without needing the overhead of
+setting it up from scratch again.
+.RE
+ (Added in 7.19.6)
+.IP CURLOPT_SSH_KEYDATA
+Pass a void * as parameter. This pointer will be passed along verbatim to the
+callback set with \fICURLOPT_SSH_KEYFUNCTION\fP. (Added in 7.19.6)
+.SH OTHER OPTIONS
+.IP CURLOPT_PRIVATE
+Pass a void * as parameter, pointing to data that should be associated with
+this curl handle. The pointer can subsequently be retrieved using
+\fIcurl_easy_getinfo(3)\fP with the CURLINFO_PRIVATE option. libcurl itself
+does nothing with this data. (Added in 7.10.3)
+.IP CURLOPT_SHARE
+Pass a share handle as a parameter. The share handle must have been created by
+a previous call to \fIcurl_share_init(3)\fP. Setting this option, will make
+this curl handle use the data from the shared handle instead of keeping the
+data to itself. This enables several curl handles to share data. If the curl
+handles are used simultaneously in multiple threads, you \fBMUST\fP use the
+locking methods in the share handle. See \fIcurl_share_setopt(3)\fP for
+details.
+
+If you add a share that is set to share cookies, your easy handle will use
+that cookie cache and get the cookie engine enabled. If you unshare an object
+that was using cookies (or change to another object that doesn't share
+cookies), the easy handle will get its cookie engine disabled.
+
+Data that the share object is not set to share will be dealt with the usual
+way, as if no share was used.
+.IP CURLOPT_NEW_FILE_PERMS
+Pass a long as a parameter, containing the value of the permissions that will
+be assigned to newly created files on the remote server. The default value is
+\fI0644\fP, but any valid value can be used. The only protocols that can use
+this are \fIsftp://\fP, \fIscp://\fP, and \fIfile://\fP. (Added in 7.16.4)
+.IP CURLOPT_NEW_DIRECTORY_PERMS
+Pass a long as a parameter, containing the value of the permissions that will
+be assigned to newly created directories on the remote server. The default
+value is \fI0755\fP, but any valid value can be used. The only protocols that
+can use this are \fIsftp://\fP, \fIscp://\fP, and \fIfile://\fP.
+(Added in 7.16.4)
+.SH TELNET OPTIONS
+.IP CURLOPT_TELNETOPTIONS
+Provide a pointer to a curl_slist with variables to pass to the telnet
+negotiations. The variables should be in the format <option=value>. libcurl
+supports the options 'TTYPE', 'XDISPLOC' and 'NEW_ENV'. See the TELNET
+standard for details.
+.SH RETURN VALUE
+CURLE_OK (zero) means that the option was set properly, non-zero means an
+error occurred as \fI<curl/curl.h>\fP defines. See the \fIlibcurl-errors(3)\fP
+man page for the full list with descriptions.
+
+If you try to set an option that libcurl doesn't know about, perhaps because
+the library is too old to support it or the option was removed in a recent
+version, this function will return \fICURLE_FAILED_INIT\fP.
+.SH "SEE ALSO"
+.BR curl_easy_init "(3), " curl_easy_cleanup "(3), " curl_easy_reset "(3)"
diff --git a/docs/libcurl/curl_easy_strerror.3 b/docs/libcurl/curl_easy_strerror.3
new file mode 100644
index 000000000..a26c9c5db
--- /dev/null
+++ b/docs/libcurl/curl_easy_strerror.3
@@ -0,0 +1,37 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_easy_strerror 3 "26 Apr 2004" "libcurl 7.12" "libcurl Manual"
+.SH NAME
+curl_easy_strerror - return string describing error code
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+const char *curl_easy_strerror(CURLcode errornum);
+.SH DESCRIPTION
+The curl_easy_strerror() function returns a string describing the CURLcode
+error code passed in the argument \fIerrornum\fP.
+.SH AVAILABILITY
+This function was added in libcurl 7.12.0
+.SH RETURN VALUE
+A pointer to a zero terminated string.
+.SH "SEE ALSO"
+.BR libcurl-errors "(3), " curl_multi_strerror "(3), " curl_share_strerror "(3)"
diff --git a/docs/libcurl/curl_easy_unescape.3 b/docs/libcurl/curl_easy_unescape.3
new file mode 100644
index 000000000..9b03fd0f9
--- /dev/null
+++ b/docs/libcurl/curl_easy_unescape.3
@@ -0,0 +1,51 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH curl_easy_unescape 3 "7 April 2006" "libcurl 7.15.4" "libcurl Manual"
+.SH NAME
+curl_easy_unescape - URL decodes the given string
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "char *curl_easy_unescape( CURL *" curl ", char *" url ", int "inlength
+.BI ", int *" outlength " );"
+.ad
+.SH DESCRIPTION
+This function converts the given URL encoded input string to a "plain string"
+and returns that in an allocated memory area. All input characters that are
+URL encoded (%XX where XX is a two-digit hexadecimal number) are converted to
+their binary versions.
+
+If the \fBlength\fP argument is set to 0 (zero), \fIcurl_easy_unescape(3)\fP
+will use strlen() on the input \fIurl\fP string to find out the size.
+
+If \fBoutlength\fP is non-NULL, the function will write the length of the
+returned string in the integer it points to. This allows an escaped string
+containing %00 to still get used properly after unescaping.
+
+You must \fIcurl_free(3)\fP the returned string when you're done with it.
+.SH AVAILABILITY
+Added in 7.15.4 and replaces the old \fIcurl_unescape(3)\fP function.
+.SH RETURN VALUE
+A pointer to a zero terminated string or NULL if it failed.
+.SH "SEE ALSO"
+.I curl_easy_escape(3), curl_free(3), RFC 2396
diff --git a/docs/libcurl/curl_escape.3 b/docs/libcurl/curl_escape.3
new file mode 100644
index 000000000..75fd51f2d
--- /dev/null
+++ b/docs/libcurl/curl_escape.3
@@ -0,0 +1,48 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_escape 3 "6 March 2002" "libcurl 7.9" "libcurl Manual"
+.SH NAME
+curl_escape - URL encodes the given string
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "char *curl_escape( char *" url ", int "length " );"
+.ad
+.SH DESCRIPTION
+Obsolete function. Use \fIcurl_easy_escape(3)\fP instead!
+
+This function will convert the given input string to an URL encoded string and
+return that as a new allocated string. All input characters that are not a-z,
+A-Z or 0-9 will be converted to their "URL escaped" version (%NN where NN is a
+two-digit hexadecimal number).
+
+If the 'length' argument is set to 0, curl_escape() will use strlen() on the
+input 'url' string to find out the size.
+
+You must curl_free() the returned string when you're done with it.
+.SH AVAILABILITY
+Since 7.15.4, \fIcurl_easy_escape(3)\fP should be used. This function will
+be removed in a future release.
+.SH RETURN VALUE
+A pointer to a zero terminated string or NULL if it failed.
+.SH "SEE ALSO"
+.BR curl_unescape "(3), " curl_free "(3), " RFC 2396
diff --git a/docs/libcurl/curl_formadd.3 b/docs/libcurl/curl_formadd.3
new file mode 100644
index 000000000..ce4df1e4b
--- /dev/null
+++ b/docs/libcurl/curl_formadd.3
@@ -0,0 +1,235 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_formadd 3 "24 June 2002" "libcurl 7.9.8" "libcurl Manual"
+.SH NAME
+curl_formadd - add a section to a multipart/formdata HTTP POST
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "CURLFORMcode curl_formadd(struct curl_httppost ** " firstitem,
+.BI "struct curl_httppost ** " lastitem, " ...);"
+.ad
+.SH DESCRIPTION
+curl_formadd() is used to append sections when building a multipart/formdata
+HTTP POST (sometimes referred to as RFC2388-style posts). Append one section
+at a time until you've added all the sections you want included and then you
+pass the \fIfirstitem\fP pointer as parameter to \fBCURLOPT_HTTPPOST\fP.
+\fIlastitem\fP is set after each \fIcurl_formadd(3)\fP call and on repeated
+invokes it should be left as set to allow repeated invokes to find the end of
+the list faster.
+
+After the \fIlastitem\fP pointer follow the real arguments.
+
+The pointers \fIfirstitem\fP and \fIlastitem\fP should both be pointing to
+NULL in the first call to this function. All list-data will be allocated by
+the function itself. You must call \fIcurl_formfree(3)\fP on the
+\fIfirstitem\P after the form post has been done to free the resources.
+
+Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header.
+You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual.
+
+First, there are some basics you need to understand about multipart/formdata
+posts. Each part consists of at least a NAME and a CONTENTS part. If the part
+is made for file upload, there are also a stored CONTENT-TYPE and a FILENAME.
+Below, we'll discuss what options you use to set these properties in the
+parts you want to add to your post.
+
+The options listed first are for making normal parts. The options from
+\fICURLFORM_FILE\fP through \fICURLFORM_BUFFERLENGTH\fP are for file upload
+parts.
+.SH OPTIONS
+.IP CURLFORM_COPYNAME
+followed by a string which provides the \fIname\fP of this part. libcurl
+copies the string so your application doesn't need to keep it around after
+this function call. If the name isn't NUL-terminated, or if you'd
+like it to contain zero bytes, you must set its length with
+\fBCURLFORM_NAMELENGTH\fP. The copied data will be freed by
+\fIcurl_formfree(3)\fP.
+.IP CURLFORM_PTRNAME
+followed by a string which provides the \fIname\fP of this part. libcurl
+will use the pointer and refer to the data in your application, so you
+must make sure it remains until curl no longer needs it. If the name
+isn't NUL-terminated, or if you'd like it to contain zero
+bytes, you must set its length with \fBCURLFORM_NAMELENGTH\fP.
+.IP CURLFORM_COPYCONTENTS
+followed by a pointer to the contents of this part, the actual data
+to send away. libcurl copies the provided data, so your application doesn't
+need to keep it around after this function call. If the data isn't null
+terminated, or if you'd like it to contain zero bytes, you must
+set the length of the name with \fBCURLFORM_CONTENTSLENGTH\fP. The copied
+data will be freed by \fIcurl_formfree(3)\fP.
+.IP CURLFORM_PTRCONTENTS
+followed by a pointer to the contents of this part, the actual data
+to send away. libcurl will use the pointer and refer to the data in your
+application, so you must make sure it remains until curl no longer needs it.
+If the data isn't NUL-terminated, or if you'd like it to contain zero bytes,
+you must set its length with \fBCURLFORM_CONTENTSLENGTH\fP.
+.IP CURLFORM_CONTENTSLENGTH
+followed by a long giving the length of the contents. Note that for
+\fICURLFORM_STREAM\fP contents, this option is mandatory.
+.IP CURLFORM_FILECONTENT
+followed by a filename, causes that file to be read and its contents used
+as data in this part. This part does \fInot\fP automatically become a file
+upload part simply because its data was read from a file.
+.IP CURLFORM_FILE
+followed by a filename, makes this part a file upload part. It sets the
+\fIfilename\fP field to the basename of the provided filename, it reads the
+contents of the file and passes them as data and sets the content-type if the
+given file match one of the internally known file extensions. For
+\fBCURLFORM_FILE\fP the user may send one or more files in one part by
+providing multiple \fBCURLFORM_FILE\fP arguments each followed by the filename
+(and each \fICURLFORM_FILE\fP is allowed to have a
+\fICURLFORM_CONTENTTYPE\fP).
+.IP CURLFORM_CONTENTTYPE
+is used in combination with \fICURLFORM_FILE\fP. Followed by a pointer to a
+string which provides the content-type for this part, possibly instead of an
+internally chosen one.
+.IP CURLFORM_FILENAME
+is used in combination with \fICURLFORM_FILE\fP. Followed by a pointer to a
+string, it tells libcurl to use the given string as the \fIfilename\fP in the
+file upload part instead of the actual file name.
+.IP CURLFORM_BUFFER
+is used for custom file upload parts without use of \fICURLFORM_FILE\fP. It
+tells libcurl that the file contents are already present in a buffer. The
+parameter is a string which provides the \fIfilename\fP field in the content
+header.
+.IP CURLFORM_BUFFERPTR
+is used in combination with \fICURLFORM_BUFFER\fP. The parameter is a pointer
+to the buffer to be uploaded. This buffer must not be freed until after
+\fIcurl_easy_cleanup(3)\fP is called. You must also use
+\fICURLFORM_BUFFERLENGTH\fP to set the number of bytes in the buffer.
+.IP CURLFORM_BUFFERLENGTH
+is used in combination with \fICURLFORM_BUFFER\fP. The parameter is a
+long which gives the length of the buffer.
+.IP CURLFORM_STREAM
+Tells libcurl to use the \fICURLOPT_READFUNCTION\fP callback to get data. The
+parameter you pass to \fICURLFORM_STREAM\fP is the pointer passed on to the
+read callback's fourth argument. If you want the part to look like a file
+upload one, set the \fICURLFORM_FILENAME\fP parameter as well. Note that when
+using \fICURLFORM_STREAM\fP, \fICURLFORM_CONTENTSLENGTH\fP must also be set
+with the total expected length of the part. (Option added in libcurl 7.18.2)
+.IP CURLFORM_ARRAY
+Another possibility to send options to curl_formadd() is the
+\fBCURLFORM_ARRAY\fP option, that passes a struct curl_forms array pointer as
+its value. Each curl_forms structure element has a CURLformoption and a char
+pointer. The final element in the array must be a CURLFORM_END. All available
+options can be used in an array, except the CURLFORM_ARRAY option itself! The
+last argument in such an array must always be \fBCURLFORM_END\fP.
+.IP CURLFORM_CONTENTHEADER
+specifies extra headers for the form POST section. This takes a curl_slist
+prepared in the usual way using \fBcurl_slist_append\fP and appends the list
+of headers to those libcurl automatically generates. The list must exist while
+the POST occurs, if you free it before the post completes you may experience
+problems.
+
+When you've passed the HttpPost pointer to \fIcurl_easy_setopt(3)\fP (using
+the \fICURLOPT_HTTPPOST\fP option), you must not free the list until after
+you've called \fIcurl_easy_cleanup(3)\fP for the curl handle.
+
+See example below.
+.SH RETURN VALUE
+0 means everything was ok, non-zero means an error occurred corresponding
+to a CURL_FORMADD_* constant defined in
+.I <curl/curl.h>
+.SH EXAMPLE
+.nf
+
+ struct curl_httppost* post = NULL;
+ struct curl_httppost* last = NULL;
+ char namebuffer[] = "name buffer";
+ long namelength = strlen(namebuffer);
+ char buffer[] = "test buffer";
+ char htmlbuffer[] = "<HTML>test buffer</HTML>";
+ long htmlbufferlength = strlen(htmlbuffer);
+ struct curl_forms forms[3];
+ char file1[] = "my-face.jpg";
+ char file2[] = "your-face.jpg";
+ /* add null character into htmlbuffer, to demonstrate that
+ transfers of buffers containing null characters actually work
+ */
+ htmlbuffer[8] = '\\0';
+
+ /* Add simple name/content section */
+ curl_formadd(&post, &last, CURLFORM_COPYNAME, "name",
+ CURLFORM_COPYCONTENTS, "content", CURLFORM_END);
+
+ /* Add simple name/content/contenttype section */
+ curl_formadd(&post, &last, CURLFORM_COPYNAME, "htmlcode",
+ CURLFORM_COPYCONTENTS, "<HTML></HTML>",
+ CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END);
+
+ /* Add name/ptrcontent section */
+ curl_formadd(&post, &last, CURLFORM_COPYNAME, "name_for_ptrcontent",
+ CURLFORM_PTRCONTENTS, buffer, CURLFORM_END);
+
+ /* Add ptrname/ptrcontent section */
+ curl_formadd(&post, &last, CURLFORM_PTRNAME, namebuffer,
+ CURLFORM_PTRCONTENTS, buffer, CURLFORM_NAMELENGTH,
+ namelength, CURLFORM_END);
+
+ /* Add name/ptrcontent/contenttype section */
+ curl_formadd(&post, &last, CURLFORM_COPYNAME, "html_code_with_hole",
+ CURLFORM_PTRCONTENTS, htmlbuffer,
+ CURLFORM_CONTENTSLENGTH, htmlbufferlength,
+ CURLFORM_CONTENTTYPE, "text/html", CURLFORM_END);
+
+ /* Add simple file section */
+ curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture",
+ CURLFORM_FILE, "my-face.jpg", CURLFORM_END);
+
+ /* Add file/contenttype section */
+ curl_formadd(&post, &last, CURLFORM_COPYNAME, "picture",
+ CURLFORM_FILE, "my-face.jpg",
+ CURLFORM_CONTENTTYPE, "image/jpeg", CURLFORM_END);
+
+ /* Add two file section */
+ curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures",
+ CURLFORM_FILE, "my-face.jpg",
+ CURLFORM_FILE, "your-face.jpg", CURLFORM_END);
+
+ /* Add two file section using CURLFORM_ARRAY */
+ forms[0].option = CURLFORM_FILE;
+ forms[0].value = file1;
+ forms[1].option = CURLFORM_FILE;
+ forms[1].value = file2;
+ forms[2].option = CURLFORM_END;
+
+ /* Add a buffer to upload */
+ curl_formadd(&post, &last,
+ CURLFORM_COPYNAME, "name",
+ CURLFORM_BUFFER, "data",
+ CURLFORM_BUFFERPTR, record,
+ CURLFORM_BUFFERLENGTH, record_length,
+ CURLFORM_END);
+
+ /* no option needed for the end marker */
+ curl_formadd(&post, &last, CURLFORM_COPYNAME, "pictures",
+ CURLFORM_ARRAY, forms, CURLFORM_END);
+ /* Add the content of a file as a normal post text value */
+ curl_formadd(&post, &last, CURLFORM_COPYNAME, "filecontent",
+ CURLFORM_FILECONTENT, ".bashrc", CURLFORM_END);
+ /* Set the form info */
+ curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
+
+.SH "SEE ALSO"
+.BR curl_easy_setopt "(3), "
+.BR curl_formfree "(3)"
diff --git a/docs/libcurl/curl_formfree.3 b/docs/libcurl/curl_formfree.3
new file mode 100644
index 000000000..7438a1640
--- /dev/null
+++ b/docs/libcurl/curl_formfree.3
@@ -0,0 +1,44 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_formfree 3 "6 April 2001" "libcurl 7.7.1" "libcurl Manual"
+.SH NAME
+curl_formfree - free a previously build multipart/formdata HTTP POST chain
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "void curl_formfree(struct curl_httppost *" form);
+.ad
+.SH DESCRIPTION
+curl_formfree() is used to clean up data previously built/appended with
+\fIcurl_formadd(3)\fP. This must be called when the data has been used, which
+typically means after \fIcurl_easy_perform(3)\fP has been called.
+
+The pointer to free is the same pointer you passed to the
+\fBCURLOPT_HTTPPOST\fP option, which is the \fIfirstitem\fP pointer from the
+\fIcurl_formadd(3)\fP invoke(s).
+
+\fBform\fP is the pointer as returned from a previous call to
+\fIcurl_formadd(3)\fP and may be NULL.
+.SH RETURN VALUE
+None
+.SH "SEE ALSO"
+.BR curl_formadd "(3) "
diff --git a/docs/libcurl/curl_formget.3 b/docs/libcurl/curl_formget.3
new file mode 100644
index 000000000..b52622136
--- /dev/null
+++ b/docs/libcurl/curl_formget.3
@@ -0,0 +1,70 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_formget 3 "20 June 2006" "libcurl 7.15.5" "libcurl Manual"
+.SH NAME
+curl_formget - serialize a previously built multipart/formdata HTTP POST chain
+.SH SYNOPSIS
+.nf
+.B #include <curl/curl.h>
+
+void curl_formget(struct curl_httppost * form, void *userp,
+ curl_formget_callback append );
+.SH DESCRIPTION
+curl_formget() is used to serialize data previously built/appended with
+\fIcurl_formadd(3)\fP. Accepts a void pointer as second argument named
+\fIuserp\fP which will be passed as the first argument to the
+curl_formget_callback function.
+
+.BI "typedef size_t (*curl_formget_callback)(void *" userp, " const char *" buf,
+.BI " size_t " len ");"
+
+The curl_formget_callback will be executed for each part of the HTTP POST
+chain. The character buffer passed to the callback must not be freed. The
+callback should return the buffer length passed to it on success.
+
+If the \fBCURLFORM_STREAM\fP option is used in the formpost, it will prevent
+\fIcurl_formget(3)\fP from working until you've performed the actual HTTP
+request as only then will libcurl get the actual read callback to use!
+.SH RETURN VALUE
+0 means everything was ok, non-zero means an error occurred
+.SH EXAMPLE
+.nf
+
+ size_t print_httppost_callback(void *arg, const char *buf, size_t len)
+ {
+ fwrite(buf, len, 1, stdout);
+ (*(size_t *) arg) += len;
+ return len;
+ }
+
+ size_t print_httppost(struct curl_httppost *post)
+ {
+ size_t total_size = 0;
+ if(curl_formget(post, &total_size, print_httppost_callback)) {
+ return (size_t) -1;
+ }
+ return total_size;
+ }
+.SH AVAILABILITY
+This function was added in libcurl 7.15.5
+.SH "SEE ALSO"
+.BR curl_formadd "(3) "
diff --git a/docs/libcurl/curl_free.3 b/docs/libcurl/curl_free.3
new file mode 100644
index 000000000..08ec9b6b3
--- /dev/null
+++ b/docs/libcurl/curl_free.3
@@ -0,0 +1,35 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_free 3 "12 Aug 2003" "libcurl 7.10" "libcurl Manual"
+.SH NAME
+curl_free - reclaim memory that has been obtained through a libcurl call
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "void curl_free( char *" ptr " );"
+.ad
+.SH DESCRIPTION
+curl_free reclaims memory that has been obtained through a libcurl call. Use
+curl_free() instead of free() to avoid anomalies that can result from
+differences in memory management between your application and libcurl.
+.SH "SEE ALSO"
+.I curl_unescape(3)
diff --git a/docs/libcurl/curl_getdate.3 b/docs/libcurl/curl_getdate.3
new file mode 100644
index 000000000..65eed9c57
--- /dev/null
+++ b/docs/libcurl/curl_getdate.3
@@ -0,0 +1,117 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_getdate 3 "12 Aug 2005" "libcurl 7.0" "libcurl Manual"
+.SH NAME
+curl_getdate - Convert a date string to number of seconds since January 1,
+1970
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "time_t curl_getdate(char *" datestring ", time_t *"now " );"
+.ad
+.SH DESCRIPTION
+This function returns the number of seconds since January 1st 1970 in the UTC
+time zone, for the date and time that the \fIdatestring\fP parameter
+specifies. The \fInow\fP parameter is not used, pass a NULL there.
+
+\fBNOTE:\fP This function was rewritten for the 7.12.2 release and this
+documentation covers the functionality of the new one. The new one is not
+feature-complete with the old one, but most of the formats supported by the
+new one was supported by the old too.
+.SH PARSING DATES AND TIMES
+A "date" is a string containing several items separated by whitespace. The
+order of the items is immaterial. A date string may contain many flavors of
+items:
+.TP 0.8i
+.B calendar date items
+Can be specified several ways. Month names can only be three-letter english
+abbreviations, numbers can be zero-prefixed and the year may use 2 or 4 digits.
+Examples: 06 Nov 1994, 06-Nov-94 and Nov-94 6.
+.TP
+.B time of the day items
+This string specifies the time on a given day. You must specify it with 6
+digits with two colons: HH:MM:SS. To not include the time in a date string,
+will make the function assume 00:00:00. Example: 18:19:21.
+.TP
+.B time zone items
+Specifies international time zone. There are a few acronyms supported, but in
+general you should instead use the specific relative time compared to
+UTC. Supported formats include: -1200, MST, +0100.
+.TP
+.B day of the week items
+Specifies a day of the week. Days of the week may be spelled out in full
+(using english): `Sunday', `Monday', etc or they may be abbreviated to their
+first three letters. This is usually not info that adds anything.
+.TP
+.B pure numbers
+If a decimal number of the form YYYYMMDD appears, then YYYY is read as the
+year, MM as the month number and DD as the day of the month, for the specified
+calendar date.
+.PP
+.SH EXAMPLES
+.nf
+Sun, 06 Nov 1994 08:49:37 GMT
+Sunday, 06-Nov-94 08:49:37 GMT
+Sun Nov 6 08:49:37 1994
+06 Nov 1994 08:49:37 GMT
+06-Nov-94 08:49:37 GMT
+Nov 6 08:49:37 1994
+06 Nov 1994 08:49:37
+06-Nov-94 08:49:37
+1994 Nov 6 08:49:37
+GMT 08:49:37 06-Nov-94 Sunday
+94 6 Nov 08:49:37
+1994 Nov 6
+06-Nov-94
+Sun Nov 6 94
+1994.Nov.6
+Sun/Nov/6/94/GMT
+Sun, 06 Nov 1994 08:49:37 CET
+06 Nov 1994 08:49:37 EST
+Sun, 12 Sep 2004 15:05:58 -0700
+Sat, 11 Sep 2004 21:32:11 +0200
+20040912 15:05:58 -0700
+20040911 +0200
+.fi
+.SH STANDARDS
+This parser was written to handle date formats specified in RFC 822 (including
+the update in RFC 1123) using time zone name or time zone delta and RFC 850
+(obsoleted by RFC 1036) and ANSI C's asctime() format. These formats are the
+only ones RFC2616 says HTTP applications may use.
+.SH RETURN VALUE
+This function returns -1 when it fails to parse the date string. Otherwise it
+returns the number of seconds as described.
+
+If the year is larger than 2037 on systems with 32 bit time_t, this function
+will return 0x7fffffff (since that is the largest possible signed 32 bit
+number).
+
+Having a 64 bit time_t is not a guarantee that dates beyond 03:14:07 UTC,
+January 19, 2038 will work fine. On systems with a 64 bit time_t but with a
+crippled mktime(), \fIcurl_getdate\fP will return -1 in this case.
+.SH REWRITE
+The former version of this function was built with yacc and was not only very
+large, it was also never quite understood and it wasn't possible to build with
+non-GNU tools since only GNU Bison could make it thread-safe!
+
+The rewrite was done for 7.12.2. The new one is much smaller and uses simpler
+code.
diff --git a/docs/libcurl/curl_getenv.3 b/docs/libcurl/curl_getenv.3
new file mode 100644
index 000000000..33554476a
--- /dev/null
+++ b/docs/libcurl/curl_getenv.3
@@ -0,0 +1,49 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_getenv 3 "30 April 2004" "libcurl 7.12" "libcurl Manual"
+.SH NAME
+curl_getenv - return value for environment name
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "char *curl_getenv(const char *" name ");"
+.ad
+.SH DESCRIPTION
+curl_getenv() is a portable wrapper for the getenv() function, meant to
+emulate its behaviour and provide an identical interface for all operating
+systems libcurl builds on (including win32).
+.SH AVAILABILITY
+This function will be removed from the public libcurl API in a near future. It
+will instead be made "available" by source code access only, and then as
+curlx_getenv().
+.SH RETURN VALUE
+If successful, curl_getenv() returns a pointer to the value of the specified
+environment. The memory it refers to is malloc()ed so the application must
+free() this when the data is no longer needed. When \fIcurl_getenv(3)\fP fails
+to find the specified name, it returns a null pointer.
+.SH NOTE
+Under unix operating systems, there isn't any point in returning an allocated
+memory, although other systems won't work properly if this isn't done. The
+unix implementation thus has to suffer slightly from the drawbacks of other
+systems.
+.SH "SEE ALSO"
+.BR getenv "(3C), "
diff --git a/docs/libcurl/curl_global_cleanup.3 b/docs/libcurl/curl_global_cleanup.3
new file mode 100644
index 000000000..83a54e467
--- /dev/null
+++ b/docs/libcurl/curl_global_cleanup.3
@@ -0,0 +1,49 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_global_cleanup 3 "17 Feb 2006" "libcurl 7.8" "libcurl Manual"
+.SH NAME
+curl_global_cleanup - global libcurl cleanup
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "void curl_global_cleanup(void);"
+.ad
+.SH DESCRIPTION
+This function releases resources acquired by \fBcurl_global_init(3)\fP.
+
+You should call \fIcurl_global_cleanup(3)\fP once for each call you make to
+\fIcurl_global_init(3)\fP, after you are done using libcurl.
+
+\fBThis function is not thread safe.\fP You must not call it when any other
+thread in the program (i.e. a thread sharing the same memory) is running.
+This doesn't just mean no other thread that is using libcurl. Because
+\fBcurl_global_cleanup(3)\fP calls functions of other libraries that are
+similarly thread unsafe, it could conflict with any other thread that uses
+these other libraries.
+
+See the description in \fBlibcurl(3)\fP of global environment requirements for
+details of how to use this function.
+
+.SH "SEE ALSO"
+.BR curl_global_init "(3), "
+.BR libcurl "(3), "
+
diff --git a/docs/libcurl/curl_global_init.3 b/docs/libcurl/curl_global_init.3
new file mode 100644
index 000000000..d91e1bdb7
--- /dev/null
+++ b/docs/libcurl/curl_global_init.3
@@ -0,0 +1,80 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_global_init 3 "11 May 2004" "libcurl 7.12" "libcurl Manual"
+.SH NAME
+curl_global_init - Global libcurl initialisation
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "CURLcode curl_global_init(long " flags ");"
+.ad
+.SH DESCRIPTION
+This function sets up the program environment that libcurl needs. Think of it
+as an extension of the library loader.
+
+This function must be called at least once within a program (a program is all
+the code that shares a memory space) before the program calls any other
+function in libcurl. The environment it sets up is constant for the life of
+the program and is the same for every program, so multiple calls have the same
+effect as one call.
+
+The flags option is a bit pattern that tells libcurl exactly what features to
+init, as described below. Set the desired bits by ORing the values together.
+In normal operation, you must specify CURL_GLOBAL_ALL. Don't use any other
+value unless you are familiar with it and mean to control internal operations of
+libcurl.
+
+\fBThis function is not thread safe.\fP You must not call it when any other
+thread in the program (i.e. a thread sharing the same memory) is running.
+This doesn't just mean no other thread that is using libcurl. Because
+\fIcurl_global_init()\fP calls functions of other libraries that are similarly
+thread unsafe, it could conflict with any other thread that uses these other
+libraries.
+
+See the description in \fBlibcurl\fP(3) of global environment requirements for
+details of how to use this function.
+
+.SH FLAGS
+.TP 5
+.B CURL_GLOBAL_ALL
+Initialize everything possible. This sets all known bits.
+.TP
+.B CURL_GLOBAL_SSL
+Initialize SSL
+.TP
+.B CURL_GLOBAL_WIN32
+Initialize the Win32 socket libraries.
+.TP
+.B CURL_GLOBAL_NOTHING
+Initialise nothing extra. This sets no bit.
+.TP
+.B CURL_GLOBAL_DEFAULT
+A sensible default. It will init both SSL and Win32. Right now, this equals
+the functionality of the \fBCURL_GLOBAL_ALL\fP mask.
+.SH RETURN VALUE
+If this function returns non-zero, something went wrong and you cannot use the
+other curl functions.
+.SH "SEE ALSO"
+.BR curl_global_init_mem "(3), "
+.BR curl_global_cleanup "(3), "
+.BR curl_easy_init "(3) "
+.BR libcurl "(3) "
diff --git a/docs/libcurl/curl_global_init_mem.3 b/docs/libcurl/curl_global_init_mem.3
new file mode 100644
index 000000000..d13a17c6e
--- /dev/null
+++ b/docs/libcurl/curl_global_init_mem.3
@@ -0,0 +1,60 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_global_init_mem 3 "10 May 2004" "libcurl 7.12.0" "libcurl Manual"
+.SH NAME
+curl_global_init_mem - Global libcurl initialisation with memory callbacks
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.nf
+.B "CURLcode curl_global_init_mem(long " flags,
+.B " curl_malloc_callback "m,
+.B " curl_free_callback "f,
+.B " curl_realloc_callback "r,
+.B " curl_strdup_callback "s,
+.B " curl_calloc_callback "c ");"
+.SH DESCRIPTION
+This function works exactly as \fIcurl_global_init(3)\fP with one addition: it
+allows the application to set callbacks to replace the otherwise used internal
+memory functions.
+
+This man page only adds documentation for the callbacks, see the
+\fIcurl_global_init(3)\fP man page for all the rest. When you use this
+function, all callback arguments must be set to valid function pointers.
+
+The prototypes for the given callbacks should match these:
+.IP "void *malloc_callback(size_t size);"
+To replace malloc()
+.IP "void free_callback(void *ptr);"
+To replace free()
+.IP "void *realloc_callback(void *ptr, size_t size);"
+To replace realloc()
+.IP "char *strdup_callback(const char *str);"
+To replace strdup()
+.IP "void *calloc_callback(size_t nmemb, size_t size);"
+To replace calloc()
+.SH "CAUTION"
+Manipulating these gives considerable powers to the application to severly
+screw things up for libcurl. Take care!
+.SH "SEE ALSO"
+.BR curl_global_init "(3), "
+.BR curl_global_cleanup "(3), "
+
diff --git a/docs/libcurl/curl_mprintf.3 b/docs/libcurl/curl_mprintf.3
new file mode 100644
index 000000000..cbf10e1ab
--- /dev/null
+++ b/docs/libcurl/curl_mprintf.3
@@ -0,0 +1,109 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_printf 3 "30 April 2004" "libcurl 7.12" "libcurl Manual"
+.SH NAME
+curl_maprintf, curl_mfprintf, curl_mprintf, curl_msnprintf, curl_msprintf
+curl_mvaprintf, curl_mvfprintf, curl_mvprintf, curl_mvsnprintf,
+curl_mvsprintf - formatted output conversion
+.SH SYNOPSIS
+.B #include <curl/mprintf.h>
+.sp
+.BI "int curl_mprintf(const char *" format ", ...);"
+.br
+.BI "int curl_mfprintf(FILE *" fd ", const char *" format ", ...);"
+.br
+.BI "int curl_msprintf(char *" buffer ", const char *" format ", ...);"
+.br
+.BI "int curl_msnprintf(char *" buffer ", size_t " maxlength ", const char *" format ", ...);"
+.br
+.BI "int curl_mvprintf(const char *" format ", va_list " args ");"
+.br
+.BI "int curl_mvfprintf(FILE *" fd ", const char *" format ", va_list " args ");"
+.br
+.BI "int curl_mvsprintf(char *" buffer ", const char *" format ", va_list " args ");"
+.br
+.BI "int curl_mvsnprintf(char *" buffer ", size_t " maxlength ", const char *" format ", va_list " args ");"
+.br
+.BI "char *curl_maprintf(const char *" format ", ...);"
+.br
+.BI "char *curl_mvaprintf(const char *" format ", va_list " args ");"
+.SH DESCRIPTION
+These are all functions that produce output according to a format string and
+given arguments. These are mostly clones of the well-known C-style functions
+and there will be no detailed explanation of all available formatting rules
+and usage here.
+
+See this table for notable exceptions.
+.RS
+.TP
+.B curl_mprintf()
+Normal printf() clone.
+.TP
+.B curl_mfprintf()
+Normal fprintf() clone.
+.TP
+.B curl_msprintf()
+Normal sprintf() clone.
+.TP
+.B curl_msnprintf()
+snprintf() clone. Many systems don't have this. It is just like \fBsprintf\fP
+but with an extra argument after the buffer that specifies the length of the
+target buffer.
+.TP
+.B curl_mvprintf()
+Normal vprintf() clone.
+.TP
+.B curl_mvfprintf()
+Normal vfprintf() clone.
+.TP
+.B curl_mvsprintf()
+Normal vsprintf() clone.
+.TP
+.B curl_mvsnprintf()
+vsnprintf() clone. Many systems don't have this. It is just like
+\fBvsprintf\fP but with an extra argument after the buffer that specifies the
+length of the target buffer.
+.TP
+.B curl_maprintf()
+Like printf() but returns the output string as a malloc()ed string. The
+returned string must be free()ed by the receiver.
+.TP
+.B curl_mvaprintf()
+Like curl_maprintf() but takes a va_list pointer argument instead of a
+variable amount of arguments.
+.RE
+
+To easily use all these cloned functions instead of the normal ones, #define
+_MPRINTF_REPLACE before you include the <curl/mprintf.h> file. Then all the
+normal names like printf, fprintf, sprintf etc will use the curl-functions
+instead.
+.SH AVAILABILITY
+These function will be removed from the public libcurl API in a near
+future. They will instead be made "available" by source code access only, and
+then as curlx_-prefixed functions. See lib/README.curlx for further details.
+.SH RETURN VALUE
+The \fBcurl_maprintf\fP and \fBcurl_mvaprintf\fP functions return a pointer to
+a newly allocated string, or NULL if it failed.
+
+All other functions return the number of characters they actually outputted.
+.SH "SEE ALSO"
+.BR printf "(3), " sprintf "(3), " fprintf "(3), " vprintf "(3) "
diff --git a/docs/libcurl/curl_multi_add_handle.3 b/docs/libcurl/curl_multi_add_handle.3
new file mode 100644
index 000000000..bae2c90fe
--- /dev/null
+++ b/docs/libcurl/curl_multi_add_handle.3
@@ -0,0 +1,57 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_multi_add_handle 3 "4 March 2002" "libcurl 7.9.5" "libcurl Manual"
+.SH NAME
+curl_multi_add_handle - add an easy handle to a multi session
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLMcode curl_multi_add_handle(CURLM *multi_handle, CURL *easy_handle);
+.ad
+.SH DESCRIPTION
+Adds a standard easy handle to the multi stack. This function call will make
+this \fImulti_handle\fP control the specified \fIeasy_handle\fP.
+Furthermore, libcurl now initiates the connection associated with the
+specified \fIeasy_handle\fP.
+
+When an easy handle has been added to a multi stack, you can not and you must
+not use \fIcurl_easy_perform(3)\fP on that handle!
+
+If the easy handle is not set to use a shared (CURLOPT_SHARE) or global DNS
+cache (CURLOPT_DNS_USE_GLOBAL_CACHE), it will be made to use the DNS cache
+that is shared between all easy handles within the multi handle when
+\fIcurl_multi_add_handle(3)\fP is called.
+
+The easy handle will remain added until you remove it again with
+\fIcurl_multi_remove_handle(3)\fP. You should remove the easy handle from the
+multi stack before you terminate first the easy handle and then the multi
+handle:
+
+1 - \fIcurl_multi_remove_handle(3)\fP
+
+2 - \fIcurl_easy_cleanup(3)\fP
+
+3 - \fIcurl_multi_cleanup(3)\fP
+.SH RETURN VALUE
+CURLMcode type, general libcurl multi interface error code.
+.SH "SEE ALSO"
+.BR curl_multi_cleanup "(3)," curl_multi_init "(3)"
diff --git a/docs/libcurl/curl_multi_assign.3 b/docs/libcurl/curl_multi_assign.3
new file mode 100644
index 000000000..0b580fe27
--- /dev/null
+++ b/docs/libcurl/curl_multi_assign.3
@@ -0,0 +1,63 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_multi_assign 3 "9 Jul 2006" "libcurl 7.16.0" "libcurl Manual"
+.SH NAME
+curl_multi_assign \- set data to association with an internal socket
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLMcode curl_multi_assign(CURLM *multi_handle, curl_socket_t sockfd,
+ void *sockptr);
+.SH DESCRIPTION
+This function assigns an association in the multi handle between the given
+socket and a private pointer of the application. This is (only) useful for
+\fIcurl_multi_socket(3)\fP uses.
+
+When set, the \fIsockptr\fP pointer will be passed to all future socket
+callbacks for the specific \fIsockfd\fP socket.
+
+If the given \fIsockfd\fP isn't already in use by libcurl, this function will
+return an error.
+
+libcurl only keeps one single pointer associated with a socket, so calling
+this function several times for the same socket will make the last set pointer
+get used.
+
+The idea here being that this association (socket to private pointer) is
+something that just about every application that uses this API will need and
+then libcurl can just as well do it since it already has an internal hash
+table lookup for this.
+.SH "RETURN VALUE"
+The standard CURLMcode for multi interface error codes.
+.SH "TYPICAL USAGE"
+In a typical application you allocate a struct or at least use some kind of
+semi-dynamic data for each socket that we must wait for action on when using
+the \fIcurl_multi_socket(3)\fP approach.
+
+When our socket-callback gets called by libcurl and we get to know about yet
+another socket to wait for, we can use \fIcurl_multi_assign(3)\fP to point out
+the particular data so that when we get updates about this same socket again,
+we don't have to find the struct associated with this socket by ourselves.
+.SH AVAILABILITY
+This function was added in libcurl 7.15.5, although not deemed stable yet.
+.SH "SEE ALSO"
+.BR curl_multi_setopt "(3), " curl_multi_socket "(3) "
diff --git a/docs/libcurl/curl_multi_cleanup.3 b/docs/libcurl/curl_multi_cleanup.3
new file mode 100644
index 000000000..e83c9f01b
--- /dev/null
+++ b/docs/libcurl/curl_multi_cleanup.3
@@ -0,0 +1,46 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_multi_cleanup 3 "1 March 2002" "libcurl 7.9.5" "libcurl Manual"
+.SH NAME
+curl_multi_cleanup - close down a multi session
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "CURLMcode curl_multi_cleanup( CURLM *multi_handle );"
+.ad
+.SH DESCRIPTION
+Cleans up and removes a whole multi stack. It does not free or touch any
+individual easy handles in any way - they still need to be closed
+individually, using the usual \fIcurl_easy_cleanup(3)\fP way. The order of
+cleaning up should be:
+
+1 - \fIcurl_multi_remove_handle(3)\fP before any easy handles are cleaned up
+
+2 - \fIcurl_easy_cleanup(3)\fP can now be called independently since the easy
+handle is no longer connected to the multi handle
+
+3 - \fIcurl_multi_cleanup(3)\fP should be called when all easy handles are
+removed
+.SH RETURN VALUE
+CURLMcode type, general libcurl multi interface error code.
+.SH "SEE ALSO"
+.BR curl_multi_init "(3)," curl_easy_cleanup "(3)," curl_easy_init "(3)"
diff --git a/docs/libcurl/curl_multi_fdset.3 b/docs/libcurl/curl_multi_fdset.3
new file mode 100644
index 000000000..3dbdc4504
--- /dev/null
+++ b/docs/libcurl/curl_multi_fdset.3
@@ -0,0 +1,70 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_multi_fdset 3 "2 Jan 2006" "libcurl 7.16.0" "libcurl Manual"
+.SH NAME
+curl_multi_fdset - extracts file descriptor information from a multi handle
+.SH SYNOPSIS
+.nf
+#include <curl/curl.h>
+
+CURLMcode curl_multi_fdset(CURLM *multi_handle,
+ fd_set *read_fd_set,
+ fd_set *write_fd_set,
+ fd_set *exc_fd_set,
+ int *max_fd);
+.ad
+.SH DESCRIPTION
+This function extracts file descriptor information from a given multi_handle.
+libcurl returns its fd_set sets. The application can use these to select() on,
+but be sure to FD_ZERO them before calling this function as
+\fIcurl_multi_fdset(3)\fP only adds its own descriptors, it doesn't zero or
+otherwise remove any others. The \fIcurl_multi_perform(3)\fP function should be
+called as soon as one of them is ready to be read from or written to.
+
+If no file descriptors are set by libcurl, \fImax_fd\fP will contain -1 when
+this function returns. Otherwise it will contain the higher descriptor number
+libcurl set. When libcurl returns -1 in \fImax_fd\fP, it is because libcurl
+currently does something that isn't possible for your application to monitor
+with a socket and unfortunately you can then not know exactly when the current
+action is completed using select(). When max_fd returns with -1, you need to
+wait a while and then proceed and call \fIcurl_multi_perform\fP anyway. How
+long to wait? I would suggest 100 milliseconds at least, but you may want to
+test it out in your own particular conditions to find a suitable value.
+
+When doing select(), you should use \fBcurl_multi_timeout\fP to figure out how
+long to wait for action. Call \fIcurl_multi_perform\fP even if no activity has
+been seen on the fd_sets after the timeout expires as otherwise internal
+retries and timeouts may not work as you'd think and want.
+
+If one of the sockets used by libcurl happens to be larger than what can be
+set in an fd_set, which on POSIX systems means that the file descriptor is
+larger than FD_SETSIZE, then libcurl will try to not set it. Setting a too
+large file descriptor in an fd_set implies an out of bounds write which can
+cause crashes, or worse. The effect of NOT storing it will possibly save you
+from the crash, but will make your program NOT wait for sockets it should wait
+for...
+.SH RETURN VALUE
+CURLMcode type, general libcurl multi interface error code. See
+\fIlibcurl-errors(3)\fP
+.SH "SEE ALSO"
+.BR curl_multi_cleanup "(3), " curl_multi_init "(3), "
+.BR curl_multi_timeout "(3), " curl_multi_perform "(3) "
diff --git a/docs/libcurl/curl_multi_info_read.3 b/docs/libcurl/curl_multi_info_read.3
new file mode 100644
index 000000000..875176486
--- /dev/null
+++ b/docs/libcurl/curl_multi_info_read.3
@@ -0,0 +1,76 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_multi_info_read 3 "18 Dec 2004" "libcurl 7.10.3" "libcurl Manual"
+.SH NAME
+curl_multi_info_read - read multi stack informationals
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLMsg *curl_multi_info_read( CURLM *multi_handle,
+ int *msgs_in_queue);
+.ad
+.SH DESCRIPTION
+Ask the multi handle if there are any messages/informationals from the
+individual transfers. Messages may include informationals such as an error
+code from the transfer or just the fact that a transfer is completed. More
+details on these should be written down as well.
+
+Repeated calls to this function will return a new struct each time, until a
+NULL is returned as a signal that there is no more to get at this point. The
+integer pointed to with \fImsgs_in_queue\fP will contain the number of
+remaining messages after this function was called.
+
+When you fetch a message using this function, it is removed from the internal
+queue so calling this function again will not return the same message
+again. It will instead return new messages at each new invoke until the queue
+is emptied.
+
+\fBWARNING:\fP The data the returned pointer points to will not survive
+calling \fIcurl_multi_cleanup(3)\fP, \fIcurl_multi_remove_handle(3)\fP or
+\fIcurl_easy_cleanup(3)\fP.
+
+The 'CURLMsg' struct is very simple and only contains very basic information.
+If more involved information is wanted, the particular "easy handle" in
+present in that struct and can thus be used in subsequent regular
+\fIcurl_easy_getinfo(3)\fP calls (or similar):
+
+.nf
+ struct CURLMsg {
+ CURLMSG msg; /* what this message means */
+ CURL *easy_handle; /* the handle it concerns */
+ union {
+ void *whatever; /* message-specific data */
+ CURLcode result; /* return code for transfer */
+ } data;
+ };
+.fi
+When \fBmsg\fP is \fICURLMSG_DONE\fP, the message identifies a transfer that
+is done, and then \fBresult\fP contains the return code for the easy handle
+that just completed.
+
+At this point, there are no other \fBmsg\fP types defined.
+.SH "RETURN VALUE"
+A pointer to a filled-in struct, or NULL if it failed or ran out of
+structs. It also writes the number of messages left in the queue (after this
+read) in the integer the second argument points to.
+.SH "SEE ALSO"
+.BR curl_multi_cleanup "(3), " curl_multi_init "(3), " curl_multi_perform "(3)"
diff --git a/docs/libcurl/curl_multi_init.3 b/docs/libcurl/curl_multi_init.3
new file mode 100644
index 000000000..ca9374e15
--- /dev/null
+++ b/docs/libcurl/curl_multi_init.3
@@ -0,0 +1,40 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_multi_init 3 "1 March 2002" "libcurl 7.9.5" "libcurl Manual"
+.SH NAME
+curl_multi_init - create a multi handle
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "CURLM *curl_multi_init( );"
+.ad
+.SH DESCRIPTION
+This function returns a CURLM handle to be used as input to all the other
+multi-functions, sometimes referred to as a multi handle in some places in the
+documentation. This init call MUST have a corresponding call to
+\fIcurl_multi_cleanup(3)\fP when the operation is complete.
+.SH RETURN VALUE
+If this function returns NULL, something went wrong and you cannot use the
+other curl functions.
+.SH "SEE ALSO"
+.BR curl_multi_cleanup "(3)," curl_global_init "(3)," curl_easy_init "(3)"
+
diff --git a/docs/libcurl/curl_multi_perform.3 b/docs/libcurl/curl_multi_perform.3
new file mode 100644
index 000000000..304197b1a
--- /dev/null
+++ b/docs/libcurl/curl_multi_perform.3
@@ -0,0 +1,78 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_multi_perform 3 "1 March 2002" "libcurl 7.9.5" "libcurl Manual"
+.SH NAME
+curl_multi_perform - reads/writes available data from each easy handle
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles);
+.ad
+.SH DESCRIPTION
+This function handles transfers on all the added handles that need attention
+in an non-blocking fashion.
+
+When an application has found out there's data available for the multi_handle
+or a timeout has elapsed, the application should call this function to
+read/write whatever there is to read or write right now etc.
+curl_multi_perform() returns as soon as the reads/writes are done. This
+function does not require that there actually is any data available for
+reading or that data can be written, it can be called just in case. It will
+write the number of handles that still transfer data in the second argument's
+integer-pointer.
+
+If the amount of \fIrunning_handles\fP is changed from the previous call (or
+is less than the amount of easy handles you've added to the multi handle), you
+know that there is one or more transfers less "running". You can then call
+\fIcurl_multi_info_read(3)\fP to get information about each individual
+completed transfer, and that returned info includes CURLcode and more. If an
+added handle fails very quickly, it may never be counted as a running_handle.
+
+When \fIrunning_handles\fP is set to zero (0) on the return of this function,
+there is no longer any transfers in progress.
+.SH "RETURN VALUE"
+CURLMcode type, general libcurl multi interface error code.
+
+Before version 7.20.0: If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this
+basically means that you should call \fIcurl_multi_perform\fP again, before
+you select() on more actions. You don't have to do it immediately, but the
+return code means that libcurl may have more data available to return or that
+there may be more data to send off before it is "satisfied". Do note that
+\fIcurl_multi_perform(3)\fP will return \fICURLM_CALL_MULTI_PERFORM\fP only
+when it wants to be called again \fBimmediately\fP. When things are fine and
+there is nothing immediate it wants done, it'll return \fICURLM_OK\fP and you
+need to wait for \&"action" and then call this function again.
+
+This function only returns errors etc regarding the whole multi stack.
+Problems still might have occurred on individual transfers even when this
+function returns \fICURLM_OK\fP. Use \fIcurl_multi_info_read(3)\fP to figure
+out how individual transfers did.
+.SH "TYPICAL USAGE"
+Most applications will use \fIcurl_multi_fdset(3)\fP to get the multi_handle's
+file descriptors, and \fIcurl_multi_timeout(3)\fP to get a suitable timeout
+period, then it'll wait for action on the file descriptors using
+\fBselect(3)\fP. As soon as one or more file descriptor is ready,
+\fIcurl_multi_perform(3)\fP gets called.
+.SH "SEE ALSO"
+.BR curl_multi_cleanup "(3), " curl_multi_init "(3), "
+.BR curl_multi_fdset "(3), " curl_multi_info_read "(3), "
+.BR libcurl-errors "(3)"
diff --git a/docs/libcurl/curl_multi_remove_handle.3 b/docs/libcurl/curl_multi_remove_handle.3
new file mode 100644
index 000000000..ad6d2bac8
--- /dev/null
+++ b/docs/libcurl/curl_multi_remove_handle.3
@@ -0,0 +1,43 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_multi_remove_handle 3 "6 March 2002" "libcurl 7.9.5" "libcurl Manual"
+.SH NAME
+curl_multi_remove_handle - remove an easy handle from a multi session
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLMcode curl_multi_remove_handle(CURLM *multi_handle, CURL *easy_handle);
+.ad
+.SH DESCRIPTION
+Removes a given easy_handle from the multi_handle. This will make the
+specified easy handle be removed from this multi handle's control.
+
+When the easy handle has been removed from a multi stack, it is again
+perfectly legal to invoke \fIcurl_easy_perform()\fP on this easy handle.
+
+Removing an easy handle while being used, will effectively halt the transfer
+in progress involving that easy handle. All other easy handles and transfers
+will remain unaffected.
+.SH RETURN VALUE
+CURLMcode type, general libcurl multi interface error code.
+.SH "SEE ALSO"
+.BR curl_multi_cleanup "(3)," curl_multi_init "(3)"
diff --git a/docs/libcurl/curl_multi_setopt.3 b/docs/libcurl/curl_multi_setopt.3
new file mode 100644
index 000000000..baaaaeac0
--- /dev/null
+++ b/docs/libcurl/curl_multi_setopt.3
@@ -0,0 +1,103 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_multi_setopt 3 "10 Oct 2006" "libcurl 7.16.0" "libcurl Manual"
+.SH NAME
+curl_multi_setopt \- set options for a curl multi handle
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLMcode curl_multi_setopt(CURLM * multi_handle, CURLMoption option, param);
+.SH DESCRIPTION
+curl_multi_setopt() is used to tell a libcurl multi handle how to behave. By
+using the appropriate options to \fIcurl_multi_setopt(3)\fP, you can change
+libcurl's behaviour when using that multi handle. All options are set with
+the \fIoption\fP followed by the parameter \fIparam\fP. That parameter can be
+a \fBlong\fP, a \fBfunction pointer\fP, an \fBobject pointer\fP or a
+\fBcurl_off_t\fP type, depending on what the specific option expects. Read
+this manual carefully as bad input values may cause libcurl to behave badly!
+You can only set one option in each function call.
+
+.SH OPTIONS
+.IP CURLMOPT_SOCKETFUNCTION
+Pass a pointer to a function matching the \fBcurl_socket_callback\fP
+prototype. The \fIcurl_multi_socket_action(3)\fP function informs the
+application about updates in the socket (file descriptor) status by doing
+none, one, or multiple calls to the curl_socket_callback given in the
+\fBparam\fP argument. They update the status with changes since the previous
+time a \fIcurl_multi_socket(3)\fP function was called. If the given callback
+pointer is NULL, no callback will be called. Set the callback's \fBuserp\fP
+argument with \fICURLMOPT_SOCKETDATA\fP. See \fIcurl_multi_socket(3)\fP for
+more callback details.
+.IP CURLMOPT_SOCKETDATA
+Pass a pointer to whatever you want passed to the \fBcurl_socket_callback\fP's
+forth argument, the userp pointer. This is not used by libcurl but only
+passed-thru as-is. Set the callback pointer with
+\fICURLMOPT_SOCKETFUNCTION\fP.
+.IP CURLMOPT_PIPELINING
+Pass a long set to 1 to enable or 0 to disable. Enabling pipelining on a multi
+handle will make it attempt to perform HTTP Pipelining as far as possible for
+transfers using this handle. This means that if you add a second request that
+can use an already existing connection, the second request will be \&"piped"
+on the same connection rather than being executed in parallel. (Added in
+7.16.0)
+.IP CURLMOPT_TIMERFUNCTION
+Pass a pointer to a function matching the \fBcurl_multi_timer_callback\fP
+prototype. This function will then be called when the timeout value
+changes. The timeout value is at what latest time the application should call
+one of the \&"performing" functions of the multi interface
+(\fIcurl_multi_socket_action(3)\fP and \fIcurl_multi_perform(3)\fP) - to allow
+libcurl to keep timeouts and retries etc to work. A timeout value of -1 means
+that there is no timeout at all, and 0 means that the timeout is already
+reached. Libcurl attempts to limit calling this only when the fixed future
+timeout time actually changes. See also \fICURLMOPT_TIMERDATA\fP. This
+callback can be used instead of, or in addition to,
+\fIcurl_multi_timeout(3)\fP. (Added in 7.16.0)
+.IP CURLMOPT_TIMERDATA
+Pass a pointer to whatever you want passed to the
+\fBcurl_multi_timer_callback\fP's third argument, the userp pointer. This is
+not used by libcurl but only passed-thru as-is. Set the callback pointer with
+\fICURLMOPT_TIMERFUNCTION\fP. (Added in 7.16.0)
+.IP CURLMOPT_MAXCONNECTS
+Pass a long. The set number will be used as the maximum amount of
+simultaneously open connections that libcurl may cache. Default is 10, and
+libcurl will enlarge the size for each added easy handle to make it fit 4
+times the number of added easy handles.
+
+By setting this option, you can prevent the cache size from growing beyond the
+limit set by you.
+
+When the cache is full, curl closes the oldest one in the cache to prevent the
+number of open connections from increasing.
+
+This option is for the multi handle's use only, when using the easy interface
+you should instead use the \fICURLOPT_MAXCONNECTS\fP option.
+
+(Added in 7.16.3)
+.SH RETURNS
+The standard CURLMcode for multi interface error codes. Note that it returns a
+CURLM_UNKNOWN_OPTION if you try setting an option that this version of libcurl
+doesn't know of.
+.SH AVAILABILITY
+This function was added in libcurl 7.15.4.
+.SH "SEE ALSO"
+.BR curl_multi_cleanup "(3), " curl_multi_init "(3), "
+.BR curl_multi_socket "(3), " curl_multi_info_read "(3)"
diff --git a/docs/libcurl/curl_multi_socket.3 b/docs/libcurl/curl_multi_socket.3
new file mode 100644
index 000000000..6b262f292
--- /dev/null
+++ b/docs/libcurl/curl_multi_socket.3
@@ -0,0 +1,158 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_multi_socket 3 "9 Jul 2006" "libcurl 7.16.0" "libcurl Manual"
+.SH NAME
+curl_multi_socket \- reads/writes available data
+.SH SYNOPSIS
+.nf
+#include <curl/curl.h>
+CURLMcode curl_multi_socket(CURLM * multi_handle, curl_socket_t sockfd,
+ int *running_handles);
+
+CURLMcode curl_multi_socket_all(CURLM *multi_handle,
+ int *running_handles);
+.fi
+.SH DESCRIPTION
+These functions are deprecated. Do not use! See
+\fIcurl_multi_socket_action(3)\fP instead!
+
+At return, the integer \fBrunning_handles\fP points to will contain the number
+of still running easy handles within the multi handle. When this number
+reaches zero, all transfers are complete/done. Note that when you call
+\fIcurl_multi_socket_action(3)\fP on a specific socket and the counter
+decreases by one, it DOES NOT necessarily mean that this exact socket/transfer
+is the one that completed. Use \fIcurl_multi_info_read(3)\fP to figure out
+which easy handle that completed.
+
+The \fBcurl_multi_socket_action(3)\fP functions inform the application about
+updates in the socket (file descriptor) status by doing none, one, or multiple
+calls to the socket callback function set with the CURLMOPT_SOCKETFUNCTION
+option to \fIcurl_multi_setopt(3)\fP. They update the status with changes
+since the previous time the callback was called.
+
+Get the timeout time by setting the \fICURLMOPT_TIMERFUNCTION\fP option with
+\fIcurl_multi_setopt(3)\fP. Your application will then get called with
+information on how long to wait for socket actions at most before doing the
+timeout action: call the \fBcurl_multi_socket_action(3)\fP function with the
+\fBsockfd\fP argument set to CURL_SOCKET_TIMEOUT. You can also use the
+\fIcurl_multi_timeout(3)\fP function to poll the value at any given time, but
+for an event-based system using the callback is far better than relying on
+polling the timeout value.
+
+Usage of \fIcurl_multi_socket(3)\fP is deprecated, whereas the function is
+equivalent to \fIcurl_multi_socket_action(3)\fP with \fBev_bitmask\fP set to
+0.
+
+Force libcurl to (re-)check all its internal sockets and transfers instead of
+just a single one by calling \fBcurl_multi_socket_all(3)\fP. Note that there
+should not be any reason to use this function!
+.SH "CALLBACK DETAILS"
+
+The socket \fBcallback\fP function uses a prototype like this
+.nf
+
+ int curl_socket_callback(CURL *easy, /* easy handle */
+ curl_socket_t s, /* socket */
+ int action, /* see values below */
+ void *userp, /* private callback pointer */
+ void *socketp); /* private socket pointer */
+
+.fi
+The callback MUST return 0.
+
+The \fIeasy\fP argument is a pointer to the easy handle that deals with this
+particular socket. Note that a single handle may work with several sockets
+simultaneously.
+
+The \fIs\fP argument is the actual socket value as you use it within your
+system.
+
+The \fIaction\fP argument to the callback has one of five values:
+.RS
+.IP "CURL_POLL_NONE (0)"
+register, not interested in readiness (yet)
+.IP "CURL_POLL_IN (1)"
+register, interested in read readiness
+.IP "CURL_POLL_OUT (2)"
+register, interested in write readiness
+.IP "CURL_POLL_INOUT (3)"
+register, interested in both read and write readiness
+.IP "CURL_POLL_REMOVE (4)"
+unregister
+.RE
+
+The \fIsocketp\fP argument is a private pointer you have previously set with
+\fIcurl_multi_assign(3)\fP to be associated with the \fIs\fP socket. If no
+pointer has been set, socketp will be NULL. This argument is of course a
+service to applications that want to keep certain data or structs that are
+strictly associated to the given socket.
+
+The \fIuserp\fP argument is a private pointer you have previously set with
+\fIcurl_multi_setopt(3)\fP and the CURLMOPT_SOCKETDATA option.
+.SH "RETURN VALUE"
+CURLMcode type, general libcurl multi interface error code.
+
+Legacy: If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this basically means
+that you should call \fIcurl_multi_socket(3)\fP again, before you wait for
+more actions on libcurl's sockets. You don't have to do it immediately, but
+the return code means that libcurl may have more data available to return or
+that there may be more data to send off before it is "satisfied".
+
+In modern libcurls, \fICURLM_CALL_MULTI_PERFORM\fP or
+\fICURLM_CALL_MULTI_SOKCET\fP should not be returned and no application needs
+to care about them.
+
+NOTE that the return code is for the whole multi stack. Problems still might have
+occurred on individual transfers even when one of these functions
+return OK.
+.SH "TYPICAL USAGE"
+1. Create a multi handle
+
+2. Set the socket callback with CURLMOPT_SOCKETFUNCTION
+
+3. Set the timeout callback with CURLMOPT_TIMERFUNCTION, to get to know what
+timeout value to use when waiting for socket activities.
+
+4. Add easy handles with curl_multi_add_handle()
+
+5. Provide some means to manage the sockets libcurl is using, so you can check
+them for activity. This can be done through your application code, or by way
+of an external library such as libevent or glib.
+
+6. Wait for activity on any of libcurl's sockets, use the timeout value your
+callback has been told
+
+7, When activity is detected, call curl_multi_socket_action() for the
+socket(s) that got action. If no activity is detected and the timeout expires,
+call \fIcurl_multi_socket_action(3)\fP with \fICURL_SOCKET_TIMEOUT\fP
+
+8. Go back to step 6.
+.SH AVAILABILITY
+This function was added in libcurl 7.15.4, and is deemed stable since
+7.16.0.
+
+\fIcurl_multi_socket(3)\fP is deprecated, use
+\fIcurl_multi_socket_action(3)\fP instead!
+.SH "SEE ALSO"
+.BR curl_multi_cleanup "(3), " curl_multi_init "(3), "
+.BR curl_multi_fdset "(3), " curl_multi_info_read "(3), "
+.BR "the hiperfifo.c example"
diff --git a/docs/libcurl/curl_multi_socket_action.3 b/docs/libcurl/curl_multi_socket_action.3
new file mode 100644
index 000000000..ac3b176c7
--- /dev/null
+++ b/docs/libcurl/curl_multi_socket_action.3
@@ -0,0 +1,149 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_multi_socket_action 3 "9 Jul 2006" "libcurl 7.16.0" "libcurl Manual"
+.SH NAME
+curl_multi_socket_action \- reads/writes available data given an action
+.SH SYNOPSIS
+.nf
+#include <curl/curl.h>
+
+CURLMcode curl_multi_socket_action(CURLM * multi_handle,
+ curl_socket_t sockfd, int ev_bitmask,
+ int *running_handles);
+.fi
+.SH DESCRIPTION
+When the application has detected action on a socket handled by libcurl, it
+should call \fIcurl_multi_socket_action(3)\fP with the \fBsockfd\fP argument
+set to the socket with the action. When the events on a socket are known, they
+can be passed as an events bitmask \fBev_bitmask\fP by first setting
+\fBev_bitmask\fP to 0, and then adding using bitwise OR (|) any combination of
+events to be chosen from CURL_CSELECT_IN, CURL_CSELECT_OUT or
+CURL_CSELECT_ERR. When the events on a socket are unknown, pass 0 instead, and
+libcurl will test the descriptor internally.
+
+At return, the integer \fBrunning_handles\fP points to will contain the number
+of running easy handles within the multi handle. When this number reaches
+zero, all transfers are complete/done. When you call
+\fIcurl_multi_socket_action(3)\fP on a specific socket and the counter
+decreases by one, it DOES NOT necessarily mean that this exact socket/transfer
+is the one that completed. Use \fIcurl_multi_info_read(3)\fP to figure out
+which easy handle that completed.
+
+The \fBcurl_multi_socket_action(3)\fP functions inform the application about
+updates in the socket (file descriptor) status by doing none, one, or multiple
+calls to the socket callback function set with the CURLMOPT_SOCKETFUNCTION
+option to \fIcurl_multi_setopt(3)\fP. They update the status with changes
+since the previous time the callback was called.
+
+Get the timeout time by setting the \fICURLMOPT_TIMERFUNCTION\fP option with
+\fIcurl_multi_setopt(3)\fP. Your application will then get called with
+information on how long to wait for socket actions at most before doing the
+timeout action: call the \fBcurl_multi_socket_action(3)\fP function with the
+\fBsockfd\fP argument set to CURL_SOCKET_TIMEOUT. You can also use the
+\fIcurl_multi_timeout(3)\fP function to poll the value at any given time, but
+for an event-based system using the callback is far better than relying on
+polling the timeout value.
+.SH "CALLBACK DETAILS"
+
+The socket \fBcallback\fP function uses a prototype like this
+.nf
+
+ int curl_socket_callback(CURL *easy, /* easy handle */
+ curl_socket_t s, /* socket */
+ int action, /* see values below */
+ void *userp, /* private callback pointer */
+ void *socketp); /* private socket pointer */
+
+.fi
+The callback MUST return 0.
+
+The \fIeasy\fP argument is a pointer to the easy handle that deals with this
+particular socket. Note that a single handle may work with several sockets
+simultaneously.
+
+The \fIs\fP argument is the actual socket value as you use it within your
+system.
+
+The \fIaction\fP argument to the callback has one of five values:
+.RS
+.IP "CURL_POLL_NONE (0)"
+register, not interested in readiness (yet)
+.IP "CURL_POLL_IN (1)"
+register, interested in read readiness
+.IP "CURL_POLL_OUT (2)"
+register, interested in write readiness
+.IP "CURL_POLL_INOUT (3)"
+register, interested in both read and write readiness
+.IP "CURL_POLL_REMOVE (4)"
+unregister
+.RE
+
+The \fIsocketp\fP argument is a private pointer you have previously set with
+\fIcurl_multi_assign(3)\fP to be associated with the \fIs\fP socket. If no
+pointer has been set, socketp will be NULL. This argument is of course a
+service to applications that want to keep certain data or structs that are
+strictly associated to the given socket.
+
+The \fIuserp\fP argument is a private pointer you have previously set with
+\fIcurl_multi_setopt(3)\fP and the CURLMOPT_SOCKETDATA option.
+.SH "RETURN VALUE"
+CURLMcode type, general libcurl multi interface error code.
+
+Before version 7.20.0: If you receive \fICURLM_CALL_MULTI_PERFORM\fP, this
+basically means that you should call \fIcurl_multi_socket_action(3)\fP again
+before you wait for more actions on libcurl's sockets. You don't have to do it
+immediately, but the return code means that libcurl may have more data
+available to return or that there may be more data to send off before it is
+"satisfied".
+
+The return code from this function is for the whole multi stack. Problems
+still might have occurred on individual transfers even when one of these
+functions return OK.
+.SH "TYPICAL USAGE"
+1. Create a multi handle
+
+2. Set the socket callback with CURLMOPT_SOCKETFUNCTION
+
+3. Set the timeout callback with CURLMOPT_TIMERFUNCTION, to get to know what
+timeout value to use when waiting for socket activities.
+
+4. Add easy handles with curl_multi_add_handle()
+
+5. Provide some means to manage the sockets libcurl is using, so you can check
+them for activity. This can be done through your application code, or by way
+of an external library such as libevent or glib.
+
+6. Call curl_multi_socket_action(...CURL_SOCKET_TIMEOUT...) to kickstart
+everything. To get one or more callbacks called.
+
+7. Wait for activity on any of libcurl's sockets, use the timeout value your
+callback has been told
+
+8, When activity is detected, call curl_multi_socket_action() for the
+socket(s) that got action. If no activity is detected and the timeout expires,
+call \fIcurl_multi_socket_action(3)\fP with \fICURL_SOCKET_TIMEOUT\fP
+.SH AVAILABILITY
+This function was added in libcurl 7.15.4, and is deemed stable since 7.16.0.
+.SH "SEE ALSO"
+.BR curl_multi_cleanup "(3), " curl_multi_init "(3), "
+.BR curl_multi_fdset "(3), " curl_multi_info_read "(3), "
+.BR "the hiperfifo.c example"
diff --git a/docs/libcurl/curl_multi_socket_all.3 b/docs/libcurl/curl_multi_socket_all.3
new file mode 100644
index 000000000..428dd06f9
--- /dev/null
+++ b/docs/libcurl/curl_multi_socket_all.3
@@ -0,0 +1 @@
+.so man3/curl_multi_socket.3
diff --git a/docs/libcurl/curl_multi_strerror.3 b/docs/libcurl/curl_multi_strerror.3
new file mode 100644
index 000000000..40d0974c5
--- /dev/null
+++ b/docs/libcurl/curl_multi_strerror.3
@@ -0,0 +1,37 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_multi_strerror 3 "26 Apr 2004" "libcurl 7.12" "libcurl Manual"
+.SH NAME
+curl_multi_strerror - return string describing error code
+.SH SYNOPSIS
+.nf
+.B #include <curl/curl.h>
+.BI "const char *curl_multi_strerror(CURLMcode " errornum ");"
+.SH DESCRIPTION
+The curl_multi_strerror() function returns a string describing the CURLMcode
+error code passed in the argument \fIerrornum\fP.
+.SH AVAILABILITY
+This function was added in libcurl 7.12.0
+.SH RETURN VALUE
+A pointer to a zero terminated string.
+.SH "SEE ALSO"
+.BR libcurl-errors "(3), " curl_easy_strerror "(3), " curl_share_strerror "(3)"
diff --git a/docs/libcurl/curl_multi_timeout.3 b/docs/libcurl/curl_multi_timeout.3
new file mode 100644
index 000000000..5ad8008ea
--- /dev/null
+++ b/docs/libcurl/curl_multi_timeout.3
@@ -0,0 +1,63 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_multi_timeout 3 "2 Jan 2006" "libcurl 7.16.0" "libcurl Manual"
+.SH NAME
+curl_multi_timeout \- how long to wait for action before proceeding
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLMcode curl_multi_timeout(CURLM *multi_handle, long *timeout);
+.SH DESCRIPTION
+
+An application using the libcurl multi interface should call
+\fBcurl_multi_timeout(3)\fP to figure out how long it should wait for socket
+actions \- at most \- before proceeding.
+
+Proceeding means either doing the socket-style timeout action: call the
+\fBcurl_multi_socket_action(3)\fP function with the \fBsockfd\fP argument set
+to CURL_SOCKET_TIMEOUT, or call \fBcurl_multi_perform(3)\fP if you're using
+the simpler and older multi interface approach.
+
+The timeout value returned in the long \fBtimeout\fP points to, is in number
+of milliseconds at this very moment. If 0, it means you should proceed
+immediately without waiting for anything. If it returns -1, there's no timeout
+at all set.
+
+An application that uses the multi_socket API SHOULD not use this function, but
+SHOULD instead use \fIcurl_multi_setopt(3)\fP and its
+\fPCURLMOPT_TIMERFUNCTION\fP option for proper and desired behavior.
+
+Note: if libcurl returns a -1 timeout here, it just means that libcurl
+currently has no stored timeout value. You must not wait too long (more than a
+few seconds perhaps) before you call curl_multi_perform() again.
+.SH "RETURN VALUE"
+The standard CURLMcode for multi interface error codes.
+.SH "TYPICAL USAGE"
+Call \fBcurl_multi_timeout(3)\fP, then wait for action on the sockets. You
+figure out which sockets to wait for by calling \fBcurl_multi_fdset(3)\fP or
+by a previous call to \fBcurl_multi_socket(3)\fP.
+.SH AVAILABILITY
+This function was added in libcurl 7.15.4.
+.SH "SEE ALSO"
+.BR curl_multi_fdset "(3), " curl_multi_info_read "(3), "
+.BR curl_multi_socket "(3), " curl_multi_setopt "(3) "
+
diff --git a/docs/libcurl/curl_multi_wait.3 b/docs/libcurl/curl_multi_wait.3
new file mode 100644
index 000000000..b14760bf3
--- /dev/null
+++ b/docs/libcurl/curl_multi_wait.3
@@ -0,0 +1,75 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_multi_wait 3 "12 Jul 2012" "libcurl 7.28.0" "libcurl Manual"
+.SH NAME
+curl_multi_wait - polls on all easy handles in a multi handle
+.SH SYNOPSIS
+.nf
+#include <curl/curl.h>
+
+CURLMcode curl_multi_wait(CURLM *multi_handle,
+ struct curl_waitfd extra_fds[],
+ unsigned int extra_nfds,
+ int timeout_ms,
+ int *numfds);
+.ad
+.SH DESCRIPTION
+This function polls on all file descriptors used by the curl easy handles
+contained in the given multi handle set. It will block until activity is
+detected on at least one of the handles or \fItimeout_ms\fP has passed.
+
+The calling application may pass additional curl_waitfd structures which are
+similar to \fIpoll(2)\fP's pollfd structure to be waited on in the same call.
+
+On completion, if \fInumfds\fP is supplied, it will be populated with the
+number of file descriptors on which interesting events occured.
+
+If no extra file descriptors are provided and libcurl has no file descriptor
+to offer to wait for, this function will return immediately.
+
+This function is encouraged to be used instead of select(3) when using the
+multi interface to allow applications to easier circumvent the common problem
+with 1024 maximum file descriptors.
+.SH curl_waitfd
+.nf
+struct curl_waitfd {
+ curl_socket_t fd;
+ short events;
+ short revents;
+};
+.fi
+.IP CURL_WAIT_POLLIN
+Bit flag to curl_waitfd.events indicating the socket should poll on read
+events such as new data received.
+.IP CURL_WAIT_POLLPRI
+Bit flag to curl_waitfd.events indicating the socket should poll on high
+priority read events such as out of band data.
+.IP CURL_WAIT_POLLOUT
+Bit flag to curl_waitfd.events indicating the socket should poll on write
+events such as the socket being clear to write without blocking.
+.SH RETURN VALUE
+CURLMcode type, general libcurl multi interface error code. See
+\fIlibcurl-errors(3)\fP
+.SH AVAILABILITY
+This function was added in libcurl 7.28.0.
+.SH "SEE ALSO"
+.BR curl_multi_fdset "(3), " curl_multi_perform "(3)"
diff --git a/docs/libcurl/curl_share_cleanup.3 b/docs/libcurl/curl_share_cleanup.3
new file mode 100644
index 000000000..3af1707bb
--- /dev/null
+++ b/docs/libcurl/curl_share_cleanup.3
@@ -0,0 +1,40 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_share_cleanup 3 "8 Aug 2003" "libcurl 7.10.7" "libcurl Manual"
+.SH NAME
+curl_share_cleanup - Clean up a shared object
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "CURLSHcode curl_share_cleanup(CURLSH *" share_handle ");"
+.ad
+.SH DESCRIPTION
+This function deletes a shared object. The share handle cannot be used anymore
+when this function has been called.
+
+.SH RETURN VALUE
+CURLSHE_OK (zero) means that the option was set properly, non-zero means an
+error occurred as \fI<curl/curl.h>\fP defines. See the \fIlibcurl-errors.3\fP
+man page for the full list with descriptions. If an error occurs, then the
+share object will not be deleted.
+.SH "SEE ALSO"
+.BR curl_share_init "(3), " curl_share_setopt "(3)"
diff --git a/docs/libcurl/curl_share_init.3 b/docs/libcurl/curl_share_init.3
new file mode 100644
index 000000000..ce00d958e
--- /dev/null
+++ b/docs/libcurl/curl_share_init.3
@@ -0,0 +1,44 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_share_init 3 "8 Aug 2003" "libcurl 7.10.7" "libcurl Manual"
+.SH NAME
+curl_share_init - Create a shared object
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "CURLSH *curl_share_init( );"
+.ad
+.SH DESCRIPTION
+This function returns a CURLSH handle to be used as input to all the other
+share-functions, sometimes referred to as a share handle in some places in the
+documentation. This init call MUST have a corresponding call to
+\fIcurl_share_cleanup\fP when all operations using the share are complete.
+
+This \fIshare handle\fP is what you pass to curl using the \fICURLOPT_SHARE\fP
+option with \fIcurl_easy_setopt(3)\fP, to make that specific curl handle use
+the data in this share.
+.SH RETURN VALUE
+If this function returns NULL, something went wrong (out of memory, etc.)
+and therefore the share object was not created.
+.SH "SEE ALSO"
+.BR curl_share_cleanup "(3), " curl_share_setopt "(3)"
+
diff --git a/docs/libcurl/curl_share_setopt.3 b/docs/libcurl/curl_share_setopt.3
new file mode 100644
index 000000000..c196743ff
--- /dev/null
+++ b/docs/libcurl/curl_share_setopt.3
@@ -0,0 +1,85 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_share_setopt 3 "8 Aug 2003" "libcurl 7.10.7" "libcurl Manual"
+.SH NAME
+curl_share_setopt - Set options for a shared object
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+CURLSHcode curl_share_setopt(CURLSH *share, CURLSHoption option, parameter);
+.ad
+.SH DESCRIPTION
+Set the \fIoption\fP to \fIparameter\fP for the given \fIshare\fP.
+.SH OPTIONS
+.IP CURLSHOPT_LOCKFUNC
+The \fIparameter\fP must be a pointer to a function matching the following
+prototype:
+
+void lock_function(CURL *handle, curl_lock_data data, curl_lock_access access,
+void *userptr);
+
+\fIdata\fP defines what data libcurl wants to lock, and you must make sure that
+only one lock is given at any time for each kind of data.
+
+\fIaccess\fP defines what access type libcurl wants, shared or single.
+
+\fIuserptr\fP is the pointer you set with \fICURLSHOPT_USERDATA\fP.
+.IP CURLSHOPT_UNLOCKFUNC
+The \fIparameter\fP must be a pointer to a function matching the following
+prototype:
+
+void unlock_function(CURL *handle, curl_lock_data data, void *userptr);
+
+\fIdata\fP defines what data libcurl wants to unlock, and you must make sure
+that only one lock is given at any time for each kind of data.
+
+\fIuserptr\fP is the pointer you set with \fICURLSHOPT_USERDATA\fP.
+.IP CURLSHOPT_SHARE
+The \fIparameter\fP specifies a type of data that should be shared. This may
+be set to one of the values described below.
+.RS
+.IP CURL_LOCK_DATA_COOKIE
+Cookie data will be shared across the easy handles using this shared object.
+.IP CURL_LOCK_DATA_DNS
+Cached DNS hosts will be shared across the easy handles using this shared
+object. Note that when you use the multi interface, all easy handles added to
+the same multi handle will share DNS cache by default without this having to
+be used!
+.IP CURL_LOCK_DATA_SSL_SESSION
+SSL session IDs will be shared across the easy handles using this shared
+object. This will reduce the time spent in the SSL handshake when reconnecting
+to the same server. Note SSL session IDs are reused within the same easy handle
+by default.
+.RE
+.IP CURLSHOPT_UNSHARE
+This option does the opposite of \fICURLSHOPT_SHARE\fP. It specifies that
+the specified \fIparameter\fP will no longer be shared. Valid values are
+the same as those for \fICURLSHOPT_SHARE\fP.
+.IP CURLSHOPT_USERDATA
+The \fIparameter\fP allows you to specify a pointer to data that will be passed
+to the lock_function and unlock_function each time it is called.
+.SH RETURN VALUE
+CURLSHE_OK (zero) means that the option was set properly, non-zero means an
+error occurred as \fI<curl/curl.h>\fP defines. See the \fIlibcurl-errors.3\fP
+man page for the full list with descriptions.
+.SH "SEE ALSO"
+.BR curl_share_cleanup "(3), " curl_share_init "(3)"
diff --git a/docs/libcurl/curl_share_strerror.3 b/docs/libcurl/curl_share_strerror.3
new file mode 100644
index 000000000..f1bc39867
--- /dev/null
+++ b/docs/libcurl/curl_share_strerror.3
@@ -0,0 +1,37 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_share_strerror 3 "26 Apr 2004" "libcurl 7.12" "libcurl Manual"
+.SH NAME
+curl_share_strerror - return string describing error code
+.SH SYNOPSIS
+.nf
+.B #include <curl/curl.h>
+.BI "const char *curl_share_strerror(CURLSHcode " errornum ");"
+.SH DESCRIPTION
+The curl_share_strerror() function returns a string describing the CURLSHcode
+error code passed in the argument \fIerrornum\fP.
+.SH AVAILABILITY
+This function was added in libcurl 7.12.0
+.SH RETURN VALUE
+A pointer to a zero terminated string.
+.SH "SEE ALSO"
+.BR libcurl-errors "(3), " curl_multi_strerror "(3), " curl_easy_strerror "(3)"
diff --git a/docs/libcurl/curl_slist_append.3 b/docs/libcurl/curl_slist_append.3
new file mode 100644
index 000000000..529560e8a
--- /dev/null
+++ b/docs/libcurl/curl_slist_append.3
@@ -0,0 +1,56 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_slist_append 3 "19 Jun 2003" "libcurl 7.10.4" "libcurl Manual"
+.SH NAME
+curl_slist_append - add a string to an slist
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "struct curl_slist *curl_slist_append(struct curl_slist *" list,
+.BI "const char * "string ");"
+.ad
+.SH DESCRIPTION
+curl_slist_append() appends a specified string to a linked list of
+strings. The existing \fIlist\fP should be passed as the first argument while
+the new list is returned from this function. The specified \fIstring\fP has
+been appended when this function returns. curl_slist_append() copies the
+string.
+
+The list should be freed again (after usage) with
+\fBcurl_slist_free_all(3)\fP.
+.SH RETURN VALUE
+A null pointer is returned if anything went wrong, otherwise the new list
+pointer is returned.
+.SH EXAMPLE
+.nf
+ CURL handle;
+ struct curl_slist *slist=NULL;
+
+ slist = curl_slist_append(slist, "pragma:");
+ curl_easy_setopt(handle, CURLOPT_HTTPHEADER, slist);
+
+ curl_easy_perform(handle);
+
+ curl_slist_free_all(slist); /* free the list again */
+.fi
+.SH "SEE ALSO"
+.BR curl_slist_free_all "(3), "
diff --git a/docs/libcurl/curl_slist_free_all.3 b/docs/libcurl/curl_slist_free_all.3
new file mode 100644
index 000000000..fab3d6080
--- /dev/null
+++ b/docs/libcurl/curl_slist_free_all.3
@@ -0,0 +1,37 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_slist_free_all 3 "5 March 2001" "libcurl 7.0" "libcurl Manual"
+.SH NAME
+curl_slist_free_all - free an entire curl_slist list
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "void curl_slist_free_all(struct curl_slist *" list);
+.ad
+.SH DESCRIPTION
+curl_slist_free_all() removes all traces of a previously built curl_slist
+linked list.
+.SH RETURN VALUE
+Nothing.
+.SH "SEE ALSO"
+.BR curl_slist_append "(3), "
+
diff --git a/docs/libcurl/curl_strequal.3 b/docs/libcurl/curl_strequal.3
new file mode 100644
index 000000000..ce575d7ac
--- /dev/null
+++ b/docs/libcurl/curl_strequal.3
@@ -0,0 +1,51 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_strequal 3 "30 April 2004" "libcurl 7.12" "libcurl Manual"
+.SH NAME
+curl_strequal, curl_strnequal - case insensitive string comparisons
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "int curl_strequal(char *" str1 ", char *" str2 ");"
+.sp
+.BI "int curl_strenqual(char *" str1 ", char *" str2 ", size_t " len ");"
+.SH DESCRIPTION
+The
+.B curl_strequal()
+function compares the two strings \fIstr1\fP and \fIstr2\fP, ignoring the case
+of the characters. It returns a non-zero (TRUE) integer if the strings are
+identical.
+.sp
+The \fBcurl_strnequal()\fP function is similar, except it only compares the
+first \fIlen\fP characters of \fIstr1\fP.
+.sp
+These functions are provided by libcurl to enable applications to compare
+strings in a truly portable manner. There are no standard portable case
+insensitive string comparison functions. These two work on all platforms.
+.SH AVAILABILITY
+These functions will be removed from the public libcurl API in a near
+future. They will instead be made "available" by source code access only, and
+then as curlx_strequal() and curlx_strenqual().
+.SH RETURN VALUE
+Non-zero if the strings are identical. Zero if they're not.
+.SH "SEE ALSO"
+.BR strcmp "(3), " strcasecmp "(3)"
diff --git a/docs/libcurl/curl_strnequal.3 b/docs/libcurl/curl_strnequal.3
new file mode 100644
index 000000000..ce41d3e41
--- /dev/null
+++ b/docs/libcurl/curl_strnequal.3
@@ -0,0 +1 @@
+.so man3/curl_strequal.3
diff --git a/docs/libcurl/curl_unescape.3 b/docs/libcurl/curl_unescape.3
new file mode 100644
index 000000000..2a24866d3
--- /dev/null
+++ b/docs/libcurl/curl_unescape.3
@@ -0,0 +1,48 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_unescape 3 "22 March 2001" "libcurl 7.7" "libcurl Manual"
+.SH NAME
+curl_unescape - URL decodes the given string
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "char *curl_unescape( char *" url ", int "length " );"
+.ad
+.SH DESCRIPTION
+Obsolete function. Use \fIcurl_easy_unescape(3)\fP instead!
+
+This function will convert the given URL encoded input string to a "plain
+string" and return that as a new allocated string. All input characters that
+are URL encoded (%XX where XX is a two-digit hexadecimal number) will be
+converted to their plain text versions.
+
+If the 'length' argument is set to 0, curl_unescape() will use strlen() on the
+input 'url' string to find out the size.
+
+You must curl_free() the returned string when you're done with it.
+.SH AVAILABILITY
+Since 7.15.4, \fIcurl_easy_unescape(3)\fP should be used. This function will
+be removed in a future release.
+.SH RETURN VALUE
+A pointer to a zero terminated string or NULL if it failed.
+.SH "SEE ALSO"
+.I curl_easy_escape(3), curl_easy_unescape(3), curl_free(3), RFC 2396
diff --git a/docs/libcurl/curl_version.3 b/docs/libcurl/curl_version.3
new file mode 100644
index 000000000..003329800
--- /dev/null
+++ b/docs/libcurl/curl_version.3
@@ -0,0 +1,36 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH curl_version 3 "5 March 2001" "libcurl 7.0" "libcurl Manual"
+.SH NAME
+curl_version - returns the libcurl version string
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "char *curl_version( );"
+.ad
+.SH DESCRIPTION
+Returns a human readable string with the version number of libcurl and some of
+its important components (like OpenSSL version).
+.SH RETURN VALUE
+A pointer to a zero terminated string.
+.SH "SEE ALSO"
+.BR curl_version_info "(3)"
diff --git a/docs/libcurl/curl_version_info.3 b/docs/libcurl/curl_version_info.3
new file mode 100644
index 000000000..ccb202834
--- /dev/null
+++ b/docs/libcurl/curl_version_info.3
@@ -0,0 +1,154 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH curl_version_info 3 "10 June 2009" "libcurl 7.19.6" "libcurl Manual"
+.SH NAME
+curl_version_info - returns run-time libcurl version info
+.SH SYNOPSIS
+.B #include <curl/curl.h>
+.sp
+.BI "curl_version_info_data *curl_version_info( CURLversion "type ");"
+.ad
+.SH DESCRIPTION
+Returns a pointer to a filled in struct with information about various
+run-time features in libcurl. \fItype\fP should be set to the version of this
+functionality by the time you write your program. This way, libcurl will
+always return a proper struct that your program understands, while programs in
+the future might get a different struct. CURLVERSION_NOW will be the most
+recent one for the library you have installed:
+
+ data = curl_version_info(CURLVERSION_NOW);
+
+Applications should use this information to judge if things are possible to do
+or not, instead of using compile-time checks, as dynamic/DLL libraries can be
+changed independent of applications.
+
+The curl_version_info_data struct looks like this
+
+.nf
+typedef struct {
+ CURLversion age; /* see description below */
+
+ /* when 'age' is 0 or higher, the members below also exist: */
+ const char *version; /* human readable string */
+ unsigned int version_num; /* numeric representation */
+ const char *host; /* human readable string */
+ int features; /* bitmask, see below */
+ char *ssl_version; /* human readable string */
+ long ssl_version_num; /* not used, always zero */
+ const char *libz_version; /* human readable string */
+ const char **protocols; /* list of protocols */
+
+ /* when 'age' is 1 or higher, the members below also exist: */
+ const char *ares; /* human readable string */
+ int ares_num; /* number */
+
+ /* when 'age' is 2 or higher, the member below also exists: */
+ const char *libidn; /* human readable string */
+
+ /* when 'age' is 3 or higher, the members below also exist: */
+ int iconv_ver_num; /* '_libiconv_version' if iconv support enabled */
+
+ const char *libssh_version; /* human readable string */
+
+} curl_version_info_data;
+.fi
+
+\fIage\fP describes what the age of this struct is. The number depends on how
+new the libcurl you're using is. You are however guaranteed to get a struct that you
+have a matching struct for in the header, as you tell libcurl your "age" with
+the input argument.
+
+\fIversion\fP is just an ascii string for the libcurl version.
+
+\fIversion_num\fP is a 24 bit number created like this: <8 bits major number>
+| <8 bits minor number> | <8 bits patch number>. Version 7.9.8 is therefore
+returned as 0x070908.
+
+\fIhost\fP is an ascii string showing what host information that this libcurl
+was built for. As discovered by a configure script or set by the build
+environment.
+
+\fIfeatures\fP can have none, one or more bits set, and the currently defined
+bits are:
+.RS
+.IP CURL_VERSION_IPV6
+supports IPv6
+.IP CURL_VERSION_KERBEROS4
+supports kerberos4 (when using FTP)
+.IP CURL_VERSION_SSL
+supports SSL (HTTPS/FTPS) (Added in 7.10)
+.IP CURL_VERSION_LIBZ
+supports HTTP deflate using libz (Added in 7.10)
+.IP CURL_VERSION_NTLM
+supports HTTP NTLM (added in 7.10.6)
+.IP CURL_VERSION_GSSNEGOTIATE
+supports HTTP GSS-Negotiate (added in 7.10.6)
+.IP CURL_VERSION_DEBUG
+libcurl was built with debug capabilities (added in 7.10.6)
+.IP CURL_VERSION_CURLDEBUG
+libcurl was built with memory tracking debug capabilities. This is mainly of
+interest for libcurl hackers. (added in 7.19.6)
+.IP CURL_VERSION_ASYNCHDNS
+libcurl was built with support for asynchronous name lookups, which allows
+more exact timeouts (even on Windows) and less blocking when using the multi
+interface. (added in 7.10.7)
+.IP CURL_VERSION_SPNEGO
+libcurl was built with support for SPNEGO authentication (Simple and Protected
+GSS-API Negotiation Mechanism, defined in RFC 2478.) (added in 7.10.8)
+.IP CURL_VERSION_LARGEFILE
+libcurl was built with support for large files. (Added in 7.11.1)
+.IP CURL_VERSION_IDN
+libcurl was built with support for IDNA, domain names with international
+letters. (Added in 7.12.0)
+.IP CURL_VERSION_SSPI
+libcurl was built with support for SSPI. This is only available on Windows and
+makes libcurl use Windows-provided functions for NTLM authentication. It also
+allows libcurl to use the current user and the current user's password without
+the app having to pass them on. (Added in 7.13.2)
+.IP CURL_VERSION_CONV
+libcurl was built with support for character conversions, as provided by the
+CURLOPT_CONV_* callbacks. (Added in 7.15.4)
+.IP CURL_VERSION_TLSAUTH_SRP
+libcurl was built with support for TLS-SRP. (Added in 7.21.4)
+.IP CURL_VERSION_NTLM_WB
+libcurl was built with support for NTLM delegation to a winbind helper.
+(Added in 7.22.0)
+.RE
+\fIssl_version\fP is an ASCII string for the OpenSSL version used. If libcurl
+has no SSL support, this is NULL.
+
+\fIssl_version_num\fP is the numerical OpenSSL version value as defined by the
+OpenSSL project. If libcurl has no SSL support, this is 0.
+
+\fIlibz_version\fP is an ASCII string (there is no numerical version). If
+libcurl has no libz support, this is NULL.
+
+\fIprotocols\fP is a pointer to an array of char * pointers, containing the
+names protocols that libcurl supports (using lowercase letters). The protocol
+names are the same as would be used in URLs. The array is terminated by a NULL
+entry.
+.SH RETURN VALUE
+A pointer to a curl_version_info_data struct.
+.SH "SEE ALSO"
+\fIcurl_version(3)\fP
+
diff --git a/docs/libcurl/getinfo-times b/docs/libcurl/getinfo-times
new file mode 100644
index 000000000..d767d7aae
--- /dev/null
+++ b/docs/libcurl/getinfo-times
@@ -0,0 +1,27 @@
+An overview of the six time values available from curl_easy_getinfo()
+
+curk_easy_perform()
+ |
+ |--NT
+ |--|--CT
+ |--|--|--PT
+ |--|--|--|--ST
+ |--|--|--TT
+ |--|--|--|--|--RT
+
+NT = CURLINFO_NAMELOOKUP_TIME. The time it took from the start until the name
+ resolving was completed.
+CT = CURLINFO_CONNECT_TIME. The time it took from the start until the connect
+ to the remote host (or proxy) was completed.
+PT = CURLINFO_PRETRANSFER_TIME. The time it took from the start until the file
+ transfer is just about to begin. This includes all pre-transfer commands
+ and negotiations that are specific to the particular protocol(s)
+ involved.
+ST = CURLINFO_STARTTRANSFER_TIME. The time it took from the start until the
+ first byte is just about to be transferred.
+TT = CURLINFO_TOTAL_TIME. Time of the previous transfer. This time does not
+ include the connect time (CT), so if you want the complete operation
+ time, you should add that.
+RT = CURLINFO_REDIRECT_TIME. The time it took for all redirection steps
+ include name lookup, connect, pretransfer and transfer before final
+ transaction was started. So, this is zero if no redirection took place.
diff --git a/docs/libcurl/index.html b/docs/libcurl/index.html
new file mode 100644
index 000000000..287a2dd69
--- /dev/null
+++ b/docs/libcurl/index.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html><head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<title>Index to libcurl documentation</title>
+</head>
+
+<body>
+<h1 align="center">Index to libcurl documentation</h1>
+
+<h2>Programs</h2>
+<p><a href="../index.html">curl and tools</a>
+
+<h2>Overviews</h2>
+<A HREF="libcurl.html">libcurl</A>
+<br><a href="libcurl-easy.html">libcurl-easy</a>
+<br><a href="libcurl-multi.html">libcurl-multi</a>
+<br><a href="libcurl-share.html">libcurl-share</a>
+<br><a href="libcurl-errors.html">libcurl-errors</a>
+<br><a href="libcurl-tutorial.html">libcurl-tutorial</a>
+
+<H2>Library Functions (A-Z)</H2>
+<a href="curl_easy_cleanup.html">curl_easy_cleanup</A>
+<br><a href="curl_easy_duphandle.html">curl_easy_duphandle</A>
+<br><a href="curl_easy_getinfo.html">curl_easy_getinfo</A>
+<br><a href="curl_easy_init.html">curl_easy_init</A>
+<br><a href="curl_easy_perform.html">curl_easy_perform</A>
+<br><a href="curl_easy_recv.html">curl_easy_recv</A>
+<br><a href="curl_easy_reset.html">curl_easy_reset</A>
+<br><a href="curl_easy_send.html">curl_easy_send</A>
+<br><a href="curl_easy_setopt.html">curl_easy_setopt</A>
+<br><a href="curl_easy_strerror.html">curl_easy_strerror</A>
+<br><a href="curl_escape.html">curl_escape</A>
+<br><a href="curl_formadd.html">curl_formadd</A>
+<br><a href="curl_formfree.html">curl_formfree</A>
+<br><a href="curl_free.html">curl_free</A>
+<br><a href="curl_getdate.html">curl_getdate</A>
+<br><a href="curl_getenv.html">curl_getenv</A>
+<br><a href="curl_global_cleanup.html">curl_global_cleanup</A>
+<br><a href="curl_global_init.html">curl_global_init</A>
+<br><a href="curl_global_init_mem.html">curl_global_init_mem</A>
+<br><a href="curl_mprintf.html">curl_mprintf</A>
+<br><a href="curl_multi_add_handle.html">curl_multi_add_handle</a>
+<br><a href="curl_multi_cleanup.html">curl_multi_cleanup</a>
+<br><a href="curl_multi_fdset.html">curl_multi_fdset</a>
+<br><a href="curl_multi_info_read.html">curl_multi_info_read</a>
+<br><a href="curl_multi_init.html">curl_multi_init</a>
+<br><a href="curl_multi_perform.html">curl_multi_perform</a>
+<br><a href="curl_multi_remove_handle.html">curl_multi_remove_handle</a>
+<br><a href="curl_multi_strerror.html">curl_multi_strerror.html</a>
+<br><a href="curl_share_cleanup.html">curl_share_cleanup</A>
+<br><a href="curl_share_init.html">curl_share_init</A>
+<br><a href="curl_share_setopt.html">curl_share_setopt</A>
+<br><a href="curl_share_strerror.html">curl_share_strerror.html</a>
+<br><a href="curl_slist_append.html">curl_slist_append</A>
+<br><a href="curl_slist_free_all.html">curl_slist_free_all</A>
+<br><a href="curl_strequal.html">curl_strequal and curl_strnequal</A>
+<br><a href="curl_unescape.html">curl_unescape</A>
+<br><a href="curl_version.html">curl_version</A>
+<br><a href="curl_version_info.html">curl_version_info</A>
+
+</body></html>
diff --git a/docs/libcurl/libcurl-easy.3 b/docs/libcurl/libcurl-easy.3
new file mode 100644
index 000000000..698a4ce72
--- /dev/null
+++ b/docs/libcurl/libcurl-easy.3
@@ -0,0 +1,45 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH libcurl 3 "12 Aug 2003" "libcurl 7.10.7" "libcurl easy interface"
+.SH NAME
+libcurl-easy \- easy interface overview
+.SH DESCRIPTION
+When using libcurl's "easy" interface you init your session and get a handle
+(often referred to as an "easy handle"), which you use as input to the easy
+interface functions you use. Use \fIcurl_easy_init(3)\fP to get the handle.
+
+You continue by setting all the options you want in the upcoming transfer, the
+most important among them is the URL itself (you can't transfer anything
+without a specified URL as you may have figured out yourself). You might want
+to set some callbacks as well that will be called from the library when data
+is available etc. \fIcurl_easy_setopt(3)\fP is used for all this.
+
+When all is setup, you tell libcurl to perform the transfer using
+\fIcurl_easy_perform(3)\fP. It will then do the entire operation and won't
+return until it is done (successfully or not).
+
+After the transfer has been made, you can set new options and make another
+transfer, or if you're done, cleanup the session by calling
+\fIcurl_easy_cleanup(3)\fP. If you want persistent connections, you don't
+cleanup immediately, but instead run ahead and perform other transfers using
+the same easy handle.
+
diff --git a/docs/libcurl/libcurl-errors.3 b/docs/libcurl/libcurl-errors.3
new file mode 100644
index 000000000..beee3971f
--- /dev/null
+++ b/docs/libcurl/libcurl-errors.3
@@ -0,0 +1,289 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH libcurl-errors 3 "1 Jan 2010" "libcurl 7.20.0" "libcurl errors"
+.SH NAME
+libcurl-errors \- error codes in libcurl
+.SH DESCRIPTION
+This man page includes most, if not all, available error codes in libcurl.
+Why they occur and possibly what you can do to fix the problem are also included.
+.SH "CURLcode"
+Almost all "easy" interface functions return a CURLcode error code. No matter
+what, using the \fIcurl_easy_setopt(3)\fP option \fICURLOPT_ERRORBUFFER\fP is
+a good idea as it will give you a human readable error string that may offer
+more details about the cause of the error than just the error code.
+\fIcurl_easy_strerror(3)\fP can be called to get an error string from a
+given CURLcode number.
+
+CURLcode is one of the following:
+.IP "CURLE_OK (0)"
+All fine. Proceed as usual.
+.IP "CURLE_UNSUPPORTED_PROTOCOL (1)"
+The URL you passed to libcurl used a protocol that this libcurl does not
+support. The support might be a compile-time option that you didn't use, it
+can be a misspelled protocol string or just a protocol libcurl has no code
+for.
+.IP "CURLE_FAILED_INIT (2)"
+Very early initialization code failed. This is likely to be an internal error
+or problem, or a resource problem where something fundamental couldn't get
+done at init time.
+.IP "CURLE_URL_MALFORMAT (3)"
+The URL was not properly formatted.
+.IP "CURLE_NOT_BUILT_IN (4)"
+A requested feature, protocol or option was not found built-in in this libcurl
+due to a build-time decision. This means that a feature or option was not
+enabled or explicitly disabled when libcurl was built and in order to get it
+to function you have to get a rebuilt libcurl.
+.IP "CURLE_COULDNT_RESOLVE_PROXY (5)"
+Couldn't resolve proxy. The given proxy host could not be resolved.
+.IP "CURLE_COULDNT_RESOLVE_HOST (6)"
+Couldn't resolve host. The given remote host was not resolved.
+.IP "CURLE_COULDNT_CONNECT (7)"
+Failed to connect() to host or proxy.
+.IP "CURLE_FTP_WEIRD_SERVER_REPLY (8)"
+After connecting to a FTP server, libcurl expects to get a certain reply
+back. This error code implies that it got a strange or bad reply. The given
+remote server is probably not an OK FTP server.
+.IP "CURLE_REMOTE_ACCESS_DENIED (9)"
+We were denied access to the resource given in the URL. For FTP, this occurs
+while trying to change to the remote directory.
+.IP "CURLE_FTP_ACCEPT_FAILED (10)"
+While waiting for the server to connect back when an active FTP session is
+used, an error code was sent over the control connection or similar.
+.IP "CURLE_FTP_WEIRD_PASS_REPLY (11)"
+After having sent the FTP password to the server, libcurl expects a proper
+reply. This error code indicates that an unexpected code was returned.
+.IP "CURLE_FTP_ACCEPT_TIMEOUT (12)"
+During an active FTP session while waiting for the server to connect, the
+\fICURLOPT_ACCEPTTIMOUT_MS\fP (or the internal default) timeout expired.
+.IP "CURLE_FTP_WEIRD_PASV_REPLY (13)"
+libcurl failed to get a sensible result back from the server as a response to
+either a PASV or a EPSV command. The server is flawed.
+.IP "CURLE_FTP_WEIRD_227_FORMAT (14)"
+FTP servers return a 227-line as a response to a PASV command. If libcurl
+fails to parse that line, this return code is passed back.
+.IP "CURLE_FTP_CANT_GET_HOST (15)"
+An internal failure to lookup the host used for the new connection.
+.IP "CURLE_FTP_COULDNT_SET_TYPE (17)"
+Received an error when trying to set the transfer mode to binary or ASCII.
+.IP "CURLE_PARTIAL_FILE (18)"
+A file transfer was shorter or larger than expected. This happens when the
+server first reports an expected transfer size, and then delivers data that
+doesn't match the previously given size.
+.IP "CURLE_FTP_COULDNT_RETR_FILE (19)"
+This was either a weird reply to a 'RETR' command or a zero byte transfer
+complete.
+.IP "CURLE_QUOTE_ERROR (21)"
+When sending custom "QUOTE" commands to the remote server, one of the commands
+returned an error code that was 400 or higher (for FTP) or otherwise
+indicated unsuccessful completion of the command.
+.IP "CURLE_HTTP_RETURNED_ERROR (22)"
+This is returned if CURLOPT_FAILONERROR is set TRUE and the HTTP server
+returns an error code that is >= 400.
+.IP "CURLE_WRITE_ERROR (23)"
+An error occurred when writing received data to a local file, or an error was
+returned to libcurl from a write callback.
+.IP "CURLE_UPLOAD_FAILED (25)"
+Failed starting the upload. For FTP, the server typically denied the STOR
+command. The error buffer usually contains the server's explanation for this.
+.IP "CURLE_READ_ERROR (26)"
+There was a problem reading a local file or an error returned by the read
+callback.
+.IP "CURLE_OUT_OF_MEMORY (27)"
+A memory allocation request failed. This is serious badness and
+things are severely screwed up if this ever occurs.
+.IP "CURLE_OPERATION_TIMEDOUT (28)"
+Operation timeout. The specified time-out period was reached according to the
+conditions.
+.IP "CURLE_FTP_PORT_FAILED (30)"
+The FTP PORT command returned error. This mostly happens when you haven't
+specified a good enough address for libcurl to use. See \fICURLOPT_FTPPORT\fP.
+.IP "CURLE_FTP_COULDNT_USE_REST (31)"
+The FTP REST command returned error. This should never happen if the server is
+sane.
+.IP "CURLE_RANGE_ERROR (33)"
+The server does not support or accept range requests.
+.IP "CURLE_HTTP_POST_ERROR (34)"
+This is an odd error that mainly occurs due to internal confusion.
+.IP "CURLE_SSL_CONNECT_ERROR (35)"
+A problem occurred somewhere in the SSL/TLS handshake. You really want the
+error buffer and read the message there as it pinpoints the problem slightly
+more. Could be certificates (file formats, paths, permissions), passwords, and
+others.
+.IP "CURLE_BAD_DOWNLOAD_RESUME (36)"
+The download could not be resumed because the specified offset was out of the
+file boundary.
+.IP "CURLE_FILE_COULDNT_READ_FILE (37)"
+A file given with FILE:// couldn't be opened. Most likely because the file
+path doesn't identify an existing file. Did you check file permissions?
+.IP "CURLE_LDAP_CANNOT_BIND (38)"
+LDAP cannot bind. LDAP bind operation failed.
+.IP "CURLE_LDAP_SEARCH_FAILED (39)"
+LDAP search failed.
+.IP "CURLE_FUNCTION_NOT_FOUND (41)"
+Function not found. A required zlib function was not found.
+.IP "CURLE_ABORTED_BY_CALLBACK (42)"
+Aborted by callback. A callback returned "abort" to libcurl.
+.IP "CURLE_BAD_FUNCTION_ARGUMENT (43)"
+Internal error. A function was called with a bad parameter.
+.IP "CURLE_INTERFACE_FAILED (45)"
+Interface error. A specified outgoing interface could not be used. Set which
+interface to use for outgoing connections' source IP address with
+CURLOPT_INTERFACE.
+.IP "CURLE_TOO_MANY_REDIRECTS (47)"
+Too many redirects. When following redirects, libcurl hit the maximum amount.
+Set your limit with CURLOPT_MAXREDIRS.
+.IP "CURLE_UNKNOWN_OPTION (48)"
+An option passed to libcurl is not recognized/known. Refer to the appropriate
+documentation. This is most likely a problem in the program that uses
+libcurl. The error buffer might contain more specific information about which
+exact option it concerns.
+.IP "CURLE_TELNET_OPTION_SYNTAX (49)"
+A telnet option string was Illegally formatted.
+.IP "CURLE_PEER_FAILED_VERIFICATION (51)"
+The remote server's SSL certificate or SSH md5 fingerprint was deemed not OK.
+.IP "CURLE_GOT_NOTHING (52)"
+Nothing was returned from the server, and under the circumstances, getting
+nothing is considered an error.
+.IP "CURLE_SSL_ENGINE_NOTFOUND (53)"
+The specified crypto engine wasn't found.
+.IP "CURLE_SSL_ENGINE_SETFAILED (54)"
+Failed setting the selected SSL crypto engine as default!
+.IP "CURLE_SEND_ERROR (55)"
+Failed sending network data.
+.IP "CURLE_RECV_ERROR (56)"
+Failure with receiving network data.
+.IP "CURLE_SSL_CERTPROBLEM (58)"
+problem with the local client certificate.
+.IP "CURLE_SSL_CIPHER (59)"
+Couldn't use specified cipher.
+.IP "CURLE_SSL_CACERT (60)"
+Peer certificate cannot be authenticated with known CA certificates.
+.IP "CURLE_BAD_CONTENT_ENCODING (61)"
+Unrecognized transfer encoding.
+.IP "CURLE_LDAP_INVALID_URL (62)"
+Invalid LDAP URL.
+.IP "CURLE_FILESIZE_EXCEEDED (63)"
+Maximum file size exceeded.
+.IP "CURLE_USE_SSL_FAILED (64)"
+Requested FTP SSL level failed.
+.IP "CURLE_SEND_FAIL_REWIND (65)"
+When doing a send operation curl had to rewind the data to retransmit, but the
+rewinding operation failed.
+.IP "CURLE_SSL_ENGINE_INITFAILED (66)"
+Initiating the SSL Engine failed.
+.IP "CURLE_LOGIN_DENIED (67)"
+The remote server denied curl to login (Added in 7.13.1)
+.IP "CURLE_TFTP_NOTFOUND (68)"
+File not found on TFTP server.
+.IP "CURLE_TFTP_PERM (69)"
+Permission problem on TFTP server.
+.IP "CURLE_REMOTE_DISK_FULL (70)"
+Out of disk space on the server.
+.IP "CURLE_TFTP_ILLEGAL (71)"
+Illegal TFTP operation.
+.IP "CURLE_TFTP_UNKNOWNID (72)"
+Unknown TFTP transfer ID.
+.IP "CURLE_REMOTE_FILE_EXISTS (73)"
+File already exists and will not be overwritten.
+.IP "CURLE_TFTP_NOSUCHUSER (74)"
+This error should never be returned by a properly functioning TFTP server.
+.IP "CURLE_CONV_FAILED (75)"
+Character conversion failed.
+.IP "CURLE_CONV_REQD (76)"
+Caller must register conversion callbacks.
+.IP "CURLE_SSL_CACERT_BADFILE (77)"
+Problem with reading the SSL CA cert (path? access rights?)
+.IP "CURLE_REMOTE_FILE_NOT_FOUND (78)"
+The resource referenced in the URL does not exist.
+.IP "CURLE_SSH (79)"
+An unspecified error occurred during the SSH session.
+.IP "CURLE_SSL_SHUTDOWN_FAILED (80)"
+Failed to shut down the SSL connection.
+.IP "CURLE_AGAIN (81)"
+Socket is not ready for send/recv wait till it's ready and try again. This
+return code is only returned from \fIcurl_easy_recv(3)\fP and
+\fIcurl_easy_send(3)\fP (Added in 7.18.2)
+.IP "CURLE_SSL_CRL_BADFILE (82)"
+Failed to load CRL file (Added in 7.19.0)
+.IP "CURLE_SSL_ISSUER_ERROR (83)"
+Issuer check failed (Added in 7.19.0)
+.IP "CURLE_FTP_PRET_FAILED (84)"
+The FTP server does not understand the PRET command at all or does not support
+the given argument. Be careful when using \fICURLOPT_CUSTOMREQUEST\fP, a
+custom LIST command will be sent with PRET CMD before PASV as well. (Added in
+7.20.0)
+.IP "CURLE_RTSP_CSEQ_ERROR (85)"
+Mismatch of RTSP CSeq numbers.
+.IP "CURLE_RTSP_SESSION_ERROR (86)"
+Mismatch of RTSP Session Identifiers.
+.IP "CURLE_FTP_BAD_FILE_LIST (87)"
+Unable to parse FTP file list (during FTP wildcard downloading).
+.IP "CURLE_CHUNK_FAILED (88)"
+Chunk callback reported error.
+.IP "CURLE_OBSOLETE*"
+These error codes will never be returned. They were used in an old libcurl
+version and are currently unused.
+.SH "CURLMcode"
+This is the generic return code used by functions in the libcurl multi
+interface. Also consider \fIcurl_multi_strerror(3)\fP.
+.IP "CURLM_CALL_MULTI_PERFORM (-1)"
+This is not really an error. It means you should call
+\fIcurl_multi_perform(3)\fP again without doing select() or similar in
+between. Before version 7.20.0 this could be returned by
+\fIcurl_multi_perform(3)\fP, but in later versions this return code is never
+used.
+.IP "CURLM_OK (0)"
+Things are fine.
+.IP "CURLM_BAD_HANDLE (1)"
+The passed-in handle is not a valid CURLM handle.
+.IP "CURLM_BAD_EASY_HANDLE (2)"
+An easy handle was not good/valid. It could mean that it isn't an easy handle
+at all, or possibly that the handle already is in used by this or another
+multi handle.
+.IP "CURLM_OUT_OF_MEMORY (3)"
+You are doomed.
+.IP "CURLM_INTERNAL_ERROR (4)"
+This can only be returned if libcurl bugs. Please report it to us!
+.IP "CURLM_BAD_SOCKET (5)"
+The passed-in socket is not a valid one that libcurl already knows about.
+(Added in 7.15.4)
+.IP "CURLM_UNKNOWN_OPTION (6)"
+curl_multi_setopt() with unsupported option
+(Added in 7.15.4)
+.SH "CURLSHcode"
+The "share" interface will return a CURLSHcode to indicate when an error has
+occurred. Also consider \fIcurl_share_strerror(3)\fP.
+.IP "CURLSHE_OK (0)"
+All fine. Proceed as usual.
+.IP "CURLSHE_BAD_OPTION (1)"
+An invalid option was passed to the function.
+.IP "CURLSHE_IN_USE (2)"
+The share object is currently in use.
+.IP "CURLSHE_INVALID (3)"
+An invalid share object was passed to the function.
+.IP "CURLSHE_NOMEM (4)"
+Not enough memory was available.
+(Added in 7.12.0)
+.IP "CURLSHE_NOT_BUILT_IN (5)"
+The requested sharing could not be done because the library you use don't have
+that particular feature enabled. (Added in 7.23.0)
diff --git a/docs/libcurl/libcurl-multi.3 b/docs/libcurl/libcurl-multi.3
new file mode 100644
index 000000000..2af029961
--- /dev/null
+++ b/docs/libcurl/libcurl-multi.3
@@ -0,0 +1,151 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH libcurl-multi 3 "3 Feb 2007" "libcurl 7.16.0" "libcurl multi interface"
+.SH NAME
+libcurl-multi \- how to use the multi interface
+.SH DESCRIPTION
+This is an overview on how to use the libcurl multi interface in your C
+programs. There are specific man pages for each function mentioned in
+here. There's also the \fIlibcurl-tutorial(3)\fP man page for a complete
+tutorial to programming with libcurl and the \fIlibcurl-easy(3)\fP man page
+for an overview of the libcurl easy interface.
+
+All functions in the multi interface are prefixed with curl_multi.
+.SH "OBJECTIVES"
+The multi interface offers several abilities that the easy interface doesn't.
+They are mainly:
+
+1. Enable a "pull" interface. The application that uses libcurl decides where
+and when to ask libcurl to get/send data.
+
+2. Enable multiple simultaneous transfers in the same thread without making it
+complicated for the application.
+
+3. Enable the application to wait for action on its own file descriptors and
+curl's file descriptors simultaneous easily.
+.SH "ONE MULTI HANDLE MANY EASY HANDLES"
+To use the multi interface, you must first create a 'multi handle' with
+\fIcurl_multi_init(3)\fP. This handle is then used as input to all further
+curl_multi_* functions.
+
+Each single transfer is built up with an easy handle. You must create them,
+and setup the appropriate options for each easy handle, as outlined in the
+\fIlibcurl(3)\fP man page, using \fIcurl_easy_setopt(3)\fP.
+
+When the easy handle is setup for a transfer, then instead of using
+\fIcurl_easy_perform(3)\fP (as when using the easy interface for transfers),
+you should instead add the easy handle to the multi handle using
+\fIcurl_multi_add_handle(3)\fP. The multi handle is sometimes referred to as a
+\'multi stack\' because of the fact that it may hold a large amount of easy
+handles.
+
+Should you change your mind, the easy handle is again removed from the multi
+stack using \fIcurl_multi_remove_handle(3)\fP. Once removed from the multi
+handle, you can again use other easy interface functions like
+\fIcurl_easy_perform(3)\fP on the handle or whatever you think is necessary.
+
+Adding the easy handle to the multi handle does not start the transfer.
+Remember that one of the main ideas with this interface is to let your
+application drive. You drive the transfers by invoking
+\fIcurl_multi_perform(3)\fP. libcurl will then transfer data if there is
+anything available to transfer. It'll use the callbacks and everything else
+you have setup in the individual easy handles. It'll transfer data on all
+current transfers in the multi stack that are ready to transfer anything. It
+may be all, it may be none.
+
+Your application can acquire knowledge from libcurl when it would like to get
+invoked to transfer data, so that you don't have to busy-loop and call that
+\fIcurl_multi_perform(3)\fP like crazy. \fIcurl_multi_fdset(3)\fP offers an
+interface using which you can extract fd_sets from libcurl to use in select()
+or poll() calls in order to get to know when the transfers in the multi stack
+might need attention. This also makes it very easy for your program to wait
+for input on your own private file descriptors at the same time or perhaps
+timeout every now and then, should you want that.
+
+\fIcurl_multi_perform(3)\fP stores the number of still running transfers in
+one of its input arguments, and by reading that you can figure out when all
+the transfers in the multi handles are done. 'done' does not mean
+successful. One or more of the transfers may have failed. Tracking when this
+number changes, you know when one or more transfers are done.
+
+To get information about completed transfers, to figure out success or not and
+similar, \fIcurl_multi_info_read(3)\fP should be called. It can return a
+message about a current or previous transfer. Repeated invokes of the function
+get more messages until the message queue is empty. The information you
+receive there includes an easy handle pointer which you may use to identify
+which easy handle the information regards.
+
+When a single transfer is completed, the easy handle is still left added to
+the multi stack. You need to first remove the easy handle with
+\fIcurl_multi_remove_handle(3)\fP and then close it with
+\fIcurl_easy_cleanup(3)\fP, or possibly set new options to it and add it again
+with \fIcurl_multi_add_handle(3)\fP to start another transfer.
+
+When all transfers in the multi stack are done, cleanup the multi handle with
+\fIcurl_multi_cleanup(3)\fP. Be careful and please note that you \fBMUST\fP
+invoke separate \fIcurl_easy_cleanup(3)\fP calls on every single easy handle
+to clean them up properly.
+
+If you want to re-use an easy handle that was added to the multi handle for
+transfer, you must first remove it from the multi stack and then re-add it
+again (possibly after having altered some options at your own choice).
+.SH "MULTI_SOCKET"
+\fIcurl_multi_socket_action(3)\fP function offers a way for applications to
+not only avoid being forced to use select(), but it also offers a much more
+high-performance API that will make a significant difference for applications
+using large numbers of simultaneous connections.
+
+\fIcurl_multi_socket_action(3)\fP is then used instead of
+\fIcurl_multi_perform(3)\fP.
+
+When using this API, you add easy handles to the multi handle just as with the
+normal multi interface. Then you also set two callbacks with the
+CURLMOPT_SOCKETFUNCTION and CURLMOPT_TIMERFUNCTION options to
+\fIcurl_multi_setopt(3)\fP.
+
+The API is then designed to inform your application about which sockets
+libcurl is currently using and for what activities (read and/or write) on
+those sockets your application is expected to wait for.
+
+Your application must then make sure to receive all sockets informed about in
+the CURLMOPT_SOCKETFUNCTION callback and make sure it reacts on the given
+activity on them. When a socket has the given activity, you call
+\fIcurl_multi_socket_action(3)\fP specifying which socket and action there
+are.
+
+The CURLMOPT_TIMERFUNCTION callback is called to set a timeout. When that
+timeout expires, your application should call the
+\fIcurl_multi_socket_action(3)\fP function saying it was due to a timeout.
+.SH "BLOCKING"
+A few areas in the code are still using blocking code, even when used from the
+multi interface. While we certainly want and intend for these to get fixed in
+the future, you should be aware of the following current restrictions:
+
+.nf
+ - Name resolves unless the c-ares or threaded-resolver backends are used
+ - NSS SSL connections
+ - HTTP proxy CONNECT operations
+ - SOCKS proxy handshakes
+ - file:// transfers
+ - TELNET transfers
+.fi
diff --git a/docs/libcurl/libcurl-share.3 b/docs/libcurl/libcurl-share.3
new file mode 100644
index 000000000..583902152
--- /dev/null
+++ b/docs/libcurl/libcurl-share.3
@@ -0,0 +1,62 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH libcurl-share 3 "8 Aug 2003" "libcurl 7.10.7" "libcurl share interface"
+.SH NAME
+libcurl-share \- how to use the share interface
+.SH DESCRIPTION
+This is an overview on how to use the libcurl share interface in your C
+programs. There are specific man pages for each function mentioned in
+here.
+
+All functions in the share interface are prefixed with curl_share.
+
+.SH "OBJECTIVES"
+The share interface was added to enable sharing of data between curl
+\&"handles".
+.SH "ONE SET OF DATA - MANY TRANSFERS"
+You can have multiple easy handles share data between them. Have them update
+and use the \fBsame\fP cookie database or DNS cache! This way, each single
+transfer will take advantage from data updates made by the other transfer(s).
+.SH "SHARE OBJECT"
+You create a shared object with \fIcurl_share_init(3)\fP. It returns a handle
+for a newly created one.
+
+You tell the shared object what data you want it to share by using
+\fIcurl_share_setopt(3)\fP.
+
+Since you can use this share from multiple threads, and libcurl has no
+internal thread synchronization, you must provide mutex callbacks if you're
+using this multi-threaded. You set lock and unlock functions with
+\fIcurl_share_setopt(3)\fP too.
+
+Then, you make an easy handle to use this share, you set the
+\fICURLOPT_SHARE\fP option with \fIcurl_easy_setopt(3)\fP, and pass in share
+handle. You can make any number of easy handles share the same share handle.
+
+To make an easy handle stop using that particular share, you set
+\fICURLOPT_SHARE\fP to NULL for that easy handle. To make a handle stop
+sharing a particular data, you can \fICURLSHOPT_UNSHARE\fP it.
+
+When you're done using the share, make sure that no easy handle is still using
+it, and call \fIcurl_share_cleanup(3)\fP on the handle.
+.SH "SEE ALSO"
+.BR curl_share_init "(3), " curl_share_setopt "(3), " curl_share_cleanup "(3)"
diff --git a/docs/libcurl/libcurl-tutorial.3 b/docs/libcurl/libcurl-tutorial.3
new file mode 100644
index 000000000..1cca23f33
--- /dev/null
+++ b/docs/libcurl/libcurl-tutorial.3
@@ -0,0 +1,1369 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH libcurl-tutorial 3 "4 Mar 2009" "libcurl" "libcurl programming"
+.SH NAME
+libcurl-tutorial \- libcurl programming tutorial
+.SH "Objective"
+This document attempts to describe the general principles and some basic
+approaches to consider when programming with libcurl. The text will focus
+mainly on the C interface but might apply fairly well on other interfaces as
+well as they usually follow the C one pretty closely.
+
+This document will refer to 'the user' as the person writing the source code
+that uses libcurl. That would probably be you or someone in your position.
+What will be generally referred to as 'the program' will be the collected
+source code that you write that is using libcurl for transfers. The program
+is outside libcurl and libcurl is outside of the program.
+
+To get more details on all options and functions described herein, please
+refer to their respective man pages.
+
+.SH "Building"
+There are many different ways to build C programs. This chapter will assume a
+UNIX-style build process. If you use a different build system, you can still
+read this to get general information that may apply to your environment as
+well.
+.IP "Compiling the Program"
+Your compiler needs to know where the libcurl headers are located. Therefore
+you must set your compiler's include path to point to the directory where you
+installed them. The 'curl-config'[3] tool can be used to get this information:
+
+$ curl-config --cflags
+
+.IP "Linking the Program with libcurl"
+When having compiled the program, you need to link your object files to create
+a single executable. For that to succeed, you need to link with libcurl and
+possibly also with other libraries that libcurl itself depends on. Like the
+OpenSSL libraries, but even some standard OS libraries may be needed on the
+command line. To figure out which flags to use, once again the 'curl-config'
+tool comes to the rescue:
+
+$ curl-config --libs
+
+.IP "SSL or Not"
+libcurl can be built and customized in many ways. One of the things that
+varies from different libraries and builds is the support for SSL-based
+transfers, like HTTPS and FTPS. If a supported SSL library was detected
+properly at build-time, libcurl will be built with SSL support. To figure out
+if an installed libcurl has been built with SSL support enabled, use
+\&'curl-config' like this:
+
+$ curl-config --feature
+
+And if SSL is supported, the keyword 'SSL' will be written to stdout,
+possibly together with a few other features that could be either on or off on
+for different libcurls.
+
+See also the "Features libcurl Provides" further down.
+.IP "autoconf macro"
+When you write your configure script to detect libcurl and setup variables
+accordingly, we offer a prewritten macro that probably does everything you
+need in this area. See docs/libcurl/libcurl.m4 file - it includes docs on how
+to use it.
+
+.SH "Portable Code in a Portable World"
+The people behind libcurl have put a considerable effort to make libcurl work
+on a large amount of different operating systems and environments.
+
+You program libcurl the same way on all platforms that libcurl runs on. There
+are only very few minor considerations that differ. If you just make sure to
+write your code portable enough, you may very well create yourself a very
+portable program. libcurl shouldn't stop you from that.
+
+.SH "Global Preparation"
+The program must initialize some of the libcurl functionality globally. That
+means it should be done exactly once, no matter how many times you intend to
+use the library. Once for your program's entire life time. This is done using
+
+ curl_global_init()
+
+and it takes one parameter which is a bit pattern that tells libcurl what to
+initialize. Using \fICURL_GLOBAL_ALL\fP will make it initialize all known
+internal sub modules, and might be a good default option. The current two bits
+that are specified are:
+.RS
+.IP "CURL_GLOBAL_WIN32"
+which only does anything on Windows machines. When used on
+a Windows machine, it'll make libcurl initialize the win32 socket
+stuff. Without having that initialized properly, your program cannot use
+sockets properly. You should only do this once for each application, so if
+your program already does this or of another library in use does it, you
+should not tell libcurl to do this as well.
+.IP CURL_GLOBAL_SSL
+which only does anything on libcurls compiled and built SSL-enabled. On these
+systems, this will make libcurl initialize the SSL library properly for this
+application. This only needs to be done once for each application so if your
+program or another library already does this, this bit should not be needed.
+.RE
+
+libcurl has a default protection mechanism that detects if
+\fIcurl_global_init(3)\fP hasn't been called by the time
+\fIcurl_easy_perform(3)\fP is called and if that is the case, libcurl runs the
+function itself with a guessed bit pattern. Please note that depending solely
+on this is not considered nice nor very good.
+
+When the program no longer uses libcurl, it should call
+\fIcurl_global_cleanup(3)\fP, which is the opposite of the init call. It will
+then do the reversed operations to cleanup the resources the
+\fIcurl_global_init(3)\fP call initialized.
+
+Repeated calls to \fIcurl_global_init(3)\fP and \fIcurl_global_cleanup(3)\fP
+should be avoided. They should only be called once each.
+
+.SH "Features libcurl Provides"
+It is considered best-practice to determine libcurl features at run-time
+rather than at build-time (if possible of course). By calling
+\fIcurl_version_info(3)\fP and checking out the details of the returned
+struct, your program can figure out exactly what the currently running libcurl
+supports.
+
+.SH "Handle the Easy libcurl"
+libcurl first introduced the so called easy interface. All operations in the
+easy interface are prefixed with 'curl_easy'.
+
+Recent libcurl versions also offer the multi interface. More about that
+interface, what it is targeted for and how to use it is detailed in a separate
+chapter further down. You still need to understand the easy interface first,
+so please continue reading for better understanding.
+
+To use the easy interface, you must first create yourself an easy handle. You
+need one handle for each easy session you want to perform. Basically, you
+should use one handle for every thread you plan to use for transferring. You
+must never share the same handle in multiple threads.
+
+Get an easy handle with
+
+ easyhandle = curl_easy_init();
+
+It returns an easy handle. Using that you proceed to the next step: setting
+up your preferred actions. A handle is just a logic entity for the upcoming
+transfer or series of transfers.
+
+You set properties and options for this handle using
+\fIcurl_easy_setopt(3)\fP. They control how the subsequent transfer or
+transfers will be made. Options remain set in the handle until set again to
+something different. Alas, multiple requests using the same handle will use
+the same options.
+
+Many of the options you set in libcurl are "strings", pointers to data
+terminated with a zero byte. When you set strings with
+\fIcurl_easy_setopt(3)\fP, libcurl makes its own copy so that they don't
+need to be kept around in your application after being set[4].
+
+One of the most basic properties to set in the handle is the URL. You set
+your preferred URL to transfer with CURLOPT_URL in a manner similar to:
+
+.nf
+ curl_easy_setopt(handle, CURLOPT_URL, "http://domain.com/");
+.fi
+
+Let's assume for a while that you want to receive data as the URL identifies a
+remote resource you want to get here. Since you write a sort of application
+that needs this transfer, I assume that you would like to get the data passed
+to you directly instead of simply getting it passed to stdout. So, you write
+your own function that matches this prototype:
+
+ size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp);
+
+You tell libcurl to pass all data to this function by issuing a function
+similar to this:
+
+ curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, write_data);
+
+You can control what data your callback function gets in the fourth argument
+by setting another property:
+
+ curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, &internal_struct);
+
+Using that property, you can easily pass local data between your application
+and the function that gets invoked by libcurl. libcurl itself won't touch the
+data you pass with \fICURLOPT_WRITEDATA\fP.
+
+libcurl offers its own default internal callback that will take care of the data
+if you don't set the callback with \fICURLOPT_WRITEFUNCTION\fP. It will then
+simply output the received data to stdout. You can have the default callback
+write the data to a different file handle by passing a 'FILE *' to a file
+opened for writing with the \fICURLOPT_WRITEDATA\fP option.
+
+Now, we need to take a step back and have a deep breath. Here's one of those
+rare platform-dependent nitpicks. Did you spot it? On some platforms[2],
+libcurl won't be able to operate on files opened by the program. Thus, if you
+use the default callback and pass in an open file with
+\fICURLOPT_WRITEDATA\fP, it will crash. You should therefore avoid this to
+make your program run fine virtually everywhere.
+
+(\fICURLOPT_WRITEDATA\fP was formerly known as \fICURLOPT_FILE\fP. Both names
+still work and do the same thing).
+
+If you're using libcurl as a win32 DLL, you MUST use the
+\fICURLOPT_WRITEFUNCTION\fP if you set \fICURLOPT_WRITEDATA\fP - or you will
+experience crashes.
+
+There are of course many more options you can set, and we'll get back to a few
+of them later. Let's instead continue to the actual transfer:
+
+ success = curl_easy_perform(easyhandle);
+
+\fIcurl_easy_perform(3)\fP will connect to the remote site, do the necessary
+commands and receive the transfer. Whenever it receives data, it calls the
+callback function we previously set. The function may get one byte at a time,
+or it may get many kilobytes at once. libcurl delivers as much as possible as
+often as possible. Your callback function should return the number of bytes it
+\&"took care of". If that is not the exact same amount of bytes that was
+passed to it, libcurl will abort the operation and return with an error code.
+
+When the transfer is complete, the function returns a return code that informs
+you if it succeeded in its mission or not. If a return code isn't enough for
+you, you can use the CURLOPT_ERRORBUFFER to point libcurl to a buffer of yours
+where it'll store a human readable error message as well.
+
+If you then want to transfer another file, the handle is ready to be used
+again. Mind you, it is even preferred that you re-use an existing handle if
+you intend to make another transfer. libcurl will then attempt to re-use the
+previous connection.
+
+For some protocols, downloading a file can involve a complicated process of
+logging in, setting the transfer mode, changing the current directory and
+finally transferring the file data. libcurl takes care of all that
+complication for you. Given simply the URL to a file, libcurl will take care
+of all the details needed to get the file moved from one machine to another.
+
+.SH "Multi-threading Issues"
+The first basic rule is that you must \fBnever\fP simultaneously share a
+libcurl handle (be it easy or multi or whatever) between multiple
+threads. Only use one handle in one thread at any time. You can pass the
+handles around among threads, but you must never use a single handle from more
+than one thread at any given time.
+
+libcurl is completely thread safe, except for two issues: signals and SSL/TLS
+handlers. Signals are used for timing out name resolves (during DNS lookup) -
+when built without c-ares support and not on Windows.
+
+If you are accessing HTTPS or FTPS URLs in a multi-threaded manner, you are
+then of course using the underlying SSL library multi-threaded and those libs
+might have their own requirements on this issue. Basically, you need to
+provide one or two functions to allow it to function properly. For all
+details, see this:
+
+OpenSSL
+
+ http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
+
+GnuTLS
+
+ http://www.gnu.org/software/gnutls/manual/html_node/Multi_002dthreaded-applications.html
+
+NSS
+
+ is claimed to be thread-safe already without anything required.
+
+PolarSSL
+
+ Required actions unknown.
+
+yassl
+
+ Required actions unknown.
+
+axTLS
+
+ Required actions unknown.
+
+When using multiple threads you should set the CURLOPT_NOSIGNAL option to 1
+for all handles. Everything will or might work fine except that timeouts are
+not honored during the DNS lookup - which you can work around by building
+libcurl with c-ares support. c-ares is a library that provides asynchronous
+name resolves. On some platforms, libcurl simply will not function properly
+multi-threaded unless this option is set.
+
+Also, note that CURLOPT_DNS_USE_GLOBAL_CACHE is not thread-safe.
+
+.SH "When It Doesn't Work"
+There will always be times when the transfer fails for some reason. You might
+have set the wrong libcurl option or misunderstood what the libcurl option
+actually does, or the remote server might return non-standard replies that
+confuse the library which then confuses your program.
+
+There's one golden rule when these things occur: set the CURLOPT_VERBOSE
+option to 1. It'll cause the library to spew out the entire protocol
+details it sends, some internal info and some received protocol data as well
+(especially when using FTP). If you're using HTTP, adding the headers in the
+received output to study is also a clever way to get a better understanding
+why the server behaves the way it does. Include headers in the normal body
+output with CURLOPT_HEADER set 1.
+
+Of course, there are bugs left. We need to know about them to be able
+to fix them, so we're quite dependent on your bug reports! When you do report
+suspected bugs in libcurl, please include as many details as you possibly can: a
+protocol dump that CURLOPT_VERBOSE produces, library version, as much as
+possible of your code that uses libcurl, operating system name and version,
+compiler name and version etc.
+
+If CURLOPT_VERBOSE is not enough, you increase the level of debug data your
+application receive by using the CURLOPT_DEBUGFUNCTION.
+
+Getting some in-depth knowledge about the protocols involved is never wrong,
+and if you're trying to do funny things, you might very well understand
+libcurl and how to use it better if you study the appropriate RFC documents
+at least briefly.
+
+.SH "Upload Data to a Remote Site"
+libcurl tries to keep a protocol independent approach to most transfers, thus
+uploading to a remote FTP site is very similar to uploading data to a HTTP
+server with a PUT request.
+
+Of course, first you either create an easy handle or you re-use one existing
+one. Then you set the URL to operate on just like before. This is the remote
+URL, that we now will upload.
+
+Since we write an application, we most likely want libcurl to get the upload
+data by asking us for it. To make it do that, we set the read callback and
+the custom pointer libcurl will pass to our read callback. The read callback
+should have a prototype similar to:
+
+ size_t function(char *bufptr, size_t size, size_t nitems, void *userp);
+
+Where bufptr is the pointer to a buffer we fill in with data to upload and
+size*nitems is the size of the buffer and therefore also the maximum amount
+of data we can return to libcurl in this call. The 'userp' pointer is the
+custom pointer we set to point to a struct of ours to pass private data
+between the application and the callback.
+
+ curl_easy_setopt(easyhandle, CURLOPT_READFUNCTION, read_function);
+
+ curl_easy_setopt(easyhandle, CURLOPT_READDATA, &filedata);
+
+Tell libcurl that we want to upload:
+
+ curl_easy_setopt(easyhandle, CURLOPT_UPLOAD, 1L);
+
+A few protocols won't behave properly when uploads are done without any prior
+knowledge of the expected file size. So, set the upload file size using the
+CURLOPT_INFILESIZE_LARGE for all known file sizes like this[1]:
+
+.nf
+ /* in this example, file_size must be an curl_off_t variable */
+ curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE_LARGE, file_size);
+.fi
+
+When you call \fIcurl_easy_perform(3)\fP this time, it'll perform all the
+necessary operations and when it has invoked the upload it'll call your
+supplied callback to get the data to upload. The program should return as much
+data as possible in every invoke, as that is likely to make the upload perform
+as fast as possible. The callback should return the number of bytes it wrote
+in the buffer. Returning 0 will signal the end of the upload.
+
+.SH "Passwords"
+Many protocols use or even require that user name and password are provided
+to be able to download or upload the data of your choice. libcurl offers
+several ways to specify them.
+
+Most protocols support that you specify the name and password in the URL
+itself. libcurl will detect this and use them accordingly. This is written
+like this:
+
+ protocol://user:password@example.com/path/
+
+If you need any odd letters in your user name or password, you should enter
+them URL encoded, as %XX where XX is a two-digit hexadecimal number.
+
+libcurl also provides options to set various passwords. The user name and
+password as shown embedded in the URL can instead get set with the
+CURLOPT_USERPWD option. The argument passed to libcurl should be a char * to
+a string in the format "user:password". In a manner like this:
+
+ curl_easy_setopt(easyhandle, CURLOPT_USERPWD, "myname:thesecret");
+
+Another case where name and password might be needed at times, is for those
+users who need to authenticate themselves to a proxy they use. libcurl offers
+another option for this, the CURLOPT_PROXYUSERPWD. It is used quite similar
+to the CURLOPT_USERPWD option like this:
+
+ curl_easy_setopt(easyhandle, CURLOPT_PROXYUSERPWD, "myname:thesecret");
+
+There's a long time UNIX "standard" way of storing ftp user names and
+passwords, namely in the $HOME/.netrc file. The file should be made private
+so that only the user may read it (see also the "Security Considerations"
+chapter), as it might contain the password in plain text. libcurl has the
+ability to use this file to figure out what set of user name and password to
+use for a particular host. As an extension to the normal functionality,
+libcurl also supports this file for non-FTP protocols such as HTTP. To make
+curl use this file, use the CURLOPT_NETRC option:
+
+ curl_easy_setopt(easyhandle, CURLOPT_NETRC, 1L);
+
+And a very basic example of how such a .netrc file may look like:
+
+.nf
+ machine myhost.mydomain.com
+ login userlogin
+ password secretword
+.fi
+
+All these examples have been cases where the password has been optional, or
+at least you could leave it out and have libcurl attempt to do its job
+without it. There are times when the password isn't optional, like when
+you're using an SSL private key for secure transfers.
+
+To pass the known private key password to libcurl:
+
+ curl_easy_setopt(easyhandle, CURLOPT_KEYPASSWD, "keypassword");
+
+.SH "HTTP Authentication"
+The previous chapter showed how to set user name and password for getting
+URLs that require authentication. When using the HTTP protocol, there are
+many different ways a client can provide those credentials to the server and
+you can control which way libcurl will (attempt to) use them. The default HTTP
+authentication method is called 'Basic', which is sending the name and
+password in clear-text in the HTTP request, base64-encoded. This is insecure.
+
+At the time of this writing, libcurl can be built to use: Basic, Digest, NTLM,
+Negotiate, GSS-Negotiate and SPNEGO. You can tell libcurl which one to use
+with CURLOPT_HTTPAUTH as in:
+
+ curl_easy_setopt(easyhandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
+
+And when you send authentication to a proxy, you can also set authentication
+type the same way but instead with CURLOPT_PROXYAUTH:
+
+ curl_easy_setopt(easyhandle, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);
+
+Both these options allow you to set multiple types (by ORing them together),
+to make libcurl pick the most secure one out of the types the server/proxy
+claims to support. This method does however add a round-trip since libcurl
+must first ask the server what it supports:
+
+ curl_easy_setopt(easyhandle, CURLOPT_HTTPAUTH,
+ CURLAUTH_DIGEST|CURLAUTH_BASIC);
+
+For convenience, you can use the 'CURLAUTH_ANY' define (instead of a list
+with specific types) which allows libcurl to use whatever method it wants.
+
+When asking for multiple types, libcurl will pick the available one it
+considers "best" in its own internal order of preference.
+
+.SH "HTTP POSTing"
+We get many questions regarding how to issue HTTP POSTs with libcurl the
+proper way. This chapter will thus include examples using both different
+versions of HTTP POST that libcurl supports.
+
+The first version is the simple POST, the most common version, that most HTML
+pages using the <form> tag uses. We provide a pointer to the data and tell
+libcurl to post it all to the remote site:
+
+.nf
+ char *data="name=daniel&project=curl";
+ curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, data);
+ curl_easy_setopt(easyhandle, CURLOPT_URL, "http://posthere.com/");
+
+ curl_easy_perform(easyhandle); /* post away! */
+.fi
+
+Simple enough, huh? Since you set the POST options with the
+CURLOPT_POSTFIELDS, this automatically switches the handle to use POST in the
+upcoming request.
+
+Ok, so what if you want to post binary data that also requires you to set the
+Content-Type: header of the post? Well, binary posts prevent libcurl from
+being able to do strlen() on the data to figure out the size, so therefore we
+must tell libcurl the size of the post data. Setting headers in libcurl
+requests are done in a generic way, by building a list of our own headers and
+then passing that list to libcurl.
+
+.nf
+ struct curl_slist *headers=NULL;
+ headers = curl_slist_append(headers, "Content-Type: text/xml");
+
+ /* post binary data */
+ curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, binaryptr);
+
+ /* set the size of the postfields data */
+ curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDSIZE, 23L);
+
+ /* pass our list of custom made headers */
+ curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, headers);
+
+ curl_easy_perform(easyhandle); /* post away! */
+
+ curl_slist_free_all(headers); /* free the header list */
+.fi
+
+While the simple examples above cover the majority of all cases where HTTP
+POST operations are required, they don't do multi-part formposts. Multi-part
+formposts were introduced as a better way to post (possibly large) binary data
+and were first documented in the RFC1867 (updated in RFC2388). They're called
+multi-part because they're built by a chain of parts, each part being a single
+unit of data. Each part has its own name and contents. You can in fact create
+and post a multi-part formpost with the regular libcurl POST support described
+above, but that would require that you build a formpost yourself and provide
+to libcurl. To make that easier, libcurl provides \fIcurl_formadd(3)\fP. Using
+this function, you add parts to the form. When you're done adding parts, you
+post the whole form.
+
+The following example sets two simple text parts with plain textual contents,
+and then a file with binary contents and uploads the whole thing.
+
+.nf
+ struct curl_httppost *post=NULL;
+ struct curl_httppost *last=NULL;
+ curl_formadd(&post, &last,
+ CURLFORM_COPYNAME, "name",
+ CURLFORM_COPYCONTENTS, "daniel", CURLFORM_END);
+ curl_formadd(&post, &last,
+ CURLFORM_COPYNAME, "project",
+ CURLFORM_COPYCONTENTS, "curl", CURLFORM_END);
+ curl_formadd(&post, &last,
+ CURLFORM_COPYNAME, "logotype-image",
+ CURLFORM_FILECONTENT, "curl.png", CURLFORM_END);
+
+ /* Set the form info */
+ curl_easy_setopt(easyhandle, CURLOPT_HTTPPOST, post);
+
+ curl_easy_perform(easyhandle); /* post away! */
+
+ /* free the post data again */
+ curl_formfree(post);
+.fi
+
+Multipart formposts are chains of parts using MIME-style separators and
+headers. It means that each one of these separate parts get a few headers set
+that describe the individual content-type, size etc. To enable your
+application to handicraft this formpost even more, libcurl allows you to
+supply your own set of custom headers to such an individual form part. You can
+of course supply headers to as many parts as you like, but this little example
+will show how you set headers to one specific part when you add that to the
+post handle:
+
+.nf
+ struct curl_slist *headers=NULL;
+ headers = curl_slist_append(headers, "Content-Type: text/xml");
+
+ curl_formadd(&post, &last,
+ CURLFORM_COPYNAME, "logotype-image",
+ CURLFORM_FILECONTENT, "curl.xml",
+ CURLFORM_CONTENTHEADER, headers,
+ CURLFORM_END);
+
+ curl_easy_perform(easyhandle); /* post away! */
+
+ curl_formfree(post); /* free post */
+ curl_slist_free_all(headers); /* free custom header list */
+.fi
+
+Since all options on an easyhandle are "sticky", they remain the same until
+changed even if you do call \fIcurl_easy_perform(3)\fP, you may need to tell
+curl to go back to a plain GET request if you intend to do one as your
+next request. You force an easyhandle to go back to GET by using the
+CURLOPT_HTTPGET option:
+
+ curl_easy_setopt(easyhandle, CURLOPT_HTTPGET, 1L);
+
+Just setting CURLOPT_POSTFIELDS to "" or NULL will *not* stop libcurl from
+doing a POST. It will just make it POST without any data to send!
+
+.SH "Showing Progress"
+
+For historical and traditional reasons, libcurl has a built-in progress meter
+that can be switched on and then makes it present a progress meter in your
+terminal.
+
+Switch on the progress meter by, oddly enough, setting CURLOPT_NOPROGRESS to
+zero. This option is set to 1 by default.
+
+For most applications however, the built-in progress meter is useless and
+what instead is interesting is the ability to specify a progress
+callback. The function pointer you pass to libcurl will then be called on
+irregular intervals with information about the current transfer.
+
+Set the progress callback by using CURLOPT_PROGRESSFUNCTION. And pass a
+pointer to a function that matches this prototype:
+
+.nf
+ int progress_callback(void *clientp,
+ double dltotal,
+ double dlnow,
+ double ultotal,
+ double ulnow);
+.fi
+
+If any of the input arguments is unknown, a 0 will be passed. The first
+argument, the 'clientp' is the pointer you pass to libcurl with
+CURLOPT_PROGRESSDATA. libcurl won't touch it.
+
+.SH "libcurl with C++"
+
+There's basically only one thing to keep in mind when using C++ instead of C
+when interfacing libcurl:
+
+The callbacks CANNOT be non-static class member functions
+
+Example C++ code:
+
+.nf
+class AClass {
+ static size_t write_data(void *ptr, size_t size, size_t nmemb,
+ void *ourpointer)
+ {
+ /* do what you want with the data */
+ }
+ }
+.fi
+
+.SH "Proxies"
+
+What "proxy" means according to Merriam-Webster: "a person authorized to act
+for another" but also "the agency, function, or office of a deputy who acts as
+a substitute for another".
+
+Proxies are exceedingly common these days. Companies often only offer Internet
+access to employees through their proxies. Network clients or user-agents ask
+the proxy for documents, the proxy does the actual request and then it returns
+them.
+
+libcurl supports SOCKS and HTTP proxies. When a given URL is wanted, libcurl
+will ask the proxy for it instead of trying to connect to the actual host
+identified in the URL.
+
+If you're using a SOCKS proxy, you may find that libcurl doesn't quite support
+all operations through it.
+
+For HTTP proxies: the fact that the proxy is a HTTP proxy puts certain
+restrictions on what can actually happen. A requested URL that might not be a
+HTTP URL will be still be passed to the HTTP proxy to deliver back to
+libcurl. This happens transparently, and an application may not need to
+know. I say "may", because at times it is very important to understand that
+all operations over a HTTP proxy use the HTTP protocol. For example, you
+can't invoke your own custom FTP commands or even proper FTP directory
+listings.
+
+.IP "Proxy Options"
+
+To tell libcurl to use a proxy at a given port number:
+
+ curl_easy_setopt(easyhandle, CURLOPT_PROXY, "proxy-host.com:8080");
+
+Some proxies require user authentication before allowing a request, and you
+pass that information similar to this:
+
+ curl_easy_setopt(easyhandle, CURLOPT_PROXYUSERPWD, "user:password");
+
+If you want to, you can specify the host name only in the CURLOPT_PROXY
+option, and set the port number separately with CURLOPT_PROXYPORT.
+
+Tell libcurl what kind of proxy it is with CURLOPT_PROXYTYPE (if not, it will
+default to assume a HTTP proxy):
+
+ curl_easy_setopt(easyhandle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
+
+.IP "Environment Variables"
+
+libcurl automatically checks and uses a set of environment variables to know
+what proxies to use for certain protocols. The names of the variables are
+following an ancient de facto standard and are built up as "[protocol]_proxy"
+(note the lower casing). Which makes the variable \&'http_proxy' checked for a
+name of a proxy to use when the input URL is HTTP. Following the same rule,
+the variable named 'ftp_proxy' is checked for FTP URLs. Again, the proxies are
+always HTTP proxies, the different names of the variables simply allows
+different HTTP proxies to be used.
+
+The proxy environment variable contents should be in the format
+\&"[protocol://][user:password@]machine[:port]". Where the protocol:// part is
+simply ignored if present (so http://proxy and bluerk://proxy will do the
+same) and the optional port number specifies on which port the proxy operates
+on the host. If not specified, the internal default port number will be used
+and that is most likely *not* the one you would like it to be.
+
+There are two special environment variables. 'all_proxy' is what sets proxy
+for any URL in case the protocol specific variable wasn't set, and
+\&'no_proxy' defines a list of hosts that should not use a proxy even though a
+variable may say so. If 'no_proxy' is a plain asterisk ("*") it matches all
+hosts.
+
+To explicitly disable libcurl's checking for and using the proxy environment
+variables, set the proxy name to "" - an empty string - with CURLOPT_PROXY.
+.IP "SSL and Proxies"
+
+SSL is for secure point-to-point connections. This involves strong encryption
+and similar things, which effectively makes it impossible for a proxy to
+operate as a "man in between" which the proxy's task is, as previously
+discussed. Instead, the only way to have SSL work over a HTTP proxy is to ask
+the proxy to tunnel trough everything without being able to check or fiddle
+with the traffic.
+
+Opening an SSL connection over a HTTP proxy is therefor a matter of asking the
+proxy for a straight connection to the target host on a specified port. This
+is made with the HTTP request CONNECT. ("please mr proxy, connect me to that
+remote host").
+
+Because of the nature of this operation, where the proxy has no idea what kind
+of data that is passed in and out through this tunnel, this breaks some of the
+very few advantages that come from using a proxy, such as caching. Many
+organizations prevent this kind of tunneling to other destination port numbers
+than 443 (which is the default HTTPS port number).
+
+.IP "Tunneling Through Proxy"
+As explained above, tunneling is required for SSL to work and often even
+restricted to the operation intended for SSL; HTTPS.
+
+This is however not the only time proxy-tunneling might offer benefits to
+you or your application.
+
+As tunneling opens a direct connection from your application to the remote
+machine, it suddenly also re-introduces the ability to do non-HTTP
+operations over a HTTP proxy. You can in fact use things such as FTP
+upload or FTP custom commands this way.
+
+Again, this is often prevented by the administrators of proxies and is
+rarely allowed.
+
+Tell libcurl to use proxy tunneling like this:
+
+ curl_easy_setopt(easyhandle, CURLOPT_HTTPPROXYTUNNEL, 1L);
+
+In fact, there might even be times when you want to do plain HTTP
+operations using a tunnel like this, as it then enables you to operate on
+the remote server instead of asking the proxy to do so. libcurl will not
+stand in the way for such innovative actions either!
+
+.IP "Proxy Auto-Config"
+
+Netscape first came up with this. It is basically a web page (usually using a
+\&.pac extension) with a Javascript that when executed by the browser with the
+requested URL as input, returns information to the browser on how to connect
+to the URL. The returned information might be "DIRECT" (which means no proxy
+should be used), "PROXY host:port" (to tell the browser where the proxy for
+this particular URL is) or "SOCKS host:port" (to direct the browser to a SOCKS
+proxy).
+
+libcurl has no means to interpret or evaluate Javascript and thus it doesn't
+support this. If you get yourself in a position where you face this nasty
+invention, the following advice have been mentioned and used in the past:
+
+- Depending on the Javascript complexity, write up a script that translates it
+to another language and execute that.
+
+- Read the Javascript code and rewrite the same logic in another language.
+
+- Implement a Javascript interpreter; people have successfully used the
+Mozilla Javascript engine in the past.
+
+- Ask your admins to stop this, for a static proxy setup or similar.
+
+.SH "Persistence Is The Way to Happiness"
+
+Re-cycling the same easy handle several times when doing multiple requests is
+the way to go.
+
+After each single \fIcurl_easy_perform(3)\fP operation, libcurl will keep the
+connection alive and open. A subsequent request using the same easy handle to
+the same host might just be able to use the already open connection! This
+reduces network impact a lot.
+
+Even if the connection is dropped, all connections involving SSL to the same
+host again, will benefit from libcurl's session ID cache that drastically
+reduces re-connection time.
+
+FTP connections that are kept alive save a lot of time, as the command-
+response round-trips are skipped, and also you don't risk getting blocked
+without permission to login again like on many FTP servers only allowing N
+persons to be logged in at the same time.
+
+libcurl caches DNS name resolving results, to make lookups of a previously
+looked up name a lot faster.
+
+Other interesting details that improve performance for subsequent requests
+may also be added in the future.
+
+Each easy handle will attempt to keep the last few connections alive for a
+while in case they are to be used again. You can set the size of this "cache"
+with the CURLOPT_MAXCONNECTS option. Default is 5. There is very seldom any
+point in changing this value, and if you think of changing this it is often
+just a matter of thinking again.
+
+To force your upcoming request to not use an already existing connection (it
+will even close one first if there happens to be one alive to the same host
+you're about to operate on), you can do that by setting CURLOPT_FRESH_CONNECT
+to 1. In a similar spirit, you can also forbid the upcoming request to be
+"lying" around and possibly get re-used after the request by setting
+CURLOPT_FORBID_REUSE to 1.
+
+.SH "HTTP Headers Used by libcurl"
+When you use libcurl to do HTTP requests, it'll pass along a series of headers
+automatically. It might be good for you to know and understand these. You
+can replace or remove them by using the CURLOPT_HTTPHEADER option.
+
+.IP "Host"
+This header is required by HTTP 1.1 and even many 1.0 servers and should be
+the name of the server we want to talk to. This includes the port number if
+anything but default.
+
+.IP "Accept"
+\&"*/*".
+
+.IP "Expect"
+When doing POST requests, libcurl sets this header to \&"100-continue" to ask
+the server for an "OK" message before it proceeds with sending the data part
+of the post. If the POSTed data amount is deemed "small", libcurl will not use
+this header.
+
+.SH "Customizing Operations"
+There is an ongoing development today where more and more protocols are built
+upon HTTP for transport. This has obvious benefits as HTTP is a tested and
+reliable protocol that is widely deployed and has excellent proxy-support.
+
+When you use one of these protocols, and even when doing other kinds of
+programming you may need to change the traditional HTTP (or FTP or...)
+manners. You may need to change words, headers or various data.
+
+libcurl is your friend here too.
+
+.IP CUSTOMREQUEST
+If just changing the actual HTTP request keyword is what you want, like when
+GET, HEAD or POST is not good enough for you, CURLOPT_CUSTOMREQUEST is there
+for you. It is very simple to use:
+
+ curl_easy_setopt(easyhandle, CURLOPT_CUSTOMREQUEST, "MYOWNREQUEST");
+
+When using the custom request, you change the request keyword of the actual
+request you are performing. Thus, by default you make a GET request but you can
+also make a POST operation (as described before) and then replace the POST
+keyword if you want to. You're the boss.
+
+.IP "Modify Headers"
+HTTP-like protocols pass a series of headers to the server when doing the
+request, and you're free to pass any amount of extra headers that you
+think fit. Adding headers is this easy:
+
+.nf
+ struct curl_slist *headers=NULL; /* init to NULL is important */
+
+ headers = curl_slist_append(headers, "Hey-server-hey: how are you?");
+ headers = curl_slist_append(headers, "X-silly-content: yes");
+
+ /* pass our list of custom made headers */
+ curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, headers);
+
+ curl_easy_perform(easyhandle); /* transfer http */
+
+ curl_slist_free_all(headers); /* free the header list */
+.fi
+
+\&... and if you think some of the internally generated headers, such as
+Accept: or Host: don't contain the data you want them to contain, you can
+replace them by simply setting them too:
+
+.nf
+ headers = curl_slist_append(headers, "Accept: Agent-007");
+ headers = curl_slist_append(headers, "Host: munged.host.line");
+.fi
+
+.IP "Delete Headers"
+If you replace an existing header with one with no contents, you will prevent
+the header from being sent. For instance, if you want to completely prevent the
+\&"Accept:" header from being sent, you can disable it with code similar to this:
+
+ headers = curl_slist_append(headers, "Accept:");
+
+Both replacing and canceling internal headers should be done with careful
+consideration and you should be aware that you may violate the HTTP protocol
+when doing so.
+
+.IP "Enforcing chunked transfer-encoding"
+
+By making sure a request uses the custom header "Transfer-Encoding: chunked"
+when doing a non-GET HTTP operation, libcurl will switch over to "chunked"
+upload, even though the size of the data to upload might be known. By default,
+libcurl usually switches over to chunked upload automatically if the upload
+data size is unknown.
+
+.IP "HTTP Version"
+
+All HTTP requests includes the version number to tell the server which version
+we support. libcurl speaks HTTP 1.1 by default. Some very old servers don't
+like getting 1.1-requests and when dealing with stubborn old things like that,
+you can tell libcurl to use 1.0 instead by doing something like this:
+
+ curl_easy_setopt(easyhandle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+
+.IP "FTP Custom Commands"
+
+Not all protocols are HTTP-like, and thus the above may not help you when
+you want to make, for example, your FTP transfers to behave differently.
+
+Sending custom commands to a FTP server means that you need to send the
+commands exactly as the FTP server expects them (RFC959 is a good guide
+here), and you can only use commands that work on the control-connection
+alone. All kinds of commands that require data interchange and thus need
+a data-connection must be left to libcurl's own judgement. Also be aware
+that libcurl will do its very best to change directory to the target
+directory before doing any transfer, so if you change directory (with CWD
+or similar) you might confuse libcurl and then it might not attempt to
+transfer the file in the correct remote directory.
+
+A little example that deletes a given file before an operation:
+
+.nf
+ headers = curl_slist_append(headers, "DELE file-to-remove");
+
+ /* pass the list of custom commands to the handle */
+ curl_easy_setopt(easyhandle, CURLOPT_QUOTE, headers);
+
+ curl_easy_perform(easyhandle); /* transfer ftp data! */
+
+ curl_slist_free_all(headers); /* free the header list */
+.fi
+
+If you would instead want this operation (or chain of operations) to happen
+_after_ the data transfer took place the option to \fIcurl_easy_setopt(3)\fP
+would instead be called CURLOPT_POSTQUOTE and used the exact same way.
+
+The custom FTP command will be issued to the server in the same order they are
+added to the list, and if a command gets an error code returned back from the
+server, no more commands will be issued and libcurl will bail out with an
+error code (CURLE_QUOTE_ERROR). Note that if you use CURLOPT_QUOTE to send
+commands before a transfer, no transfer will actually take place when a quote
+command has failed.
+
+If you set the CURLOPT_HEADER to 1, you will tell libcurl to get
+information about the target file and output "headers" about it. The headers
+will be in "HTTP-style", looking like they do in HTTP.
+
+The option to enable headers or to run custom FTP commands may be useful to
+combine with CURLOPT_NOBODY. If this option is set, no actual file content
+transfer will be performed.
+
+.IP "FTP Custom CUSTOMREQUEST"
+If you do want to list the contents of a FTP directory using your own defined FTP
+command, CURLOPT_CUSTOMREQUEST will do just that. "NLST" is the default one
+for listing directories but you're free to pass in your idea of a good
+alternative.
+
+.SH "Cookies Without Chocolate Chips"
+In the HTTP sense, a cookie is a name with an associated value. A server sends
+the name and value to the client, and expects it to get sent back on every
+subsequent request to the server that matches the particular conditions
+set. The conditions include that the domain name and path match and that the
+cookie hasn't become too old.
+
+In real-world cases, servers send new cookies to replace existing ones to
+update them. Server use cookies to "track" users and to keep "sessions".
+
+Cookies are sent from server to clients with the header Set-Cookie: and
+they're sent from clients to servers with the Cookie: header.
+
+To just send whatever cookie you want to a server, you can use CURLOPT_COOKIE
+to set a cookie string like this:
+
+ curl_easy_setopt(easyhandle, CURLOPT_COOKIE, "name1=var1; name2=var2;");
+
+In many cases, that is not enough. You might want to dynamically save
+whatever cookies the remote server passes to you, and make sure those cookies
+are then used accordingly on later requests.
+
+One way to do this, is to save all headers you receive in a plain file and
+when you make a request, you tell libcurl to read the previous headers to
+figure out which cookies to use. Set the header file to read cookies from with
+CURLOPT_COOKIEFILE.
+
+The CURLOPT_COOKIEFILE option also automatically enables the cookie parser in
+libcurl. Until the cookie parser is enabled, libcurl will not parse or
+understand incoming cookies and they will just be ignored. However, when the
+parser is enabled the cookies will be understood and the cookies will be kept
+in memory and used properly in subsequent requests when the same handle is
+used. Many times this is enough, and you may not have to save the cookies to
+disk at all. Note that the file you specify to CURLOPT_COOKIEFILE doesn't have
+to exist to enable the parser, so a common way to just enable the parser and
+not read any cookies is to use the name of a file you know doesn't exist.
+
+If you would rather use existing cookies that you've previously received with
+your Netscape or Mozilla browsers, you can make libcurl use that cookie file
+as input. The CURLOPT_COOKIEFILE is used for that too, as libcurl will
+automatically find out what kind of file it is and act accordingly.
+
+Perhaps the most advanced cookie operation libcurl offers, is saving the
+entire internal cookie state back into a Netscape/Mozilla formatted cookie
+file. We call that the cookie-jar. When you set a file name with
+CURLOPT_COOKIEJAR, that file name will be created and all received cookies
+will be stored in it when \fIcurl_easy_cleanup(3)\fP is called. This enables
+cookies to get passed on properly between multiple handles without any
+information getting lost.
+
+.SH "FTP Peculiarities We Need"
+
+FTP transfers use a second TCP/IP connection for the data transfer. This is
+usually a fact you can forget and ignore but at times this fact will come
+back to haunt you. libcurl offers several different ways to customize how the
+second connection is being made.
+
+libcurl can either connect to the server a second time or tell the server to
+connect back to it. The first option is the default and it is also what works
+best for all the people behind firewalls, NATs or IP-masquerading setups.
+libcurl then tells the server to open up a new port and wait for a second
+connection. This is by default attempted with EPSV first, and if that doesn't
+work it tries PASV instead. (EPSV is an extension to the original FTP spec
+and does not exist nor work on all FTP servers.)
+
+You can prevent libcurl from first trying the EPSV command by setting
+CURLOPT_FTP_USE_EPSV to zero.
+
+In some cases, you will prefer to have the server connect back to you for the
+second connection. This might be when the server is perhaps behind a firewall
+or something and only allows connections on a single port. libcurl then
+informs the remote server which IP address and port number to connect to.
+This is made with the CURLOPT_FTPPORT option. If you set it to "-", libcurl
+will use your system's "default IP address". If you want to use a particular
+IP, you can set the full IP address, a host name to resolve to an IP address
+or even a local network interface name that libcurl will get the IP address
+from.
+
+When doing the "PORT" approach, libcurl will attempt to use the EPRT and the
+LPRT before trying PORT, as they work with more protocols. You can disable
+this behavior by setting CURLOPT_FTP_USE_EPRT to zero.
+
+.SH "Headers Equal Fun"
+
+Some protocols provide "headers", meta-data separated from the normal
+data. These headers are by default not included in the normal data stream,
+but you can make them appear in the data stream by setting CURLOPT_HEADER to
+1.
+
+What might be even more useful, is libcurl's ability to separate the headers
+from the data and thus make the callbacks differ. You can for example set a
+different pointer to pass to the ordinary write callback by setting
+CURLOPT_WRITEHEADER.
+
+Or, you can set an entirely separate function to receive the headers, by
+using CURLOPT_HEADERFUNCTION.
+
+The headers are passed to the callback function one by one, and you can
+depend on that fact. It makes it easier for you to add custom header parsers
+etc.
+
+\&"Headers" for FTP transfers equal all the FTP server responses. They aren't
+actually true headers, but in this case we pretend they are! ;-)
+
+.SH "Post Transfer Information"
+
+ [ curl_easy_getinfo ]
+
+.SH "Security Considerations"
+
+The libcurl project takes security seriously. The library is written with
+caution and precautions are taken to mitigate many kinds of risks encountered
+while operating with potentially malicious servers on the Internet. It is a
+powerful library, however, which allows application writers to make trade offs
+between ease of writing and exposure to potential risky operations. If
+used the right way, you can use libcurl to transfer data pretty safely.
+
+Many applications are used in closed networks where users and servers
+can be trusted, but many others are used on arbitrary servers and are fed
+input from potentially untrusted users. Following is a discussion about
+some risks in the ways in which applications commonly use libcurl and
+potential mitigations of those risks. It is by no means comprehensive, but
+shows classes of attacks that robust applications should consider. The
+Common Weakness Enumeration project at http://cwe.mitre.org/ is a good
+reference for many of these and similar types of weaknesses of which
+application writers should be aware.
+
+.IP "Command Lines"
+If you use a command line tool (such as curl) that uses libcurl, and you give
+options to the tool on the command line those options can very likely get read
+by other users of your system when they use 'ps' or other tools to list
+currently running processes.
+
+To avoid this problem, never feed sensitive things to programs using command
+line options. Write them to a protected file and use the \-K option to
+avoid this.
+
+.IP ".netrc"
+\&.netrc is a pretty handy file/feature that allows you to login quickly and
+automatically to frequently visited sites. The file contains passwords in
+clear text and is a real security risk. In some cases, your .netrc is also
+stored in a home directory that is NFS mounted or used on another network
+based file system, so the clear text password will fly through your network
+every time anyone reads that file!
+
+To avoid this problem, don't use .netrc files and never store passwords in
+plain text anywhere.
+
+.IP "Clear Text Passwords"
+Many of the protocols libcurl supports send name and password unencrypted as
+clear text (HTTP Basic authentication, FTP, TELNET etc). It is very easy for
+anyone on your network or a network nearby yours to just fire up a network
+analyzer tool and eavesdrop on your passwords. Don't let the fact that HTTP
+Basic uses base64 encoded passwords fool you. They may not look readable at a
+first glance, but they very easily "deciphered" by anyone within seconds.
+
+To avoid this problem, use HTTP authentication methods or other protocols that
+don't let snoopers see your password: HTTP with Digest, NTLM or GSS
+authentication, HTTPS, FTPS, SCP, SFTP and FTP-Kerberos are a few examples.
+
+.IP "Redirects"
+The CURLOPT_FOLLOWLOCATION option automatically follows HTTP redirects sent
+by a remote server. These redirects can refer to any kind of URL, not just
+HTTP. A redirect to a file: URL would cause the libcurl to read (or write)
+arbitrary files from the local filesystem. If the application returns
+the data back to the user (as would happen in some kinds of CGI scripts),
+an attacker could leverage this to read otherwise forbidden data (e.g.
+file://localhost/etc/passwd).
+
+If authentication credentials are stored in the ~/.netrc file, or Kerberos
+is in use, any other URL type (not just file:) that requires
+authentication is also at risk. A redirect such as
+ftp://some-internal-server/private-file would then return data even when
+the server is password protected.
+
+In the same way, if an unencrypted SSH private key has been configured for
+the user running the libcurl application, SCP: or SFTP: URLs could access
+password or private-key protected resources,
+e.g. sftp://user@some-internal-server/etc/passwd
+
+The CURLOPT_REDIR_PROTOCOLS and CURLOPT_NETRC options can be used to
+mitigate against this kind of attack.
+
+A redirect can also specify a location available only on the machine running
+libcurl, including servers hidden behind a firewall from the attacker.
+e.g. http://127.0.0.1/ or http://intranet/delete-stuff.cgi?delete=all or
+tftp://bootp-server/pc-config-data
+
+Apps can mitigate against this by disabling CURLOPT_FOLLOWLOCATION and
+handling redirects itself, sanitizing URLs as necessary. Alternately, an
+app could leave CURLOPT_FOLLOWLOCATION enabled but set CURLOPT_REDIR_PROTOCOLS
+and install a CURLOPT_OPENSOCKETFUNCTION callback function in which addresses
+are sanitized before use.
+
+.IP "Private Resources"
+A user who can control the DNS server of a domain being passed in within
+a URL can change the address of the host to a local, private address
+which the libcurl application will then use. e.g. The innocuous URL
+http://fuzzybunnies.example.com/ could actually resolve to the IP address
+of a server behind a firewall, such as 127.0.0.1 or 10.1.2.3
+Apps can mitigate against this by setting a CURLOPT_OPENSOCKETFUNCTION
+and checking the address before a connection.
+
+All the malicious scenarios regarding redirected URLs apply just as well
+to non-redirected URLs, if the user is allowed to specify an arbitrary URL
+that could point to a private resource. For example, a web app providing
+a translation service might happily translate file://localhost/etc/passwd
+and display the result. Apps can mitigate against this with the
+CURLOPT_PROTOCOLS option as well as by similar mitigation techniques for
+redirections.
+
+A malicious FTP server could in response to the PASV command return an
+IP address and port number for a server local to the app running libcurl
+but behind a firewall. Apps can mitigate against this by using the
+CURLOPT_FTP_SKIP_PASV_IP option or CURLOPT_FTPPORT.
+
+.IP Uploads
+When uploading, a redirect can cause a local (or remote) file to be
+overwritten. Apps must not allow any unsanitized URL to be passed in
+for uploads. Also, CURLOPT_FOLLOWLOCATION should not be used on uploads.
+Instead, the app should handle redirects itself, sanitizing each URL first.
+
+.IP Authentication
+Use of CURLOPT_UNRESTRICTED_AUTH could cause authentication information to
+be sent to an unknown second server. Apps can mitigate against this
+by disabling CURLOPT_FOLLOWLOCATION and handling redirects itself,
+sanitizing where necessary.
+
+Use of the CURLAUTH_ANY option to CURLOPT_HTTPAUTH could result in user
+name and password being sent in clear text to an HTTP server. Instead,
+use CURLAUTH_ANYSAFE which ensures that the password is encrypted over
+the network, or else fail the request.
+
+Use of the CURLUSESSL_TRY option to CURLOPT_USE_SSL could result in user
+name and password being sent in clear text to an FTP server. Instead,
+use CURLUSESSL_CONTROL to ensure that an encrypted connection is used or
+else fail the request.
+
+.IP Cookies
+If cookies are enabled and cached, then a user could craft a URL which
+performs some malicious action to a site whose authentication is already
+stored in a cookie. e.g. http://mail.example.com/delete-stuff.cgi?delete=all
+Apps can mitigate against this by disabling cookies or clearing them
+between requests.
+
+.IP "Dangerous URLs"
+SCP URLs can contain raw commands within the scp: URL, which is a side effect
+of how the SCP protocol is designed. e.g.
+scp://user:pass@host/a;date >/tmp/test;
+Apps must not allow unsanitized SCP: URLs to be passed in for downloads.
+
+.IP "Denial of Service"
+A malicious server could cause libcurl to effectively hang by sending
+a trickle of data through, or even no data at all but just keeping the TCP
+connection open. This could result in a denial-of-service attack. The
+CURLOPT_TIMEOUT and/or CURLOPT_LOW_SPEED_LIMIT options can be used to
+mitigate against this.
+
+A malicious server could cause libcurl to effectively hang by starting to
+send data, then severing the connection without cleanly closing the
+TCP connection. The app could install a CURLOPT_SOCKOPTFUNCTION callback
+function and set the TCP SO_KEEPALIVE option to mitigate against this.
+Setting one of the timeout options would also work against this attack.
+
+A malicious server could cause libcurl to download an infinite amount of
+data, potentially causing all of memory or disk to be filled. Setting
+the CURLOPT_MAXFILESIZE_LARGE option is not sufficient to guard against this.
+Instead, the app should monitor the amount of data received within the
+write or progress callback and abort once the limit is reached.
+
+A malicious HTTP server could cause an infinite redirection loop, causing a
+denial-of-service. This can be mitigated by using the CURLOPT_MAXREDIRS
+option.
+
+.IP "Arbitrary Headers"
+User-supplied data must be sanitized when used in options like
+CURLOPT_USERAGENT, CURLOPT_HTTPHEADER, CURLOPT_POSTFIELDS and others that
+are used to generate structured data. Characters like embedded carriage
+returns or ampersands could allow the user to create additional headers or
+fields that could cause malicious transactions.
+
+.IP "Server-supplied Names"
+A server can supply data which the application may, in some cases, use as
+a file name. The curl command-line tool does this with --remote-header-name,
+using the Content-disposition: header to generate a file name. An application
+could also use CURLINFO_EFFECTIVE_URL to generate a file name from a
+server-supplied redirect URL. Special care must be taken to sanitize such
+names to avoid the possibility of a malicious server supplying one like
+"/etc/passwd", "\autoexec.bat" or even ".bashrc".
+
+.IP "Server Certificates"
+A secure application should never use the CURLOPT_SSL_VERIFYPEER option to
+disable certificate validation. There are numerous attacks that are enabled
+by apps that fail to properly validate server TLS/SSL certificates,
+thus enabling a malicious server to spoof a legitimate one. HTTPS without
+validated certificates is potentially as insecure as a plain HTTP connection.
+
+.IP "Showing What You Do"
+On a related issue, be aware that even in situations like when you have
+problems with libcurl and ask someone for help, everything you reveal in order
+to get best possible help might also impose certain security related
+risks. Host names, user names, paths, operating system specifics, etc (not to
+mention passwords of course) may in fact be used by intruders to gain
+additional information of a potential target.
+
+To avoid this problem, you must of course use your common sense. Often, you
+can just edit out the sensitive data or just search/replace your true
+information with faked data.
+
+.SH "Multiple Transfers Using the multi Interface"
+
+The easy interface as described in detail in this document is a synchronous
+interface that transfers one file at a time and doesn't return until it is
+done.
+
+The multi interface, on the other hand, allows your program to transfer
+multiple files in both directions at the same time, without forcing you
+to use multiple threads. The name might make it seem that the multi
+interface is for multi-threaded programs, but the truth is almost the
+reverse. The multi interface can allow a single-threaded application
+to perform the same kinds of multiple, simultaneous transfers that
+multi-threaded programs can perform. It allows many of the benefits
+of multi-threaded transfers without the complexity of managing and
+synchronizing many threads.
+
+To use this interface, you are better off if you first understand the basics
+of how to use the easy interface. The multi interface is simply a way to make
+multiple transfers at the same time by adding up multiple easy handles into
+a "multi stack".
+
+You create the easy handles you want and you set all the options just like you
+have been told above, and then you create a multi handle with
+\fIcurl_multi_init(3)\fP and add all those easy handles to that multi handle
+with \fIcurl_multi_add_handle(3)\fP.
+
+When you've added the handles you have for the moment (you can still add new
+ones at any time), you start the transfers by calling
+\fIcurl_multi_perform(3)\fP.
+
+\fIcurl_multi_perform(3)\fP is asynchronous. It will only execute as little as
+possible and then return back control to your program. It is designed to never
+block.
+
+The best usage of this interface is when you do a select() on all possible
+file descriptors or sockets to know when to call libcurl again. This also
+makes it easy for you to wait and respond to actions on your own application's
+sockets/handles. You figure out what to select() for by using
+\fIcurl_multi_fdset(3)\fP, that fills in a set of fd_set variables for you
+with the particular file descriptors libcurl uses for the moment.
+
+When you then call select(), it'll return when one of the file handles signal
+action and you then call \fIcurl_multi_perform(3)\fP to allow libcurl to do
+what it wants to do. Take note that libcurl does also feature some time-out
+code so we advise you to never use very long timeouts on select() before you
+call \fIcurl_multi_perform(3)\fP, which thus should be called unconditionally
+every now and then even if none of its file descriptors have signaled
+ready. Another precaution you should use: always call
+\fIcurl_multi_fdset(3)\fP immediately before the select() call since the
+current set of file descriptors may change when calling a curl function.
+
+If you want to stop the transfer of one of the easy handles in the stack, you
+can use \fIcurl_multi_remove_handle(3)\fP to remove individual easy
+handles. Remember that easy handles should be \fIcurl_easy_cleanup(3)\fPed.
+
+When a transfer within the multi stack has finished, the counter of running
+transfers (as filled in by \fIcurl_multi_perform(3)\fP) will decrease. When
+the number reaches zero, all transfers are done.
+
+\fIcurl_multi_info_read(3)\fP can be used to get information about completed
+transfers. It then returns the CURLcode for each easy transfer, to allow you
+to figure out success on each individual transfer.
+
+.SH "SSL, Certificates and Other Tricks"
+
+ [ seeding, passwords, keys, certificates, ENGINE, ca certs ]
+
+.SH "Sharing Data Between Easy Handles"
+You can share some data between easy handles when the easy interface is used,
+and some data is share automatically when you use the multi interface.
+
+When you add easy handles to a multi handle, these easy handles will
+automatically share a lot of the data that otherwise would be kept on a
+per-easy handle basis when the easy interface is used.
+
+The DNS cache is shared between handles within a multi handle, making
+subsequent name resolvings faster and the connection pool that is kept to
+better allow persistent connections and connection re-use is shared. If you're
+using the easy interface, you can still share these between specific easy
+handles by using the share interface, see \fIlibcurl-share(3)\fP.
+
+Some things are never shared automatically, not within multi handles, like for
+example cookies so the only way to share that is with the share interface.
+.SH "Footnotes"
+
+.IP "[1]"
+libcurl 7.10.3 and later have the ability to switch over to chunked
+Transfer-Encoding in cases where HTTP uploads are done with data of an unknown
+size.
+.IP "[2]"
+This happens on Windows machines when libcurl is built and used as a
+DLL. However, you can still do this on Windows if you link with a static
+library.
+.IP "[3]"
+The curl-config tool is generated at build-time (on UNIX-like systems) and
+should be installed with the 'make install' or similar instruction that
+installs the library, header files, man pages etc.
+.IP "[4]"
+This behavior was different in versions before 7.17.0, where strings had to
+remain valid past the end of the \fIcurl_easy_setopt(3)\fP call.
diff --git a/docs/libcurl/libcurl.3 b/docs/libcurl/libcurl.3
new file mode 100644
index 000000000..d2dcd7838
--- /dev/null
+++ b/docs/libcurl/libcurl.3
@@ -0,0 +1,222 @@
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at http://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.TH libcurl 3 "19 March 2002" "libcurl 7.9.6" "libcurl overview"
+.SH NAME
+libcurl \- client-side URL transfers
+.SH DESCRIPTION
+This is a short overview on how to use libcurl in your C programs. There are
+specific man pages for each function mentioned in here. There are also the
+\fIlibcurl-easy(3)\fP man page, the \fIlibcurl-multi(3)\fP man page, the
+\fIlibcurl-share(3)\fP man page and the \fIlibcurl-tutorial(3)\fP man page for
+in-depth understanding on how to program with libcurl.
+
+There are more than thirty custom bindings available that bring libcurl access
+to your favourite language. Look elsewhere for documentation on those.
+
+libcurl has a global constant environment that you must set up and
+maintain while using libcurl. This essentially means you call
+\fIcurl_global_init(3)\fP at the start of your program and
+\fIcurl_global_cleanup(3)\fP at the end. See GLOBAL CONSTANTS below
+for details.
+
+To transfer files, you always set up an "easy handle" using
+\fIcurl_easy_init(3)\fP, but when you want the file(s) transferred you have
+the option of using the "easy" interface, or the "multi" interface.
+
+The easy interface is a synchronous interface with which you call
+\fIcurl_easy_perform(3)\fP and let it perform the transfer. When it is
+completed, the function returns and you can continue. More details are found in
+the \fIlibcurl-easy(3)\fP man page.
+
+The multi interface on the other hand is an asynchronous interface, that you
+call and that performs only a little piece of the transfer on each invoke. It
+is perfect if you want to do things while the transfer is in progress, or
+similar. The multi interface allows you to select() on libcurl action, and
+even to easily download multiple files simultaneously using a single thread. See further details in the \fIlibcurl-multi(3)\fP man page.
+
+You can have multiple easy handles share certain data, even if they are used
+in different threads. This magic is setup using the share interface, as
+described in the \fIlibcurl-share(3)\fP man page.
+
+There is also a series of other helpful functions to use, including these:
+.RS
+.IP curl_version_info()
+gets detailed libcurl (and other used libraries) version info
+.IP curl_getdate()
+converts a date string to time_t
+.IP curl_easy_getinfo()
+get information about a performed transfer
+.IP curl_formadd()
+helps building an HTTP form POST
+.IP curl_formfree()
+free a list built with \fIcurl_formadd(3)\fP
+.IP curl_slist_append()
+builds a linked list
+.IP curl_slist_free_all()
+frees a whole curl_slist
+.RE
+
+.SH "LINKING WITH LIBCURL"
+On unix-like machines, there's a tool named curl-config that gets installed
+with the rest of the curl stuff when 'make install' is performed.
+
+curl-config is added to make it easier for applications to link with libcurl
+and developers to learn about libcurl and how to use it.
+
+Run 'curl-config --libs' to get the (additional) linker options you need to
+link with the particular version of libcurl you've installed. See the
+\fIcurl-config(1)\fP man page for further details.
+
+Unix-like operating system that ship libcurl as part of their distributions
+often don't provide the curl-config tool, but simply install the library and
+headers in the common path for this purpose.
+
+.SH "LIBCURL SYMBOL NAMES"
+All public functions in the libcurl interface are prefixed with 'curl_' (with
+a lowercase c). You can find other functions in the library source code, but
+other prefixes indicate that the functions are private and may change without
+further notice in the next release.
+
+Only use documented functions and functionality!
+.SH "PORTABILITY"
+libcurl works
+.B exactly
+the same, on any of the platforms it compiles and builds on.
+.SH "THREADS"
+Never ever call curl-functions simultaneously using the same handle from
+several threads. libcurl is thread-safe and can be used in any number of
+threads, but you must use separate curl handles if you want to use libcurl in
+more than one thread simultaneously.
+
+The global environment functions are not thread-safe. See GLOBAL CONSTANTS
+below for details.
+
+.SH "PERSISTENT CONNECTIONS"
+Persistent connections means that libcurl can re-use the same connection for
+several transfers, if the conditions are right.
+
+libcurl will \fBalways\fP attempt to use persistent connections. Whenever you
+use \fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP, libcurl will
+attempt to use an existing connection to do the transfer, and if none exists
+it'll open a new one that will be subject for re-use on a possible following
+call to \fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP.
+
+To allow libcurl to take full advantage of persistent connections, you should
+do as many of your file transfers as possible using the same curl handle. When
+you call \fIcurl_easy_cleanup(3)\fP, all the possibly open connections held by
+libcurl will be closed and forgotten.
+
+Note that the options set with \fIcurl_easy_setopt(3)\fP will be used on
+every repeated \fIcurl_easy_perform(3)\fP call.
+
+.SH "GLOBAL CONSTANTS"
+There are a variety of constants that libcurl uses, mainly through its
+internal use of other libraries, which are too complicated for the
+library loader to set up. Therefore, a program must call a library
+function after the program is loaded and running to finish setting up
+the library code. For example, when libcurl is built for SSL
+capability via the GNU TLS library, there is an elaborate tree inside
+that library that describes the SSL protocol.
+
+\fIcurl_global_init()\fP is the function that you must call. This may
+allocate resources (e.g. the memory for the GNU TLS tree mentioned
+above), so the companion function \fIcurl_global_cleanup()\fP releases
+them.
+
+The basic rule for constructing a program that uses libcurl is this:
+Call \fIcurl_global_init()\fP, with a \fICURL_GLOBAL_ALL\fP argument,
+immediately after the program starts, while it is still only one
+thread and before it uses libcurl at all. Call
+\fIcurl_global_cleanup()\fP immediately before the program exits, when
+the program is again only one thread and after its last use of
+libcurl.
+
+You can call both of these multiple times, as long as all calls meet
+these requirements and the number of calls to each is the same.
+
+It isn't actually required that the functions be called at the beginning
+and end of the program -- that's just usually the easiest way to do it.
+It \fIis\fP required that the functions be called when no other thread
+in the program is running.
+
+These global constant functions are \fInot thread safe\fP, so you must
+not call them when any other thread in the program is running. It
+isn't good enough that no other thread is using libcurl at the time,
+because these functions internally call similar functions of other
+libraries, and those functions are similarly thread-unsafe. You can't
+generally know what these libraries are, or whether other threads are
+using them.
+
+The global constant situation merits special consideration when the
+code you are writing to use libcurl is not the main program, but rather
+a modular piece of a program, e.g. another library. As a module,
+your code doesn't know about other parts of the program -- it doesn't
+know whether they use libcurl or not. And its code doesn't necessarily
+run at the start and end of the whole program.
+
+A module like this must have global constant functions of its own,
+just like \fIcurl_global_init()\fP and \fIcurl_global_cleanup()\fP.
+The module thus has control at the beginning and end of the program
+and has a place to call the libcurl functions. Note that if multiple
+modules in the program use libcurl, they all will separately call the
+libcurl functions, and that's OK because only the first
+\fIcurl_global_init()\fP and the last \fIcurl_global_cleanup()\fP in a
+program change anything. (libcurl uses a reference count in static
+memory).
+
+In a C++ module, it is common to deal with the global constant
+situation by defining a special class that represents the global
+constant environment of the module. A program always has exactly one
+object of the class, in static storage. That way, the program
+automatically calls the constructor of the object as the program
+starts up and the destructor as it terminates. As the author of this
+libcurl-using module, you can make the constructor call
+\fIcurl_global_init()\fP and the destructor call
+\fIcurl_global_cleanup()\fP and satisfy libcurl's requirements without
+your user having to think about it.
+
+\fIcurl_global_init()\fP has an argument that tells what particular
+parts of the global constant environment to set up. In order to
+successfully use any value except \fICURL_GLOBAL_ALL\fP (which says to
+set up the whole thing), you must have specific knowledge of internal
+workings of libcurl and all other parts of the program of which it is
+part.
+
+A special part of the global constant environment is the identity of
+the memory allocator. \fIcurl_global_init()\fP selects the system
+default memory allocator, but you can use \fIcurl_global_init_mem()\fP
+to supply one of your own. However, there is no way to use
+\fIcurl_global_init_mem()\fP in a modular program -- all modules in
+the program that might use libcurl would have to agree on one
+allocator.
+
+There is a failsafe in libcurl that makes it usable in simple
+situations without you having to worry about the global constant
+environment at all: \fIcurl_easy_init()\fP sets up the environment
+itself if it hasn't been done yet. The resources it acquires to do so
+get released by the operating system automatically when the program
+exits.
+
+This failsafe feature exists mainly for backward compatibility because
+there was a time when the global functions didn't exist. Because it
+is sufficient only in the simplest of programs, it is not recommended
+for any program to rely on it.
diff --git a/docs/libcurl/libcurl.m4 b/docs/libcurl/libcurl.m4
new file mode 100644
index 000000000..d7d5a5259
--- /dev/null
+++ b/docs/libcurl/libcurl.m4
@@ -0,0 +1,251 @@
+# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION],
+# [ACTION-IF-YES], [ACTION-IF-NO])
+# ----------------------------------------------------------
+# David Shaw <dshaw@jabberwocky.com> May-09-2006
+#
+# Checks for libcurl. DEFAULT-ACTION is the string yes or no to
+# specify whether to default to --with-libcurl or --without-libcurl.
+# If not supplied, DEFAULT-ACTION is yes. MINIMUM-VERSION is the
+# minimum version of libcurl to accept. Pass the version as a regular
+# version number like 7.10.1. If not supplied, any version is
+# accepted. ACTION-IF-YES is a list of shell commands to run if
+# libcurl was successfully found and passed the various tests.
+# ACTION-IF-NO is a list of shell commands that are run otherwise.
+# Note that using --without-libcurl does run ACTION-IF-NO.
+#
+# This macro #defines HAVE_LIBCURL if a working libcurl setup is
+# found, and sets @LIBCURL@ and @LIBCURL_CPPFLAGS@ to the necessary
+# values. Other useful defines are LIBCURL_FEATURE_xxx where xxx are
+# the various features supported by libcurl, and LIBCURL_PROTOCOL_yyy
+# where yyy are the various protocols supported by libcurl. Both xxx
+# and yyy are capitalized. See the list of AH_TEMPLATEs at the top of
+# the macro for the complete list of possible defines. Shell
+# variables $libcurl_feature_xxx and $libcurl_protocol_yyy are also
+# defined to 'yes' for those features and protocols that were found.
+# Note that xxx and yyy keep the same capitalization as in the
+# curl-config list (e.g. it's "HTTP" and not "http").
+#
+# Users may override the detected values by doing something like:
+# LIBCURL="-lcurl" LIBCURL_CPPFLAGS="-I/usr/myinclude" ./configure
+#
+# For the sake of sanity, this macro assumes that any libcurl that is
+# found is after version 7.7.2, the first version that included the
+# curl-config script. Note that it is very important for people
+# packaging binary versions of libcurl to include this script!
+# Without curl-config, we can only guess what protocols are available,
+# or use curl_version_info to figure it out at runtime.
+
+AC_DEFUN([LIBCURL_CHECK_CONFIG],
+[
+ AH_TEMPLATE([LIBCURL_FEATURE_SSL],[Defined if libcurl supports SSL])
+ AH_TEMPLATE([LIBCURL_FEATURE_KRB4],[Defined if libcurl supports KRB4])
+ AH_TEMPLATE([LIBCURL_FEATURE_IPV6],[Defined if libcurl supports IPv6])
+ AH_TEMPLATE([LIBCURL_FEATURE_LIBZ],[Defined if libcurl supports libz])
+ AH_TEMPLATE([LIBCURL_FEATURE_ASYNCHDNS],[Defined if libcurl supports AsynchDNS])
+ AH_TEMPLATE([LIBCURL_FEATURE_IDN],[Defined if libcurl supports IDN])
+ AH_TEMPLATE([LIBCURL_FEATURE_SSPI],[Defined if libcurl supports SSPI])
+ AH_TEMPLATE([LIBCURL_FEATURE_NTLM],[Defined if libcurl supports NTLM])
+
+ AH_TEMPLATE([LIBCURL_PROTOCOL_HTTP],[Defined if libcurl supports HTTP])
+ AH_TEMPLATE([LIBCURL_PROTOCOL_HTTPS],[Defined if libcurl supports HTTPS])
+ AH_TEMPLATE([LIBCURL_PROTOCOL_FTP],[Defined if libcurl supports FTP])
+ AH_TEMPLATE([LIBCURL_PROTOCOL_FTPS],[Defined if libcurl supports FTPS])
+ AH_TEMPLATE([LIBCURL_PROTOCOL_FILE],[Defined if libcurl supports FILE])
+ AH_TEMPLATE([LIBCURL_PROTOCOL_TELNET],[Defined if libcurl supports TELNET])
+ AH_TEMPLATE([LIBCURL_PROTOCOL_LDAP],[Defined if libcurl supports LDAP])
+ AH_TEMPLATE([LIBCURL_PROTOCOL_DICT],[Defined if libcurl supports DICT])
+ AH_TEMPLATE([LIBCURL_PROTOCOL_TFTP],[Defined if libcurl supports TFTP])
+ AH_TEMPLATE([LIBCURL_PROTOCOL_RTSP],[Defined if libcurl supports RTSP])
+ AH_TEMPLATE([LIBCURL_PROTOCOL_POP3],[Defined if libcurl supports POP3])
+ AH_TEMPLATE([LIBCURL_PROTOCOL_IMAP],[Defined if libcurl supports IMAP])
+ AH_TEMPLATE([LIBCURL_PROTOCOL_SMTP],[Defined if libcurl supports SMTP])
+
+ AC_ARG_WITH(libcurl,
+ AC_HELP_STRING([--with-libcurl=PREFIX],[look for the curl library in PREFIX/lib and headers in PREFIX/include]),
+ [_libcurl_with=$withval],[_libcurl_with=ifelse([$1],,[yes],[$1])])
+
+ if test "$_libcurl_with" != "no" ; then
+
+ AC_PROG_AWK
+
+ _libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'"
+
+ _libcurl_try_link=yes
+
+ if test -d "$_libcurl_with" ; then
+ LIBCURL_CPPFLAGS="-I$withval/include"
+ _libcurl_ldflags="-L$withval/lib"
+ AC_PATH_PROG([_libcurl_config],[curl-config],[],
+ ["$withval/bin"])
+ else
+ AC_PATH_PROG([_libcurl_config],[curl-config],[],[$PATH])
+ fi
+
+ if test x$_libcurl_config != "x" ; then
+ AC_CACHE_CHECK([for the version of libcurl],
+ [libcurl_cv_lib_curl_version],
+ [libcurl_cv_lib_curl_version=`$_libcurl_config --version | $AWK '{print $[]2}'`])
+
+ _libcurl_version=`echo $libcurl_cv_lib_curl_version | $_libcurl_version_parse`
+ _libcurl_wanted=`echo ifelse([$2],,[0],[$2]) | $_libcurl_version_parse`
+
+ if test $_libcurl_wanted -gt 0 ; then
+ AC_CACHE_CHECK([for libcurl >= version $2],
+ [libcurl_cv_lib_version_ok],
+ [
+ if test $_libcurl_version -ge $_libcurl_wanted ; then
+ libcurl_cv_lib_version_ok=yes
+ else
+ libcurl_cv_lib_version_ok=no
+ fi
+ ])
+ fi
+
+ if test $_libcurl_wanted -eq 0 || test x$libcurl_cv_lib_version_ok = xyes ; then
+ if test x"$LIBCURL_CPPFLAGS" = "x" ; then
+ LIBCURL_CPPFLAGS=`$_libcurl_config --cflags`
+ fi
+ if test x"$LIBCURL" = "x" ; then
+ LIBCURL=`$_libcurl_config --libs`
+
+ # This is so silly, but Apple actually has a bug in their
+ # curl-config script. Fixed in Tiger, but there are still
+ # lots of Panther installs around.
+ case "${host}" in
+ powerpc-apple-darwin7*)
+ LIBCURL=`echo $LIBCURL | sed -e 's|-arch i386||g'`
+ ;;
+ esac
+ fi
+
+ # All curl-config scripts support --feature
+ _libcurl_features=`$_libcurl_config --feature`
+
+ # Is it modern enough to have --protocols? (7.12.4)
+ if test $_libcurl_version -ge 461828 ; then
+ _libcurl_protocols=`$_libcurl_config --protocols`
+ fi
+ else
+ _libcurl_try_link=no
+ fi
+
+ unset _libcurl_wanted
+ fi
+
+ if test $_libcurl_try_link = yes ; then
+
+ # we didn't find curl-config, so let's see if the user-supplied
+ # link line (or failing that, "-lcurl") is enough.
+ LIBCURL=${LIBCURL-"$_libcurl_ldflags -lcurl"}
+
+ AC_CACHE_CHECK([whether libcurl is usable],
+ [libcurl_cv_lib_curl_usable],
+ [
+ _libcurl_save_cppflags=$CPPFLAGS
+ CPPFLAGS="$LIBCURL_CPPFLAGS $CPPFLAGS"
+ _libcurl_save_libs=$LIBS
+ LIBS="$LIBCURL $LIBS"
+
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <curl/curl.h>]],[[
+/* Try and use a few common options to force a failure if we are
+ missing symbols or can't link. */
+int x;
+curl_easy_setopt(NULL,CURLOPT_URL,NULL);
+x=CURL_ERROR_SIZE;
+x=CURLOPT_WRITEFUNCTION;
+x=CURLOPT_FILE;
+x=CURLOPT_ERRORBUFFER;
+x=CURLOPT_STDERR;
+x=CURLOPT_VERBOSE;
+if (x) ;
+]])],libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no)
+
+ CPPFLAGS=$_libcurl_save_cppflags
+ LIBS=$_libcurl_save_libs
+ unset _libcurl_save_cppflags
+ unset _libcurl_save_libs
+ ])
+
+ if test $libcurl_cv_lib_curl_usable = yes ; then
+
+ # Does curl_free() exist in this version of libcurl?
+ # If not, fake it with free()
+
+ _libcurl_save_cppflags=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS"
+ _libcurl_save_libs=$LIBS
+ LIBS="$LIBS $LIBCURL"
+
+ AC_CHECK_FUNC(curl_free,,
+ AC_DEFINE(curl_free,free,
+ [Define curl_free() as free() if our version of curl lacks curl_free.]))
+
+ CPPFLAGS=$_libcurl_save_cppflags
+ LIBS=$_libcurl_save_libs
+ unset _libcurl_save_cppflags
+ unset _libcurl_save_libs
+
+ AC_DEFINE(HAVE_LIBCURL,1,
+ [Define to 1 if you have a functional curl library.])
+ AC_SUBST(LIBCURL_CPPFLAGS)
+ AC_SUBST(LIBCURL)
+
+ for _libcurl_feature in $_libcurl_features ; do
+ AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1])
+ eval AS_TR_SH(libcurl_feature_$_libcurl_feature)=yes
+ done
+
+ if test "x$_libcurl_protocols" = "x" ; then
+
+ # We don't have --protocols, so just assume that all
+ # protocols are available
+ _libcurl_protocols="HTTP FTP FILE TELNET LDAP DICT TFTP"
+
+ if test x$libcurl_feature_SSL = xyes ; then
+ _libcurl_protocols="$_libcurl_protocols HTTPS"
+
+ # FTPS wasn't standards-compliant until version
+ # 7.11.0 (0x070b00 == 461568)
+ if test $_libcurl_version -ge 461568; then
+ _libcurl_protocols="$_libcurl_protocols FTPS"
+ fi
+ fi
+
+ # RTSP, IMAP, POP3 and SMTP were added in
+ # 7.20.0 (0x071400 == 463872)
+ if test $_libcurl_version -ge 463872; then
+ _libcurl_protocols="$_libcurl_protocols RTSP IMAP POP3 SMTP"
+ fi
+ fi
+
+ for _libcurl_protocol in $_libcurl_protocols ; do
+ AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1])
+ eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes
+ done
+ else
+ unset LIBCURL
+ unset LIBCURL_CPPFLAGS
+ fi
+ fi
+
+ unset _libcurl_try_link
+ unset _libcurl_version_parse
+ unset _libcurl_config
+ unset _libcurl_feature
+ unset _libcurl_features
+ unset _libcurl_protocol
+ unset _libcurl_protocols
+ unset _libcurl_version
+ unset _libcurl_ldflags
+ fi
+
+ if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then
+ # This is the IF-NO path
+ ifelse([$4],,:,[$4])
+ else
+ # This is the IF-YES path
+ ifelse([$3],,:,[$3])
+ fi
+
+ unset _libcurl_with
+])dnl
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
new file mode 100644
index 000000000..1de1aceb7
--- /dev/null
+++ b/docs/libcurl/symbols-in-versions
@@ -0,0 +1,705 @@
+ _ _ ____ _
+ ___| | | | _ \| |
+ / __| | | | |_) | |
+ | (__| |_| | _ <| |___
+ \___|\___/|_| \_\_____|
+
+ This document lists defines and other symbols present in libcurl, together
+ with exact information about the first libcurl version that provides the
+ symbol, the first version in which the symbol was marked as deprecated and
+ for a few symbols the last version that featured it. The names appear in
+ alphabetical order.
+
+ Name Introduced Deprecated Removed
+
+CURLAUTH_ANY 7.10.6
+CURLAUTH_ANYSAFE 7.10.6
+CURLAUTH_BASIC 7.10.6
+CURLAUTH_DIGEST 7.10.6
+CURLAUTH_DIGEST_IE 7.19.3
+CURLAUTH_GSSNEGOTIATE 7.10.6
+CURLAUTH_NONE 7.10.6
+CURLAUTH_NTLM 7.10.6
+CURLAUTH_NTLM_WB 7.22.0
+CURLAUTH_ONLY 7.21.3
+CURLCLOSEPOLICY_CALLBACK 7.7
+CURLCLOSEPOLICY_LEAST_RECENTLY_USED 7.7
+CURLCLOSEPOLICY_LEAST_TRAFFIC 7.7
+CURLCLOSEPOLICY_NONE 7.7
+CURLCLOSEPOLICY_OLDEST 7.7
+CURLCLOSEPOLICY_SLOWEST 7.7
+CURLE_ABORTED_BY_CALLBACK 7.1
+CURLE_AGAIN 7.18.2
+CURLE_ALREADY_COMPLETE 7.7.2
+CURLE_BAD_CALLING_ORDER 7.1 7.17.0
+CURLE_BAD_CONTENT_ENCODING 7.10
+CURLE_BAD_DOWNLOAD_RESUME 7.10
+CURLE_BAD_FUNCTION_ARGUMENT 7.1
+CURLE_BAD_PASSWORD_ENTERED 7.4.2 7.17.0
+CURLE_CHUNK_FAILED 7.21.0
+CURLE_CONV_FAILED 7.15.4
+CURLE_CONV_REQD 7.15.4
+CURLE_COULDNT_CONNECT 7.1
+CURLE_COULDNT_RESOLVE_HOST 7.1
+CURLE_COULDNT_RESOLVE_PROXY 7.1
+CURLE_FAILED_INIT 7.1
+CURLE_FILESIZE_EXCEEDED 7.10.8
+CURLE_FILE_COULDNT_READ_FILE 7.1
+CURLE_FTP_ACCEPT_FAILED 7.24.0
+CURLE_FTP_ACCEPT_TIMEOUT 7.24.0
+CURLE_FTP_ACCESS_DENIED 7.1
+CURLE_FTP_BAD_DOWNLOAD_RESUME 7.1 7.1
+CURLE_FTP_BAD_FILE_LIST 7.21.0
+CURLE_FTP_CANT_GET_HOST 7.1
+CURLE_FTP_CANT_RECONNECT 7.1 7.17.0
+CURLE_FTP_COULDNT_GET_SIZE 7.1 7.17.0
+CURLE_FTP_COULDNT_RETR_FILE 7.1
+CURLE_FTP_COULDNT_SET_ASCII 7.1 7.17.0
+CURLE_FTP_COULDNT_SET_BINARY 7.1 7.17.0
+CURLE_FTP_COULDNT_SET_TYPE 7.17.0
+CURLE_FTP_COULDNT_STOR_FILE 7.1
+CURLE_FTP_COULDNT_USE_REST 7.1
+CURLE_FTP_PARTIAL_FILE 7.1 7.1
+CURLE_FTP_PORT_FAILED 7.1
+CURLE_FTP_PRET_FAILED 7.20.0
+CURLE_FTP_QUOTE_ERROR 7.1 7.17.0
+CURLE_FTP_SSL_FAILED 7.11.0 7.17.0
+CURLE_FTP_USER_PASSWORD_INCORRECT 7.1 7.17.0
+CURLE_FTP_WEIRD_227_FORMAT 7.1
+CURLE_FTP_WEIRD_PASS_REPLY 7.1
+CURLE_FTP_WEIRD_PASV_REPLY 7.1
+CURLE_FTP_WEIRD_SERVER_REPLY 7.1
+CURLE_FTP_WEIRD_USER_REPLY 7.1 7.17.0
+CURLE_FTP_WRITE_ERROR 7.1 7.17.0
+CURLE_FUNCTION_NOT_FOUND 7.1
+CURLE_GOT_NOTHING 7.9.1
+CURLE_HTTP_NOT_FOUND 7.1
+CURLE_HTTP_PORT_FAILED 7.3 7.12.0
+CURLE_HTTP_POST_ERROR 7.1
+CURLE_HTTP_RANGE_ERROR 7.1 7.17.0
+CURLE_HTTP_RETURNED_ERROR 7.10.3
+CURLE_INTERFACE_FAILED 7.12.0
+CURLE_LDAP_CANNOT_BIND 7.1
+CURLE_LDAP_INVALID_URL 7.10.8
+CURLE_LDAP_SEARCH_FAILED 7.1
+CURLE_LIBRARY_NOT_FOUND 7.1 7.17.0
+CURLE_LOGIN_DENIED 7.13.1
+CURLE_MALFORMAT_USER 7.1 7.17.0
+CURLE_NOT_BUILT_IN 7.21.5
+CURLE_OK 7.1
+CURLE_OPERATION_TIMEDOUT 7.10.2
+CURLE_OPERATION_TIMEOUTED 7.1 7.17.0
+CURLE_OUT_OF_MEMORY 7.1
+CURLE_PARTIAL_FILE 7.1
+CURLE_PEER_FAILED_VERIFICATION 7.17.1
+CURLE_QUOTE_ERROR 7.17.0
+CURLE_RANGE_ERROR 7.17.0
+CURLE_READ_ERROR 7.1
+CURLE_RECV_ERROR 7.10
+CURLE_REMOTE_ACCESS_DENIED 7.17.0
+CURLE_REMOTE_DISK_FULL 7.17.0
+CURLE_REMOTE_FILE_EXISTS 7.17.0
+CURLE_REMOTE_FILE_NOT_FOUND 7.16.1
+CURLE_RTSP_CSEQ_ERROR 7.20.0
+CURLE_RTSP_SESSION_ERROR 7.20.0
+CURLE_SEND_ERROR 7.10
+CURLE_SEND_FAIL_REWIND 7.12.3
+CURLE_SHARE_IN_USE 7.9.6 7.17.0
+CURLE_SSH 7.16.1
+CURLE_SSL_CACERT 7.10
+CURLE_SSL_CACERT_BADFILE 7.16.0
+CURLE_SSL_CERTPROBLEM 7.10
+CURLE_SSL_CIPHER 7.10
+CURLE_SSL_CONNECT_ERROR 7.1
+CURLE_SSL_CRL_BADFILE 7.19.0
+CURLE_SSL_ENGINE_INITFAILED 7.12.3
+CURLE_SSL_ENGINE_NOTFOUND 7.9.3
+CURLE_SSL_ENGINE_SETFAILED 7.9.3
+CURLE_SSL_ISSUER_ERROR 7.19.0
+CURLE_SSL_PEER_CERTIFICATE 7.8 7.17.1
+CURLE_SSL_SHUTDOWN_FAILED 7.16.1
+CURLE_TELNET_OPTION_SYNTAX 7.7
+CURLE_TFTP_DISKFULL 7.15.0 7.17.0
+CURLE_TFTP_EXISTS 7.15.0 7.17.0
+CURLE_TFTP_ILLEGAL 7.15.0
+CURLE_TFTP_NOSUCHUSER 7.15.0
+CURLE_TFTP_NOTFOUND 7.15.0
+CURLE_TFTP_PERM 7.15.0
+CURLE_TFTP_UNKNOWNID 7.15.0
+CURLE_TOO_MANY_REDIRECTS 7.5
+CURLE_UNKNOWN_OPTION 7.21.5
+CURLE_UNKNOWN_TELNET_OPTION 7.7
+CURLE_UNSUPPORTED_PROTOCOL 7.1
+CURLE_UPLOAD_FAILED 7.16.3
+CURLE_URL_MALFORMAT 7.1
+CURLE_URL_MALFORMAT_USER 7.1 7.17.0
+CURLE_USE_SSL_FAILED 7.17.0
+CURLE_WRITE_ERROR 7.1
+CURLFILETYPE_DEVICE_BLOCK 7.21.0
+CURLFILETYPE_DEVICE_CHAR 7.21.0
+CURLFILETYPE_DIRECTORY 7.21.0
+CURLFILETYPE_DOOR 7.21.0
+CURLFILETYPE_FILE 7.21.0
+CURLFILETYPE_NAMEDPIPE 7.21.0
+CURLFILETYPE_SOCKET 7.21.0
+CURLFILETYPE_SYMLINK 7.21.0
+CURLFILETYPE_UNKNOWN 7.21.0
+CURLFINFOFLAG_KNOWN_FILENAME 7.21.0
+CURLFINFOFLAG_KNOWN_FILETYPE 7.21.0
+CURLFINFOFLAG_KNOWN_GID 7.21.0
+CURLFINFOFLAG_KNOWN_HLINKCOUNT 7.21.0
+CURLFINFOFLAG_KNOWN_PERM 7.21.0
+CURLFINFOFLAG_KNOWN_SIZE 7.21.0
+CURLFINFOFLAG_KNOWN_TIME 7.21.0
+CURLFINFOFLAG_KNOWN_UID 7.21.0
+CURLFORM_ARRAY 7.9.1
+CURLFORM_ARRAY_END 7.9.1 7.9.5 7.9.6
+CURLFORM_ARRAY_START 7.9.1 7.9.5 7.9.6
+CURLFORM_BUFFER 7.9.8
+CURLFORM_BUFFERLENGTH 7.9.8
+CURLFORM_BUFFERPTR 7.9.8
+CURLFORM_CONTENTHEADER 7.9.3
+CURLFORM_CONTENTSLENGTH 7.9
+CURLFORM_CONTENTTYPE 7.9
+CURLFORM_COPYCONTENTS 7.9
+CURLFORM_COPYNAME 7.9
+CURLFORM_END 7.9
+CURLFORM_FILE 7.9
+CURLFORM_FILECONTENT 7.9.1
+CURLFORM_FILENAME 7.9.6
+CURLFORM_NAMELENGTH 7.9
+CURLFORM_NOTHING 7.9
+CURLFORM_PTRCONTENTS 7.9
+CURLFORM_PTRNAME 7.9
+CURLFORM_STREAM 7.18.2
+CURLFTPAUTH_DEFAULT 7.12.2
+CURLFTPAUTH_SSL 7.12.2
+CURLFTPAUTH_TLS 7.12.2
+CURLFTPMETHOD_DEFAULT 7.15.3
+CURLFTPMETHOD_MULTICWD 7.15.3
+CURLFTPMETHOD_NOCWD 7.15.3
+CURLFTPMETHOD_SINGLECWD 7.15.3
+CURLFTPSSL_ALL 7.11.0 7.17.0
+CURLFTPSSL_CCC_ACTIVE 7.16.2
+CURLFTPSSL_CCC_NONE 7.16.2
+CURLFTPSSL_CCC_PASSIVE 7.16.1
+CURLFTPSSL_CONTROL 7.11.0 7.17.0
+CURLFTPSSL_NONE 7.11.0 7.17.0
+CURLFTPSSL_TRY 7.11.0 7.17.0
+CURLFTP_CREATE_DIR 7.19.4
+CURLFTP_CREATE_DIR_NONE 7.19.4
+CURLFTP_CREATE_DIR_RETRY 7.19.4
+CURLGSSAPI_DELEGATION_FLAG 7.22.0
+CURLGSSAPI_DELEGATION_NONE 7.22.0
+CURLGSSAPI_DELEGATION_POLICY_FLAG 7.22.0
+CURLINFO_APPCONNECT_TIME 7.19.0
+CURLINFO_CERTINFO 7.19.1
+CURLINFO_CONDITION_UNMET 7.19.4
+CURLINFO_CONNECT_TIME 7.4.1
+CURLINFO_CONTENT_LENGTH_DOWNLOAD 7.6.1
+CURLINFO_CONTENT_LENGTH_UPLOAD 7.6.1
+CURLINFO_CONTENT_TYPE 7.9.4
+CURLINFO_COOKIELIST 7.14.1
+CURLINFO_DATA_IN 7.9.6
+CURLINFO_DATA_OUT 7.9.6
+CURLINFO_DOUBLE 7.4.1
+CURLINFO_EFFECTIVE_URL 7.4
+CURLINFO_END 7.9.6
+CURLINFO_FILETIME 7.5
+CURLINFO_FTP_ENTRY_PATH 7.15.4
+CURLINFO_HEADER_IN 7.9.6
+CURLINFO_HEADER_OUT 7.9.6
+CURLINFO_HEADER_SIZE 7.4.1
+CURLINFO_HTTPAUTH_AVAIL 7.10.8
+CURLINFO_HTTP_CODE 7.4.1 7.10.8
+CURLINFO_HTTP_CONNECTCODE 7.10.7
+CURLINFO_LASTONE 7.4.1
+CURLINFO_LASTSOCKET 7.15.2
+CURLINFO_LOCAL_IP 7.21.0
+CURLINFO_LOCAL_PORT 7.21.0
+CURLINFO_LONG 7.4.1
+CURLINFO_MASK 7.4.1
+CURLINFO_NAMELOOKUP_TIME 7.4.1
+CURLINFO_NONE 7.4.1
+CURLINFO_NUM_CONNECTS 7.12.3
+CURLINFO_OS_ERRNO 7.12.2
+CURLINFO_PRETRANSFER_TIME 7.4.1
+CURLINFO_PRIMARY_IP 7.19.0
+CURLINFO_PRIMARY_PORT 7.21.0
+CURLINFO_PRIVATE 7.10.3
+CURLINFO_PROXYAUTH_AVAIL 7.10.8
+CURLINFO_REDIRECT_COUNT 7.9.7
+CURLINFO_REDIRECT_TIME 7.9.7
+CURLINFO_REDIRECT_URL 7.18.2
+CURLINFO_REQUEST_SIZE 7.4.1
+CURLINFO_RESPONSE_CODE 7.10.8
+CURLINFO_RTSP_CLIENT_CSEQ 7.20.0
+CURLINFO_RTSP_CSEQ_RECV 7.20.0
+CURLINFO_RTSP_SERVER_CSEQ 7.20.0
+CURLINFO_RTSP_SESSION_ID 7.20.0
+CURLINFO_SIZE_DOWNLOAD 7.4.1
+CURLINFO_SIZE_UPLOAD 7.4.1
+CURLINFO_SLIST 7.12.3
+CURLINFO_SPEED_DOWNLOAD 7.4.1
+CURLINFO_SPEED_UPLOAD 7.4.1
+CURLINFO_SSL_DATA_IN 7.12.1
+CURLINFO_SSL_DATA_OUT 7.12.1
+CURLINFO_SSL_ENGINES 7.12.3
+CURLINFO_SSL_VERIFYRESULT 7.5
+CURLINFO_STARTTRANSFER_TIME 7.9.2
+CURLINFO_STRING 7.4.1
+CURLINFO_TEXT 7.9.6
+CURLINFO_TOTAL_TIME 7.4.1
+CURLINFO_TYPEMASK 7.4.1
+CURLIOCMD_NOP 7.12.3
+CURLIOCMD_RESTARTREAD 7.12.3
+CURLIOE_FAILRESTART 7.12.3
+CURLIOE_OK 7.12.3
+CURLIOE_UNKNOWNCMD 7.12.3
+CURLKHMATCH_MISMATCH 7.19.6
+CURLKHMATCH_MISSING 7.19.6
+CURLKHMATCH_OK 7.19.6
+CURLKHSTAT_DEFER 7.19.6
+CURLKHSTAT_FINE 7.19.6
+CURLKHSTAT_FINE_ADD_TO_FILE 7.19.6
+CURLKHSTAT_REJECT 7.19.6
+CURLKHTYPE_DSS 7.19.6
+CURLKHTYPE_RSA 7.19.6
+CURLKHTYPE_RSA1 7.19.6
+CURLKHTYPE_UNKNOWN 7.19.6
+CURLMOPT_MAXCONNECTS 7.16.3
+CURLMOPT_PIPELINING 7.16.0
+CURLMOPT_SOCKETDATA 7.15.4
+CURLMOPT_SOCKETFUNCTION 7.15.4
+CURLMOPT_TIMERDATA 7.16.0
+CURLMOPT_TIMERFUNCTION 7.16.0
+CURLMSG_DONE 7.9.6
+CURLMSG_NONE 7.9.6
+CURLM_BAD_EASY_HANDLE 7.9.6
+CURLM_BAD_HANDLE 7.9.6
+CURLM_BAD_SOCKET 7.15.4
+CURLM_CALL_MULTI_PERFORM 7.9.6
+CURLM_CALL_MULTI_SOCKET 7.15.5
+CURLM_INTERNAL_ERROR 7.9.6
+CURLM_OK 7.9.6
+CURLM_OUT_OF_MEMORY 7.9.6
+CURLM_UNKNOWN_OPTION 7.15.4
+CURLOPTTYPE_FUNCTIONPOINT 7.1
+CURLOPTTYPE_LONG 7.1
+CURLOPTTYPE_OBJECTPOINT 7.1
+CURLOPTTYPE_OFF_T 7.11.0
+CURLOPT_ACCEPTTIMEOUT_MS 7.24.0
+CURLOPT_ACCEPT_ENCODING 7.21.6
+CURLOPT_ADDRESS_SCOPE 7.19.0
+CURLOPT_APPEND 7.17.0
+CURLOPT_AUTOREFERER 7.1
+CURLOPT_BUFFERSIZE 7.10
+CURLOPT_CAINFO 7.4.2
+CURLOPT_CAPATH 7.9.8
+CURLOPT_CERTINFO 7.19.1
+CURLOPT_CHUNK_BGN_FUNCTION 7.21.0
+CURLOPT_CHUNK_DATA 7.21.0
+CURLOPT_CHUNK_END_FUNCTION 7.21.0
+CURLOPT_CLOSEFUNCTION 7.7 7.11.1 7.15.5
+CURLOPT_CLOSEPOLICY 7.7 7.16.1
+CURLOPT_CLOSESOCKETDATA 7.21.7
+CURLOPT_CLOSESOCKETFUNCTION 7.21.7
+CURLOPT_CONNECTTIMEOUT 7.7
+CURLOPT_CONNECTTIMEOUT_MS 7.16.2
+CURLOPT_CONNECT_ONLY 7.15.2
+CURLOPT_CONV_FROM_NETWORK_FUNCTION 7.15.4
+CURLOPT_CONV_FROM_UTF8_FUNCTION 7.15.4
+CURLOPT_CONV_TO_NETWORK_FUNCTION 7.15.4
+CURLOPT_COOKIE 7.1
+CURLOPT_COOKIEFILE 7.1
+CURLOPT_COOKIEJAR 7.9
+CURLOPT_COOKIELIST 7.14.1
+CURLOPT_COOKIESESSION 7.9.7
+CURLOPT_COPYPOSTFIELDS 7.17.1
+CURLOPT_CRLF 7.1
+CURLOPT_CRLFILE 7.19.0
+CURLOPT_CUSTOMREQUEST 7.1
+CURLOPT_DEBUGDATA 7.9.6
+CURLOPT_DEBUGFUNCTION 7.9.6
+CURLOPT_DIRLISTONLY 7.17.0
+CURLOPT_DNS_CACHE_TIMEOUT 7.9.3
+CURLOPT_DNS_SERVERS 7.24.0
+CURLOPT_DNS_USE_GLOBAL_CACHE 7.9.3 7.11.1
+CURLOPT_EGDSOCKET 7.7
+CURLOPT_ENCODING 7.10
+CURLOPT_ERRORBUFFER 7.1
+CURLOPT_FAILONERROR 7.1
+CURLOPT_FILE 7.1 7.9.7
+CURLOPT_FILETIME 7.5
+CURLOPT_FNMATCH_DATA 7.21.0
+CURLOPT_FNMATCH_FUNCTION 7.21.0
+CURLOPT_FOLLOWLOCATION 7.1
+CURLOPT_FORBID_REUSE 7.7
+CURLOPT_FRESH_CONNECT 7.7
+CURLOPT_FTPAPPEND 7.1 7.16.4
+CURLOPT_FTPASCII 7.1 7.11.1 7.15.5
+CURLOPT_FTPLISTONLY 7.1 7.16.4
+CURLOPT_FTPPORT 7.1
+CURLOPT_FTPSSLAUTH 7.12.2
+CURLOPT_FTP_ACCOUNT 7.13.0
+CURLOPT_FTP_ALTERNATIVE_TO_USER 7.15.5
+CURLOPT_FTP_CREATE_MISSING_DIRS 7.10.7
+CURLOPT_FTP_FILEMETHOD 7.15.1
+CURLOPT_FTP_RESPONSE_TIMEOUT 7.10.8
+CURLOPT_FTP_SKIP_PASV_IP 7.15.0
+CURLOPT_FTP_SSL 7.11.0 7.16.4
+CURLOPT_FTP_SSL_CCC 7.16.1
+CURLOPT_FTP_USE_EPRT 7.10.5
+CURLOPT_FTP_USE_EPSV 7.9.2
+CURLOPT_FTP_USE_PRET 7.20.0
+CURLOPT_GSSAPI_DELEGATION 7.22.0
+CURLOPT_HEADER 7.1
+CURLOPT_HEADERDATA 7.10
+CURLOPT_HEADERFUNCTION 7.7.2
+CURLOPT_HTTP200ALIASES 7.10.3
+CURLOPT_HTTPAUTH 7.10.6
+CURLOPT_HTTPGET 7.8.1
+CURLOPT_HTTPHEADER 7.1
+CURLOPT_HTTPPOST 7.1
+CURLOPT_HTTPPROXYTUNNEL 7.3
+CURLOPT_HTTPREQUEST 7.1 - 7.15.5
+CURLOPT_HTTP_CONTENT_DECODING 7.16.2
+CURLOPT_HTTP_TRANSFER_DECODING 7.16.2
+CURLOPT_HTTP_VERSION 7.9.1
+CURLOPT_IGNORE_CONTENT_LENGTH 7.14.1
+CURLOPT_INFILE 7.1 7.9.7
+CURLOPT_INFILESIZE 7.1
+CURLOPT_INFILESIZE_LARGE 7.11.0
+CURLOPT_INTERFACE 7.3
+CURLOPT_INTERLEAVEDATA 7.20.0
+CURLOPT_INTERLEAVEFUNCTION 7.20.0
+CURLOPT_IOCTLDATA 7.12.3
+CURLOPT_IOCTLFUNCTION 7.12.3
+CURLOPT_IPRESOLVE 7.10.8
+CURLOPT_ISSUERCERT 7.19.0
+CURLOPT_KEYPASSWD 7.17.0
+CURLOPT_KRB4LEVEL 7.3 7.17.0
+CURLOPT_KRBLEVEL 7.16.4
+CURLOPT_LOCALPORT 7.15.2
+CURLOPT_LOCALPORTRANGE 7.15.2
+CURLOPT_LOW_SPEED_LIMIT 7.1
+CURLOPT_LOW_SPEED_TIME 7.1
+CURLOPT_MAIL_AUTH 7.25.0
+CURLOPT_MAIL_FROM 7.20.0
+CURLOPT_MAIL_RCPT 7.20.0
+CURLOPT_MAXCONNECTS 7.7
+CURLOPT_MAXFILESIZE 7.10.8
+CURLOPT_MAXFILESIZE_LARGE 7.11.0
+CURLOPT_MAXREDIRS 7.5
+CURLOPT_MAX_RECV_SPEED_LARGE 7.15.5
+CURLOPT_MAX_SEND_SPEED_LARGE 7.15.5
+CURLOPT_MUTE 7.1 7.8 7.15.5
+CURLOPT_NETRC 7.1
+CURLOPT_NETRC_FILE 7.11.0
+CURLOPT_NEW_DIRECTORY_PERMS 7.16.4
+CURLOPT_NEW_FILE_PERMS 7.16.4
+CURLOPT_NOBODY 7.1
+CURLOPT_NOPROGRESS 7.1
+CURLOPT_NOPROXY 7.19.4
+CURLOPT_NOSIGNAL 7.10
+CURLOPT_NOTHING 7.1.1 7.11.1 7.11.0
+CURLOPT_OPENSOCKETDATA 7.17.1
+CURLOPT_OPENSOCKETFUNCTION 7.17.1
+CURLOPT_PASSWDDATA 7.4.2 7.11.1 7.15.5
+CURLOPT_PASSWDFUNCTION 7.4.2 7.11.1 7.15.5
+CURLOPT_PASSWORD 7.19.1
+CURLOPT_PASV_HOST 7.12.1 7.16.0 7.15.5
+CURLOPT_PORT 7.1
+CURLOPT_POST 7.1
+CURLOPT_POST301 7.17.1 7.19.1
+CURLOPT_POSTFIELDS 7.1
+CURLOPT_POSTFIELDSIZE 7.2
+CURLOPT_POSTFIELDSIZE_LARGE 7.11.1
+CURLOPT_POSTQUOTE 7.1
+CURLOPT_POSTREDIR 7.19.1
+CURLOPT_PREQUOTE 7.9.5
+CURLOPT_PRIVATE 7.10.3
+CURLOPT_PROGRESSDATA 7.1
+CURLOPT_PROGRESSFUNCTION 7.1
+CURLOPT_PROTOCOLS 7.19.4
+CURLOPT_PROXY 7.1
+CURLOPT_PROXYAUTH 7.10.7
+CURLOPT_PROXYPASSWORD 7.19.1
+CURLOPT_PROXYPORT 7.1
+CURLOPT_PROXYTYPE 7.10
+CURLOPT_PROXYUSERNAME 7.19.1
+CURLOPT_PROXYUSERPWD 7.1
+CURLOPT_PROXY_TRANSFER_MODE 7.18.0
+CURLOPT_PUT 7.1
+CURLOPT_QUOTE 7.1
+CURLOPT_RANDOM_FILE 7.7
+CURLOPT_RANGE 7.1
+CURLOPT_READDATA 7.9.7
+CURLOPT_READFUNCTION 7.1
+CURLOPT_REDIR_PROTOCOLS 7.19.4
+CURLOPT_REFERER 7.1
+CURLOPT_RESOLVE 7.21.3
+CURLOPT_RESUME_FROM 7.1
+CURLOPT_RESUME_FROM_LARGE 7.11.0
+CURLOPT_RTSPHEADER 7.20.0
+CURLOPT_RTSP_CLIENT_CSEQ 7.20.0
+CURLOPT_RTSP_REQUEST 7.20.0
+CURLOPT_RTSP_SERVER_CSEQ 7.20.0
+CURLOPT_RTSP_SESSION_ID 7.20.0
+CURLOPT_RTSP_STREAM_URI 7.20.0
+CURLOPT_RTSP_TRANSPORT 7.20.0
+CURLOPT_SEEKDATA 7.18.0
+CURLOPT_SEEKFUNCTION 7.18.0
+CURLOPT_SERVER_RESPONSE_TIMEOUT 7.20.0
+CURLOPT_SHARE 7.10
+CURLOPT_SOCKOPTDATA 7.16.0
+CURLOPT_SOCKOPTFUNCTION 7.16.0
+CURLOPT_SOCKS5_GSSAPI_NEC 7.19.4
+CURLOPT_SOCKS5_GSSAPI_SERVICE 7.19.4
+CURLOPT_SOURCE_HOST 7.12.1 - 7.15.5
+CURLOPT_SOURCE_PATH 7.12.1 - 7.15.5
+CURLOPT_SOURCE_PORT 7.12.1 - 7.15.5
+CURLOPT_SOURCE_POSTQUOTE 7.12.1 - 7.15.5
+CURLOPT_SOURCE_PREQUOTE 7.12.1 - 7.15.5
+CURLOPT_SOURCE_QUOTE 7.13.0 - 7.15.5
+CURLOPT_SOURCE_URL 7.13.0 - 7.15.5
+CURLOPT_SOURCE_USERPWD 7.12.1 - 7.15.5
+CURLOPT_SSH_AUTH_TYPES 7.16.1
+CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 7.17.1
+CURLOPT_SSH_KEYDATA 7.19.6
+CURLOPT_SSH_KEYFUNCTION 7.19.6
+CURLOPT_SSH_KNOWNHOSTS 7.19.6
+CURLOPT_SSH_PRIVATE_KEYFILE 7.16.1
+CURLOPT_SSH_PUBLIC_KEYFILE 7.16.1
+CURLOPT_SSLCERT 7.1
+CURLOPT_SSLCERTPASSWD 7.1.1 7.17.0
+CURLOPT_SSLCERTTYPE 7.9.3
+CURLOPT_SSLENGINE 7.9.3
+CURLOPT_SSLENGINE_DEFAULT 7.9.3
+CURLOPT_SSLKEY 7.9.3
+CURLOPT_SSLKEYPASSWD 7.9.3 7.17.0
+CURLOPT_SSLKEYTYPE 7.9.3
+CURLOPT_SSLVERSION 7.1
+CURLOPT_SSL_CIPHER_LIST 7.9
+CURLOPT_SSL_CTX_DATA 7.10.6
+CURLOPT_SSL_CTX_FUNCTION 7.10.6
+CURLOPT_SSL_OPTIONS 7.25.0
+CURLOPT_SSL_SESSIONID_CACHE 7.16.0
+CURLOPT_SSL_VERIFYHOST 7.8.1
+CURLOPT_SSL_VERIFYPEER 7.4.2
+CURLOPT_STDERR 7.1
+CURLOPT_TCP_KEEPALIVE 7.25.0
+CURLOPT_TCP_KEEPIDLE 7.25.0
+CURLOPT_TCP_KEEPINTVL 7.25.0
+CURLOPT_TCP_NODELAY 7.11.2
+CURLOPT_TELNETOPTIONS 7.7
+CURLOPT_TFTP_BLKSIZE 7.19.4
+CURLOPT_TIMECONDITION 7.1
+CURLOPT_TIMEOUT 7.1
+CURLOPT_TIMEOUT_MS 7.16.2
+CURLOPT_TIMEVALUE 7.1
+CURLOPT_TLSAUTH_PASSWORD 7.21.4
+CURLOPT_TLSAUTH_TYPE 7.21.4
+CURLOPT_TLSAUTH_USERNAME 7.21.4
+CURLOPT_TRANSFERTEXT 7.1.1
+CURLOPT_TRANSFER_ENCODING 7.21.6
+CURLOPT_UNRESTRICTED_AUTH 7.10.4
+CURLOPT_UPLOAD 7.1
+CURLOPT_URL 7.1
+CURLOPT_USERAGENT 7.1
+CURLOPT_USERNAME 7.19.1
+CURLOPT_USERPWD 7.1
+CURLOPT_USE_SSL 7.17.0
+CURLOPT_VERBOSE 7.1
+CURLOPT_WILDCARDMATCH 7.21.0
+CURLOPT_WRITEDATA 7.9.7
+CURLOPT_WRITEFUNCTION 7.1
+CURLOPT_WRITEHEADER 7.1
+CURLOPT_WRITEINFO 7.1
+CURLPAUSE_ALL 7.18.0
+CURLPAUSE_CONT 7.18.0
+CURLPAUSE_RECV 7.18.0
+CURLPAUSE_RECV_CONT 7.18.0
+CURLPAUSE_SEND 7.18.0
+CURLPAUSE_SEND_CONT 7.18.0
+CURLPROTO_ALL 7.19.4
+CURLPROTO_DICT 7.19.4
+CURLPROTO_FILE 7.19.4
+CURLPROTO_FTP 7.19.4
+CURLPROTO_FTPS 7.19.4
+CURLPROTO_GOPHER 7.21.2
+CURLPROTO_HTTP 7.19.4
+CURLPROTO_HTTPS 7.19.4
+CURLPROTO_IMAP 7.20.0
+CURLPROTO_IMAPS 7.20.0
+CURLPROTO_LDAP 7.19.4
+CURLPROTO_LDAPS 7.19.4
+CURLPROTO_POP3 7.20.0
+CURLPROTO_POP3S 7.20.0
+CURLPROTO_RTMP 7.21.0
+CURLPROTO_RTMPE 7.21.0
+CURLPROTO_RTMPS 7.21.0
+CURLPROTO_RTMPT 7.21.0
+CURLPROTO_RTMPTE 7.21.0
+CURLPROTO_RTMPTS 7.21.0
+CURLPROTO_RTSP 7.20.0
+CURLPROTO_SCP 7.19.4
+CURLPROTO_SFTP 7.19.4
+CURLPROTO_SMTP 7.20.0
+CURLPROTO_SMTPS 7.20.0
+CURLPROTO_TELNET 7.19.4
+CURLPROTO_TFTP 7.19.4
+CURLPROXY_HTTP 7.10
+CURLPROXY_HTTP_1_0 7.19.4
+CURLPROXY_SOCKS4 7.10
+CURLPROXY_SOCKS4A 7.18.0
+CURLPROXY_SOCKS5 7.10
+CURLPROXY_SOCKS5_HOSTNAME 7.18.0
+CURLSHE_BAD_OPTION 7.10.3
+CURLSHE_INVALID 7.10.3
+CURLSHE_IN_USE 7.10.3
+CURLSHE_NOMEM 7.12.0
+CURLSHE_NOT_BUILT_IN 7.23.0
+CURLSHE_OK 7.10.3
+CURLSHOPT_LOCKFUNC 7.10.3
+CURLSHOPT_NONE 7.10.3
+CURLSHOPT_SHARE 7.10.3
+CURLSHOPT_UNLOCKFUNC 7.10.3
+CURLSHOPT_UNSHARE 7.10.3
+CURLSHOPT_USERDATA 7.10.3
+CURLSOCKTYPE_ACCEPT 7.28.0
+CURLSOCKTYPE_IPCXN 7.16.0
+CURLSSH_AUTH_AGENT 7.28.0
+CURLSSH_AUTH_ANY 7.16.1
+CURLSSH_AUTH_DEFAULT 7.16.1
+CURLSSH_AUTH_HOST 7.16.1
+CURLSSH_AUTH_KEYBOARD 7.16.1
+CURLSSH_AUTH_NONE 7.16.1
+CURLSSH_AUTH_PASSWORD 7.16.1
+CURLSSH_AUTH_PUBLICKEY 7.16.1
+CURLSSLOPT_ALLOW_BEAST 7.25.0
+CURLUSESSL_ALL 7.17.0
+CURLUSESSL_CONTROL 7.17.0
+CURLUSESSL_NONE 7.17.0
+CURLUSESSL_TRY 7.17.0
+CURLVERSION_FIRST 7.10
+CURLVERSION_FOURTH 7.16.1
+CURLVERSION_NOW 7.10
+CURLVERSION_SECOND 7.11.1
+CURLVERSION_THIRD 7.12.0
+CURL_CHUNK_BGN_FUNC_FAIL 7.21.0
+CURL_CHUNK_BGN_FUNC_OK 7.21.0
+CURL_CHUNK_BGN_FUNC_SKIP 7.21.0
+CURL_CHUNK_END_FUNC_FAIL 7.21.0
+CURL_CHUNK_END_FUNC_OK 7.21.0
+CURL_CSELECT_ERR 7.16.3
+CURL_CSELECT_IN 7.16.3
+CURL_CSELECT_OUT 7.16.3
+CURL_EASY_NONE 7.14.0 - 7.15.4
+CURL_EASY_TIMEOUT 7.14.0 - 7.15.4
+CURL_ERROR_SIZE 7.1
+CURL_FNMATCHFUNC_FAIL 7.21.0
+CURL_FNMATCHFUNC_MATCH 7.21.0
+CURL_FNMATCHFUNC_NOMATCH 7.21.0
+CURL_FORMADD_DISABLED 7.12.1
+CURL_FORMADD_ILLEGAL_ARRAY 7.9.8
+CURL_FORMADD_INCOMPLETE 7.9.8
+CURL_FORMADD_MEMORY 7.9.8
+CURL_FORMADD_NULL 7.9.8
+CURL_FORMADD_OK 7.9.8
+CURL_FORMADD_OPTION_TWICE 7.9.8
+CURL_FORMADD_UNKNOWN_OPTION 7.9.8
+CURL_GLOBAL_ALL 7.8
+CURL_GLOBAL_DEFAULT 7.8
+CURL_GLOBAL_NOTHING 7.8
+CURL_GLOBAL_SSL 7.8
+CURL_GLOBAL_WIN32 7.8.1
+CURL_HTTP_VERSION_1_0 7.9.1
+CURL_HTTP_VERSION_1_1 7.9.1
+CURL_HTTP_VERSION_NONE 7.9.1
+CURL_IPRESOLVE_V4 7.10.8
+CURL_IPRESOLVE_V6 7.10.8
+CURL_IPRESOLVE_WHATEVER 7.10.8
+CURL_LOCK_ACCESS_NONE 7.10.3
+CURL_LOCK_ACCESS_SHARED 7.10.3
+CURL_LOCK_ACCESS_SINGLE 7.10.3
+CURL_LOCK_DATA_CONNECT 7.10.3
+CURL_LOCK_DATA_COOKIE 7.10.3
+CURL_LOCK_DATA_DNS 7.10.3
+CURL_LOCK_DATA_NONE 7.10.3
+CURL_LOCK_DATA_SHARE 7.10.4
+CURL_LOCK_DATA_SSL_SESSION 7.10.3
+CURL_LOCK_TYPE_CONNECT 7.10 - 7.10.2
+CURL_LOCK_TYPE_COOKIE 7.10 - 7.10.2
+CURL_LOCK_TYPE_DNS 7.10 - 7.10.2
+CURL_LOCK_TYPE_NONE 7.10 - 7.10.2
+CURL_LOCK_TYPE_SSL_SESSION 7.10 - 7.10.2
+CURL_MAX_HTTP_HEADER 7.19.7
+CURL_MAX_WRITE_SIZE 7.9.7
+CURL_NETRC_IGNORED 7.9.8
+CURL_NETRC_OPTIONAL 7.9.8
+CURL_NETRC_REQUIRED 7.9.8
+CURL_POLL_IN 7.14.0
+CURL_POLL_INOUT 7.14.0
+CURL_POLL_NONE 7.14.0
+CURL_POLL_OUT 7.14.0
+CURL_POLL_REMOVE 7.14.0
+CURL_PROGRESS_BAR 7.1.1 - 7.4.1
+CURL_PROGRESS_STATS 7.1.1 - 7.4.1
+CURL_READFUNC_ABORT 7.12.1
+CURL_READFUNC_PAUSE 7.18.0
+CURL_REDIR_GET_ALL 7.19.1
+CURL_REDIR_POST_301 7.19.1
+CURL_REDIR_POST_302 7.19.1
+CURL_REDIR_POST_303 7.25.1
+CURL_REDIR_POST_ALL 7.19.1
+CURL_RTSPREQ_ANNOUNCE 7.20.0
+CURL_RTSPREQ_DESCRIBE 7.20.0
+CURL_RTSPREQ_GET_PARAMETER 7.20.0
+CURL_RTSPREQ_NONE 7.20.0
+CURL_RTSPREQ_OPTIONS 7.20.0
+CURL_RTSPREQ_PAUSE 7.20.0
+CURL_RTSPREQ_PLAY 7.20.0
+CURL_RTSPREQ_RECEIVE 7.20.0
+CURL_RTSPREQ_RECORD 7.20.0
+CURL_RTSPREQ_SETUP 7.20.0
+CURL_RTSPREQ_SET_PARAMETER 7.20.0
+CURL_RTSPREQ_TEARDOWN 7.20.0
+CURL_SEEKFUNC_CANTSEEK 7.19.5
+CURL_SEEKFUNC_FAIL 7.19.5
+CURL_SEEKFUNC_OK 7.19.5
+CURL_SOCKET_BAD 7.14.0
+CURL_SOCKET_TIMEOUT 7.14.0
+CURL_SOCKOPT_ALREADY_CONNECTED 7.21.5
+CURL_SOCKOPT_ERROR 7.21.5
+CURL_SOCKOPT_OK 7.21.5
+CURL_SSLVERSION_DEFAULT 7.9.2
+CURL_SSLVERSION_SSLv2 7.9.2
+CURL_SSLVERSION_SSLv3 7.9.2
+CURL_SSLVERSION_TLSv1 7.9.2
+CURL_TIMECOND_IFMODSINCE 7.9.7
+CURL_TIMECOND_IFUNMODSINCE 7.9.7
+CURL_TIMECOND_LASTMOD 7.9.7
+CURL_TIMECOND_NONE 7.9.7
+CURL_TLSAUTH_NONE 7.21.4
+CURL_TLSAUTH_SRP 7.21.4
+CURL_VERSION_ASYNCHDNS 7.10.7
+CURL_VERSION_CONV 7.15.4
+CURL_VERSION_CURLDEBUG 7.19.6
+CURL_VERSION_DEBUG 7.10.6
+CURL_VERSION_GSSNEGOTIATE 7.10.6
+CURL_VERSION_IDN 7.12.0
+CURL_VERSION_IPV6 7.10
+CURL_VERSION_KERBEROS4 7.10
+CURL_VERSION_LARGEFILE 7.11.1
+CURL_VERSION_LIBZ 7.10
+CURL_VERSION_NTLM 7.10.6
+CURL_VERSION_NTLM_WB 7.22.0
+CURL_VERSION_SPNEGO 7.10.8
+CURL_VERSION_SSL 7.10
+CURL_VERSION_SSPI 7.13.2
+CURL_VERSION_TLSAUTH_SRP 7.21.4
+CURL_WAIT_POLLIN 7.28.0
+CURL_WAIT_POLLOUT 7.28.0
+CURL_WAIT_POLLPRI 7.28.0
+CURL_WRITEFUNC_PAUSE 7.18.0
diff --git a/docs/libcurl/symbols.pl b/docs/libcurl/symbols.pl
new file mode 100755
index 000000000..d1ff7a656
--- /dev/null
+++ b/docs/libcurl/symbols.pl
@@ -0,0 +1,100 @@
+#!/usr/bin/perl
+#***************************************************************************
+# _ _ ____ _
+# Project ___| | | | _ \| |
+# / __| | | | |_) | |
+# | (__| |_| | _ <| |___
+# \___|\___/|_| \_\_____|
+#
+# Copyright (C) 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+#
+# Experience has shown that the symbols-in-versions file is very useful to
+# applications that want to build with a wide range of libcurl versions.
+# It is however easy to get it wrong and the source gets a bit messy with all
+# the fixed numerical comparisions.
+#
+# The point of this script is to provide an easy-to-use macro for libcurl-
+# using applications to do preprocessor checks for specific libcurl defines,
+# and yet make the code clearly show what the macro is used for.
+#
+# Run this script and generate libcurl-symbols.h and then use that header in
+# a fashion similar to:
+#
+# #include "libcurl-symbols.h"
+#
+# #if LIBCURL_HAS(CURLOPT_MUTE)
+# has mute
+# #else
+# no mute
+# #endif
+#
+#
+open F, "<symbols-in-versions";
+
+sub str2num {
+ my ($str)=@_;
+ if($str =~ /([0-9]*)\.([0-9]*)\.*([0-9]*)/) {
+ return sprintf("0x%06x", $1<<16 | $2 << 8 | $3);
+ }
+}
+
+print <<EOS
+
+#include <curl/curl.h>
+
+#define LIBCURL_HAS(x) \\
+ (defined(x ## _FIRST) && (x ## _FIRST <= LIBCURL_VERSION_NUM) && \\
+ (!defined(x ## _LAST) || ( x ## _LAST >= LIBCURL_VERSION_NUM)))
+
+EOS
+ ;
+
+while(<F>) {
+ if(/^(CURL[^ ]*)[ \t]*(.*)/) {
+ my ($sym, $vers)=($1, $2);
+
+ my $intr;
+ my $rm;
+ my $dep;
+
+ # is there removed info?
+ if($vers =~ /([\d.]+)[ \t-]+([\d.]+)[ \t]+([\d.]+)/) {
+ ($intr, $dep, $rm)=($1, $2, $3);
+ }
+ # is it a dep-only line?
+ elsif($vers =~ /([\d.]+)[ \t-]+([\d.]+)/) {
+ ($intr, $dep)=($1, $2);
+ }
+ else {
+ $intr = $vers;
+ }
+
+ my $inum = str2num($intr);
+
+ print <<EOS
+#define ${sym}_FIRST $inum /* Added in $intr */
+EOS
+;
+ my $irm = str2num($rm);
+ if($rm) {
+ print <<EOS
+#define ${sym}_LAST $irm /* Last featured in $rm */
+EOS
+;
+ }
+
+ }
+}
diff --git a/docs/mk-ca-bundle.1 b/docs/mk-ca-bundle.1
new file mode 100644
index 000000000..f7904398f
--- /dev/null
+++ b/docs/mk-ca-bundle.1
@@ -0,0 +1,51 @@
+.Dd April 27, 2012
+.Dt MK-CA-BUNDLE 1
+.Os
+.Sh NAME
+.Nm mk-ca-bundle
+.Nd create a new ca-bundle.crt from mozilla's certdata.txt
+.Sh SYNOPSIS
+.Nm
+.Op Fl bilnqtuv
+.Or outputfile
+.Sh DESCRIPTION
+The
+.Nm
+tool downloads the certdata.txt file from Mozilla's source tree, then
+parses certdata.txt and extracts CA Root Certificates into PEM format.
+These are then processed with the OpenSSL commandline tool to produce the
+final ca-bundle.crt file.
+.Sh OPTIONS
+The following options are supported by
+.Nm :
+.Bl -tag -width _h
+.It Fl b
+backup an existing version of ca-bundle.crt
+.It Fl i
+print version info about used modules
+.It Fl l
+print license info about certdata.txt
+.It Fl n
+no download of certdata.txt (to use existing)
+.It Fl q
+be really quiet (no progress output at all)
+.It Fl t
+include plain text listing of certificates
+.It Fl u
+unlink (remove) certdata.txt after processing
+.It Fl v
+be verbose and print out processed CAs
+.El
+.Sh EXIT STATUS
+.Ex -std
+.Sh SEE ALSO
+.Xr curl 1
+.Sh HISTORY
+.Nm
+was based on the parse-certs script written by
+.An Roland Krikava
+and hacked by
+.An Guenter Knauf .
+This manual page was written by
+.An Jan Schaumann
+.Aq jschauma@netmeister.org .