gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-sync] 01/01: skeleton


From: gnunet
Subject: [taler-sync] 01/01: skeleton
Date: Wed, 13 Nov 2019 15:01:13 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository sync.

commit c8047726772c2f4a18a6b0ebc7ce879bf260860a
Author: Christian Grothoff <address@hidden>
AuthorDate: Wed Nov 13 15:01:09 2019 +0100

    skeleton
---
 .gitignore                            |  63 +++
 AUTHORS                               |   1 +
 COPYING                               | 661 ++++++++++++++++++++++++++++++
 COPYING.AGPL                          | 661 ++++++++++++++++++++++++++++++
 ChangeLog                             |   2 +
 INSTALL                               | 368 +++++++++++++++++
 Makefile.am                           |  26 ++
 NEWS                                  |   0
 README                                |  36 ++
 bootstrap                             |  31 ++
 configure.ac                          | 309 ++++++++++++++
 contrib/gnunet.tag                    |  55 +++
 contrib/uncrustify.cfg                |  78 ++++
 contrib/uncrustify_precommit          |  35 ++
 m4/ax_lib_postgresql.m4               | 155 +++++++
 m4/ax_prog_doxygen.m4                 | 586 ++++++++++++++++++++++++++
 m4/libcurl.m4                         | 251 ++++++++++++
 m4/libgnurl.m4                        | 250 ++++++++++++
 src/Makefile.am                       |   3 +
 src/include/Makefile.am               |  10 +
 src/include/platform.h                |  60 +++
 src/include/sync_database_lib.h       |  46 +++
 src/include/sync_database_plugin.h    | 117 ++++++
 src/include/sync_service.h            |  64 +++
 src/lib/Makefile.am                   |  32 ++
 src/lib/sync_api_upload.c             |  57 +++
 src/sync/Makefile.am                  |  28 ++
 src/sync/sync-httpd.c                 | 744 ++++++++++++++++++++++++++++++++++
 src/sync/sync-httpd.h                 | 148 +++++++
 src/sync/sync-httpd_backup.c          |  56 +++
 src/sync/sync-httpd_backup.h          |  53 +++
 src/sync/sync-httpd_mhd.c             | 156 +++++++
 src/sync/sync-httpd_mhd.h             | 113 ++++++
 src/sync/sync-httpd_parsing.c         | 272 +++++++++++++
 src/sync/sync-httpd_parsing.h         |  93 +++++
 src/sync/sync-httpd_responses.c       | 408 +++++++++++++++++++
 src/sync/sync-httpd_responses.h       | 244 +++++++++++
 src/sync/sync.conf                    |  31 ++
 src/syncdb/Makefile.am                |  62 +++
 src/syncdb/plugin_sync_postgres.c     | 284 +++++++++++++
 src/syncdb/sync_db_plugin.c           | 149 +++++++
 src/syncdb/sync_db_postgres.conf      |   7 +
 src/syncdb/test_sync_db.c             | 200 +++++++++
 src/syncdb/test_sync_db_postgres.conf |   7 +
 44 files changed, 7012 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1ecf3bd
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,63 @@
+Makefile
+Makefile.in
+aclocal.m4
+anastasis_config.h
+anastasis_config.h.in
+anastasis_config.h.in~
+autom4te.cache/
+compile
+config.guess
+config.log
+config.status
+config.sub
+configure
+contrib/uncrustify.sh
+depcomp
+doc/Makefile
+install-sh
+libtool
+ltmain.sh
+missing
+src/Makefile
+src/Makefile.in
+src/util/.deps/
+src/util/.libs/
+src/stasis/Makefile
+src/stasis/Makefile.in
+src/stasis/libanastasis_plugin_db_postgres.la
+src/stasis/plugin_anastasis_postgres.lo
+src/stasis/plugin_anastasis_postgres.o
+src/stasis/.deps/
+src/backend/Makefile
+src/backend/Makefile.in
+src/include/Makefile
+src/include/Makefile.in
+src/lib/.deps/
+src/lib/Makefile
+src/lib/Makefile.in
+stamp-h1
+test-driver
+uncrustify.cfg
+doc/Makefile.in
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
+*.swp
+src/lib/.libs
+*.lo
+*.o
+*.la
+src/util/.deps/
+src/backend/.deps/
+src/backend/.idea/
+src/backend/.libs/
+src/stasis/.libs/
+src/backend/anastasis-httpd
+doc/Makefile.in
+src/include/Makefile.in
+
+A
+A
+
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..eb41b69
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Christian Grothoff
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..dba13ed
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,661 @@
+                    GNU AFFERO GENERAL PUBLIC LICENSE
+                       Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+  A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate.  Many developers of free software are heartened and
+encouraged by the resulting cooperation.  However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+  The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community.  It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server.  Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+  An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals.  This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU Affero General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Remote Network Interaction; Use with the GNU General Public License.
+
+  Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software.  This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time.  Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source.  For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code.  There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<http://www.gnu.org/licenses/>.
diff --git a/COPYING.AGPL b/COPYING.AGPL
new file mode 100644
index 0000000..dba13ed
--- /dev/null
+++ b/COPYING.AGPL
@@ -0,0 +1,661 @@
+                    GNU AFFERO GENERAL PUBLIC LICENSE
+                       Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+  A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate.  Many developers of free software are heartened and
+encouraged by the resulting cooperation.  However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+  The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community.  It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server.  Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+  An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals.  This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU Affero General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Remote Network Interaction; Use with the GNU General Public License.
+
+  Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software.  This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time.  Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source.  For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code.  There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<http://www.gnu.org/licenses/>.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..823d0fa
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,2 @@
+Tue 18 Jun 2019 04:19:29 PM CEST
+       Initial project setup. -CG
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..8865734
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,368 @@
+Installation Instructions
+*************************
+
+   Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software
+Foundation, Inc.
+
+   Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.  This file is offered as-is,
+without warranty of any kind.
+
+Basic Installation
+==================
+
+   Briefly, the shell command './configure && make && make install'
+should configure, build, and install this package.  The following
+more-detailed instructions are generic; see the 'README' file for
+instructions specific to this package.  Some packages provide this
+'INSTALL' file but do not implement all of the features documented
+below.  The lack of an optional feature in a given package is not
+necessarily a bug.  More recommendations for GNU packages can be found
+in *note Makefile Conventions: (standards)Makefile Conventions.
+
+   The 'configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a 'Makefile' in each directory of the package.
+It may also create one or more '.h' files containing system-dependent
+definitions.  Finally, it creates a shell script 'config.status' that
+you can run in the future to recreate the current configuration, and a
+file 'config.log' containing compiler output (useful mainly for
+debugging 'configure').
+
+   It can also use an optional file (typically called 'config.cache' and
+enabled with '--cache-file=config.cache' or simply '-C') that saves the
+results of its tests to speed up reconfiguring.  Caching is disabled by
+default to prevent problems with accidental use of stale cache files.
+
+   If you need to do unusual things to compile the package, please try
+to figure out how 'configure' could check whether to do them, and mail
+diffs or instructions to the address given in the 'README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point 'config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file 'configure.ac' (or 'configure.in') is used to create
+'configure' by a program called 'autoconf'.  You need 'configure.ac' if
+you want to change it or regenerate 'configure' using a newer version of
+'autoconf'.
+
+   The simplest way to compile this package is:
+
+  1. 'cd' to the directory containing the package's source code and type
+     './configure' to configure the package for your system.
+
+     Running 'configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
+
+  2. Type 'make' to compile the package.
+
+  3. Optionally, type 'make check' to run any self-tests that come with
+     the package, generally using the just-built uninstalled binaries.
+
+  4. Type 'make install' to install the programs and any data files and
+     documentation.  When installing into a prefix owned by root, it is
+     recommended that the package be configured and built as a regular
+     user, and only the 'make install' phase executed with root
+     privileges.
+
+  5. Optionally, type 'make installcheck' to repeat any self-tests, but
+     this time using the binaries in their final installed location.
+     This target does not install anything.  Running this target as a
+     regular user, particularly if the prior 'make install' required
+     root privileges, verifies that the installation completed
+     correctly.
+
+  6. You can remove the program binaries and object files from the
+     source code directory by typing 'make clean'.  To also remove the
+     files that 'configure' created (so you can compile the package for
+     a different kind of computer), type 'make distclean'.  There is
+     also a 'make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+  7. Often, you can also type 'make uninstall' to remove the installed
+     files again.  In practice, not all packages have tested that
+     uninstallation works correctly, even though it is required by the
+     GNU Coding Standards.
+
+  8. Some packages, particularly those that use Automake, provide 'make
+     distcheck', which can by used by developers to test that all other
+     targets like 'make install' and 'make uninstall' work correctly.
+     This target is generally not run by end users.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the 'configure' script does not know about.  Run './configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give 'configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here is
+an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you can use GNU 'make'.  'cd' to the
+directory where you want the object files and executables to go and run
+the 'configure' script.  'configure' automatically checks for the source
+code in the directory that 'configure' is in and in '..'.  This is known
+as a "VPATH" build.
+
+   With a non-GNU 'make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use 'make distclean' before
+reconfiguring for another architecture.
+
+   On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple '-arch' options to the
+compiler but only a single '-arch' option to the preprocessor.  Like
+this:
+
+     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CPP="gcc -E" CXXCPP="g++ -E"
+
+   This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the 'lipo' tool if you have problems.
+
+Installation Names
+==================
+
+   By default, 'make install' installs the package's commands under
+'/usr/local/bin', include files under '/usr/local/include', etc.  You
+can specify an installation prefix other than '/usr/local' by giving
+'configure' the option '--prefix=PREFIX', where PREFIX must be an
+absolute file name.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option '--exec-prefix=PREFIX' to 'configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like '--bindir=DIR' to specify different values for particular
+kinds of files.  Run 'configure --help' for a list of the directories
+you can set and what kinds of files go in them.  In general, the default
+for these options is expressed in terms of '${prefix}', so that
+specifying just '--prefix' will affect all of the other directory
+specifications that were not explicitly provided.
+
+   The most portable way to affect installation locations is to pass the
+correct locations to 'configure'; however, many packages provide one or
+both of the following shortcuts of passing variable assignments to the
+'make install' command line to change installation locations without
+having to reconfigure or recompile.
+
+   The first method involves providing an override variable for each
+affected directory.  For example, 'make install
+prefix=/alternate/directory' will choose an alternate location for all
+directory configuration variables that were expressed in terms of
+'${prefix}'.  Any directories that were specified during 'configure',
+but not in terms of '${prefix}', must each be overridden at install time
+for the entire installation to be relocated.  The approach of makefile
+variable overrides for each directory variable is required by the GNU
+Coding Standards, and ideally causes no recompilation.  However, some
+platforms have known limitations with the semantics of shared libraries
+that end up requiring recompilation when using this method, particularly
+noticeable in packages that use GNU Libtool.
+
+   The second method involves providing the 'DESTDIR' variable.  For
+example, 'make install DESTDIR=/alternate/directory' will prepend
+'/alternate/directory' before all installation names.  The approach of
+'DESTDIR' overrides is not required by the GNU Coding Standards, and
+does not work on platforms that have drive letters.  On the other hand,
+it does better at avoiding recompilation issues, and works well even
+when some directory options were not specified in terms of '${prefix}'
+at 'configure' time.
+
+Optional Features
+=================
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving 'configure' the
+option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'.
+
+   Some packages pay attention to '--enable-FEATURE' options to
+'configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to '--with-PACKAGE' options, where PACKAGE
+is something like 'gnu-as' or 'x' (for the X Window System).  The
+'README' should mention any '--enable-' and '--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, 'configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the 'configure' options '--x-includes=DIR' and
+'--x-libraries=DIR' to specify their locations.
+
+   Some packages offer the ability to configure how verbose the
+execution of 'make' will be.  For these packages, running './configure
+--enable-silent-rules' sets the default to minimal output, which can be
+overridden with 'make V=1'; while running './configure
+--disable-silent-rules' sets the default to verbose, which can be
+overridden with 'make V=0'.
+
+Particular systems
+==================
+
+   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU CC
+is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+     ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+   HP-UX 'make' updates targets which have the same time stamps as their
+prerequisites, which makes it generally unusable when shipped generated
+files such as 'configure' are involved.  Use GNU 'make' instead.
+
+   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its '<wchar.h>' header file.  The option '-nodtk' can be used as a
+workaround.  If GNU CC is not installed, it is therefore recommended to
+try
+
+     ./configure CC="cc"
+
+and if that doesn't work, try
+
+     ./configure CC="cc -nodtk"
+
+   On Solaris, don't put '/usr/ucb' early in your 'PATH'.  This
+directory contains several dysfunctional programs; working variants of
+these programs are available in '/usr/bin'.  So, if you need '/usr/ucb'
+in your 'PATH', put it _after_ '/usr/bin'.
+
+   On Haiku, software installed for all users goes in '/boot/common',
+not '/usr/local'.  It is recommended to use the following options:
+
+     ./configure --prefix=/boot/common
+
+Specifying the System Type
+==========================
+
+   There may be some features 'configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, 'configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+'--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as 'sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS
+     KERNEL-OS
+
+   See the file 'config.sub' for the possible values of each field.  If
+'config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option '--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with '--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for 'configure' scripts to share,
+you can create a site shell script called 'config.site' that gives
+default values for variables like 'CC', 'cache_file', and 'prefix'.
+'configure' looks for 'PREFIX/share/config.site' if it exists, then
+'PREFIX/etc/config.site' if it exists.  Or, you can set the
+'CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all 'configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to 'configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the 'configure' command line, using 'VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified 'gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an
+Autoconf limitation.  Until the limitation is lifted, you can use this
+workaround:
+
+     CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+'configure' Invocation
+======================
+
+   'configure' recognizes the following options to control how it
+operates.
+
+'--help'
+'-h'
+     Print a summary of all of the options to 'configure', and exit.
+
+'--help=short'
+'--help=recursive'
+     Print a summary of the options unique to this package's
+     'configure', and exit.  The 'short' variant lists options used only
+     in the top level, while the 'recursive' variant lists options also
+     present in any nested packages.
+
+'--version'
+'-V'
+     Print the version of Autoconf used to generate the 'configure'
+     script, and exit.
+
+'--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally 'config.cache'.  FILE defaults to '/dev/null' to
+     disable caching.
+
+'--config-cache'
+'-C'
+     Alias for '--cache-file=config.cache'.
+
+'--quiet'
+'--silent'
+'-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to '/dev/null' (any error
+     messages will still be shown).
+
+'--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     'configure' can determine that directory automatically.
+
+'--prefix=DIR'
+     Use DIR as the installation prefix.  *note Installation Names:: for
+     more details, including other options available for fine-tuning the
+     installation locations.
+
+'--no-create'
+'-n'
+     Run the configure checks, but stop before creating any output
+     files.
+
+'configure' also accepts some other, not widely useful, options.  Run
+'configure --help' for more details.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..3227908
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,26 @@
+# This Makefile is in the public domain
+
+if DOC_ONLY
+if ENABLE_DOC
+  SUBDIRS = . doc
+else
+  SUBDIRS = .
+endif
+else
+if ENABLE_DOC
+  SUBDIRS = . src doc
+else
+  SUBDIRS = . src doc
+endif
+endif
+
+@DX_RULES@
+
+ACLOCAL_AMFLAGS = -I m4
+EXTRA_DIST = \
+ AUTHORS \
+ COPYING.AGPL \
+ contrib/gnunet.tag \
+ contrib/uncrustify.cfg \
+ contrib/uncrustify_precommit \
+ Doxyfile
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644
index 0000000..326a1d9
--- /dev/null
+++ b/README
@@ -0,0 +1,36 @@
+TALER MERCHANT
+
+1. DESCRIPTION
+
+Under the name 'Taler merchant' there are two main objectives: one is to
+implement a common helper (called 'backend') for all the existing merchants
+willing to integrate Taler in their existing online shops, whereas the other
+objective is implementing some demonstrator shops which use that backend.
+
+2. INNOVATIVE ASPECTS
+
+This component allows merchants to receive payments without invading the
+customers' privacy. Of course, this applies mostly for digital goods, as the
+merchant does not need to know the customer's physical address.
+
+3. PLANNING/PERSPECTIVES
+
+Since the main component's part is the backend, and it is supposed to work with
+preexisting shops, a massive backend's testing with existing shop portals 
should
+be accomplished.
+
+
+4. DEPENDENCIES
+
+libjansson: MIT License, AGPL- and LGPL-Compatible, owned by Petri Lehtinen 
and other individuals
+libgcrypt: LGPL, owned by Free Software Foundation
+postgresql: PostgreSQL License, AGPL- and LGPL-Compatible, owned by The 
PostgreSQL
+Global Development Group
+libgnunetutil (in all of its variants): GPLv3+, owned by GNUnet e.V.
+PHP:  PHP License, AGPL- and LGPL-Compatible, owned by The PHP Group
+
+5. DIRECTORY STRUCTURE
+
+- 'src/' contains the "backend", a C piece of software which implements cryto 
routines
+  and communication with the 'exchange'
+ 'doc/' contains documentation files, like TeXinfo
diff --git a/bootstrap b/bootstrap
new file mode 100755
index 0000000..65d653e
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+if ! git --version >/dev/null; then
+  echo "git not installed"
+  exit 1
+fi
+
+echo "$0: Updating submodules"
+echo | git submodule update --init
+
+# This is more portable than `which' but comes with
+# the caveat of not(?) properly working on busybox's ash:
+existence()
+{
+    command -v "$1" >/dev/null 2>&1
+}
+
+
+if existence uncrustify; then
+    echo "Installing uncrustify hook and configuration"
+    # Install uncrustify format symlink (if possible)
+    ln -s contrib/uncrustify.cfg uncrustify.cfg 2> /dev/null
+    # Install pre-commit hook (if possible)
+    ln -s ../../contrib/uncrustify_precommit .git/hooks/pre-commit 2> /dev/null
+else
+    echo "Uncrustify not detected, hook not installed. Please install 
uncrustify if you plan on doing development"
+fi
+
+
+echo "$0: Running autoreconf"
+autoreconf -if
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..1250b6d
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,309 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+#
+# This configure file is in the public domain
+
+AC_PREREQ([2.69])
+AC_INIT([anastasis], [0.5.0], [address@hidden])
+AC_CONFIG_SRCDIR([src/backend/anastasis-httpd.c])
+AC_CONFIG_HEADERS([anastasis_config.h])
+# support for non-recursive builds
+AM_INIT_AUTOMAKE([subdir-objects 1.9 tar-pax])
+
+# pretty build rules
+AM_SILENT_RULES([yes])
+
+AC_CONFIG_MACRO_DIR([m4])
+
+LT_INIT
+
+DX_INIT_DOXYGEN([anastasis],,,
+DX_PS_FEATURE(OFF),
+DX_PDF_FEATURE(OFF),
+DX_RTF_FEATURE(OFF),
+DX_CHI_FEATURE(OFF),
+DX_XML_FEATURE(OFF))
+
+AC_MSG_CHECKING([whether to compile documentation ONLY])
+AC_ARG_ENABLE([only-doc],
+  [AS_HELP_STRING([--enable-only-doc], [only compile Taler documentation])],
+  [doc_only=${enableval}],
+  [doc_only=no])
+AC_MSG_RESULT($doc_only)
+AM_CONDITIONAL([DOC_ONLY], [test "$doc_only" = "yes"])
+
+
+# Not indented as it covers most of the file...
+AS_IF([test "x$doc_only" != xyes],[
+
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_CC_C99
+
+CFLAGS="-Wall $CFLAGS"
+
+# Checks for header files.
+AC_CHECK_HEADERS([stdint.h stdlib.h string.h unistd.h])
+
+# Check for GNUnet's libgnunetutil.
+libgnunetutil=0
+AC_MSG_CHECKING([for libgnunetutil])
+AC_ARG_WITH(gnunet,
+            [AS_HELP_STRING([--with-gnunet=PFX], [base of GNUnet 
installation])],
+            [AC_MSG_RESULT([given as $with_gnunet])],
+            [AC_MSG_RESULT(not given)
+             with_gnunet=yes])
+AS_CASE([$with_gnunet],
+        [yes], [],
+        [no], [AC_MSG_ERROR([--with-gnunet is required])],
+        [LDFLAGS="-L$with_gnunet/lib $LDFLAGS"
+         CPPFLAGS="-I$with_gnunet/include $CPPFLAGS"])
+AC_CHECK_HEADERS([gnunet/platform.h gnunet/gnunet_util_lib.h],
+ [AC_CHECK_LIB([gnunetutil], [GNUNET_SCHEDULER_run], libgnunetutil=1)],
+  [], [#ifdef HAVE_GNUNET_PLATFORM_H
+        #include <gnunet/platform.h>
+       #endif])
+AS_IF([test $libgnunetutil != 1],
+  [AC_MSG_ERROR([[
+***
+*** You need libgnunetutil to build this program.
+*** This library is part of GNUnet, available at
+***   https://gnunet.org
+*** ]])])
+
+
+# test for postgres
+AX_LIB_POSTGRESQL([9.3])
+AS_IF([test "x$found_postgresql" = "xyes"],[postgres=true])
+AM_CONDITIONAL(HAVE_POSTGRESQL, test x$postgres = xtrue)
+
+# Check for Taler's libtalerpq
+libtalerpq=0
+AC_MSG_CHECKING([for libtalerpq])
+AC_ARG_WITH(exchange,
+            [AS_HELP_STRING([--with-exchange=PFX], [base of Taler EXCHANGE 
installation])],
+            [AC_MSG_RESULT([given as $with_exchange])],
+            [AC_MSG_RESULT(not given)
+             with_exchange=yes])
+AS_CASE([$with_exchange],
+        [yes], [],
+        [no], [AC_MSG_ERROR([--with-exchange is required])],
+        [LDFLAGS="-L$with_exchange/lib $LDFLAGS"
+         CPPFLAGS="-I$with_exchange/include $CPPFLAGS $POSTGRESQL_CPPFLAGS"])
+
+CPPFLAGS="$CPPFLAGS $POSTGRESQL_CPPFLAGS"
+LDFLAGS="$LDFLAGS -L/usr/local/lib"
+
+AC_CHECK_HEADERS([gnunet/gnunet_pq_lib.h],
+ [AC_CHECK_LIB([gnunetpq], [GNUNET_PQ_connect_with_cfg], libgnunetpq=1)],
+   [], [#ifdef HAVE_GNUNET_PLATFORM_H
+        #include <gnunet/platform.h>
+       #endif])
+AM_CONDITIONAL(HAVE_GNUNETPQ, test x$libgnunetpq = x1)
+
+# check for libmicrohttpd
+microhttpd=0
+AC_MSG_CHECKING([for microhttpd])
+AC_ARG_WITH([microhttpd],
+            [AS_HELP_STRING([--with-microhttpd=PFX], [base of microhttpd 
installation])],
+            [AC_MSG_RESULT([given as $with_microhttpd])],
+            [AC_MSG_RESULT([not given])
+             with_microhttpd=yes])
+AS_CASE([$with_microhttpd],
+        [yes], [],
+        [no], [AC_MSG_ERROR([--with-microhttpd is required])],
+        [LDFLAGS="-L$with_microhttpd/lib $LDFLAGS"
+         CPPFLAGS="-I$with_microhttpd/include $CPPFLAGS"])
+AC_CHECK_LIB(microhttpd,MHD_start_daemon,
+  [AC_CHECK_HEADER([microhttpd.h],[microhttpd=1])])
+AS_IF([test $microhttpd = 0],
+  [AC_MSG_ERROR([[
+***
+*** You need libmicrohttpd to build this program.
+*** ]])])
+
+jansson=0
+PKG_CHECK_MODULES([JANSSON], [jansson >= 2.3],
+                  [LDFLAGS="$JANSSON_LIBS $LDFLAGS"
+                   CPPFLAGS="$JANSSON_CFLAGS $CPPFLAGS"],
+                  [AC_MSG_ERROR([[
+***
+*** You need libjansson to build this program.
+***]])])
+
+# check for libgnurl
+# libgnurl
+LIBGNURL_CHECK_CONFIG(,7.34.0,gnurl=1,gnurl=0)
+AS_IF([test "x$gnurl" = x1],[
+       AM_CONDITIONAL(HAVE_LIBGNURL, true)
+       AC_DEFINE([HAVE_LIBGNURL],[1],[Have libgnurl])
+],[
+       AM_CONDITIONAL(HAVE_LIBGNURL, false)
+])
+
+# libcurl-gnutls
+LIBCURL_CHECK_CONFIG(,7.34.0,[curl=true],[curl=false])
+AS_IF([test "x$curl" = xtrue],
+      [LDFLAGS="-L$with_libcurl/lib $LDFLAGS"
+       CPPFLAGS="-I$with_libcurl/include $CPPFLAGS"
+       AC_CHECK_HEADERS([curl/curl.h],
+                        [AC_CHECK_DECLS(CURLINFO_TLS_SESSION,
+                         [curl=true],
+                         [curl=false],
+                         [[#include <curl/curl.h>]])],
+                        [curl=false])
+       # need libcurl-gnutls.so, everything else is not acceptable
+       AC_CHECK_LIB([curl-gnutls],
+                    [curl_easy_getinfo],,
+                    [curl=false])])
+       # cURL must support CURLINFO_TLS_SESSION, version >= 7.34
+
+# Check for curl/curl.h and gnurl/curl.h so we can use #ifdef
+# HAVE_CURL_CURL_H later (the above LIBCURL_CHECK_CONFIG accepted
+# *either* header set).
+AC_CHECK_HEADERS([curl/curl.h],,
+  curl=false
+  AC_CHECK_HEADERS([gnurl/curl.h],,
+  gnurl=false))
+
+# libgnurl
+AS_IF([test "x$gnurl" = "x0"],
+      [AS_IF([test "x$curl" = "x0"],
+              [AC_MSG_NOTICE([NOTICE: libgnurl not found. taler-bank support 
will not be compiled.])],
+              [AC_MSG_NOTICE([WARNING: libgnurl not found, trying to use 
libcurl-gnutls instead.])])])
+
+AS_IF([test x$curl = xfalse],
+       [AM_CONDITIONAL(HAVE_LIBCURL, false)
+        AS_IF([test "x$gnurl" = "x0"],
+              [AC_MSG_WARN([GNU Taler requires libcurl-gnutls  >= 7.34])])],
+       [AM_CONDITIONAL(HAVE_LIBCURL, true)
+       AC_DEFINE([HAVE_LIBCURL],[1],[Have CURL])])
+
+# check for libtalertwistertesting
+twistertesting=0
+AC_MSG_CHECKING([for talerwtistertesting])
+AC_ARG_WITH([twister],
+            [AS_HELP_STRING([--with-twister=PFX], [base of 
libtalertwistertesting])],
+            [AC_MSG_RESULT([given as $with_twister])],
+            [AC_MSG_RESULT([not given])
+             with_twister=yes])
+AS_CASE([$with_twister],
+        [yes], [],
+        [no], [AC_MSG_WARN([no twister-testing will be compiled])],
+        [LDFLAGS="-L$with_twister/lib $LDFLAGS"
+         CPPFLAGS="-I$with_twister/include $CPPFLAGS"])
+
+AC_CHECK_HEADERS([taler/taler_twister_testing_lib.h],
+ [AC_CHECK_LIB([talertwistertesting], [TALER_TESTING_run_twister], 
twistertesting=1,, [-ltalerexchange -ltalerbank])],
+   [], [#ifdef HAVE_GNUNET_PLATFORM_H
+        #include <gnunet/platform.h>
+       #endif])
+AM_CONDITIONAL(HAVE_TWISTER, test x$twistertesting = x1)
+
+# gcov compilation
+AC_MSG_CHECKING(whether to compile with support for code coverage analysis)
+AC_ARG_ENABLE([coverage],
+              AS_HELP_STRING([--enable-coverage],
+                             [compile the library with code coverage support]),
+              [use_gcov=${enableval}],
+              [use_gcov=no])
+AC_MSG_RESULT($use_gcov)
+AM_CONDITIONAL([USE_COVERAGE], [test "x$use_gcov" = "xyes"])
+
+# Require minimum libgcrypt version
+need_libgcrypt_version=1.6.1
+AC_DEFINE_UNQUOTED([NEED_LIBGCRYPT_VERSION], ["$need_libgcrypt_version"],
+                                             [minimum version of libgcrypt 
required])
+AM_PATH_LIBGCRYPT([$need_libgcrypt_version])
+
+# logging
+extra_logging=0
+AC_ARG_ENABLE([logging],
+   AS_HELP_STRING([--enable-logging@<:@=value@:>@],[Enable logging calls. 
Possible values: yes,no,verbose ('yes' is the default)]),
+   [AS_IF([test "x$enableval" = "xyes"], [],
+          [test "x$enableval" = "xno"], 
[AC_DEFINE([GNUNET_CULL_LOGGING],[],[Define to cull all logging calls])],
+          [test "x$enableval" = "xverbose"], [extra_logging=1]
+          [test "x$enableval" = "xveryverbose"], [extra_logging=2])
+   ], [])
+AC_DEFINE_UNQUOTED([GNUNET_EXTRA_LOGGING],[$extra_logging],[1 if extra logging 
is enabled, 2 for very verbose extra logging, 0 otherwise])
+
+# version info
+AC_PATH_PROG(gitcommand, git)
+AC_MSG_CHECKING(for source being under a VCS)
+git_version=
+AS_IF([test ! "X$gitcommand" = "X"],
+[
+  git_version=$(cd $srcdir ; git rev-list --full-history --all --abbrev-commit 
| head -n 1 2>/dev/null)
+])
+AS_IF([test "X$git_version" = "X"],
+  [
+    vcs_name="no"
+    vcs_version="\"release\""
+  ],
+  [
+    vcs_name="yes, git-svn"
+    vcs_version="\"git-$git_version\""
+  ])
+AC_MSG_RESULT($vcs_name)
+
+AC_MSG_CHECKING(VCS version)
+AC_MSG_RESULT($vcs_version)
+AC_DEFINE_UNQUOTED(VCS_VERSION, [$vcs_version], [VCS revision/hash or tarball 
version])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+AC_TYPE_UINT64_T
+AC_TYPE_INTMAX_T
+AC_TYPE_UINTMAX_T
+
+# Checks for library functions.
+AC_CHECK_FUNCS([strdup])
+
+
+AC_ARG_ENABLE([[doc]],
+  [AS_HELP_STRING([[--disable-doc]], [do not build any documentation])], ,
+    [enable_doc=yes])
+test "x$enable_doc" = "xno" || enable_doc=yes
+AM_CONDITIONAL([ENABLE_DOC], [test "x$enable_doc" = "xyes"])
+
+
+],[  # this is about the doc-only if on top of the file
+
+# logic if doc_only is set, make sure conditionals are still defined
+AM_CONDITIONAL([HAVE_GNUNETPQ], [false])
+AM_CONDITIONAL([HAVE_POSTGRESQL], [false])
+AM_CONDITIONAL([HAVE_LIBCURL], [false])
+AM_CONDITIONAL([HAVE_LIBGNURL], [false])
+AM_CONDITIONAL([USE_COVERAGE], [false])
+AM_CONDITIONAL([ENABLE_DOC], [true])
+AM_CONDITIONAL([HAVE_TWISTER], [true])
+
+
+# end of 'doc_only'
+])
+
+
+# should experimental code be compiled (code that may not yet compile / have 
passing test cases)?
+AC_MSG_CHECKING(whether to compile experimental code)
+AC_ARG_ENABLE([experimental],
+   [AS_HELP_STRING([--enable-experimental], [enable compiling experimental 
code])],
+   [enable_experimental=${enableval}],
+   [enable_experimental=no])
+AC_MSG_RESULT($enable_experimental)
+AM_CONDITIONAL([HAVE_EXPERIMENTAL], [test "x$enable_experimental" = "xyes"])
+
+
+AC_CONFIG_FILES([Makefile
+doc/Makefile
+src/Makefile
+src/util/Makefile
+src/stasis/Makefile
+src/backend/Makefile
+src/include/Makefile
+src/lib/Makefile
+])
+AC_OUTPUT
diff --git a/contrib/gnunet.tag b/contrib/gnunet.tag
new file mode 100644
index 0000000..1cf4f0d
--- /dev/null
+++ b/contrib/gnunet.tag
@@ -0,0 +1,55 @@
+<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
+<tagfile>
+  <compound kind="file">
+    <name>gnunet_util_lib.h</name>
+    <path></path>
+    <filename>gnunet_util_lib.h</filename>
+    <member kind="define">
+      <type>#define</type>
+      <name>GNUNET_YES</name>
+      <anchorfile>gnunet_util_lib.h</anchorfile>
+      <arglist></arglist>
+    </member>
+    <member kind="define">
+      <type>#define</type>
+      <name>GNUNET_OK</name>
+      <anchorfile>gnunet_util_lib.h</anchorfile>
+      <arglist></arglist>
+    </member>
+    <member kind="define">
+      <type>#define</type>
+      <name>GNUNET_NO</name>
+      <anchorfile>gnunet_util_lib.h</anchorfile>
+      <arglist></arglist>
+    </member>
+    <member kind="define">
+      <type>#define</type>
+      <name>GNUNET_SYSERR</name>
+      <anchorfile>gnunet_util_lib.h</anchorfile>
+      <arglist></arglist>
+    </member>
+    <member kind="define">
+      <type>#define</type>
+      <name>GNUNET_TIME_UNIT_FOREVER_ABS</name>
+      <anchorfile>gnunet_util_lib.h</anchorfile>
+      <arglist></arglist>
+    </member>
+  </compound>
+  <compound kind="file">
+    <name>gnunet_pq_lib.h</name>
+    <path></path>
+    <filename>gnunet_pq_lib.h</filename>
+    <member kind="define">
+      <type>#define</type>
+      <name>GNUNET_PQ_query_param_end</name>
+      <anchorfile>gnunet_pq_lib.h</anchorfile>
+      <arglist></arglist>
+    </member>
+    <member kind="typedef">
+      <type>int</type>
+      <name>GNUNET_PQ_ResultConverter</name>
+      <anchorfile>gnunet_pq_lib.h</anchorfile>
+      <arglist>)(void *cls, PGresult *result, int row, const char *fname, 
size_t *dst_size, void *dst)</arglist>
+    </member>
+  </compound>
+</tagfile>
diff --git a/contrib/uncrustify.cfg b/contrib/uncrustify.cfg
new file mode 100644
index 0000000..f56c8e7
--- /dev/null
+++ b/contrib/uncrustify.cfg
@@ -0,0 +1,78 @@
+input_tab_size = 2
+output_tab_size = 2
+
+indent_columns = 2
+indent_with_tabs = 0
+indent_case_brace = 2
+indent_label=-16
+
+code_width=80
+#cmd_width=80
+
+# Leave most comments alone for now
+cmt_indent_multi=false
+sp_cmt_cpp_start=add
+
+sp_not=add
+
+sp_func_call_user_paren_paren=remove
+sp_inside_fparen=remove
+sp_after_cast=add
+
+ls_for_split_full=true
+ls_func_split_full=true
+ls_code_width=true
+
+# Arithmetic operations in wrapped expressions should be at the start
+# of the line.
+pos_arith=lead
+
+# Fully parenthesize boolean exprs
+mod_full_paren_if_bool=true
+
+# Braces should be on their own line
+nl_fdef_brace=add
+nl_enum_brace=add
+nl_struct_brace=add
+nl_union_brace=add
+nl_if_brace=add
+nl_brace_else=add
+nl_elseif_brace=add
+nl_while_brace=add
+nl_switch_brace=add
+
+# no newline between "else" and "if"
+nl_else_if=remove
+
+nl_func_paren=remove
+nl_assign_brace=remove
+
+# No extra newlines that cause noisy diffs
+nl_start_of_file=remove
+# If there's no new line, it's not a text file!
+nl_end_of_file=add
+
+sp_inside_paren = remove
+
+sp_arith = add
+sp_arith_additive = add
+
+# We want spaces before and after "="
+sp_before_assign = add
+sp_after_assign = add
+
+# we want "char *foo;"
+sp_after_ptr_star = remove
+sp_between_ptr_star = remove
+
+# we want "if (foo) { ... }"
+sp_before_sparen = add
+
+sp_inside_fparen = remove
+
+# add space before function call and decl: "foo (x)"
+sp_func_call_paren = add
+sp_func_proto_paren = add
+sp_func_proto_paren_empty = add
+sp_func_def_paren = add
+sp_func_def_paren_empty = add
diff --git a/contrib/uncrustify_precommit b/contrib/uncrustify_precommit
new file mode 100755
index 0000000..fd29998
--- /dev/null
+++ b/contrib/uncrustify_precommit
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+# use as .git/hooks/pre-commit
+
+exec 1>&2
+
+RET=0
+changed=$(git diff --cached --name-only)
+crustified=""
+
+for f in $changed;
+do
+ if echo $f | grep \\.[c,h]\$ > /dev/null
+ then
+    # compare result of uncrustify with changes
+    #
+    # only change any of the invocations here if
+    # they are portable across all cmp and shell
+    # implementations !
+    uncrustify -q -c uncrustify.cfg -f $f | cmp -s $f -
+    if test $? = 1 ;
+    then
+      crustified=" $crustified $f"
+      RET=1
+    fi
+  fi
+done
+
+if [ $RET = 1 ];
+then
+  echo "Run"
+  echo "uncrustify --no-backup -c uncrustify.cfg ${crustified}"
+  echo "before commiting."
+fi
+exit $RET
diff --git a/m4/ax_lib_postgresql.m4 b/m4/ax_lib_postgresql.m4
new file mode 100644
index 0000000..11b6991
--- /dev/null
+++ b/m4/ax_lib_postgresql.m4
@@ -0,0 +1,155 @@
+# ===========================================================================
+#     http://www.gnu.org/software/autoconf-archive/ax_lib_postgresql.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_LIB_POSTGRESQL([MINIMUM-VERSION])
+#
+# DESCRIPTION
+#
+#   This macro provides tests of availability of PostgreSQL 'libpq' library
+#   of particular version or newer.
+#
+#   AX_LIB_POSTGRESQL macro takes only one argument which is optional. If
+#   there is no required version passed, then macro does not run version
+#   test.
+#
+#   The --with-postgresql option takes one of three possible values:
+#
+#   no - do not check for PostgreSQL client library
+#
+#   yes - do check for PostgreSQL library in standard locations (pg_config
+#   should be in the PATH)
+#
+#   path - complete path to pg_config utility, use this option if pg_config
+#   can't be found in the PATH
+#
+#   This macro calls:
+#
+#     AC_SUBST(POSTGRESQL_CPPFLAGS)
+#     AC_SUBST(POSTGRESQL_LDFLAGS)
+#     AC_SUBST(POSTGRESQL_VERSION)
+#
+#   And sets:
+#
+#     HAVE_POSTGRESQL
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Mateusz Loskot <address@hidden>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 9
+
+AC_DEFUN([AX_LIB_POSTGRESQL],
+[
+    AC_ARG_WITH([postgresql],
+        AS_HELP_STRING([--with-postgresql=@<:@ARG@:>@],
+            [use PostgreSQL library @<:@default=yes@:>@, optionally specify 
path to pg_config]
+        ),
+        [
+        if test "$withval" = "no"; then
+            want_postgresql="no"
+        elif test "$withval" = "yes"; then
+            want_postgresql="yes"
+        else
+            want_postgresql="yes"
+            PG_CONFIG="$withval"
+        fi
+        ],
+        [want_postgresql="yes"]
+    )
+
+    POSTGRESQL_CPPFLAGS=""
+    POSTGRESQL_LDFLAGS=""
+    POSTGRESQL_VERSION=""
+
+    dnl
+    dnl Check PostgreSQL libraries (libpq)
+    dnl
+
+    if test "$want_postgresql" = "yes"; then
+
+        if test -z "$PG_CONFIG" -o test; then
+            AC_PATH_PROG([PG_CONFIG], [pg_config], [])
+        fi
+
+        if test ! -x "$PG_CONFIG"; then
+            dnl AC_MSG_ERROR([$PG_CONFIG does not exist or it is not an 
exectuable file])
+            PG_CONFIG="no"
+            found_postgresql="no"
+        fi
+
+        if test "$PG_CONFIG" != "no"; then
+            AC_MSG_CHECKING([for PostgreSQL libraries])
+
+            POSTGRESQL_CPPFLAGS="-I`$PG_CONFIG --includedir`"
+            POSTGRESQL_LDFLAGS="-L`$PG_CONFIG --libdir`"
+
+            POSTGRESQL_VERSION=`$PG_CONFIG --version | sed -e 's#PostgreSQL 
##' | awk '{print $1}'`
+
+            AC_DEFINE([HAVE_POSTGRESQL], [1],
+                [Define to 1 if PostgreSQL libraries are available])
+
+            found_postgresql="yes"
+            AC_MSG_RESULT([yes])
+        else
+            found_postgresql="no"
+            AC_MSG_RESULT([no])
+        fi
+    fi
+
+    dnl
+    dnl Check if required version of PostgreSQL is available
+    dnl
+
+
+    postgresql_version_req=ifelse([$1], [], [], [$1])
+
+    if test "$found_postgresql" = "yes" -a -n "$postgresql_version_req"; then
+
+        AC_MSG_CHECKING([if PostgreSQL version $POSTGRESQL_VERSION is >= 
$postgresql_version_req])
+
+        dnl Decompose required version string of PostgreSQL
+        dnl and calculate its number representation
+        postgresql_version_req_major=`expr $postgresql_version_req : 
'\([[0-9]]*\)'`
+        postgresql_version_req_minor=`expr $postgresql_version_req : 
'[[0-9]]*\.\([[0-9]]*\)'`
+        postgresql_version_req_micro=`expr $postgresql_version_req : 
'[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
+        if test "x$postgresql_version_req_micro" = "x"; then
+            postgresql_version_req_micro="0"
+        fi
+
+        postgresql_version_req_number=`expr $postgresql_version_req_major \* 
1000000 \
+                                   \+ $postgresql_version_req_minor \* 1000 \
+                                   \+ $postgresql_version_req_micro`
+
+        dnl Decompose version string of installed PostgreSQL
+        dnl and calculate its number representation
+        postgresql_version_major=`expr $POSTGRESQL_VERSION : '\([[0-9]]*\)'`
+        postgresql_version_minor=`expr $POSTGRESQL_VERSION : 
'[[0-9]]*\.\([[0-9]]*\)'`
+        postgresql_version_micro=`expr $POSTGRESQL_VERSION : 
'[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
+        if test "x$postgresql_version_micro" = "x"; then
+            postgresql_version_micro="0"
+        fi
+
+        postgresql_version_number=`expr $postgresql_version_major \* 1000000 \
+                                   \+ $postgresql_version_minor \* 1000 \
+                                   \+ $postgresql_version_micro`
+
+        postgresql_version_check=`expr $postgresql_version_number \>\= 
$postgresql_version_req_number`
+        if test "$postgresql_version_check" = "1"; then
+            AC_MSG_RESULT([yes])
+        else
+            AC_MSG_RESULT([no])
+        fi
+    fi
+
+    AC_SUBST([POSTGRESQL_VERSION])
+    AC_SUBST([POSTGRESQL_CPPFLAGS])
+    AC_SUBST([POSTGRESQL_LDFLAGS])
+])
diff --git a/m4/ax_prog_doxygen.m4 b/m4/ax_prog_doxygen.m4
new file mode 100644
index 0000000..a371f7f
--- /dev/null
+++ b/m4/ax_prog_doxygen.m4
@@ -0,0 +1,586 @@
+# ===========================================================================
+#     https://www.gnu.org/software/autoconf-archive/ax_prog_doxygen.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   DX_INIT_DOXYGEN(PROJECT-NAME, [DOXYFILE-PATH], [OUTPUT-DIR], ...)
+#   DX_DOXYGEN_FEATURE(ON|OFF)
+#   DX_DOT_FEATURE(ON|OFF)
+#   DX_HTML_FEATURE(ON|OFF)
+#   DX_CHM_FEATURE(ON|OFF)
+#   DX_CHI_FEATURE(ON|OFF)
+#   DX_MAN_FEATURE(ON|OFF)
+#   DX_RTF_FEATURE(ON|OFF)
+#   DX_XML_FEATURE(ON|OFF)
+#   DX_PDF_FEATURE(ON|OFF)
+#   DX_PS_FEATURE(ON|OFF)
+#
+# DESCRIPTION
+#
+#   The DX_*_FEATURE macros control the default setting for the given
+#   Doxygen feature. Supported features are 'DOXYGEN' itself, 'DOT' for
+#   generating graphics, 'HTML' for plain HTML, 'CHM' for compressed HTML
+#   help (for MS users), 'CHI' for generating a separate .chi file by the
+#   .chm file, and 'MAN', 'RTF', 'XML', 'PDF' and 'PS' for the appropriate
+#   output formats. The environment variable DOXYGEN_PAPER_SIZE may be
+#   specified to override the default 'a4wide' paper size.
+#
+#   By default, HTML, PDF and PS documentation is generated as this seems to
+#   be the most popular and portable combination. MAN pages created by
+#   Doxygen are usually problematic, though by picking an appropriate subset
+#   and doing some massaging they might be better than nothing. CHM and RTF
+#   are specific for MS (note that you can't generate both HTML and CHM at
+#   the same time). The XML is rather useless unless you apply specialized
+#   post-processing to it.
+#
+#   The macros mainly control the default state of the feature. The use can
+#   override the default by specifying --enable or --disable. The macros
+#   ensure that contradictory flags are not given (e.g.,
+#   --enable-doxygen-html and --enable-doxygen-chm,
+#   --enable-doxygen-anything with --disable-doxygen, etc.) Finally, each
+#   feature will be automatically disabled (with a warning) if the required
+#   programs are missing.
+#
+#   Once all the feature defaults have been specified, call DX_INIT_DOXYGEN
+#   with the following parameters: a one-word name for the project for use
+#   as a filename base etc., an optional configuration file name (the
+#   default is '$(srcdir)/Doxyfile', the same as Doxygen's default), and an
+#   optional output directory name (the default is 'doxygen-doc'). To run
+#   doxygen multiple times for different configuration files and output
+#   directories provide more parameters: the second, forth, sixth, etc
+#   parameter are configuration file names and the third, fifth, seventh,
+#   etc parameter are output directories. No checking is done to catch
+#   duplicates.
+#
+#   Automake Support
+#
+#   The DX_RULES substitution can be used to add all needed rules to the
+#   Makefile. Note that this is a substitution without being a variable:
+#   only the @DX_RULES@ syntax will work.
+#
+#   The provided targets are:
+#
+#     doxygen-doc: Generate all doxygen documentation.
+#
+#     doxygen-run: Run doxygen, which will generate some of the
+#                  documentation (HTML, CHM, CHI, MAN, RTF, XML)
+#                  but will not do the post processing required
+#                  for the rest of it (PS, PDF).
+#
+#     doxygen-ps:  Generate doxygen PostScript documentation.
+#
+#     doxygen-pdf: Generate doxygen PDF documentation.
+#
+#   Note that by default these are not integrated into the automake targets.
+#   If doxygen is used to generate man pages, you can achieve this
+#   integration by setting man3_MANS to the list of man pages generated and
+#   then adding the dependency:
+#
+#     $(man3_MANS): doxygen-doc
+#
+#   This will cause make to run doxygen and generate all the documentation.
+#
+#   The following variable is intended for use in Makefile.am:
+#
+#     DX_CLEANFILES = everything to clean.
+#
+#   Then add this variable to MOSTLYCLEANFILES.
+#
+# LICENSE
+#
+#   Copyright (c) 2009 Oren Ben-Kiki <address@hidden>
+#   Copyright (c) 2015 Olaf Mandel <address@hidden>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 23
+
+## ----------##
+## Defaults. ##
+## ----------##
+
+DX_ENV=""
+AC_DEFUN([DX_FEATURE_doc],  ON)
+AC_DEFUN([DX_FEATURE_dot],  OFF)
+AC_DEFUN([DX_FEATURE_man],  OFF)
+AC_DEFUN([DX_FEATURE_html], ON)
+AC_DEFUN([DX_FEATURE_chm],  OFF)
+AC_DEFUN([DX_FEATURE_chi],  OFF)
+AC_DEFUN([DX_FEATURE_rtf],  OFF)
+AC_DEFUN([DX_FEATURE_xml],  OFF)
+AC_DEFUN([DX_FEATURE_pdf],  ON)
+AC_DEFUN([DX_FEATURE_ps],   ON)
+
+## --------------- ##
+## Private macros. ##
+## --------------- ##
+
+# DX_ENV_APPEND(VARIABLE, VALUE)
+# ------------------------------
+# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen and add it
+# as a substitution (but not a Makefile variable). The substitution
+# is skipped if the variable name is VERSION.
+AC_DEFUN([DX_ENV_APPEND],
+[AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])dnl
+m4_if([$1], [VERSION], [], [AC_SUBST([$1], [$2])dnl
+AM_SUBST_NOTMAKE([$1])])dnl
+])
+
+# DX_DIRNAME_EXPR
+# ---------------
+# Expand into a shell expression prints the directory part of a path.
+AC_DEFUN([DX_DIRNAME_EXPR],
+         [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
+
+# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
+# -------------------------------------
+# Expands according to the M4 (static) status of the feature.
+AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
+
+# DX_REQUIRE_PROG(VARIABLE, PROGRAM)
+# ----------------------------------
+# Require the specified program to be found for the DX_CURRENT_FEATURE to work.
+AC_DEFUN([DX_REQUIRE_PROG], [
+AC_PATH_TOOL([$1], [$2])
+if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then
+    AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
+    AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0)
+fi
+])
+
+# DX_TEST_FEATURE(FEATURE)
+# ------------------------
+# Expand to a shell expression testing whether the feature is active.
+AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
+
+# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
+# -------------------------------------------------
+# Verify that a required features has the right state before trying to turn on
+# the DX_CURRENT_FEATURE.
+AC_DEFUN([DX_CHECK_DEPEND], [
+test "$DX_FLAG_$1" = "$2" \
+|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
+                            requires, contradicts) doxygen-DX_CURRENT_FEATURE])
+])
+
+# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
+# ----------------------------------------------------------
+# Turn off the DX_CURRENT_FEATURE if the required feature is off.
+AC_DEFUN([DX_CLEAR_DEPEND], [
+test "$DX_FLAG_$1" = "$2" || AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0)
+])
+
+# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
+#                CHECK_DEPEND, CLEAR_DEPEND,
+#                REQUIRE, DO-IF-ON, DO-IF-OFF)
+# --------------------------------------------
+# Parse the command-line option controlling a feature. CHECK_DEPEND is called
+# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
+# otherwise CLEAR_DEPEND is called to turn off the default state if a required
+# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
+# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
+# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
+AC_DEFUN([DX_ARG_ABLE], [
+    AC_DEFUN([DX_CURRENT_FEATURE], [$1])
+    AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
+    AC_ARG_ENABLE(doxygen-$1,
+                  [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
+                                                      [--enable-doxygen-$1]),
+                                  DX_IF_FEATURE([$1], [don't $2], [$2]))],
+                  [
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    AC_SUBST([DX_FLAG_$1], 1)
+    $3
+;; #(
+n|N|no|No|NO)
+    AC_SUBST([DX_FLAG_$1], 0)
+;; #(
+*)
+    AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
+;;
+esac
+], [
+AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
+$4
+])
+if DX_TEST_FEATURE([$1]); then
+    $5
+    :
+fi
+if DX_TEST_FEATURE([$1]); then
+    $6
+    :
+else
+    $7
+    :
+fi
+])
+
+## -------------- ##
+## Public macros. ##
+## -------------- ##
+
+# DX_XXX_FEATURE(DEFAULT_STATE)
+# -----------------------------
+AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc],  [$1])])
+AC_DEFUN([DX_DOT_FEATURE],     [AC_DEFUN([DX_FEATURE_dot], [$1])])
+AC_DEFUN([DX_MAN_FEATURE],     [AC_DEFUN([DX_FEATURE_man],  [$1])])
+AC_DEFUN([DX_HTML_FEATURE],    [AC_DEFUN([DX_FEATURE_html], [$1])])
+AC_DEFUN([DX_CHM_FEATURE],     [AC_DEFUN([DX_FEATURE_chm],  [$1])])
+AC_DEFUN([DX_CHI_FEATURE],     [AC_DEFUN([DX_FEATURE_chi],  [$1])])
+AC_DEFUN([DX_RTF_FEATURE],     [AC_DEFUN([DX_FEATURE_rtf],  [$1])])
+AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
+AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
+AC_DEFUN([DX_PDF_FEATURE],     [AC_DEFUN([DX_FEATURE_pdf],  [$1])])
+AC_DEFUN([DX_PS_FEATURE],      [AC_DEFUN([DX_FEATURE_ps],   [$1])])
+
+# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR], ...)
+# --------------------------------------------------------------
+# PROJECT also serves as the base name for the documentation files.
+# The default CONFIG-FILE is "$(srcdir)/Doxyfile" and OUTPUT-DOC-DIR is
+# "doxygen-doc".
+# More arguments are interpreted as interleaved CONFIG-FILE and
+# OUTPUT-DOC-DIR values.
+AC_DEFUN([DX_INIT_DOXYGEN], [
+
+# Files:
+AC_SUBST([DX_PROJECT], [$1])
+AC_SUBST([DX_CONFIG], ['ifelse([$2], [], [$(srcdir)/Doxyfile], [$2])'])
+AC_SUBST([DX_DOCDIR], ['ifelse([$3], [], [doxygen-doc], [$3])'])
+m4_if(m4_eval(3 < m4_count($@)), 1, [m4_for([DX_i], 4, m4_count($@), 2,
+      [AC_SUBST([DX_CONFIG]m4_eval(DX_i[/2]),
+                'm4_default_nblank_quoted(m4_argn(DX_i, $@),
+                                          [$(srcdir)/Doxyfile])')])])dnl
+m4_if(m4_eval(3 < m4_count($@)), 1, [m4_for([DX_i], 5, m4_count($@,), 2,
+      [AC_SUBST([DX_DOCDIR]m4_eval([(]DX_i[-1)/2]),
+                'm4_default_nblank_quoted(m4_argn(DX_i, $@),
+                                          [doxygen-doc])')])])dnl
+m4_define([DX_loop], m4_dquote(m4_if(m4_eval(3 < m4_count($@)), 1,
+          [m4_for([DX_i], 4, m4_count($@), 2, [, m4_eval(DX_i[/2])])],
+          [])))dnl
+
+# Environment variables used inside doxygen.cfg:
+DX_ENV_APPEND(SRCDIR, $srcdir)
+DX_ENV_APPEND(PROJECT, $DX_PROJECT)
+DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
+
+# Doxygen itself:
+DX_ARG_ABLE(doc, [generate any doxygen documentation],
+            [],
+            [],
+            [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
+             DX_REQUIRE_PROG([DX_PERL], perl)],
+            [DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
+
+# Dot for graphics:
+DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_DOT], dot)],
+            [DX_ENV_APPEND(HAVE_DOT, YES)
+             DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
+            [DX_ENV_APPEND(HAVE_DOT, NO)])
+
+# Man pages generation:
+DX_ARG_ABLE(man, [generate doxygen manual pages],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_MAN, YES)],
+            [DX_ENV_APPEND(GENERATE_MAN, NO)])
+
+# RTF file generation:
+DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_RTF, YES)],
+            [DX_ENV_APPEND(GENERATE_RTF, NO)])
+
+# XML file generation:
+DX_ARG_ABLE(xml, [generate doxygen XML documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_XML, YES)],
+            [DX_ENV_APPEND(GENERATE_XML, NO)])
+
+# (Compressed) HTML help generation:
+DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_HHC], hhc)],
+            [DX_ENV_APPEND(HHC_PATH, $DX_HHC)
+             DX_ENV_APPEND(GENERATE_HTML, YES)
+             DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
+            [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
+
+# Separate CHI file generation.
+DX_ARG_ABLE(chi, [generate doxygen separate compressed HTML help index file],
+            [DX_CHECK_DEPEND(chm, 1)],
+            [DX_CLEAR_DEPEND(chm, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_CHI, YES)],
+            [DX_ENV_APPEND(GENERATE_CHI, NO)])
+
+# Plain HTML pages generation:
+DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
+            [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
+            [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
+            [],
+            [DX_ENV_APPEND(GENERATE_HTML, YES)],
+            [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
+
+# PostScript file generation:
+DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_LATEX], latex)
+             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
+             DX_REQUIRE_PROG([DX_DVIPS], dvips)
+             DX_REQUIRE_PROG([DX_EGREP], egrep)])
+
+# PDF file generation:
+DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
+             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
+             DX_REQUIRE_PROG([DX_EGREP], egrep)])
+
+# LaTeX generation for PS and/or PDF:
+if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
+    DX_ENV_APPEND(GENERATE_LATEX, YES)
+else
+    DX_ENV_APPEND(GENERATE_LATEX, NO)
+fi
+
+# Paper size for PS and/or PDF:
+AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
+           [a4wide (default), a4, letter, legal or executive])
+case "$DOXYGEN_PAPER_SIZE" in
+#(
+"")
+    AC_SUBST(DOXYGEN_PAPER_SIZE, "")
+;; #(
+a4wide|a4|letter|legal|executive)
+    DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
+;; #(
+*)
+    AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
+;;
+esac
+
+# Rules:
+AS_IF([[test $DX_FLAG_html -eq 1]],
+[[DX_SNIPPET_html="## ------------------------------- ##
+## Rules specific for HTML output. ##
+## ------------------------------- ##
+
+DX_CLEAN_HTML = \$(DX_DOCDIR)/html]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+                \$(DX_DOCDIR]DX_i[)/html]])[
+
+"]],
+[[DX_SNIPPET_html=""]])
+AS_IF([[test $DX_FLAG_chi -eq 1]],
+[[DX_SNIPPET_chi="
+DX_CLEAN_CHI = \$(DX_DOCDIR)/\$(PACKAGE).chi]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+               \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).chi]])["]],
+[[DX_SNIPPET_chi=""]])
+AS_IF([[test $DX_FLAG_chm -eq 1]],
+[[DX_SNIPPET_chm="## ------------------------------ ##
+## Rules specific for CHM output. ##
+## ------------------------------ ##
+
+DX_CLEAN_CHM = \$(DX_DOCDIR)/chm]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+               \$(DX_DOCDIR]DX_i[)/chm]])[\
+${DX_SNIPPET_chi}
+
+"]],
+[[DX_SNIPPET_chm=""]])
+AS_IF([[test $DX_FLAG_man -eq 1]],
+[[DX_SNIPPET_man="## ------------------------------ ##
+## Rules specific for MAN output. ##
+## ------------------------------ ##
+
+DX_CLEAN_MAN = \$(DX_DOCDIR)/man]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+               \$(DX_DOCDIR]DX_i[)/man]])[
+
+"]],
+[[DX_SNIPPET_man=""]])
+AS_IF([[test $DX_FLAG_rtf -eq 1]],
+[[DX_SNIPPET_rtf="## ------------------------------ ##
+## Rules specific for RTF output. ##
+## ------------------------------ ##
+
+DX_CLEAN_RTF = \$(DX_DOCDIR)/rtf]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+               \$(DX_DOCDIR]DX_i[)/rtf]])[
+
+"]],
+[[DX_SNIPPET_rtf=""]])
+AS_IF([[test $DX_FLAG_xml -eq 1]],
+[[DX_SNIPPET_xml="## ------------------------------ ##
+## Rules specific for XML output. ##
+## ------------------------------ ##
+
+DX_CLEAN_XML = \$(DX_DOCDIR)/xml]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+               \$(DX_DOCDIR]DX_i[)/xml]])[
+
+"]],
+[[DX_SNIPPET_xml=""]])
+AS_IF([[test $DX_FLAG_ps -eq 1]],
+[[DX_SNIPPET_ps="## ----------------------------- ##
+## Rules specific for PS output. ##
+## ----------------------------- ##
+
+DX_CLEAN_PS = \$(DX_DOCDIR)/\$(PACKAGE).ps]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+              \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).ps]])[
+
+DX_PS_GOAL = doxygen-ps
+
+doxygen-ps: \$(DX_CLEAN_PS)
+
+]m4_foreach([DX_i], [DX_loop],
+[[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).ps: \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag
+       \$(DX_V_LATEX)cd \$(DX_DOCDIR]DX_i[)/latex; \\
+       rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\
+       \$(DX_LATEX) refman.tex; \\
+       \$(DX_MAKEINDEX) refman.idx; \\
+       \$(DX_LATEX) refman.tex; \\
+       countdown=5; \\
+       while \$(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\
+                         refman.log > /dev/null 2>&1 \\
+          && test \$\$countdown -gt 0; do \\
+           \$(DX_LATEX) refman.tex; \\
+            countdown=\`expr \$\$countdown - 1\`; \\
+       done; \\
+       \$(DX_DVIPS) -o ../\$(PACKAGE).ps refman.dvi
+
+]])["]],
+[[DX_SNIPPET_ps=""]])
+AS_IF([[test $DX_FLAG_pdf -eq 1]],
+[[DX_SNIPPET_pdf="## ------------------------------ ##
+## Rules specific for PDF output. ##
+## ------------------------------ ##
+
+DX_CLEAN_PDF = \$(DX_DOCDIR)/\$(PACKAGE).pdf]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+               \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).pdf]])[
+
+DX_PDF_GOAL = doxygen-pdf
+
+doxygen-pdf: \$(DX_CLEAN_PDF)
+
+]m4_foreach([DX_i], [DX_loop],
+[[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).pdf: \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag
+       \$(DX_V_LATEX)cd \$(DX_DOCDIR]DX_i[)/latex; \\
+       rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\
+       \$(DX_PDFLATEX) refman.tex; \\
+       \$(DX_MAKEINDEX) refman.idx; \\
+       \$(DX_PDFLATEX) refman.tex; \\
+       countdown=5; \\
+       while \$(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\
+                         refman.log > /dev/null 2>&1 \\
+          && test \$\$countdown -gt 0; do \\
+           \$(DX_PDFLATEX) refman.tex; \\
+           countdown=\`expr \$\$countdown - 1\`; \\
+       done; \\
+       mv refman.pdf ../\$(PACKAGE).pdf
+
+]])["]],
+[[DX_SNIPPET_pdf=""]])
+AS_IF([[test $DX_FLAG_ps -eq 1 -o $DX_FLAG_pdf -eq 1]],
+[[DX_SNIPPET_latex="## ------------------------------------------------- ##
+## Rules specific for LaTeX (shared for PS and PDF). ##
+## ------------------------------------------------- ##
+
+DX_V_LATEX = \$(_DX_v_LATEX_\$(V))
+_DX_v_LATEX_ = \$(_DX_v_LATEX_\$(AM_DEFAULT_VERBOSITY))
+_DX_v_LATEX_0 = @echo \"  LATEX \" \$][@;
+
+DX_CLEAN_LATEX = \$(DX_DOCDIR)/latex]dnl
+m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\
+                 \$(DX_DOCDIR]DX_i[)/latex]])[
+
+"]],
+[[DX_SNIPPET_latex=""]])
+
+AS_IF([[test $DX_FLAG_doc -eq 1]],
+[[DX_SNIPPET_doc="## --------------------------------- ##
+## Format-independent Doxygen rules. ##
+## --------------------------------- ##
+
+${DX_SNIPPET_html}\
+${DX_SNIPPET_chm}\
+${DX_SNIPPET_man}\
+${DX_SNIPPET_rtf}\
+${DX_SNIPPET_xml}\
+${DX_SNIPPET_ps}\
+${DX_SNIPPET_pdf}\
+${DX_SNIPPET_latex}\
+DX_V_DXGEN = \$(_DX_v_DXGEN_\$(V))
+_DX_v_DXGEN_ = \$(_DX_v_DXGEN_\$(AM_DEFAULT_VERBOSITY))
+_DX_v_DXGEN_0 = @echo \"  DXGEN \" \$<;
+
+.PHONY: doxygen-run doxygen-doc \$(DX_PS_GOAL) \$(DX_PDF_GOAL)
+
+.INTERMEDIATE: doxygen-run \$(DX_PS_GOAL) \$(DX_PDF_GOAL)
+
+doxygen-run:]m4_foreach([DX_i], [DX_loop],
+                         [[ \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag]])[
+
+doxygen-doc: doxygen-run \$(DX_PS_GOAL) \$(DX_PDF_GOAL)
+
+]m4_foreach([DX_i], [DX_loop],
+[[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag: \$(DX_CONFIG]DX_i[) 
\$(pkginclude_HEADERS)
+       \$(A""M_V_at)rm -rf \$(DX_DOCDIR]DX_i[)
+       \$(DX_V_DXGEN)\$(DX_ENV) DOCDIR=\$(DX_DOCDIR]DX_i[) \$(DX_DOXYGEN) 
\$(DX_CONFIG]DX_i[)
+       \$(A""M_V_at)echo Timestamp >\$][@
+
+]])dnl
+[DX_CLEANFILES = \\]
+m4_foreach([DX_i], [DX_loop],
+[[     \$(DX_DOCDIR]DX_i[)/doxygen_sqlite3.db \\
+       \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag \\
+]])dnl
+[      -r \\
+       \$(DX_CLEAN_HTML) \\
+       \$(DX_CLEAN_CHM) \\
+       \$(DX_CLEAN_CHI) \\
+       \$(DX_CLEAN_MAN) \\
+       \$(DX_CLEAN_RTF) \\
+       \$(DX_CLEAN_XML) \\
+       \$(DX_CLEAN_PS) \\
+       \$(DX_CLEAN_PDF) \\
+       \$(DX_CLEAN_LATEX)"]],
+[[DX_SNIPPET_doc=""]])
+AC_SUBST([DX_RULES],
+["${DX_SNIPPET_doc}"])dnl
+AM_SUBST_NOTMAKE([DX_RULES])
+
+#For debugging:
+#echo DX_FLAG_doc=$DX_FLAG_doc
+#echo DX_FLAG_dot=$DX_FLAG_dot
+#echo DX_FLAG_man=$DX_FLAG_man
+#echo DX_FLAG_html=$DX_FLAG_html
+#echo DX_FLAG_chm=$DX_FLAG_chm
+#echo DX_FLAG_chi=$DX_FLAG_chi
+#echo DX_FLAG_rtf=$DX_FLAG_rtf
+#echo DX_FLAG_xml=$DX_FLAG_xml
+#echo DX_FLAG_pdf=$DX_FLAG_pdf
+#echo DX_FLAG_ps=$DX_FLAG_ps
+#echo DX_ENV=$DX_ENV
+])
diff --git a/m4/libcurl.m4 b/m4/libcurl.m4
new file mode 100644
index 0000000..a84077a
--- /dev/null
+++ b/m4/libcurl.m4
@@ -0,0 +1,251 @@
+# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION],
+#                       [ACTION-IF-YES], [ACTION-IF-NO])
+# ----------------------------------------------------------
+#      David Shaw <address@hidden>   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_WRITEDATA;
+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/m4/libgnurl.m4 b/m4/libgnurl.m4
new file mode 100644
index 0000000..69aa166
--- /dev/null
+++ b/m4/libgnurl.m4
@@ -0,0 +1,250 @@
+# LIBGNURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION],
+#                       [ACTION-IF-YES], [ACTION-IF-NO])
+# ----------------------------------------------------------
+#      David Shaw <address@hidden>   May-09-2006
+#
+# Checks for libgnurl.  DEFAULT-ACTION is the string yes or no to
+# specify whether to default to --with-libgnurl or --without-libgnurl.
+# If not supplied, DEFAULT-ACTION is yes.  MINIMUM-VERSION is the
+# minimum version of libgnurl 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
+# libgnurl 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-libgnurl does run ACTION-IF-NO.
+#
+# This macro #defines HAVE_LIBGNURL if a working libgnurl setup is
+# found, and sets @LIBGNURL@ and @LIBGNURL_CPPFLAGS@ to the necessary
+# values.  Other useful defines are LIBGNURL_FEATURE_xxx where xxx are
+# the various features supported by libgnurl, and LIBGNURL_PROTOCOL_yyy
+# where yyy are the various protocols supported by libgnurl.  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 $libgnurl_feature_xxx and $libgnurl_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
+# gnurl-config list (e.g. it's "HTTP" and not "http").
+#
+# Users may override the detected values by doing something like:
+# LIBGNURL="-lgnurl" LIBGNURL_CPPFLAGS="-I/usr/myinclude" ./configure
+#
+# For the sake of sanity, this macro assumes that any libgnurl that is
+# found is after version 7.7.2, the first version that included the
+# gnurl-config script.  Note that it is very important for people
+# packaging binary versions of libgnurl to include this script!
+# Without gnurl-config, we can only guess what protocols are available,
+# or use gnurl_version_info to figure it out at runtime.
+
+AC_DEFUN([LIBGNURL_CHECK_CONFIG],
+[
+  AH_TEMPLATE([LIBGNURL_FEATURE_SSL],[Defined if libgnurl supports SSL])
+  AH_TEMPLATE([LIBGNURL_FEATURE_KRB4],[Defined if libgnurl supports KRB4])
+  AH_TEMPLATE([LIBGNURL_FEATURE_IPV6],[Defined if libgnurl supports IPv6])
+  AH_TEMPLATE([LIBGNURL_FEATURE_LIBZ],[Defined if libgnurl supports libz])
+  AH_TEMPLATE([LIBGNURL_FEATURE_ASYNCHDNS],[Defined if libgnurl supports 
AsynchDNS])
+  AH_TEMPLATE([LIBGNURL_FEATURE_IDN],[Defined if libgnurl supports IDN])
+  AH_TEMPLATE([LIBGNURL_FEATURE_SSPI],[Defined if libgnurl supports SSPI])
+  AH_TEMPLATE([LIBGNURL_FEATURE_NTLM],[Defined if libgnurl supports NTLM])
+
+  AH_TEMPLATE([LIBGNURL_PROTOCOL_HTTP],[Defined if libgnurl supports HTTP])
+  AH_TEMPLATE([LIBGNURL_PROTOCOL_HTTPS],[Defined if libgnurl supports HTTPS])
+  AH_TEMPLATE([LIBGNURL_PROTOCOL_FTP],[Defined if libgnurl supports FTP])
+  AH_TEMPLATE([LIBGNURL_PROTOCOL_FTPS],[Defined if libgnurl supports FTPS])
+  AH_TEMPLATE([LIBGNURL_PROTOCOL_FILE],[Defined if libgnurl supports FILE])
+  AH_TEMPLATE([LIBGNURL_PROTOCOL_TELNET],[Defined if libgnurl supports TELNET])
+  AH_TEMPLATE([LIBGNURL_PROTOCOL_LDAP],[Defined if libgnurl supports LDAP])
+  AH_TEMPLATE([LIBGNURL_PROTOCOL_DICT],[Defined if libgnurl supports DICT])
+  AH_TEMPLATE([LIBGNURL_PROTOCOL_TFTP],[Defined if libgnurl supports TFTP])
+  AH_TEMPLATE([LIBGNURL_PROTOCOL_RTSP],[Defined if libgnurl supports RTSP])
+  AH_TEMPLATE([LIBGNURL_PROTOCOL_POP3],[Defined if libgnurl supports POP3])
+  AH_TEMPLATE([LIBGNURL_PROTOCOL_IMAP],[Defined if libgnurl supports IMAP])
+  AH_TEMPLATE([LIBGNURL_PROTOCOL_SMTP],[Defined if libgnurl supports SMTP])
+
+  AC_ARG_WITH(libgnurl,
+     AC_HELP_STRING([--with-libgnurl=PREFIX],[look for the gnurl library in 
PREFIX/lib and headers in PREFIX/include]),
+     [_libgnurl_with=$withval],[_libgnurl_with=ifelse([$1],,[yes],[$1])])
+
+  if test "$_libgnurl_with" != "no" ; then
+
+     AC_PROG_AWK
+
+     _libgnurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); 
X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'"
+
+     _libgnurl_try_link=yes
+
+     if test -d "$_libgnurl_with" ; then
+        LIBGNURL_CPPFLAGS="-I$withval/include"
+        _libgnurl_ldflags="-L$withval/lib"
+        AC_PATH_PROG([_libgnurl_config],[gnurl-config],[],
+                     ["$withval/bin"])
+     else
+        AC_PATH_PROG([_libgnurl_config],[gnurl-config],[],[$PATH])
+     fi
+
+     if test x$_libgnurl_config != "x" ; then
+        AC_CACHE_CHECK([for the version of libgnurl],
+           [libgnurl_cv_lib_gnurl_version],
+           [libgnurl_cv_lib_gnurl_version=`$_libgnurl_config --version | $AWK 
'{print $[]2}'`])
+
+        _libgnurl_version=`echo $libgnurl_cv_lib_gnurl_version | 
$_libgnurl_version_parse`
+        _libgnurl_wanted=`echo ifelse([$2],,[0],[$2]) | 
$_libgnurl_version_parse`
+
+        if test $_libgnurl_wanted -gt 0 ; then
+           AC_CACHE_CHECK([for libgnurl >= version $2],
+              [libgnurl_cv_lib_version_ok],
+              [
+              if test $_libgnurl_version -ge $_libgnurl_wanted ; then
+                 libgnurl_cv_lib_version_ok=yes
+              else
+                 libgnurl_cv_lib_version_ok=no
+              fi
+              ])
+        fi
+
+        if test $_libgnurl_wanted -eq 0 || test x$libgnurl_cv_lib_version_ok = 
xyes ; then
+           if test x"$LIBGNURL_CPPFLAGS" = "x" ; then
+              LIBGNURL_CPPFLAGS=`$_libgnurl_config --cflags`
+           fi
+           if test x"$LIBGNURL" = "x" ; then
+              LIBGNURL=`$_libgnurl_config --libs`
+
+              # This is so silly, but Apple actually has a bug in their
+              # gnurl-config script.  Fixed in Tiger, but there are still
+              # lots of Panther installs around.
+              case "${host}" in
+                 powerpc-apple-darwin7*)
+                    LIBGNURL=`echo $LIBGNURL | sed -e 's|-arch i386||g'`
+                 ;;
+              esac
+           fi
+
+           # All gnurl-config scripts support --feature
+           _libgnurl_features=`$_libgnurl_config --feature`
+
+           # Is it modern enough to have --protocols? (7.12.4)
+           if test $_libgnurl_version -ge 461828 ; then
+              _libgnurl_protocols=`$_libgnurl_config --protocols`
+           fi
+        else
+           _libgnurl_try_link=no
+        fi
+
+        unset _libgnurl_wanted
+     fi
+
+     if test $_libgnurl_try_link = yes ; then
+
+        # we didn't find gnurl-config, so let's see if the user-supplied
+        # link line (or failing that, "-lgnurl") is enough.
+        LIBGNURL=${LIBGNURL-"$_libgnurl_ldflags -lgnurl"}
+
+        AC_CACHE_CHECK([whether libgnurl is usable],
+           [libgnurl_cv_lib_gnurl_usable],
+           [
+           _libgnurl_save_cppflags=$CPPFLAGS
+           CPPFLAGS="$LIBGNURL_CPPFLAGS $CPPFLAGS"
+           _libgnurl_save_libs=$LIBS
+           LIBS="$LIBGNURL $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;
+])],libgnurl_cv_lib_gnurl_usable=yes,libgnurl_cv_lib_gnurl_usable=no)
+
+           CPPFLAGS=$_libgnurl_save_cppflags
+           LIBS=$_libgnurl_save_libs
+           unset _libgnurl_save_cppflags
+           unset _libgnurl_save_libs
+           ])
+
+        if test $libgnurl_cv_lib_gnurl_usable = yes ; then
+
+           # Does gnurl_free() exist in this version of libgnurl?
+           # If not, fake it with free()
+
+           _libgnurl_save_cppflags=$CPPFLAGS
+           CPPFLAGS="$CPPFLAGS $LIBGNURL_CPPFLAGS"
+           _libgnurl_save_libs=$LIBS
+           LIBS="$LIBS $LIBGNURL"
+
+           AC_CHECK_FUNC(curl_free,,
+              AC_DEFINE(curl_free,free,
+                [Define curl_free() as free() if our version of gnurl lacks 
curl_free.]))
+
+           CPPFLAGS=$_libgnurl_save_cppflags
+           LIBS=$_libgnurl_save_libs
+           unset _libgnurl_save_cppflags
+           unset _libgnurl_save_libs
+
+           AC_DEFINE(HAVE_LIBGNURL,1,
+             [Define to 1 if you have a functional gnurl library.])
+           AC_SUBST(LIBGNURL_CPPFLAGS)
+           AC_SUBST(LIBGNURL)
+
+           for _libgnurl_feature in $_libgnurl_features ; do
+              
AC_DEFINE_UNQUOTED(AS_TR_CPP(libgnurl_feature_$_libgnurl_feature),[1])
+              eval AS_TR_SH(libgnurl_feature_$_libgnurl_feature)=yes
+           done
+
+           if test "x$_libgnurl_protocols" = "x" ; then
+
+              # We don't have --protocols, so just assume that all
+              # protocols are available
+              _libgnurl_protocols="HTTP FTP FILE TELNET LDAP DICT TFTP"
+
+              if test x$libgnurl_feature_SSL = xyes ; then
+                 _libgnurl_protocols="$_libgnurl_protocols HTTPS"
+
+                 # FTPS wasn't standards-compliant until version
+                 # 7.11.0 (0x070b00 == 461568)
+                 if test $_libgnurl_version -ge 461568; then
+                    _libgnurl_protocols="$_libgnurl_protocols FTPS"
+                 fi
+              fi
+
+              # RTSP, IMAP, POP3 and SMTP were added in
+              # 7.20.0 (0x071400 == 463872)
+              if test $_libgnurl_version -ge 463872; then
+                 _libgnurl_protocols="$_libgnurl_protocols RTSP IMAP POP3 SMTP"
+              fi
+           fi
+
+           for _libgnurl_protocol in $_libgnurl_protocols ; do
+              
AC_DEFINE_UNQUOTED(AS_TR_CPP(libgnurl_protocol_$_libgnurl_protocol),[1])
+              eval AS_TR_SH(libgnurl_protocol_$_libgnurl_protocol)=yes
+           done
+        else
+           unset LIBGNURL
+           unset LIBGNURL_CPPFLAGS
+        fi
+     fi
+
+     unset _libgnurl_try_link
+     unset _libgnurl_version_parse
+     unset _libgnurl_config
+     unset _libgnurl_feature
+     unset _libgnurl_features
+     unset _libgnurl_protocol
+     unset _libgnurl_protocols
+     unset _libgnurl_version
+     unset _libgnurl_ldflags
+  fi
+
+  if test x$_libgnurl_with = xno || test x$libgnurl_cv_lib_gnurl_usable != 
xyes ; then
+     # This is the IF-NO path
+     ifelse([$4],,:,[$4])
+  else
+     # This is the IF-YES path
+     ifelse([$3],,:,[$3])
+  fi
+
+  unset _libgnurl_with
+])dnl
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..0746ad4
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,3 @@
+# This Makefile is in the public domain
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+SUBDIRS = include syncdb sync lib
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
new file mode 100644
index 0000000..abcbfe9
--- /dev/null
+++ b/src/include/Makefile.am
@@ -0,0 +1,10 @@
+# This Makefile.am is in the public domain
+EXTRA_DIST = \
+  platform.h
+
+talerincludedir = $(includedir)/taler
+
+talerinclude_HEADERS = \
+  sync_database_plugin.h \
+  sync_service.h \
+  sync_database_lib.h
diff --git a/src/include/platform.h b/src/include/platform.h
new file mode 100644
index 0000000..b17c64f
--- /dev/null
+++ b/src/include/platform.h
@@ -0,0 +1,60 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014, 2015, 2016 GNUnet e.V. and INRIA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Affero General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file include/platform.h
+ * @brief This file contains the includes and definitions which are used by the
+ *        rest of the modules
+ * @author Sree Harsha Totakura <address@hidden>
+ */
+
+#ifndef PLATFORM_H_
+#define PLATFORM_H_
+
+/* Include our configuration header */
+#ifndef HAVE_USED_CONFIG_H
+# define HAVE_USED_CONFIG_H
+# ifdef HAVE_CONFIG_H
+#  include "sync_config.h"
+# endif
+#endif
+
+
+#if (GNUNET_EXTRA_LOGGING >= 1)
+#define VERBOSE(cmd) cmd
+#else
+#define VERBOSE(cmd) do { break; } while (0)
+#endif
+
+/* Include the features available for GNU source */
+#define _GNU_SOURCE
+
+/* Include GNUnet's platform file */
+#include <gnunet/platform.h>
+
+/* Do not use shortcuts for gcrypt mpi */
+#define GCRYPT_NO_MPI_MACROS 1
+
+/* Do not use deprecated functions from gcrypt */
+#define GCRYPT_NO_DEPRECATED 1
+
+/* Ignore MHD deprecations for now as we want to be compatible
+   to "ancient" MHD releases. */
+#define MHD_NO_DEPRECATION 1
+
+#endif  /* PLATFORM_H_ */
+
+/* end of platform.h */
diff --git a/src/include/sync_database_lib.h b/src/include/sync_database_lib.h
new file mode 100644
index 0000000..2a67ec3
--- /dev/null
+++ b/src/include/sync_database_lib.h
@@ -0,0 +1,46 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014-2017 Inria & GNUnet e.V.
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU General Public License as published by the Free Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ *
+ */
+#ifndef SYNC_DB_LIB_H
+#define SYNC_DB_LIB_H
+
+#include <taler/taler_util.h>
+#include "sync_database_plugin.h"
+
+/**
+ * Initialize the plugin.
+ *
+ * @param cfg configuration to use
+ * @return NULL on failure
+ */
+struct SYNC_DatabasePlugin *
+SYNC_DB_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg);
+
+
+/**
+ * Shutdown the plugin.
+ *
+ * @param plugin plugin to unload
+ */
+void
+SYNC_DB_plugin_unload (struct SYNC_DatabasePlugin *plugin);
+
+
+#endif  /* SYNC_DB_LIB_H */
+
+/* end of sync_database_lib.h */
diff --git a/src/include/sync_database_plugin.h 
b/src/include/sync_database_plugin.h
new file mode 100644
index 0000000..5563cf3
--- /dev/null
+++ b/src/include/sync_database_plugin.h
@@ -0,0 +1,117 @@
+/*
+  This file is part of Sync
+  Copyright (C) 2019 Taler Systems SA
+
+  Sync is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Lesser General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  Sync is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  Sync; see the file COPYING.GPL.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file include/sync_database_plugin.h
+ * @brief database access for Sync
+ * @author Christian Grothoff
+ */
+#ifndef TALER_SYNC_DATABASE_PLUGIN_H
+#define TALER_SYNC_DATABASE_PLUGIN_H
+
+#include <gnunet/gnunet_util_lib.h>
+#include <sync_error_codes.h>
+#include "sync_service.h"
+#include <jansson.h>
+#include <taler/taler_util.h>
+
+/**
+ * Handle to interact with the database.
+ *
+ * Functions ending with "_TR" run their OWN transaction scope
+ * and MUST NOT be called from within a transaction setup by the
+ * caller.  Functions ending with "_NT" require the caller to
+ * setup a transaction scope.  Functions without a suffix are
+ * simple, single SQL queries that MAY be used either way.
+ */
+struct SYNC_DatabasePlugin
+{
+
+  /**
+   * Closure for all callbacks.
+   */
+  void *cls;
+
+  /**
+   * Name of the library which generated this plugin.  Set by the
+   * plugin loader.
+   */
+  char *library_name;
+
+  /**
+   * Drop sync tables. Used for testcases.
+   *
+   * @param cls closure
+   * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
+   */
+  int
+  (*drop_tables) (void *cls);
+
+  /**
+   * Function called to perform "garbage collection" on the
+   * database, expiring records we no longer require.  Deletes
+   * all user records that are not paid up (and by cascade deletes
+   * the associated recovery documents). Also deletes expired
+   * truth and financial records older than @a fin_expire.
+   *
+   * @param cls closure
+   * @param fin_expire financial records older than the given
+   *        time stamp should be garbage collected (usual
+   *        values might be something like 6-10 years in the past)
+   * @return transaction status
+   */
+  enum SYNC_DB_QueryStatus
+  (*gc)(void *cls,
+        struct GNUNET_TIME_Absolute fin_expire);
+
+  /**
+  * Do a pre-flight check that we are not in an uncommitted transaction.
+  * If we are, try to commit the previous transaction and output a warning.
+  * Does not return anything, as we will continue regardless of the outcome.
+  *
+  * @param cls the `struct PostgresClosure` with the plugin-specific state
+  */
+  void
+  (*preflight) (void *cls);
+
+  /**
+  * Check that the database connection is still up.
+  *
+  * @param pg connection to check
+  */
+  void
+  (*check_connection) (void *cls);
+
+  /**
+   * Store backup.
+   *
+   * @param cls closure
+   * @return transaction status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*store_backup)(void *cls,
+                  ...);
+
+  /**
+   * Obtain backup.
+   *
+   * @param cls closure
+   */
+  enum GNUNET_DB_QueryStatus
+  (*lookup_backup)(void *cls,
+                   ...);
+
+};
+#endif
diff --git a/src/include/sync_service.h b/src/include/sync_service.h
new file mode 100644
index 0000000..efe46fe
--- /dev/null
+++ b/src/include/sync_service.h
@@ -0,0 +1,64 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2019 Taler Systems SA
+
+  Anastasis is free software; you can redistribute it and/or modify it under 
the
+  terms of the GNU Affero General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
details.
+
+  You should have received a copy of the GNU Lesser General Public License 
along with
+  Anastasis; see the file COPYING.LIB.  If not, see 
<http://www.gnu.org/licenses/>
+*/
+/**
+ * @file include/sync_service.h
+ * @brief C interface of libsync, a C library to use sync's HTTP API
+ * @author Christian Grothoff
+ */
+#ifndef _SYNC_SERVICE_H
+#define _SYNC_SERVICE_H
+
+#include <gnunet/gnunet_curl_lib.h>
+#include <jansson.h>
+
+
+/**
+ * An EdDSA public key that is used to identify a user's account.
+ */
+struct SYNC_AccountPubP
+{
+  struct GNUNET_CRYPTO_EddsaPublicKey pub;
+};
+
+
+struct SYNC_UploadOperation;
+
+struct SYNC_UploadOperation *
+SYNC_upload (struct GNUNET_CURL_Context *ctx,
+             const char *base_url,
+             ...);
+
+
+void
+SYNC_upload_cancel (struct SYNC_UploadOperation *uo);
+
+
+
+struct SYNC_DownloadOperation;
+
+struct SYNC_DownloadOperation *
+SYNC_download (struct GNUNET_CURL_Context *ctx,
+             const char *base_url,
+             ...);
+
+
+void
+SYNC_download_cancel (struct SYNC_DownloadOperation *uo);
+
+
+
+
+#endif  /* _SYNC_SERVICE_H */
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
new file mode 100644
index 0000000..5f05c26
--- /dev/null
+++ b/src/lib/Makefile.am
@@ -0,0 +1,32 @@
+# This Makefile.am is in the public domain
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+if USE_COVERAGE
+  AM_CFLAGS = --coverage -O0
+  XLIB = -lgcov
+endif
+
+lib_LTLIBRARIES = \
+  libsync.la
+
+libsync_la_LDFLAGS = \
+  -version-info 0:0:0 \
+  -no-undefined
+
+libsync_la_SOURCES = \
+  sync_api_upload.c
+
+libsync_la_LIBADD = \
+  -lgnunetcurl \
+  -lgnunetjson \
+  -lgnunetutil \
+  -ljansson \
+  $(XLIB)
+
+if HAVE_LIBCURL
+libsync_la_LIBADD += -lcurl
+else
+if HAVE_LIBGNURL
+libsync_la_LIBADD += -lgnurl
+endif
+endif
diff --git a/src/lib/sync_api_upload.c b/src/lib/sync_api_upload.c
new file mode 100644
index 0000000..353db1a
--- /dev/null
+++ b/src/lib/sync_api_upload.c
@@ -0,0 +1,57 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014-2017 GNUnet e.V. and INRIA
+
+  TALER is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1,
+  or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with TALER; see the file COPYING.LGPL.  If not,
+  see <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file lib/sync_api_upload.c
+ * @brief Implementation of the upload POST
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <curl/curl.h>
+#include <jansson.h>
+#include <microhttpd.h> /* just for HTTP status codes */
+#include <gnunet/gnunet_util_lib.h>
+#include <gnunet/gnunet_curl_lib.h>
+#include "anastasis_service.h"
+
+
+/**
+ * @brief
+ */
+struct SYNC_UploadOperation
+{
+
+  /**
+   * The url for this request.
+   */
+  char *url;
+
+  /**
+   * Handle for the request.
+   */
+  struct GNUNET_CURL_Job *job;
+
+  /**
+   * Reference to the execution context.
+   */
+  struct GNUNET_CURL_Context *ctx;
+
+};
+
+/* end of sync_api_upload.c */
diff --git a/src/sync/Makefile.am b/src/sync/Makefile.am
new file mode 100644
index 0000000..c703348
--- /dev/null
+++ b/src/sync/Makefile.am
@@ -0,0 +1,28 @@
+# This Makefile.am is in the public domain
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+pkgcfgdir = $(prefix)/share/taler/config.d/
+
+pkgcfg_DATA = \
+  sync.conf
+
+bin_PROGRAMS = \
+  sync-httpd
+
+sync_httpd_SOURCES = \
+  sync-httpd.c sync-httpd.h \
+  sync-httpd_parsing.c sync-httpd_parsing.h \
+  sync-httpd_responses.c sync-httpd_responses.h \
+  sync-httpd_mhd.c sync-httpd_mhd.h \
+  sync-httpd_policy.c sync-httpd_policy.h
+
+sync_httpd_LDADD = \
+  $(top_builddir)/src/stasis/libsyncdb.la \
+  -lmicrohttpd \
+  -ljansson \
+  -lgnunetcurl \
+  -lgnunetjson \
+  -lgnunetutil
+
+EXTRA_DIST = \
+  $(pkgcfg_DATA)
diff --git a/src/sync/sync-httpd.c b/src/sync/sync-httpd.c
new file mode 100644
index 0000000..d4f3830
--- /dev/null
+++ b/src/sync/sync-httpd.c
@@ -0,0 +1,744 @@
+/*
+  This file is part of TALER
+  (C) 2019 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Affero General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file backup/sync-httpd.c
+ * @brief HTTP serving layer intended to provide basic backup operations
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <microhttpd.h>
+#include <gnunet/gnunet_util_lib.h>
+#include "sync-httpd_responses.h"
+#include "sync-httpd.h"
+#include "sync-httpd_parsing.h"
+#include "sync-httpd_mhd.h"
+#include "sync_database_lib.h"
+#include "sync-httpd_policy.h"
+
+/**
+ * Backlog for listen operation on unix-domain sockets.
+ */
+#define UNIX_BACKLOG 500
+
+/**
+ * The port we are running on
+ */
+static long long unsigned port;
+
+/**
+ * Should a "Connection: close" header be added to each HTTP response?
+ */
+int TMH_sync_connection_close;
+
+/**
+ * Task running the HTTP server.
+ */
+static struct GNUNET_SCHEDULER_Task *mhd_task;
+
+/**
+ * Global return code
+ */
+static int result;
+
+/**
+ * The MHD Daemon
+ */
+static struct MHD_Daemon *mhd;
+
+/**
+ * Path for the unix domain-socket
+ * to run the daemon on.
+ */
+static char *serve_unixpath;
+
+/**
+ * File mode for unix-domain socket.
+ */
+static mode_t unixpath_mode;
+
+/**
+ * Connection handle to the our database
+ */
+struct sync_DatabasePlugin *db;
+
+
+/**
+ * Return GNUNET_YES if given a valid correlation ID and
+ * GNUNET_NO otherwise.
+ *
+ * @returns GNUNET_YES iff given a valid correlation ID
+ */
+static int
+is_valid_correlation_id (const char *correlation_id)
+{
+  if (strlen (correlation_id) >= 64)
+    return GNUNET_NO;
+  for (int i = 0; i < strlen (correlation_id); i++)
+    if (! (isalnum (correlation_id[i]) ||(correlation_id[i] == '-')))
+      return GNUNET_NO;
+  return GNUNET_YES;
+}
+
+
+/**
+ * A client has requested the given url using the given method
+ * (#MHD_HTTP_METHOD_GET, #MHD_HTTP_METHOD_PUT,
+ * #MHD_HTTP_METHOD_DELETE, #MHD_HTTP_METHOD_POST, etc).  The callback
+ * must call MHD callbacks to provide content to give back to the
+ * client and return an HTTP status code (i.e. #MHD_HTTP_OK,
+ * #MHD_HTTP_NOT_FOUND, etc.).
+ *
+ * @param cls argument given together with the function
+ *        pointer when the handler was registered with MHD
+ * @param url the requested url
+ * @param method the HTTP method used (#MHD_HTTP_METHOD_GET,
+ *        #MHD_HTTP_METHOD_PUT, etc.)
+ * @param version the HTTP version string (i.e.
+ *        #MHD_HTTP_VERSION_1_1)
+ * @param upload_data the data being uploaded (excluding HEADERS,
+ *        for a POST that fits into memory and that is encoded
+ *        with a supported encoding, the POST data will NOT be
+ *        given in upload_data and is instead available as
+ *        part of #MHD_get_connection_values; very large POST
+ *        data *will* be made available incrementally in
+ *        @a upload_data)
+ * @param upload_data_size set initially to the size of the
+ *        @a upload_data provided; the method must update this
+ *        value to the number of bytes NOT processed;
+ * @param con_cls pointer that the callback can set to some
+ *        address and that will be preserved by MHD for future
+ *        calls for this request; since the access handler may
+ *        be called many times (i.e., for a PUT/POST operation
+ *        with plenty of upload data) this allows the application
+ *        to easily associate some request-specific state.
+ *        If necessary, this state can be cleaned up in the
+ *        global #MHD_RequestCompletedCallback (which
+ *        can be set with the #MHD_OPTION_NOTIFY_COMPLETED).
+ *        Initially, `*con_cls` will be NULL.
+ * @return #MHD_YES if the connection was handled successfully,
+ *         #MHD_NO if the socket must be closed due to a serios
+ *         error while handling the request
+ */
+static int
+url_handler (void *cls,
+             struct MHD_Connection *connection,
+             const char *url,
+             const char *method,
+             const char *version,
+             const char *upload_data,
+             size_t *upload_data_size,
+             void **con_cls)
+{
+  static struct TMH_RequestHandler handlers[] = {
+    /* Landing page, tell humans to go away. */
+    { "/", MHD_HTTP_METHOD_GET, "text/plain",
+      "Hello, I'm sync. This HTTP server is not for humans.\n", 0,
+      &TMH_MHD_handler_static_response, MHD_HTTP_OK },
+    { "/agpl", MHD_HTTP_METHOD_GET, "text/plain",
+      NULL, 0,
+      &TMH_MHD_handler_agpl_redirect, MHD_HTTP_FOUND },
+    {NULL, NULL, NULL, NULL, 0, 0 }
+  };
+  static struct TMH_RequestHandler h404 = {
+    "", NULL, "text/html",
+    "<html><title>404: not found</title></html>", 0,
+    &TMH_MHD_handler_static_response, MHD_HTTP_NOT_FOUND
+  };
+
+  struct TM_HandlerContext *hc;
+  struct GNUNET_AsyncScopeId aid;
+  const char *correlation_id = NULL;
+
+  hc = *con_cls;
+
+  if (NULL == hc)
+  {
+    GNUNET_async_scope_fresh (&aid);
+    /* We only read the correlation ID on the first callback for every client 
*/
+    correlation_id = MHD_lookup_connection_value (connection,
+                                                  MHD_HEADER_KIND,
+                                                  "sync-Correlation-Id");
+    if ((NULL != correlation_id) &&
+        (GNUNET_YES != is_valid_correlation_id (correlation_id)))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "illegal incoming correlation ID\n");
+      correlation_id = NULL;
+    }
+  }
+  else
+  {
+    aid = hc->async_scope_id;
+  }
+
+  GNUNET_SCHEDULER_begin_async_scope (&aid);
+
+  if (NULL != correlation_id)
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Handling request for (%s) URL '%s', correlation_id=%s\n",
+                method,
+                url,
+                correlation_id);
+  else
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Handling request (%s) for URL '%s'\n",
+                method,
+                url);
+  if (0 == strncmp (url,
+                    "/backup/",
+                    strlen ("/backup/")))
+    {
+    // return handle_policy (...);
+    if (0 == strcmp (method, MHD_HTTP_METHOD_GET))
+    {
+      return sync_handler_backup_get (connection,
+                                     url,
+                                     con_cls);
+    }
+    if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
+    {
+      return sync_handler_backup_post (connection,
+                                       con_cls,
+                                       url,
+                                       upload_data,
+                                       upload_data_size);
+    }
+  }
+  for (unsigned int i = 0; NULL != handlers[i].url; i++)
+  {
+    struct TMH_RequestHandler *rh = &handlers[i];
+
+    if ( (0 == strcmp (url,
+                       rh->url)) &&
+         ( (NULL == rh->method) ||
+           (0 == strcmp (method,
+                         rh->method)) ) )
+    {
+      int ret;
+
+      ret = rh->handler (rh,
+                         connection,
+                         con_cls,
+                         upload_data,
+                         upload_data_size);
+      hc = *con_cls;
+      if (NULL != hc)
+      {
+        hc->rh = rh;
+        /* Store the async context ID, so we can restore it if
+         * we get another callack for this request. */
+        hc->async_scope_id = aid;
+      }
+      return ret;
+    }
+  }
+  return TMH_MHD_handler_static_response (&h404,
+                                          connection,
+                                          con_cls,
+                                          upload_data,
+                                          upload_data_size);
+}
+
+
+/**
+ * Shutdown task (magically invoked when the application is being
+ * quit)
+ *
+ * @param cls NULL
+ */
+static void
+do_shutdown (void *cls)
+{
+  if (NULL != mhd_task)
+  {
+    GNUNET_SCHEDULER_cancel (mhd_task);
+    mhd_task = NULL;
+  }
+  if (NULL != mhd)
+  {
+    MHD_stop_daemon (mhd);
+    mhd = NULL;
+  }
+  if (NULL != db)
+  {
+    sync_DB_plugin_unload (db);
+    db = NULL;
+  }
+}
+
+
+/**
+ * Function called whenever MHD is done with a request.  If the
+ * request was a POST, we may have stored a `struct Buffer *` in the
+ * @a con_cls that might still need to be cleaned up.  Call the
+ * respective function to free the memory.
+ *
+ * @param cls client-defined closure
+ * @param connection connection handle
+ * @param con_cls value as set by the last call to
+ *        the #MHD_AccessHandlerCallback
+ * @param toe reason for request termination
+ * @see #MHD_OPTION_NOTIFY_COMPLETED
+ * @ingroup request
+ */
+static void
+handle_mhd_completion_callback (void *cls,
+                                struct MHD_Connection *connection,
+                                void **con_cls,
+                                enum MHD_RequestTerminationCode toe)
+{
+  struct TM_HandlerContext *hc = *con_cls;
+
+  if (NULL == hc)
+    return;
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Finished handling request for `%s' with status %d\n",
+              hc->rh->url,
+              (int) toe);
+  hc->cc (hc);
+  *con_cls = NULL;
+}
+
+
+/**
+ * Function that queries MHD's select sets and
+ * starts the task waiting for them.
+ */
+static struct GNUNET_SCHEDULER_Task *
+prepare_daemon (void);
+
+
+/**
+ * Set if we should immediately #MHD_run again.
+ */
+static int triggered;
+
+
+/**
+ * Call MHD to process pending requests and then go back
+ * and schedule the next run.
+ *
+ * @param cls the `struct MHD_Daemon` of the HTTP server to run
+ */
+static void
+run_daemon (void *cls)
+{
+  mhd_task = NULL;
+  do {
+    triggered = 0;
+    GNUNET_assert (MHD_YES == MHD_run (mhd));
+  } while (0 != triggered);
+  mhd_task = prepare_daemon ();
+}
+
+
+/**
+ * Kick MHD to run now, to be called after MHD_resume_connection().
+ * Basically, we need to explicitly resume MHD's event loop whenever
+ * we made progress serving a request.  This function re-schedules
+ * the task processing MHD's activities to run immediately.
+ */
+void
+TMH_trigger_daemon ()
+{
+  if (NULL != mhd_task)
+  {
+    GNUNET_SCHEDULER_cancel (mhd_task);
+    mhd_task = NULL;
+    run_daemon (NULL);
+  }
+  else
+  {
+    triggered = 1;
+  }
+}
+
+
+/**
+ * Function that queries MHD's select sets and
+ * starts the task waiting for them.
+ *
+ * @param daemon_handle HTTP server to prepare to run
+ */
+static struct GNUNET_SCHEDULER_Task *
+prepare_daemon ()
+{
+  struct GNUNET_SCHEDULER_Task *ret;
+  fd_set rs;
+  fd_set ws;
+  fd_set es;
+  struct GNUNET_NETWORK_FDSet *wrs;
+  struct GNUNET_NETWORK_FDSet *wws;
+  int max;
+  MHD_UNSIGNED_LONG_LONG timeout;
+  int haveto;
+  struct GNUNET_TIME_Relative tv;
+
+  FD_ZERO (&rs);
+  FD_ZERO (&ws);
+  FD_ZERO (&es);
+  wrs = GNUNET_NETWORK_fdset_create ();
+  wws = GNUNET_NETWORK_fdset_create ();
+  max = -1;
+  GNUNET_assert (MHD_YES ==
+                 MHD_get_fdset (mhd,
+                                &rs,
+                                &ws,
+                                &es,
+                                &max));
+  haveto = MHD_get_timeout (mhd, &timeout);
+  if (haveto == MHD_YES)
+    tv.rel_value_us = (uint64_t) timeout * 1000LL;
+  else
+    tv = GNUNET_TIME_UNIT_FOREVER_REL;
+  GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1);
+  GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Adding run_daemon select task\n");
+  ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
+                                     tv,
+                                     wrs,
+                                     wws,
+                                     &run_daemon,
+                                     NULL);
+  GNUNET_NETWORK_fdset_destroy (wrs);
+  GNUNET_NETWORK_fdset_destroy (wws);
+  return ret;
+}
+
+
+/**
+ * Main function that will be run by the scheduler.
+ *
+ * @param cls closure
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be
+ *        NULL!)
+ * @param config configuration
+ */
+static void
+run (void *cls,
+     char *const *args,
+     const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *config)
+{
+  int fh;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Starting sync-httpd\n");
+
+  result = GNUNET_SYSERR;
+  GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
+                                 NULL);
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_log_setup ("sync-httpd",
+                                   "WARNING",
+                                   NULL));
+  if (NULL ==
+      (db = sync_DB_plugin_load (config)))
+  {
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+
+  {
+    const char *choices[] = {"tcp",
+                             "unix",
+                             NULL};
+
+    const char *serve_type;
+
+    if (GNUNET_OK !=
+        GNUNET_CONFIGURATION_get_value_choice (config,
+                                               "sync",
+                                               "SERVE",
+                                               choices,
+                                               &serve_type))
+    {
+      GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+                                 "sync",
+                                 "SERVE",
+                                 "serve type required");
+      GNUNET_SCHEDULER_shutdown ();
+      return;
+    }
+
+    if (0 == strcmp (serve_type, "unix"))
+    {
+      struct sockaddr_un *un;
+      char *mode;
+      struct GNUNET_NETWORK_Handle *nh;
+
+      if (GNUNET_OK !=
+          GNUNET_CONFIGURATION_get_value_filename (config,
+                                                   "sync",
+                                                   "unixpath",
+                                                   &serve_unixpath))
+      {
+        GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+                                   "sync",
+                                   "unixpath",
+                                   "unixpath required");
+        GNUNET_SCHEDULER_shutdown ();
+        return;
+      }
+
+      if (strlen (serve_unixpath) >= sizeof (un->sun_path))
+      {
+        fprintf (stderr,
+                 "Invalid configuration: unix path too long\n");
+        GNUNET_SCHEDULER_shutdown ();
+        return;
+      }
+
+      if (GNUNET_OK !=
+          GNUNET_CONFIGURATION_get_value_string (config,
+                                                 "sync",
+                                                 "UNIXPATH_MODE",
+                                                 &mode))
+      {
+        GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+                                   "sync",
+                                   "UNIXPATH_MODE");
+        GNUNET_SCHEDULER_shutdown ();
+        return;
+      }
+      errno = 0;
+      unixpath_mode = (mode_t) strtoul (mode, NULL, 8);
+      if (0 != errno)
+      {
+        GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+                                   "sync",
+                                   "UNIXPATH_MODE",
+                                   "must be octal number");
+        GNUNET_free (mode);
+        GNUNET_SCHEDULER_shutdown ();
+        return;
+      }
+      GNUNET_free (mode);
+
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  "Creating listen socket '%s' with mode %o\n",
+                  serve_unixpath, unixpath_mode);
+
+      if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (serve_unixpath))
+      {
+        GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+                                  "mkdir",
+                                  serve_unixpath);
+      }
+
+      un = GNUNET_new (struct sockaddr_un);
+      un->sun_family = AF_UNIX;
+      strncpy (un->sun_path,
+               serve_unixpath,
+               sizeof (un->sun_path) - 1);
+
+      GNUNET_NETWORK_unix_precheck (un);
+
+      if (NULL == (nh = GNUNET_NETWORK_socket_create (AF_UNIX,
+                                                      SOCK_STREAM,
+                                                      0)))
+      {
+        GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+                             "socket(AF_UNIX)");
+        GNUNET_SCHEDULER_shutdown ();
+        return;
+      }
+      if (GNUNET_OK !=
+          GNUNET_NETWORK_socket_bind (nh,
+                                      (void *) un,
+                                      sizeof (struct sockaddr_un)))
+      {
+        GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+                             "bind(AF_UNIX)");
+        GNUNET_SCHEDULER_shutdown ();
+        return;
+      }
+      if (GNUNET_OK !=
+          GNUNET_NETWORK_socket_listen (nh,
+                                        UNIX_BACKLOG))
+      {
+        GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+                             "listen(AF_UNIX)");
+        GNUNET_SCHEDULER_shutdown ();
+        return;
+      }
+
+      fh = GNUNET_NETWORK_get_fd (nh);
+      GNUNET_NETWORK_socket_free_memory_only_ (nh);
+      if (0 != chmod (serve_unixpath,
+                      unixpath_mode))
+      {
+        GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+                             "chmod");
+        GNUNET_SCHEDULER_shutdown ();
+        return;
+      }
+      port = 0;
+    }
+    else if (0 == strcmp (serve_type, "tcp"))
+    {
+      char *bind_to;
+
+      if (GNUNET_SYSERR ==
+          GNUNET_CONFIGURATION_get_value_number (config,
+                                                 "sync",
+                                                 "PORT",
+                                                 &port))
+      {
+        GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+                                   "sync",
+                                   "PORT");
+        GNUNET_SCHEDULER_shutdown ();
+        return;
+      }
+      if (GNUNET_OK ==
+          GNUNET_CONFIGURATION_get_value_string (config,
+                                                 "sync",
+                                                 "BIND_TO",
+                                                 &bind_to))
+      {
+        char port_str[6];
+        struct addrinfo hints;
+        struct addrinfo *res;
+        int ec;
+        struct GNUNET_NETWORK_Handle *nh;
+
+        GNUNET_snprintf (port_str,
+                         sizeof (port_str),
+                         "%u",
+                         (uint16_t) port);
+        memset (&hints, 0, sizeof (hints));
+        hints.ai_family = AF_UNSPEC;
+        hints.ai_socktype = SOCK_STREAM;
+        hints.ai_protocol = IPPROTO_TCP;
+        hints.ai_flags = AI_PASSIVE
+#ifdef AI_IDN
+                         | AI_IDN
+#endif
+        ;
+        if (0 !=
+            (ec = getaddrinfo (bind_to,
+                               port_str,
+                               &hints,
+                               &res)))
+        {
+          GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                      "Failed to resolve BIND_TO address `%s': %s\n",
+                      bind_to,
+                      gai_strerror (ec));
+          GNUNET_free (bind_to);
+          GNUNET_SCHEDULER_shutdown ();
+          return;
+        }
+        GNUNET_free (bind_to);
+
+        if (NULL == (nh = GNUNET_NETWORK_socket_create (res->ai_family,
+                                                        res->ai_socktype,
+                                                        res->ai_protocol)))
+        {
+          GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+                               "socket");
+          freeaddrinfo (res);
+          GNUNET_SCHEDULER_shutdown ();
+          return;
+        }
+        if (GNUNET_OK !=
+            GNUNET_NETWORK_socket_bind (nh,
+                                        res->ai_addr,
+                                        res->ai_addrlen))
+        {
+          GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+                               "bind");
+          freeaddrinfo (res);
+          GNUNET_SCHEDULER_shutdown ();
+          return;
+        }
+        freeaddrinfo (res);
+        if (GNUNET_OK !=
+            GNUNET_NETWORK_socket_listen (nh,
+                                          UNIX_BACKLOG))
+        {
+          GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+                               "listen");
+          GNUNET_SCHEDULER_shutdown ();
+          return;
+        }
+        fh = GNUNET_NETWORK_get_fd (nh);
+        GNUNET_NETWORK_socket_free_memory_only_ (nh);
+      }
+      else
+      {
+        fh = -1;
+      }
+    }
+    else
+    {
+      // not reached
+      GNUNET_assert (0);
+    }
+  }
+  mhd = MHD_start_daemon (MHD_USE_SUSPEND_RESUME | MHD_USE_DUAL_STACK,
+                          port,
+                          NULL, NULL,
+                          &url_handler, NULL,
+                          MHD_OPTION_LISTEN_SOCKET, fh,
+                          MHD_OPTION_NOTIFY_COMPLETED,
+                          &handle_mhd_completion_callback, NULL,
+                          MHD_OPTION_CONNECTION_TIMEOUT, (unsigned
+                                                          int) 10 /* 10s */,
+                          MHD_OPTION_END);
+  if (NULL == mhd)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to launch HTTP service, exiting.\n");
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  result = GNUNET_OK;
+  mhd_task = prepare_daemon ();
+}
+
+
+/**
+ * The main function of the serve tool
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ * @return 0 ok, 1 on error
+ */
+int
+main (int argc,
+      char *const *argv)
+{
+  struct GNUNET_GETOPT_CommandLineOption options[] = {
+    GNUNET_GETOPT_option_flag ('C',
+                               "connection-close",
+                               "force HTTP connections to be closed after each 
request",
+                               &TMH_sync_connection_close),
+
+    GNUNET_GETOPT_OPTION_END
+  };
+
+  if (GNUNET_OK !=
+      GNUNET_PROGRAM_run (argc, argv,
+                          "sync-httpd",
+                          "sync HTTP interface",
+                          options, &run, NULL))
+    return 3;
+  return (GNUNET_OK == result) ? 0 : 1;
+}
diff --git a/src/sync/sync-httpd.h b/src/sync/sync-httpd.h
new file mode 100644
index 0000000..56ad155
--- /dev/null
+++ b/src/sync/sync-httpd.h
@@ -0,0 +1,148 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2019 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU General Public License as published by the Free Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file sync/sync-httpd.h
+ * @brief HTTP serving layer
+ * @author Christian Grothoff
+ */
+#ifndef sync_HTTPD_H
+#define sync_HTTPD_H
+
+#include "platform.h"
+#include <microhttpd.h>
+#include "sync_database_lib.h"
+
+/**
+ * @brief Struct describing an URL and the handler for it.
+ */
+struct TMH_RequestHandler
+{
+
+  /**
+   * URL the handler is for.
+   */
+  const char *url;
+
+  /**
+   * Method the handler is for, NULL for "all".
+   */
+  const char *method;
+
+  /**
+   * Mime type to use in reply (hint, can be NULL).
+   */
+  const char *mime_type;
+
+  /**
+   * Raw data for the @e handler
+   */
+  const void *data;
+
+  /**
+   * Number of bytes in @e data, 0 for 0-terminated.
+   */
+  size_t data_size;
+
+  /**
+   * Function to call to handle the request.
+   *
+   * @param rh this struct
+   * @param mime_type the @e mime_type for the reply (hint, can be NULL)
+   * @param connection the MHD connection to handle
+   * @param[in,out] connection_cls the connection's closure (can be updated)
+   * @param upload_data upload data
+   * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
+   * @return MHD result code
+   */
+  int (*handler)(struct TMH_RequestHandler *rh,
+                 struct MHD_Connection *connection,
+                 void **connection_cls,
+                 const char *upload_data,
+                 size_t *upload_data_size);
+
+  /**
+   * Default response code.
+   */
+  int response_code;
+};
+
+
+/**
+ * Each MHD response handler that sets the "connection_cls" to a
+ * non-NULL value must use a struct that has this struct as its first
+ * member.  This struct contains a single callback, which will be
+ * invoked to clean up the memory when the contection is completed.
+ */
+struct TM_HandlerContext;
+
+/**
+ * Signature of a function used to clean up the context
+ * we keep in the "connection_cls" of MHD when handling
+ * a request.
+ *
+ * @param hc header of the context to clean up.
+ */
+typedef void
+(*TM_ContextCleanup)(struct TM_HandlerContext *hc);
+
+
+/**
+ * Each MHD response handler that sets the "connection_cls" to a
+ * non-NULL value must use a struct that has this struct as its first
+ * member.  This struct contains a single callback, which will be
+ * invoked to clean up the memory when the connection is completed.
+ */
+struct TM_HandlerContext
+{
+
+  /**
+   * Function to execute the handler-specific cleanup of the
+   * (typically larger) context.
+   */
+  TM_ContextCleanup cc;
+
+  /**
+   * Which request handler is handling this request?
+   */
+  const struct TMH_RequestHandler *rh;
+
+  /**
+   * Asynchronous request context id.
+   */
+  struct GNUNET_AsyncScopeId async_scope_id;
+};
+
+
+/**
+ * Should a "Connection: close" header be added to each HTTP response?
+ */
+extern int TMH_sync_connection_close;
+
+/**
+ * Handle to the database backend.
+ */
+extern struct sync_DatabasePlugin *db;
+
+/**
+ * Kick MHD to run now, to be called after MHD_resume_connection().
+ * Basically, we need to explicitly resume MHD's event loop whenever
+ * we made progress serving a request.  This function re-schedules
+ * the task processing MHD's activities to run immediately.
+ */
+void
+TMH_trigger_daemon (void);
+
+#endif
diff --git a/src/sync/sync-httpd_backup.c b/src/sync/sync-httpd_backup.c
new file mode 100644
index 0000000..86ba955
--- /dev/null
+++ b/src/sync/sync-httpd_backup.c
@@ -0,0 +1,56 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2019 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Affero General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
details.
+
+  You should have received a copy of the GNU Affero General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file sync-httpd_backup.c
+ * @brief functions to handle incoming requests for backups
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "sync-httpd.h"
+#include <gnunet/gnunet_util_lib.h>
+
+/**
+ * @param connection the MHD connection to handle
+ * @param[in,out] connection_cls the connection's closure (can be updated)
+ * @param upload_data upload data
+ * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
+ * @return MHD result code
+ */
+int
+sync_handler_backup_get (struct MHD_Connection *connection,
+                         const char *url,
+                         void **con_cls)
+{
+  return MHD_NO;
+}
+
+
+/**
+ * @param connection the MHD connection to handle
+ * @param[in,out] connection_cls the connection's closure (can be updated)
+ * @param upload_data upload data
+ * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
+ * @return MHD result code
+ */
+int
+sync_handler_backup_post (struct MHD_Connection *connection,
+                          void **con_cls,
+                          const char *url,
+                          const char *upload_data,
+                          size_t *upload_data_size)
+{
+  return MHD_NO;
+}
diff --git a/src/sync/sync-httpd_backup.h b/src/sync/sync-httpd_backup.h
new file mode 100644
index 0000000..1ba7408
--- /dev/null
+++ b/src/sync/sync-httpd_backup.h
@@ -0,0 +1,53 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014, 2015, 2016 GNUnet e.V.
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Affero General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
details.
+
+  You should have received a copy of the GNU Affero General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file sync-httpd_policy.h
+ * @brief functions to handle incoming requests on /backup/
+ * @author Christian Grothoff
+ */
+#ifndef SYNC_HTTPD_BACKUP_H
+#define SYNC_HTTPD_BACKUP_H
+#include <microhttpd.h>
+
+/**
+ * @param connection the MHD connection to handle
+ * @param[in,out] connection_cls the connection's closure (can be updated)
+ * @param upload_data upload data
+ * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
+ * @return MHD result code
+ */
+int
+sync_handler_backup_get (struct MHD_Connection *connection,
+                         const char *url,
+                         void **con_cls);
+
+
+/**
+ * @param connection the MHD connection to handle
+ * @param[in,out] connection_cls the connection's closure (can be updated)
+ * @param upload_data upload data
+ * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
+ * @return MHD result code
+ */
+int
+sync_handler_backup_post (struct MHD_Connection *connection,
+                          void **con_cls,
+                          const char *url,
+                          const char *upload_data,
+                          size_t *upload_data_size);
+
+
+#endif
diff --git a/src/sync/sync-httpd_mhd.c b/src/sync/sync-httpd_mhd.c
new file mode 100644
index 0000000..269316d
--- /dev/null
+++ b/src/sync/sync-httpd_mhd.c
@@ -0,0 +1,156 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014, 2015, 2016 GNUnet e.V. and INRIA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Affero General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
details.
+
+  You should have received a copy of the GNU Affero General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file sync-httpd_mhd.c
+ * @brief helpers for MHD interaction; these are TALER_EXCHANGE_handler_ 
functions
+ *        that generate simple MHD replies that do not require any real 
operations
+ *        to be performed (error handling, static pages, etc.)
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <jansson.h>
+#include "sync-httpd_mhd.h"
+#include "sync-httpd_responses.h"
+
+
+/**
+ * Function to call to handle the request by sending
+ * back static data from the @a rh.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param[in,out] connection_cls the connection's closure (can be updated)
+ * @param upload_data upload data
+ * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
+ * @return MHD result code
+ */
+int
+TMH_MHD_handler_static_response (struct TMH_RequestHandler *rh,
+                                 struct MHD_Connection *connection,
+                                 void **connection_cls,
+                                 const char *upload_data,
+                                 size_t *upload_data_size)
+{
+  struct MHD_Response *response;
+  int ret;
+
+  if (0 == rh->data_size)
+    rh->data_size = strlen ((const char *) rh->data);
+  response = MHD_create_response_from_buffer (rh->data_size,
+                                              (void *) rh->data,
+                                              MHD_RESPMEM_PERSISTENT);
+  if (NULL == response)
+  {
+    GNUNET_break (0);
+    return MHD_NO;
+  }
+  TMH_RESPONSE_add_global_headers (response);
+  if (NULL != rh->mime_type)
+    (void) MHD_add_response_header (response,
+                                    MHD_HTTP_HEADER_CONTENT_TYPE,
+                                    rh->mime_type);
+  ret = MHD_queue_response (connection,
+                            rh->response_code,
+                            response);
+  MHD_destroy_response (response);
+  return ret;
+}
+
+
+/**
+ * Function to call to handle the request by sending
+ * back a redirect to the AGPL source code.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param[in,out] connection_cls the connection's closure (can be updated)
+ * @param upload_data upload data
+ * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
+ * @return MHD result code
+ */
+int
+TMH_MHD_handler_agpl_redirect (struct TMH_RequestHandler *rh,
+                               struct MHD_Connection *connection,
+                               void **connection_cls,
+                               const char *upload_data,
+                               size_t *upload_data_size)
+{
+  const char *agpl =
+    "This server is licensed under the Affero GPL. You will now be redirected 
to the source code.";
+  struct MHD_Response *response;
+  int ret;
+
+  response = MHD_create_response_from_buffer (strlen (agpl),
+                                              (void *) agpl,
+                                              MHD_RESPMEM_PERSISTENT);
+  if (NULL == response)
+  {
+    GNUNET_break (0);
+    return MHD_NO;
+  }
+  TMH_RESPONSE_add_global_headers (response);
+  if (NULL != rh->mime_type)
+    (void) MHD_add_response_header (response,
+                                    MHD_HTTP_HEADER_CONTENT_TYPE,
+                                    rh->mime_type);
+  if (MHD_NO ==
+      MHD_add_response_header (response,
+                               MHD_HTTP_HEADER_LOCATION,
+                               "http://www.git.taler.net/sync.git";))
+  {
+    GNUNET_break (0);
+    ret = MHD_NO;
+  }
+  else
+  {
+    ret = MHD_queue_response (connection,
+                              rh->response_code,
+                              response);
+  }
+  MHD_destroy_response (response);
+  return ret;
+}
+
+
+/**
+ * Function to call to handle the request by building a JSON
+ * reply with an error message from @a rh.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param[in,out] connection_cls the connection's closure (can be updated)
+ * @param upload_data upload data
+ * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
+ * @return MHD result code
+ */
+int
+TMH_MHD_handler_send_json_pack_error (struct TMH_RequestHandler *rh,
+                                      struct MHD_Connection *connection,
+                                      void **connection_cls,
+                                      const char *upload_data,
+                                      size_t *upload_data_size)
+{
+  return TMH_RESPONSE_reply_json_pack (connection,
+                                       rh->response_code,
+                                       "{s:s}",
+                                       "error",
+                                       rh->data);
+}
+
+
+/* end of taler-exchange-httpd_mhd.c */
diff --git a/src/sync/sync-httpd_mhd.h b/src/sync/sync-httpd_mhd.h
new file mode 100644
index 0000000..b157baa
--- /dev/null
+++ b/src/sync/sync-httpd_mhd.h
@@ -0,0 +1,113 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014, 2015 GNUnet e.V. and INRIA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Affero General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
details.
+
+  You should have received a copy of the GNU Affero General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file sync-httpd_mhd.h
+ * @brief helpers for MHD interaction, used to generate simple responses
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Christian Grothoff
+ */
+#ifndef sync_HTTPD_MHD_H
+#define sync_HTTPD_MHD_H
+#include <gnunet/gnunet_util_lib.h>
+#include <microhttpd.h>
+#include "sync-httpd.h"
+
+
+/**
+ * Function to call to handle the request by sending
+ * back static data from the @a rh.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param[in,out] connection_cls the connection's closure (can be updated)
+ * @param upload_data upload data
+ * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
+ * @param mi merchant backend instance, NULL is allowed in this case!
+ * @return MHD result code
+ */
+int
+TMH_MHD_handler_static_response (struct TMH_RequestHandler *rh,
+                                 struct MHD_Connection *connection,
+                                 void **connection_cls,
+                                 const char *upload_data,
+                                 size_t *upload_data_size);
+
+
+/**
+ * Function to call to handle the request by sending
+ * back a redirect to the AGPL source code.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param[in,out] connection_cls the connection's closure (can be updated)
+ * @param upload_data upload data
+ * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
+ * @param mi merchant backend instance, never NULL
+ * @return MHD result code
+ */
+int
+TMH_MHD_handler_agpl_redirect (struct TMH_RequestHandler *rh,
+                               struct MHD_Connection *connection,
+                               void **connection_cls,
+                               const char *upload_data,
+                               size_t *upload_data_size);
+
+
+/**
+ * Function to call to handle the request by building a JSON
+ * reply from varargs.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param[in,out] connection_cls the connection's closure (can be updated)
+ * @param response_code HTTP response code to use
+ * @param do_cache can the response be cached? (0: no, 1: yes)
+ * @param fmt format string for pack
+ * @param ... varargs
+ * @return MHD result code
+ */
+int
+TMH_MHD_helper_send_json_pack (struct TMH_RequestHandler *rh,
+                               struct MHD_Connection *connection,
+                               void *connection_cls,
+                               int response_code,
+                               int do_cache,
+                               const char *fmt,
+                               ...);
+
+
+/**
+ * Function to call to handle the request by building a JSON
+ * reply with an error message from @a rh.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param[in,out] connection_cls the connection's closure (can be updated)
+ * @param upload_data upload data
+ * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
+ * @return MHD result code
+ */
+int
+TMH_MHD_handler_send_json_pack_error (struct TMH_RequestHandler *rh,
+                                      struct MHD_Connection *connection,
+                                      void **connection_cls,
+                                      const char *upload_data,
+                                      size_t *upload_data_size);
+
+
+#endif
diff --git a/src/sync/sync-httpd_parsing.c b/src/sync/sync-httpd_parsing.c
new file mode 100644
index 0000000..49d9f97
--- /dev/null
+++ b/src/sync/sync-httpd_parsing.c
@@ -0,0 +1,272 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014, 2015, 2016 GNUnet e.V.
+
+  TALER is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Affero General Public License as
+  published by the Free Software Foundation; either version 3,
+  or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU Affero General Public License for more details.
+
+  You should have received a copy of the GNU Affero General Public
+  License along with TALER; see the file COPYING.  If not,
+  see <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file sync-httpd_parsing.c
+ * @brief functions to parse incoming requests
+ *        (MHD arguments and JSON snippets)
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <taler/taler_json_lib.h>
+#include "sync-httpd_parsing.h"
+#include "sync-httpd_responses.h"
+
+/* FIXME: de-duplicate code with taler-exchange-httpd_parsing.c
+   and taler-exchange-httpd_response.c */
+
+/**
+ * Initial size for POST request buffer.
+ */
+#define REQUEST_BUFFER_INITIAL (2 * 1024)
+
+/**
+ * Maximum POST request size.
+ */
+#define REQUEST_BUFFER_MAX (1024 * 1024)
+
+
+/**
+ * Buffer for POST requests.
+ */
+struct Buffer
+{
+  /**
+   * Allocated memory
+   */
+  char *data;
+
+  /**
+   * Number of valid bytes in buffer.
+   */
+  size_t fill;
+
+  /**
+   * Number of allocated bytes in buffer.
+   */
+  size_t alloc;
+};
+
+
+
+
+/**
+ * Free the data in a buffer.  Does *not* free
+ * the buffer object itself.
+ *
+ * @param buf buffer to de-initialize
+ */
+static void
+buffer_deinit (struct Buffer *buf)
+{
+  GNUNET_free_non_null (buf->data);
+  buf->data = NULL;
+}
+
+
+
+/**
+ * Function called whenever we are done with a request
+ * to clean up our state.
+ *
+ * @param con_cls value as it was left by
+ *        #TMH_PARSE_post_json(), to be cleaned up
+ */
+void
+TMH_PARSE_post_cleanup_callback (void *con_cls)
+{
+  struct Buffer *r = con_cls;
+
+  if (NULL != r)
+  {
+    buffer_deinit (r);
+    GNUNET_free (r);
+  }
+}
+
+
+/**
+ * Process a POST request containing a JSON object.  This function
+ * realizes an MHD POST processor that will (incrementally) process
+ * JSON data uploaded to the HTTP server.  It will store the
+ * required state in the @a con_cls, which must be cleaned up
+ * using #TMH_PARSE_post_cleanup_callback().
+ *
+ * @param connection the MHD connection
+ * @param con_cls the closure (points to a `struct Buffer *`)
+ * @param upload_data the POST data
+ * @param upload_data_size number of bytes in @a upload_data
+ * @param json the JSON object for a completed request
+ * @return
+ *    #GNUNET_YES if json object was parsed or at least
+ *               may be parsed in the future (call again);
+ *               `*json` will be NULL if we need to be called again,
+ *                and non-NULL if we are done.
+ *    #GNUNET_NO if request is incomplete or invalid
+ *               (error message was generated)
+ *    #GNUNET_SYSERR on internal error
+ *               (we could not even queue an error message,
+ *                close HTTP session with MHD_NO)
+ */
+int
+TMH_PARSE_post_json (struct MHD_Connection *connection,
+                     void **con_cls,
+                     const char *upload_data,
+                     size_t *upload_data_size,
+                     json_t **json)
+{
+  enum GNUNET_JSON_PostResult pr;
+
+  pr = GNUNET_JSON_post_parser (REQUEST_BUFFER_MAX,
+                                connection,
+                                con_cls,
+                                upload_data,
+                                upload_data_size,
+                                json);
+  switch (pr)
+  {
+
+  case GNUNET_JSON_PR_OUT_OF_MEMORY:
+    return (MHD_NO == TMH_RESPONSE_reply_internal_error
+              (connection,
+              TALER_EC_PARSER_OUT_OF_MEMORY,
+              "out of memory")) ? GNUNET_SYSERR : GNUNET_NO;
+
+  case GNUNET_JSON_PR_CONTINUE:
+    return GNUNET_YES;
+
+  case GNUNET_JSON_PR_REQUEST_TOO_LARGE:
+    return (MHD_NO == TMH_RESPONSE_reply_request_too_large
+              (connection)) ? GNUNET_SYSERR : GNUNET_NO;
+
+  case GNUNET_JSON_PR_JSON_INVALID:
+    return (MHD_YES ==
+            TMH_RESPONSE_reply_invalid_json (connection))
+           ? GNUNET_NO : GNUNET_SYSERR;
+  case GNUNET_JSON_PR_SUCCESS:
+    GNUNET_break (NULL != *json);
+    return GNUNET_YES;
+  }
+  /* this should never happen */
+  GNUNET_break (0);
+  return GNUNET_SYSERR;
+}
+
+
+/**
+ * Parse JSON object into components based on the given field
+ * specification.
+ *
+ * @param connection the connection to send an error response to
+ * @param root the JSON node to start the navigation at.
+ * @param spec field specification for the parser
+ * @return
+ *    #GNUNET_YES if navigation was successful (caller is responsible
+ *                for freeing allocated variable-size data using
+ *                #GNUNET_JSON_parse_free() when done)
+ *    #GNUNET_NO if json is malformed, error response was generated
+ *    #GNUNET_SYSERR on internal error
+ */
+int
+TMH_PARSE_json_data (struct MHD_Connection *connection,
+                     const json_t *root,
+                     struct GNUNET_JSON_Specification *spec)
+{
+  int ret;
+  const char *error_json_name;
+  unsigned int error_line;
+
+  ret = GNUNET_JSON_parse (root,
+                           spec,
+                           &error_json_name,
+                           &error_line);
+  if (GNUNET_SYSERR == ret)
+  {
+    if (NULL == error_json_name)
+      error_json_name = "<no field>";
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Parsing failed due to field '%s'\n",
+                error_json_name);
+    ret = (MHD_YES ==
+           TMH_RESPONSE_reply_json_pack (connection,
+                                         MHD_HTTP_BAD_REQUEST,
+                                         "{s:s, s:s, s:I}",
+                                         "error", "parse error",
+                                         "field", error_json_name,
+                                         "line", (json_int_t) error_line))
+          ? GNUNET_NO : GNUNET_SYSERR;
+    return ret;
+  }
+  return GNUNET_YES;
+}
+
+
+
+/**
+ * Extract base32crockford encoded data from request.
+ *
+ * Queues an error response to the connection if the parameter is
+ * missing or invalid.
+ *
+ * @param connection the MHD connection
+ * @param param_name the name of the parameter with the key
+ * @param[out] out_data pointer to store the result
+ * @param out_size expected size of data
+ * @return
+ *   #GNUNET_YES if the the argument is present
+ *   #GNUNET_NO if the argument is absent or malformed
+ *   #GNUNET_SYSERR on internal error (error response could not be sent)
+ */
+int
+TMH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
+                                const char *param_name,
+                                void *out_data,
+                                size_t out_size)
+{
+  const char *str;
+
+  str = MHD_lookup_connection_value (connection,
+                                     MHD_GET_ARGUMENT_KIND,
+                                     param_name);
+  if (NULL == str)
+  {
+    return (MHD_NO ==
+            TMH_RESPONSE_reply_arg_missing (connection,
+                                            TALER_EC_PARAMETER_MISSING,
+                                            param_name))
+           ? GNUNET_SYSERR : GNUNET_NO;
+  }
+  if (GNUNET_OK !=
+      GNUNET_STRINGS_string_to_data (str,
+                                     strlen (str),
+                                     out_data,
+                                     out_size))
+    return (MHD_NO ==
+            TMH_RESPONSE_reply_arg_invalid (connection,
+                                            TALER_EC_PARAMETER_MALFORMED,
+                                            param_name))
+           ? GNUNET_SYSERR : GNUNET_NO;
+  return GNUNET_OK;
+}
+
+
+/* end of taler-merchant-httpd_parsing.c */
diff --git a/src/sync/sync-httpd_parsing.h b/src/sync/sync-httpd_parsing.h
new file mode 100644
index 0000000..b3c11cd
--- /dev/null
+++ b/src/sync/sync-httpd_parsing.h
@@ -0,0 +1,93 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014, 2015, 2016 GNUnet e.V.
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Affero General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
details.
+
+  You should have received a copy of the GNU Affero General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file sync-httpd_parsing.h
+ * @brief functions to parse incoming requests
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Christian Grothoff
+ */
+#ifndef sync_HTTPD_PARSING_H
+#define sync_HTTPD_PARSING_H
+
+#include <microhttpd.h>
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+
+/**
+ * Process a POST request containing a JSON object.  This
+ * function realizes an MHD POST processor that will
+ * (incrementally) process JSON data uploaded to the HTTP
+ * server.  It will store the required state in the
+ * "connection_cls", which must be cleaned up using
+ * #TMH_PARSE_post_cleanup_callback().
+ *
+ * @param connection the MHD connection
+ * @param con_cls the closure (points to a `struct Buffer *`)
+ * @param upload_data the POST data
+ * @param upload_data_size number of bytes in @a upload_data
+ * @param json the JSON object for a completed request
+ * @return
+ *    #GNUNET_YES if json object was parsed or at least
+ *               may be parsed in the future (call again);
+ *               `*json` will be NULL if we need to be called again,
+ *                and non-NULL if we are done.
+ *    #GNUNET_NO is request incomplete or invalid
+ *               (error message was generated)
+ *    #GNUNET_SYSERR on internal error
+ *               (we could not even queue an error message,
+ *                close HTTP session with MHD_NO)
+ */
+int
+TMH_PARSE_post_json (struct MHD_Connection *connection,
+                     void **con_cls,
+                     const char *upload_data,
+                     size_t *upload_data_size,
+                     json_t **json);
+
+
+/**
+ * Function called whenever we are done with a request
+ * to clean up our state.
+ *
+ * @param con_cls value as it was left by
+ *        #TMH_PARSE_post_json(), to be cleaned up
+ */
+void
+TMH_PARSE_post_cleanup_callback (void *con_cls);
+
+
+/**
+ * Parse JSON object into components based on the given field
+ * specification.
+ *
+ * @param connection the connection to send an error response to
+ * @param root the JSON node to start the navigation at.
+ * @param spec field specification for the parser
+ * @return
+ *    #GNUNET_YES if navigation was successful (caller is responsible
+ *                for freeing allocated variable-size data using
+ *                #GNUNET_JSON_parse_free() when done)
+ *    #GNUNET_NO if json is malformed, error response was generated
+ *    #GNUNET_SYSERR on internal error
+ */
+int
+TMH_PARSE_json_data (struct MHD_Connection *connection,
+                     const json_t *root,
+                     struct GNUNET_JSON_Specification *spec);
+
+
+#endif /* TALER_MERCHANT_HTTPD_PARSING_H */
diff --git a/src/sync/sync-httpd_responses.c b/src/sync/sync-httpd_responses.c
new file mode 100644
index 0000000..6a95555
--- /dev/null
+++ b/src/sync/sync-httpd_responses.c
@@ -0,0 +1,408 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014-2017 GNUnet e.V.
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Affero General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
details.
+
+  You should have received a copy of the GNU Affero General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file sync-httpd_responses.c
+ * @brief API for generating the various replies of the exchange; these
+ *        functions are called TMH_RESPONSE_reply_ and they generate
+ *        and queue MHD response objects for a given connection.
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "sync-httpd.h"
+#include "sync-httpd_responses.h"
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include <gnunet/gnunet_util_lib.h>
+
+
+/**
+ * Make JSON response object.
+ *
+ * @param json the json object
+ * @return MHD response object
+ */
+struct MHD_Response *
+TMH_RESPONSE_make_json (const json_t *json)
+{
+  struct MHD_Response *resp;
+  char *json_str;
+
+  json_str = json_dumps (json,
+                         JSON_INDENT (2));
+  if (NULL == json_str)
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+  resp = MHD_create_response_from_buffer (strlen (json_str),
+                                          json_str,
+                                          MHD_RESPMEM_MUST_FREE);
+  if (NULL == resp)
+  {
+    free (json_str);
+    GNUNET_break (0);
+    return NULL;
+  }
+  GNUNET_break (MHD_YES ==
+                MHD_add_response_header (resp,
+                                         MHD_HTTP_HEADER_CONTENT_TYPE,
+                                         "application/json"));
+  return resp;
+}
+
+
+/**
+ * Send JSON object as response.
+ *
+ * @param connection the MHD connection
+ * @param json the json object
+ * @param response_code the http response code
+ * @return MHD result code
+ */
+int
+TMH_RESPONSE_reply_json (struct MHD_Connection *connection,
+                         const json_t *json,
+                         unsigned int response_code)
+{
+  struct MHD_Response *resp;
+  int ret;
+
+  resp = TMH_RESPONSE_make_json (json);
+  if (NULL == resp)
+    return MHD_NO;
+  ret = MHD_queue_response (connection,
+                            response_code,
+                            resp);
+  MHD_destroy_response (resp);
+  return ret;
+}
+
+
+/**
+ * Make JSON response object.
+ *
+ * @param fmt format string for pack
+ * @param ... varargs
+ * @return MHD response object
+ */
+struct MHD_Response *
+TMH_RESPONSE_make_json_pack (const char *fmt,
+                             ...)
+{
+  json_t *json;
+  va_list argp;
+  struct MHD_Response *ret;
+  json_error_t jerror;
+
+  va_start (argp, fmt);
+  json = json_vpack_ex (&jerror,
+                        0,
+                        fmt,
+                        argp);
+  va_end (argp);
+  if (NULL == json)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to pack JSON with format `%s': %s\n",
+                fmt,
+                jerror.text);
+    GNUNET_break (0);
+    return MHD_NO;
+  }
+  ret = TMH_RESPONSE_make_json (json);
+  json_decref (json);
+  return ret;
+}
+
+
+/**
+ * Function to call to handle the request by building a JSON
+ * reply from a format string and varargs.
+ *
+ * @param connection the MHD connection to handle
+ * @param response_code HTTP response code to use
+ * @param fmt format string for pack
+ * @param ... varargs
+ * @return MHD result code
+ */
+int
+TMH_RESPONSE_reply_json_pack (struct MHD_Connection *connection,
+                              unsigned int response_code,
+                              const char *fmt,
+                              ...)
+{
+  json_t *json;
+  va_list argp;
+  int ret;
+  json_error_t jerror;
+
+  va_start (argp, fmt);
+  json = json_vpack_ex (&jerror,
+                        0,
+                        fmt,
+                        argp);
+  va_end (argp);
+  if (NULL == json)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to pack JSON with format `%s': %s\n",
+                fmt,
+                jerror.text);
+    GNUNET_break (0);
+    return MHD_NO;
+  }
+  ret = TMH_RESPONSE_reply_json (connection,
+                                 json,
+                                 response_code);
+  json_decref (json);
+  return ret;
+}
+
+
+/**
+ * Create a response indicating an internal error.
+ *
+ * @param ec error code to return
+ * @param hint hint about the internal error's nature
+ * @return a MHD response object
+ */
+struct MHD_Response *
+TMH_RESPONSE_make_error (enum TALER_ErrorCode ec,
+                         const char *hint)
+{
+  return TMH_RESPONSE_make_json_pack ("{s:I, s:s}",
+                                      "code", (json_int_t) ec,
+                                      "hint", hint);
+}
+
+
+/**
+ * Send a response indicating an internal error.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code to return
+ * @param hint hint about the internal error's nature
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
+                                   enum TALER_ErrorCode ec,
+                                   const char *hint)
+{
+  return TMH_RESPONSE_reply_json_pack (connection,
+                                       MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                       "{s:I, s:s}",
+                                       "code", (json_int_t) ec,
+                                       "hint", hint);
+}
+
+
+/**
+ * Send a response indicating that the request was too big.
+ *
+ * @param connection the MHD connection to use
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_request_too_large (struct MHD_Connection *connection)
+{
+  struct MHD_Response *resp;
+  int ret;
+
+  resp = MHD_create_response_from_buffer (0,
+                                          NULL,
+                                          MHD_RESPMEM_PERSISTENT);
+  if (NULL == resp)
+    return MHD_NO;
+  ret = MHD_queue_response (connection,
+                            MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
+                            resp);
+  MHD_destroy_response (resp);
+  return ret;
+}
+
+
+/**
+ * Send a response indicating that we did not find the @a object
+ * needed for the reply.
+ *
+ * @param connection the MHD connection to use
+ * @param response_code response code to use
+ * @param ec error code to return
+ * @param msg human-readable diagnostic
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_rc (struct MHD_Connection *connection,
+                       unsigned int response_code,
+                       enum TALER_ErrorCode ec,
+                       const char *msg)
+{
+  return TMH_RESPONSE_reply_json_pack (connection,
+                                       response_code,
+                                       "{s:I, s:s}",
+                                       "code", (json_int_t) ec,
+                                       "error", msg);
+}
+
+
+/**
+ * Send a response indicating that the JSON was malformed.
+ *
+ * @param connection the MHD connection to use
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection)
+{
+  return TMH_RESPONSE_reply_json_pack (connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       "{s:I, s:s}",
+                                       "code",
+                                       (json_int_t) TALER_EC_JSON_INVALID,
+                                       "error", "invalid json");
+}
+
+
+/**
+ * Send a response indicating that we did not find the @a object
+ * needed for the reply.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code to return
+ * @param object name of the object we did not find
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_not_found (struct MHD_Connection *connection,
+                              enum TALER_ErrorCode ec,
+                              const char *object)
+{
+  return TMH_RESPONSE_reply_json_pack (connection,
+                                       MHD_HTTP_NOT_FOUND,
+                                       "{s:I, s:s}",
+                                       "code", (json_int_t) ec,
+                                       "error", object);
+}
+
+
+/**
+ * Send a response indicating that the request was malformed.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code to return
+ * @param issue description of what was wrong with the request
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_bad_request (struct MHD_Connection *connection,
+                                enum TALER_ErrorCode ec,
+                                const char *issue)
+{
+  return TMH_RESPONSE_reply_json_pack (connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       "{s:I, s:s}",
+                                       "code", (json_int_t) ec,
+                                       "error", issue);
+}
+
+
+/**
+ * Add headers we want to return in every response.
+ * Useful for testing, like if we want to always close
+ * connections.
+ *
+ * @param response response to modify
+ */
+void
+TMH_RESPONSE_add_global_headers (struct MHD_Response *response)
+{
+  if (TMH_sync_connection_close)
+    GNUNET_break (MHD_YES ==
+                  MHD_add_response_header (response,
+                                           MHD_HTTP_HEADER_CONNECTION,
+                                           "close"));
+}
+
+
+/**
+ * Send a response indicating an external error.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code to return
+ * @param hint hint about the error's nature
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
+                                   enum TALER_ErrorCode ec,
+                                   const char *hint)
+{
+  return TMH_RESPONSE_reply_json_pack (connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       "{s:I, s:s}",
+                                       "code", (json_int_t) ec,
+                                       "hint", hint);
+}
+
+
+/**
+ * Send a response indicating a missing argument.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code to return
+ * @param param_name the parameter that is missing
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
+                                enum TALER_ErrorCode ec,
+                                const char *param_name)
+{
+  return TMH_RESPONSE_reply_json_pack (connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       "{s:s, s:I, s:s}",
+                                       "error", "missing parameter",
+                                       "code", (json_int_t) ec,
+                                       "parameter", param_name);
+}
+
+
+/**
+ * Send a response indicating an invalid argument.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code to return
+ * @param param_name the parameter that is invalid
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
+                                enum TALER_ErrorCode ec,
+                                const char *param_name)
+{
+  return TMH_RESPONSE_reply_json_pack (connection,
+                                       MHD_HTTP_BAD_REQUEST,
+                                       "{s:s, s:I, s:s}",
+                                       "error", "invalid parameter",
+                                       "code", (json_int_t) ec,
+                                       "parameter", param_name);
+}
+
+
+/* end of taler-exchange-httpd_responses.c */
diff --git a/src/sync/sync-httpd_responses.h b/src/sync/sync-httpd_responses.h
new file mode 100644
index 0000000..a98ba0d
--- /dev/null
+++ b/src/sync/sync-httpd_responses.h
@@ -0,0 +1,244 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014-2017 GNUnet e.V.
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Affero General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
details.
+
+  You should have received a copy of the GNU Affero General Public License 
along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file sync-httpd_responses.h
+ * @brief API for generating the various replies of the exchange; these
+ *        functions are called TMH_RESPONSE_reply_ and they generate
+ *        and queue MHD response objects for a given connection.
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Christian Grothoff
+ */
+#ifndef sync_HTTPD_RESPONSES_H
+#define sync_HTTPD_RESPONSES_H
+#include "sync-httpd.h"
+#include <taler/taler_util.h>
+#include <taler/taler_json_lib.h>
+#include <gnunet/gnunet_util_lib.h>
+
+
+
+/**
+ * Make JSON response object.
+ *
+ * @param json the json object
+ * @return MHD response object
+ */
+struct MHD_Response *
+TMH_RESPONSE_make_json (const json_t *json);
+
+
+/**
+ * Send JSON object as response.
+ *
+ * @param connection the MHD connection
+ * @param json the json object
+ * @param response_code the http response code
+ * @return MHD result code
+ */
+int
+TMH_RESPONSE_reply_json (struct MHD_Connection *connection,
+                         const json_t *json,
+                         unsigned int response_code);
+
+
+/**
+ * Make JSON response object.
+ *
+ * @param fmt format string for pack
+ * @param ... varargs
+ * @return MHD response object
+ */
+struct MHD_Response *
+TMH_RESPONSE_make_json_pack (const char *fmt,
+                             ...);
+
+
+
+
+/**
+ * Function to call to handle the request by building a JSON
+ * reply from a format string and varargs.
+ *
+ * @param connection the MHD connection to handle
+ * @param response_code HTTP response code to use
+ * @param fmt format string for pack
+ * @param ... varargs
+ * @return MHD result code
+ */
+int
+TMH_RESPONSE_reply_json_pack (struct MHD_Connection *connection,
+                              unsigned int response_code,
+                              const char *fmt,
+                              ...);
+
+
+/**
+ * Create a response indicating an internal error.
+ *
+ * @param ec error code to return
+ * @param hint hint about the internal error's nature
+ * @return a MHD response object
+ */
+struct MHD_Response *
+TMH_RESPONSE_make_error (enum TALER_ErrorCode ec,
+                         const char *hint);
+
+
+/**
+ * Send a response indicating an internal error.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code to return
+ * @param hint hint about the internal error's nature
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
+                                   enum TALER_ErrorCode ec,
+                                   const char *hint);
+
+
+
+
+/**
+ * Send a response indicating that the request was too big.
+ *
+ * @param connection the MHD connection to use
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_request_too_large (struct MHD_Connection *connection);
+
+
+
+/**
+ * Send a response indicating that we did not find the @a object
+ * needed for the reply.
+ *
+ * @param connection the MHD connection to use
+ * @param response_code response code to use
+ * @param ec error code to return
+ * @param msg human-readable diagnostic
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_rc (struct MHD_Connection *connection,
+                       unsigned int response_code,
+                       enum TALER_ErrorCode ec,
+                       const char *msg);
+
+
+
+/**
+ * Send a response indicating that the JSON was malformed.
+ *
+ * @param connection the MHD connection to use
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection);
+
+
+
+/**
+ * Send a response indicating that we did not find the @a object
+ * needed for the reply.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code to return
+ * @param object name of the object we did not find
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_not_found (struct MHD_Connection *connection,
+                              enum TALER_ErrorCode ec,
+                              const char *object);
+
+
+
+/**
+ * Send a response indicating that the request was malformed.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code to return
+ * @param issue description of what was wrong with the request
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_bad_request (struct MHD_Connection *connection,
+                                enum TALER_ErrorCode ec,
+                                const char *issue);
+
+
+
+
+/**
+ * Add headers we want to return in every response.
+ * Useful for testing, like if we want to always close
+ * connections.
+ *
+ * @param response response to modify
+ */
+void
+TMH_RESPONSE_add_global_headers (struct MHD_Response *response);
+
+
+
+/**
+ * Send a response indicating an external error.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code to return
+ * @param hint hint about the error's nature
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
+                                   enum TALER_ErrorCode ec,
+                                   const char *hint);
+
+
+
+
+/**
+ * Send a response indicating a missing argument.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code to return
+ * @param param_name the parameter that is missing
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
+                                enum TALER_ErrorCode ec,
+                                const char *param_name);
+
+
+/**
+ * Send a response indicating an invalid argument.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code to return
+ * @param param_name the parameter that is invalid
+ * @return a MHD result code
+ */
+int
+TMH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
+                                enum TALER_ErrorCode ec,
+                                const char *param_name);
+
+#endif
diff --git a/src/sync/sync.conf b/src/sync/sync.conf
new file mode 100644
index 0000000..9425c22
--- /dev/null
+++ b/src/sync/sync.conf
@@ -0,0 +1,31 @@
+# This file is in the public domain.
+
+# These are default/sample settings for a merchant backend.
+
+
+# General settings for the backend.
+[sync]
+
+# Use TCP or UNIX domain sockets?
+SERVE = tcp
+
+# Which HTTP port does the backend listen on?  Only used if "SERVE" is 'tcp'.
+PORT = 9966
+
+# Which IP address should we bind to? i.e. 127.0.0.1 or ::1 for loopback.
+# Can also be given as a hostname.  We will bind to the wildcard (dual-stack)
+# if left empty.  Only used if "SERVE" is 'tcp'.
+# BIND_TO =
+
+
+# Which unix domain path should we bind to? Only used if "SERVE" is 'unix'.
+UNIXPATH = ${sync_RUNTIME_DIR}/backend.http
+# What should be the file access permissions (see chmod) for "UNIXPATH"?
+UNIXPATH_MODE = 660
+
+# Which database backend do we use?
+DB = postgres
+
+# Configuration for postgres database.
+[syncdb-postgres]
+CONFIG = postgres:///sync
diff --git a/src/syncdb/Makefile.am b/src/syncdb/Makefile.am
new file mode 100644
index 0000000..56db964
--- /dev/null
+++ b/src/syncdb/Makefile.am
@@ -0,0 +1,62 @@
+# This Makefile.am is in the public domain
+AM_CPPFLAGS = -I$(top_srcdir)/src/include
+
+plugindir = $(libdir)/taler
+
+if HAVE_POSTGRESQL
+if HAVE_GNUNETPQ
+plugin_LTLIBRARIES = \
+  libsync_plugin_db_postgres.la
+endif
+endif
+
+if USE_COVERAGE
+  AM_CFLAGS = --coverage -O0
+  XLIB = -lgcov
+endif
+
+lib_LTLIBRARIES = \
+  libsyncdb.la
+
+libsyncdb_la_SOURCES = \
+  sync_db_plugin.c
+
+libsyncdb_la_LIBADD = \
+  -lgnunetpq \
+  -lpq \
+  -lgnunetutil
+libsyncdb_la_LDFLAGS = \
+   $(POSTGRESQL_LDFLAGS) \
+   -version-info 2:0:0 \
+   -no-undefined
+
+libsync_plugin_db_postgres_la_SOURCES = \
+  plugin_sync_postgres.c
+libsync_plugin_db_postgres_la_LIBADD = \
+  $(LTLIBINTL)
+libsync_plugin_db_postgres_la_LDFLAGS = \
+  $(TALER_PLUGIN_LDFLAGS) \
+  -lgnunetpq \
+  -lpq \
+  -ltalerpq \
+  -lgnunetutil $(XLIB)
+
+check_PROGRAMS = \
+ $(TESTS)
+
+test_sync_db_postgres_SOURCES = \
+  test_sync_db.c
+test_sync_db_postgres_LDFLAGS = \
+  $(top_builddir)/src/util/libsyncutil.la \
+  libsyncdb.la \
+  -lgnunetutil \
+  -lgnunetpq \
+  -ltalerutil \
+  -ltalerpq \
+  -luuid
+
+TESTS = \
+  test_sync_db-postgres
+
+EXTRA_DIST = \
+  test_sync_db_postgres.conf
diff --git a/src/syncdb/plugin_sync_postgres.c 
b/src/syncdb/plugin_sync_postgres.c
new file mode 100644
index 0000000..4e63198
--- /dev/null
+++ b/src/syncdb/plugin_sync_postgres.c
@@ -0,0 +1,284 @@
+/*
+  This file is part of TALER
+  (C) 2014--2019 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Lesser General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of ANASTASISABILITY or FITNESS 
FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file sync/plugin_syncdb_postgres.c
+ * @brief database helper functions for postgres used by the sync
+ * @author Sree Harsha Totakura <address@hidden>
+ * @author Christian Grothoff
+ * @author Marcello Stanisci
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <gnunet/gnunet_pq_lib.h>
+#include <taler/taler_pq_lib.h>
+#include "sync_database_plugin.h"
+#include "sync_database_lib.h"
+
+/**
+ * How often do we re-try if we run into a DB serialization error?
+ */
+#define MAX_RETRIES 3
+
+
+/**
+ * Type of the "cls" argument given to each of the functions in
+ * our API.
+ */
+struct PostgresClosure
+{
+
+  /**
+   * Postgres connection handle.
+   */
+  struct GNUNET_PQ_Context *conn;
+
+  /**
+   * Underlying configuration.
+   */
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  /**
+   * Name of the currently active transaction, NULL if none is active.
+   */
+  const char *transaction_name;
+
+};
+
+
+/**
+ * Drop sync tables
+ *
+ * @param cls closure our `struct Plugin`
+ * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
+ */
+static int
+postgres_drop_tables (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_try_execute ("DROP TABLE IF EXISTS backups;"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+  return GNUNET_PQ_exec_statements (pg->conn,
+                                    es);
+}
+
+
+/**
+ * Check that the database connection is still up.
+ *
+ * @param pg connection to check
+ */
+static void
+check_connection (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+  GNUNET_PQ_reconnect_if_down (pg->conn);
+}
+
+
+/**
+ * Do a pre-flight check that we are not in an uncommitted transaction.
+ * If we are, try to commit the previous transaction and output a warning.
+ * Does not return anything, as we will continue regardless of the outcome.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ */
+static void
+postgres_preflight (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_execute ("COMMIT"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  if (NULL == pg->transaction_name)
+    return; /* all good */
+  if (GNUNET_OK ==
+      GNUNET_PQ_exec_statements (pg->conn,
+                                 es))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "BUG: Preflight check committed transaction `%s'!\n",
+                pg->transaction_name);
+  }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "BUG: Preflight check failed to commit transaction `%s'!\n",
+                pg->transaction_name);
+  }
+  pg->transaction_name = NULL;
+}
+
+/**
+ * Start a transaction.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param name unique name identifying the transaction (for debugging),
+ *             must point to a constant
+ * @return #GNUNET_OK on success
+ */
+static int
+begin_transaction (void *cls,
+                   const char *name)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  check_connection (pg);
+  postgres_preflight (pg);
+  pg->transaction_name = name;
+  if (GNUNET_OK !=
+      GNUNET_PQ_exec_statements (pg->conn,
+                                 es))
+  {
+    TALER_LOG_ERROR ("Failed to start transaction\n");
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+/**
+* Roll back the current transaction of a database connection.
+*
+* @param cls the `struct PostgresClosure` with the plugin-specific state
+* @return #GNUNET_OK on success
+*/
+static void
+rollback (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    GNUNET_PQ_make_execute ("ROLLBACK"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+
+  if (GNUNET_OK !=
+      GNUNET_PQ_exec_statements (pg->conn,
+                                 es))
+  {
+    TALER_LOG_ERROR ("Failed to rollback transaction\n");
+    GNUNET_break (0);
+  }
+  pg->transaction_name = NULL;
+}
+
+/**
+ * Commit the current transaction of a database connection.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @return transaction status code
+ */
+
+static enum SYNC_DB_QueryStatus
+commit_transaction (void *cls)
+{
+  struct PostgresClosure *pg = cls;
+  enum SYNC_DB_QueryStatus qs;
+  struct GNUNET_PQ_QueryParam no_params[] = {
+    GNUNET_PQ_query_param_end
+  };
+
+  qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+                                           "do_commit",
+                                           no_params);
+  pg->transaction_name = NULL;
+  return qs;
+}
+
+
+
+/**
+ * Initialize Postgres database subsystem.
+ *
+ * @param cls a configuration instance
+ * @return NULL on error, otherwise a `struct TALER_SYNCDB_Plugin`
+ */
+void *
+libsync_plugin_db_postgres_init (void *cls)
+{
+  struct GNUNET_CONFIGURATION_Handle *cfg = cls;
+  struct PostgresClosure *pg;
+  struct SYNC_DatabasePlugin *plugin;
+  struct GNUNET_PQ_ExecuteStatement es[] = {
+    /* Orders created by the frontend, not signed or given a nonce yet.
+       The contract terms will change (nonce will be added) when moved to the
+       contract terms table */
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS backups"
+                            "("                            
+                            "data BYTEA NOT NULL,"
+                            ");"),
+    GNUNET_PQ_EXECUTE_STATEMENT_END
+  };
+  struct GNUNET_PQ_PreparedStatement ps[] = {
+    GNUNET_PQ_make_prepare ("backup_insert",
+                            "INSERT INTO backups "
+                            "(data"
+                            ") VALUES "
+                            "($1);",
+                            1),
+    GNUNET_PQ_make_prepare ("do_commit",
+                            "COMMIT",
+                            0),
+    GNUNET_PQ_PREPARED_STATEMENT_END
+  };
+
+  pg = GNUNET_new (struct PostgresClosure);
+  pg->cfg = cfg;
+  pg->conn = GNUNET_PQ_connect_with_cfg (cfg,
+                                         "syncdb-postgres",
+                                         es,
+                                         ps);
+  if (NULL == pg->conn)
+  {
+    GNUNET_free (pg);
+    return NULL;
+  }
+  plugin = GNUNET_new (struct SYNC_DatabasePlugin);
+  plugin->cls = pg;
+  plugin->drop_tables = &postgres_drop_tables;
+  plugin->preflight = &postgres_preflight;
+  plugin->rollback = &rollback;
+  plugin->commit = &commit_transaction;
+  return plugin;
+}
+
+
+/**
+ * Shutdown Postgres database subsystem.
+ *
+ * @param cls a `struct SYNC_DB_Plugin`
+ * @return NULL (always)
+ */
+void *
+libsync_plugin_db_postgres_done (void *cls)
+{
+  struct SYNC_DatabasePlugin *plugin = cls;
+  struct PostgresClosure *pg = plugin->cls;
+
+  GNUNET_PQ_disconnect (pg->conn);
+  GNUNET_free (pg);
+  GNUNET_free (plugin);
+  return NULL;
+}
+
+/* end of plugin_syncdb_postgres.c */
diff --git a/src/syncdb/sync_db_plugin.c b/src/syncdb/sync_db_plugin.c
new file mode 100644
index 0000000..6b2c6e0
--- /dev/null
+++ b/src/syncdb/sync_db_plugin.c
@@ -0,0 +1,149 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2015, 2016 GNUnet e.V. and INRIA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Lesser General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file merchantdb/merchantdb_plugin.c
+ * @brief Logic to load database plugin
+ * @author Christian Grothoff
+ * @author Sree Harsha Totakura <address@hidden>
+ */
+#include "platform.h"
+#include "anastasis_database_plugin.h"
+#include <ltdl.h>
+
+
+/**
+ * Initialize the plugin.
+ *
+ * @param cfg configuration to use
+ * @return #GNUNET_OK on success
+ */
+struct ANASTASIS_DatabasePlugin *
+ANASTASIS_DB_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+  char *plugin_name;
+  char *lib_name;
+  struct GNUNET_CONFIGURATION_Handle *cfg_dup;
+  struct ANASTASIS_DatabasePlugin *plugin;
+
+  if (GNUNET_SYSERR ==
+      GNUNET_CONFIGURATION_get_value_string (cfg,
+                                             "anastasis",
+                                             "db",
+                                             &plugin_name))
+  {
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+                               "anastasis",
+                               "db");
+    return NULL;
+  }
+  (void) GNUNET_asprintf (&lib_name,
+                          "libanastasis_plugin_db_%s",
+                          plugin_name);
+  GNUNET_free (plugin_name);
+  cfg_dup = GNUNET_CONFIGURATION_dup (cfg);
+  plugin = GNUNET_PLUGIN_load (lib_name, cfg_dup);
+  if (NULL != plugin)
+    plugin->library_name = lib_name;
+  else
+    GNUNET_free (lib_name);
+  GNUNET_CONFIGURATION_destroy (cfg_dup);
+  return plugin;
+}
+
+
+/**
+ * Shutdown the plugin.
+ *
+ * @param plugin the plugin to unload
+ */
+void
+ANASTASIS_DB_plugin_unload (struct ANASTASIS_DatabasePlugin *plugin)
+{
+  char *lib_name;
+
+  if (NULL == plugin)
+    return;
+  lib_name = plugin->library_name;
+  GNUNET_assert (NULL == GNUNET_PLUGIN_unload (lib_name,
+                                               plugin));
+  GNUNET_free (lib_name);
+}
+
+
+/**
+ * Libtool search path before we started.
+ */
+static char *old_dlsearchpath;
+
+
+/**
+ * Setup libtool paths.
+ */
+void __attribute__ ((constructor))
+plugin_init ()
+{
+  int err;
+  const char *opath;
+  char *path;
+  char *cpath;
+
+  err = lt_dlinit ();
+  if (err > 0)
+  {
+    fprintf (stderr,
+             _ ("Initialization of plugin mechanism failed: %s!\n"),
+             lt_dlerror ());
+    return;
+  }
+  opath = lt_dlgetsearchpath ();
+  if (NULL != opath)
+    old_dlsearchpath = GNUNET_strdup (opath);
+  path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR);
+  if (NULL != path)
+  {
+    if (NULL != opath)
+    {
+      GNUNET_asprintf (&cpath, "%s:%s", opath, path);
+      lt_dlsetsearchpath (cpath);
+      GNUNET_free (path);
+      GNUNET_free (cpath);
+    }
+    else
+    {
+      lt_dlsetsearchpath (path);
+      GNUNET_free (path);
+    }
+  }
+}
+
+
+/**
+ * Shutdown libtool.
+ */
+void __attribute__ ((destructor))
+plugin_fini ()
+{
+  lt_dlsetsearchpath (old_dlsearchpath);
+  if (NULL != old_dlsearchpath)
+  {
+    GNUNET_free (old_dlsearchpath);
+    old_dlsearchpath = NULL;
+  }
+  lt_dlexit ();
+}
+
+
+/* end of anastasis_db_plugin.c */
diff --git a/src/syncdb/sync_db_postgres.conf b/src/syncdb/sync_db_postgres.conf
new file mode 100644
index 0000000..0460bd2
--- /dev/null
+++ b/src/syncdb/sync_db_postgres.conf
@@ -0,0 +1,7 @@
+[anastasis]
+#The DB plugin to use
+DB = postgres
+
+[anastasisdb-postgres]
+#The connection string the plugin has to use for connecting to the database
+CONFIG = postgres:///anastasis
diff --git a/src/syncdb/test_sync_db.c b/src/syncdb/test_sync_db.c
new file mode 100644
index 0000000..e57a548
--- /dev/null
+++ b/src/syncdb/test_sync_db.c
@@ -0,0 +1,200 @@
+/*
+  This file is part of
+  (C) 2014-2017 INRIA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU Lesser General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file sync/test_sync_db.c
+ * @brief testcase for sync postgres db plugin
+ * @author Marcello Stanisci
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <taler/taler_util.h>
+#include "sync_database_plugin.h"
+#include "sync_database_lib.h"
+#include "sync_error_codes.h"
+#include <uuid/uuid.h>
+
+
+#define FAILIF(cond)                            \
+  do {                                          \
+    if (! (cond)) { break;}                       \
+    GNUNET_break (0);                           \
+    goto drop;                                     \
+  } while (0)
+
+#define RND_BLK(ptr)                                                    \
+  GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (*ptr))
+
+/**
+ * Global return value for the test.  Initially -1, set to 0 upon
+ * completion.   Other values indicate some kind of error.
+ */
+static int result;
+
+/**
+ * Handle to the plugin we are testing.
+ */
+static struct SYNC_DatabasePlugin *plugin;
+
+/**
+ * Payment Secret for the test, set to a random value
+ */
+static struct SYNC_PaymentSecretP paymentSecretP;
+
+/**
+ * User public key, set to a random value
+ */
+static struct SYNC_AccountPubP accountPubP;
+
+/**
+ * Amount which is deposited, set to random value
+ */
+static struct TALER_Amount amount;
+
+/**
+ * How many posts are paid by the payment
+ */
+static unsigned int post_counter;
+
+/**
+ * Recoverydata which is stored into the Database, set to a random value
+ */
+static void *recovery_data;
+
+/**
+ * Recovery_data for the select test
+ */
+static void *res_recovery_data;
+
+/**
+ * Truthdata which is stored into the Database, set to a random value
+ */
+static void *truth_data;
+
+/**
+ * Truth for the select test
+ */
+static void *truth;
+
+/**
+ * Keyshare which is stored into the Database, set to a random value
+ */
+static void *key_share;
+
+/**
+ * Keyshare for the select test
+ */
+static void *res_key_share;
+
+/**
+ * Mime-type of truth
+ */
+static char *mime_type;
+
+/**
+ * Mime-type of truth for the select test
+ */
+static char *res_mime_type;
+
+/**
+ * Version of a Recoverydocument
+ */
+static uint32_t version;
+
+/**
+ * Version of the latest Recoverydocument
+ */
+static uint32_t res_version;
+
+
+/**
+ * Main function that will be run by the scheduler.
+ *
+ * @param cls closure with config
+ */
+static void
+run (void *cls)
+{
+  struct GNUNET_CONFIGURATION_Handle *cfg = cls;
+
+  if (NULL == (plugin = SYNC_DB_plugin_load (cfg)))
+  {
+    result = 77;
+    return;
+  }
+  if (GNUNET_OK != plugin->drop_tables (plugin->cls))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Dropping tables failed\n");
+    result = 77;
+    return;
+  }
+  SYNC_DB_plugin_unload (plugin);
+  if (NULL == (plugin = SYNC_DB_plugin_load (cfg)))
+  {
+    result = 77;
+    return;
+  }
+
+  GNUNET_break (GNUNET_OK ==
+                plugin->drop_tables (plugin->cls));
+  SYNC_DB_plugin_unload (plugin);
+  plugin = NULL;
+}
+
+
+int
+main (int argc,
+      char *const argv[])
+{
+  const char *plugin_name;
+  char *config_filename;
+  char *testname;
+  struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  result = -1;
+  if (NULL == (plugin_name = strrchr (argv[0], (int) '-')))
+  {
+    GNUNET_break (0);
+    return -1;
+  }
+  GNUNET_log_setup (argv[0], "DEBUG", NULL);
+  plugin_name++;
+  (void) GNUNET_asprintf (&testname,
+                          "%s",
+                          plugin_name);
+  (void) GNUNET_asprintf (&config_filename,
+                          "test_sync_db_%s.conf",
+                          testname);
+  cfg = GNUNET_CONFIGURATION_create ();
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_parse (cfg,
+                                  config_filename))
+  {
+    GNUNET_break (0);
+    GNUNET_free (config_filename);
+    GNUNET_free (testname);
+    return 2;
+  }
+  GNUNET_SCHEDULER_run (&run, cfg);
+  GNUNET_CONFIGURATION_destroy (cfg);
+  GNUNET_free (config_filename);
+  GNUNET_free (testname);
+  return result;
+}
+
+/* end of test_sync_db.c */
diff --git a/src/syncdb/test_sync_db_postgres.conf 
b/src/syncdb/test_sync_db_postgres.conf
new file mode 100644
index 0000000..f91dea1
--- /dev/null
+++ b/src/syncdb/test_sync_db_postgres.conf
@@ -0,0 +1,7 @@
+[anastasis]
+#The DB plugin to use
+DB = postgres
+
+[anastasisdb-postgres]
+#The connection string the plugin has to use for connecting to the database
+CONFIG = postgres:///anastasischeck

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]